FirmwareUpload - Manouchehri/smi2021 GitHub Wiki
Summary
This is a summary of how the firmware upload is handled
Introduction
The firmware is sent from host to device when a device with USB ID: 1c88:0007 is plugged in to the computer.
More info here FirmwareDetails
Before we can upload the firmware, we have to send an Control Transfer to the device. This URB must have the following options:
- endpoint 0x80
- request type 0xc0 ( USB_DIR_IN | TYPE_VENDOR | USB_RECIP_DEVICE )
- request 0x01
- value 0x0001
- index 0x0000
- size 0x02
The device should reply with two bytes: 0x01 0x07 I'm not sure what these two bytes represent!
After this reply, the device is ready for the firmware upload. The firmware upload is done in successive Control Transfers with the following options:
- endpoint 0x00
- request type 0x40 (USB_DIR_OUT | TYPE_VENDOR | USB_RECIP_DEVICE)
- request 0x01
- value 0x0005
- index 0x0000
- data 2Byte Header, and 62 bytes of the firmware
- size 64
Every firmware part starts with the two byte header "0x05 0xff" The only firmware I've seen has been 7502 bytes long, and this splits evenly into 121 packages of 62 bytes.
The device will respond with a 0 after every package, and after the last package, we must send two bytes with the following options:
- endpoint 0x00
- request type 0x40 (USB_DIR_OUT | TYPE_VENDOR | USB_RECIP_DEVICE)
- request 0x01
- value 0x0007
- index 0x0000
- data 0x07 0x00
- size 2
I don't know what these two bytes represent either, but the data seems to be the same as the value field of the URB. In my implementation of a Linux driver, I store the two bytes we receive in the first request in an uint16_t. I then shift this value 8 bits to the left, and feed it back into both the value field and the data field of the final URB.
After this last URB is sent, the OS will detect an USB disconnect, and then a reconnect with a new USB ID (usually 1c88:003c, but this id is part of the firmware, and can easily be changed).
Details discovered during research
During my research into this, I've discovered the following:
- The value field of the URB is always equal to the first byte of the data field
- Requests for data seems to always be sent to endpoint 0x80, while upload of data goes to endpoint 0x00
- All URBs seems to have a request value of 0x01 and index value of 0