New firmware dfu issues


#1

running a 3.4-24v board, I’ve edited tup.config and used the stlinkv2 to reflash the new fw.

lsusb -v returns

bill@bill-VirtualBox:~/ODrive/Firmware$ lsusb -v

Bus 001 Device 021: ID 1209:0d33 InterBiometrics 
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            2 Communications
  bDeviceSubClass         2 Abstract (modem)
  bDeviceProtocol         0 None
  bMaxPacketSize0        64
  idVendor           0x1209 InterBiometrics
  idProduct          0x0d33

(I can paste the full output if necessary)

per your instructions running “(lsusb -d 1209:0d32 -v; lsusb -d 0483:df11 -v) | grep iSerial” returns nothing, but I get this querying dev 0d33

(lsusb -d 1209:0d33 -v; lsusb -d 0483:df11 -v) | grep iSerial
Couldn't open device, some information will be missing
  iSerial                 3 

make dfu returns error

bill@bill-VirtualBox:~/ODrive/Firmware$ make dfu
../tools/dfu.py  build/ODriveFirmware.hex
  File "../tools/dfu.py", line 19
    print = functools.partial(print, flush=True)
          ^
SyntaxError: invalid syntax
Makefile:19: recipe for target 'dfu' failed
make: *** [dfu] Error 1

Please let me know if you have suggestions. Thanks!

I notice util .py does not show a usb dev id for hw 3.4

USB_DEV_ODRIVE_3_1 = (0x1209, 0x0D31)
USB_DEV_ODRIVE_3_2 = (0x1209, 0x0D32)
USB_DEV_ODRIVE_3_3 = (0x1209, 0x0D33)

#2

It looks like dfu.py is executed with python2 instead of python3.

To verify and fix this you can do the following:

  1. Run python3 --version to confirm that you have Python 3 installed. (On the off chance that it is not, you need to install it)
  2. Run python --version to check if your default python is 2 or 3.
  3. If the output was Python 2.[...] we found the root cause. To fix it you can change the very first line in dfu.py from #!/usr/bin/env python to #!/usr/bin/env python3 or #!/usr/bin/python3.

Let me know if this fixes it so I can push the change.

About the USB PID: You’re right, there is some inconsistency. Actually the PID 0x0D32 is the only official PID so the Firmware currently announces the wrong PID. The Python tools work fine with the current (wrong) PID, so the practlcal issue is just that the instructions don’t match the firmware (as you already noticed).
I’ll push a fix and add a “Known Issues” section to the release notes.

Edit: I just noticed that the lsusb output you pasted doesn’t actually include the serial number. Does this problem persist when you power cycle the device or unplug/replug it or reboot your VM or PC? Could you ever successfully connect to the device using explore_odrive.py from inside the VM?


#3

That helped. Making progress!

I added #!/usr/bin/env python3 to line 1 of dfu.py.

Next I had to install IntelHex (which required me to install python3-pip first)

Make DFU successfully puts the STM into bootloader mode, but when that happens the new USB device connects to my host machine. I have to use virtual box menu to attach the new stm32 bootloader device.

after playing with it for a bit, attaching the stm32 in bootloader mode usb device, and running make dfu as root, it seems to work

sudo was required, otherwise I got “usb.core.USBError: [Errno 13] Access denied (insufficient permissions)
Makefile:19: recipe for target ‘dfu’ failed”

bill@bill-VirtualBox:~/ODrive/Firmware$ sudo make dfu
../tools/dfu.py  build/ODriveFirmware.hex
Waiting for ODrive...
Found device 306639663235 in DFU mode
Sectors to be flashed: 
 08000000 to 08003FFF
 08004000 to 08007FFF
 08008000 to 0800BFFF
 0800C000 to 0800FFFF
 08010000 to 0801FFFF
Erasing... done            
Flashing... done  

Great, I’m in interactive mode in explore_odrive now and can read the odrive bus voltage. Going to try to spin up the motors now.


#4

Ok cool!

Does explore_odrive.py work without sudo?
If that one works without sudo you have set up the udev rules correctly and the access issue only pretains to the device in DFU mode.
This would make sense because in DFU mode the ODrive has a different VID and PID because it runs baked-in STM code. For some reason on my system I did not have to add udev permission rules for this VID:PID pair but I actually don’t know why not.

So maybe this helps: open /etc/udev/rules.d/50-odrive.rules and append this line:

SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", MODE="0666"

Regarding the header fix, unfortunately it turns out that this breaks make dfu on Windows, so I can’t push it upstream just yet. On the upside once the ODrive tools are distributed via PyPi (pip install ...) I think this problem will just go away magically (apparently the pip installer applies exactly this header fix).


#5

Ok, added that extra line to my odrive.rules.

I had run those 3 commands to setup udev rules before, and I actually still have to run “sudo udevadm trigger” each time I connect to the udrive, even after rebooting my machine.

I’ve never had to sudo explore_odrive.py. The only issue with it is that if I exit, I have to power cycle the board before I can connect again or I get this error. Is there a proper way to exit explore_odrive so I can reattach without power cycling the board?

bill@bill-VirtualBox:~/ODrive/tools$ python3 explore_odrive.py
Waiting for device…
Traceback (most recent call last):
File “/home/bill/ODrive/tools/odrive/usbbulk_transport.py”, line 96, in get_packet
ret = self.epr.read(bufferLen, timeout)
File “/usr/lib/python3/dist-packages/usb/core.py”, line 364, in read
return self.device.read(self, size_or_buffer, timeout)
File “/usr/lib/python3/dist-packages/usb/core.py”, line 918, in read
self.__get_timeout(timeout))
File “/usr/lib/python3/dist-packages/usb/backend/libusb1.py”, line 769, in bulk_read
timeout)
File “/usr/lib/python3/dist-packages/usb/backend/libusb1.py”, line 872, in __read
_check(retval)
File “/usr/lib/python3/dist-packages/usb/backend/libusb1.py”, line 552, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “explore_odrive.py”, line 96, in
my_odrive = odrive.core.find_any(consider_usb, consider_serial, printer=printer)
File “/home/bill/ODrive/tools/odrive/core.py”, line 317, in find_any
dev = next(find_all(consider_usb, consider_serial, printer=printer, **kwargs), None)
File “/home/bill/ODrive/tools/odrive/core.py”, line 300, in find_all
yield object_from_channel(channel, printer)
File “/home/bill/ODrive/tools/odrive/core.py”, line 224, in object_from_channel
json_bytes = channel.remote_endpoint_read_buffer(0)
File “/home/bill/ODrive/tools/odrive/protocol.py”, line 280, in remote_endpoint_read_buffer
chunk = self.remote_endpoint_operation(endpoint_id, struct.pack("<I", len(buffer)), True, chunk_length)
File “/home/bill/ODrive/tools/odrive/protocol.py”, line 254, in remote_endpoint_operation
response = self._input.get_packet(deadline)
File “/home/bill/ODrive/tools/odrive/usbbulk_transport.py”, line 104, in get_packet
ret = self.epr.read(bufferLen, timeout)
File “/usr/lib/python3/dist-packages/usb/core.py”, line 364, in read
return self.device.read(self, size_or_buffer, timeout)
File “/usr/lib/python3/dist-packages/usb/core.py”, line 918, in read
self.__get_timeout(timeout))
File “/usr/lib/python3/dist-packages/usb/backend/libusb1.py”, line 769, in bulk_read
timeout)
File “/usr/lib/python3/dist-packages/usb/backend/libusb1.py”, line 872, in __read
_check(retval)
File “/usr/lib/python3/dist-packages/usb/backend/libusb1.py”, line 552, in _check
raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out


#6

Restarting the python tool should theoretically not require a board power cycle but that being said the USB connection is known to behave funky sometimes. So far it’s been kinda hard to track down the exact issue. I did not yet observe that particular failure mode you’re seeing.

There’s a feature branch sam_python_fixes where I added some measures that supposedly robustify the connection, for instance by resetting the USB device if there are connection errors.

If want to try that version you can by now install it via pip:

$ sudo pip3 install odrive --pre   # note the --pre, this is a developer prerelease
$ odrivetool
ODrive control utility v0.4
Please connect your ODrive.
Type help() for help.

Connected to ODrive 385F324D3037 as odrv0
In [1]: odrv0.vbus_voltage
Out[1]: 12.108325004577637

In [2]: 

edit: changed odrvtool to odrivetool


#7

should be odrivetool instead of odrvtool?


#8

Yes, it was renamed after I wrote that comment. I updated the comment in case someone else runs across it.