Compare commits
3 Commits
master
...
sysmoOCTSI
Author | SHA1 | Date |
---|---|---|
Kevin Redon | 5078232cce | |
Kevin Redon | 3a64538b32 | |
Kevin Redon | da201623c1 |
22
README.md
22
README.md
|
@ -1,8 +1,7 @@
|
|||
This is an implementation of the DFU mode of the [USB DFU Device Class Specification](https://usb.org/document-library/device-firmware-upgrade-11-new-version-31-aug-2004) for the Microchip SAM D5x/E5x micro-controller.
|
||||
It is meant to be used as bootloader to allow flashing the main application over USB.
|
||||
|
||||
The code has been developed for the Microchip [SAM E54 Xplained Pro](https://www.microchip.com/DevelopmentTools/ProductDetails/PartNo/ATSAME54-XPRO) development board using a [SAM E54](https://www.microchip.com/wwwproducts/en/ATSAME54P20A) micro-controller.
|
||||
It should work on any chip of the SAM D5x/E5x device family by replacing the corresponding device-specific definitions (usually including the chip name in the file name).
|
||||
This branch is specific to the proprietary sysmocom sysmoOCTSIM hardware.
|
||||
|
||||
The code uses the [Atmel START](https://start.atmel.com/) ASFv4 library.
|
||||
|
||||
|
@ -31,7 +30,7 @@ The resulting firmware binary is `AtmelStart.bin`.
|
|||
Flashing
|
||||
========
|
||||
|
||||
To flash the bootloader you can either use the [edbg tool](https://github.com/ataradov/edbg) over the EDBG interface of the SAM E54 Xplained Pro development board, or OpenICD with any SWJ adapter.
|
||||
To flash the bootloader you can use OpenOCD with any SWJ adapter.
|
||||
|
||||
The USB DFU bootloader should be flashed in a protected area of the flash memory to prevent for erasing it, as specified in data sheet section 25.6.2 Memory Organization.
|
||||
The bootloader size is configured in the NVM user configuration BOOTPROT field, as specified in data sheet section 25.6.9 NVM User Configuration.
|
||||
|
@ -40,11 +39,14 @@ We need to reserve as least 2 pages of 8192 bytes for the bootloader since it is
|
|||
This setting will also tell the bootloader where to flash the application firmware to (e.g. after the bootloader reserved space).
|
||||
The LED will blink once per second if this size is not set.
|
||||
|
||||
EDBG
|
||||
----
|
||||
ST-LINK/V2
|
||||
----------
|
||||
|
||||
To flash the USB DFU bootloader, perform the following actions:
|
||||
* remove reserved bootloader space so we can erase it: `edbg --target atmel_cm4v2 --fuse wv,29:26,15`
|
||||
* erase the whole flash: `edbg --target atmel_cm4v2 --fuse v,29:26,15 --erase`
|
||||
* program the bootloader: `edbg --target atmel_cm4v2 --fuse v,29:26,15 --program --verify --file AtmelStart.bin`
|
||||
* reserve bootloader space: `edbg --target atmel_cm4v2 --fuse wv,29:26,13`
|
||||
To flash the USB DFU bootloader, we will use OpenOCD (with the [SAM E54 patch](http://openocd.zylin.com/#/c/4272/) and a ST-LINK/V2 SWD adapter.
|
||||
The command will perform the following actions:
|
||||
* remove reserved bootloader space so we can erase it (and reset MCU for change to be effective)
|
||||
* erase the whole flash
|
||||
* program the bootloader
|
||||
* reserve bootloader space
|
||||
|
||||
`openocd --file interface/stlink.cfg --command "transport select hla_swd" --command "set CHIPNAME same54" --command "set CPUTAPID 0x2ba01477" --file target/atsame5x.cfg --command "init" --command "reset halt" --command "atsame5 bootloader 0" --command "flash erase_sector 0 0 last" --command "reset halt" --command "program ./AtmelStart.bin" --command "atsame5 bootloader 16384" --command "reset run" --command "shutdown"`
|
||||
|
|
|
@ -27,11 +27,11 @@
|
|||
#define GPIO_PIN_FUNCTION_M 12
|
||||
#define GPIO_PIN_FUNCTION_N 13
|
||||
|
||||
/** LED pin to indicate system state (pull low to switch on) */
|
||||
#define LED_SYSTEM GPIO(GPIO_PORTC, 18)
|
||||
/** LED pin to indicate system state (pull high to switch on) */
|
||||
#define LED_SYSTEM GPIO(GPIO_PORTC, 26)
|
||||
|
||||
/** User button to force DFu bootloader (connected to ground when pressed) */
|
||||
#define BUTTON_FORCE_DFU GPIO(GPIO_PORTB, 31)
|
||||
#define BUTTON_FORCE_DFU GPIO(GPIO_PORTC, 14)
|
||||
|
||||
/** USB D+/D- pins */
|
||||
#define PA24 GPIO(GPIO_PORTA, 24)
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
// <0x6140=> osmo-ASF4-DFU
|
||||
// <id> usb_dfud_idproduct
|
||||
#ifndef CONF_USB_OSMOASF4DFU_IDPRODUCT
|
||||
#define CONF_USB_OSMOASF4DFU_IDPRODUCT 0x6140
|
||||
#define CONF_USB_OSMOASF4DFU_IDPRODUCT 0x6141
|
||||
#endif
|
||||
|
||||
// <o> bcdDevice <0x0000-0xFFFF>
|
||||
|
@ -107,11 +107,11 @@
|
|||
// <s> Unicode string of iManufact
|
||||
// <id> usb_dfud_imanufact_str
|
||||
#ifndef CONF_USB_DFUD_IMANUFACT_STR
|
||||
#define CONF_USB_DFUD_IMANUFACT_STR "osmocom"
|
||||
#define CONF_USB_DFUD_IMANUFACT_STR "sysmocom"
|
||||
#endif
|
||||
|
||||
#ifndef CONF_USB_DFUD_IMANUFACT_STR_DESC
|
||||
#define CONF_USB_DFUD_IMANUFACT_STR_DESC 16, 0x03, 'o', 0x00, 's', 0x00, 'm', 0x00, 'o', 0x00, 'c', 0x00, 'o', 0x00, 'm', 0x00,
|
||||
#define CONF_USB_DFUD_IMANUFACT_STR_DESC 18, 0x03, 's', 0x00, 'y', 0x00, 's', 0x00, 'm', 0x00, 'o', 0x00, 'c', 0x00, 'o', 0x00, 'm', 0x00,
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
@ -130,11 +130,11 @@
|
|||
// <s> Unicode string of iProduct
|
||||
// <id> usb_dfud_iproduct_str
|
||||
#ifndef CONF_USB_DFUD_IPRODUCT_STR
|
||||
#define CONF_USB_DFUD_IPRODUCT_STR "osmo-ASF4-DFU"
|
||||
#define CONF_USB_DFUD_IPRODUCT_STR "sysmoOCTSIM (osmo-ASF4-DFU)"
|
||||
#endif
|
||||
|
||||
#ifndef CONF_USB_DFUD_IPRODUCT_STR_DESC
|
||||
#define CONF_USB_DFUD_IPRODUCT_STR_DESC 28, 0x03, 'o', 0x00, 's', 0x00, 'm', 0x00, 'o', 0x00, '-', 0x00, 'A', 0x00, 'S', 0x00, 'F', 0x00, '4', 0x00, '-', 0x00, 'D', 0x00, 'F', 0x00, 'U', 0x00,
|
||||
#define CONF_USB_DFUD_IPRODUCT_STR_DESC 56, 0x03, 's', 0x00, 'y', 0x00, 's', 0x00, 'm', 0x00, 'o', 0x00, 'O', 0x00, 'C', 0x00, 'T', 0x00, 'S', 0x00, 'I', 0x00, 'M', 0x00, ' ', 0x00, '(', 0x00, 'o', 0x00, 's', 0x00, 'm', 0x00, 'o', 0x00, '-', 0x00, 'A', 0x00, 'S', 0x00, 'F', 0x00, '4', 0x00, '-', 0x00, 'D', 0x00, 'F', 0x00, 'U', 0x00, ')', 0x00,
|
||||
#endif
|
||||
|
||||
// </e>
|
||||
|
|
|
@ -144,13 +144,12 @@ void system_init(void)
|
|||
init_mcu();
|
||||
|
||||
// configure system LED
|
||||
gpio_set_pin_level(LED_SYSTEM, true); // switch off LED
|
||||
gpio_set_pin_level(LED_SYSTEM, false); // switch off LED
|
||||
gpio_set_pin_direction(LED_SYSTEM, GPIO_DIRECTION_OUT);
|
||||
gpio_set_pin_function(LED_SYSTEM, GPIO_PIN_FUNCTION_OFF);
|
||||
|
||||
// configure force DFU user button
|
||||
gpio_set_pin_direction(BUTTON_FORCE_DFU, GPIO_DIRECTION_IN);
|
||||
gpio_set_pin_pull_mode(BUTTON_FORCE_DFU, GPIO_PULL_UP);
|
||||
gpio_set_pin_function(BUTTON_FORCE_DFU, GPIO_PIN_FUNCTION_OFF);
|
||||
|
||||
USB_DEVICE_INSTANCE_init();
|
||||
|
|
|
@ -48,8 +48,7 @@ static bool check_bootloader(void)
|
|||
*/
|
||||
static bool check_force_dfu(void)
|
||||
{
|
||||
gpio_set_pin_pull_mode(BUTTON_FORCE_DFU, GPIO_PULL_UP); // pull button high
|
||||
return (0 == gpio_get_pin_level(BUTTON_FORCE_DFU)); // signal is low when button is pressed
|
||||
return (0 == gpio_get_pin_level(BUTTON_FORCE_DFU)); // signal is low when button is pressed (pulled high externally)
|
||||
}
|
||||
|
||||
/** Check if the application is valid
|
||||
|
|
|
@ -80,7 +80,7 @@ static void usb_dfu_reset(const enum usb_event ev, const uint32_t param)
|
|||
void usb_dfu(void)
|
||||
{
|
||||
while (!dfudf_is_enabled()); // wait for DFU to be installed
|
||||
gpio_set_pin_level(LED_SYSTEM, false); // switch LED on to indicate USB DFU stack is ready
|
||||
gpio_set_pin_level(LED_SYSTEM, true); // switch LED on to indicate USB DFU stack is ready
|
||||
|
||||
ASSERT(hri_nvmctrl_read_STATUS_BOOTPROT_bf(FLASH_0.dev.hw) <= 15);
|
||||
uint32_t application_start_address = (15 - hri_nvmctrl_read_STATUS_BOOTPROT_bf(FLASH_0.dev.hw)) * 8192; // calculate bootloader size to know where we should write the application firmware
|
||||
|
@ -89,7 +89,7 @@ void usb_dfu(void)
|
|||
while (true) { // main DFU infinite loop
|
||||
// run the second part of the USB DFU state machine handling non-USB aspects
|
||||
if (USB_DFU_STATE_DFU_DNLOAD_SYNC == dfu_state || USB_DFU_STATE_DFU_DNBUSY == dfu_state) { // there is some data to be flashed
|
||||
gpio_set_pin_level(LED_SYSTEM, true); // switch LED off to indicate we are flashing
|
||||
gpio_set_pin_level(LED_SYSTEM, false); // switch LED off to indicate we are flashing
|
||||
if (dfu_download_length > 0) { // there is some data to be flashed
|
||||
int32_t rc = flash_write(&FLASH_0, application_start_address + dfu_download_offset, dfu_download_data, dfu_download_length); // write downloaded data chunk to flash
|
||||
if (ERR_NONE == rc) {
|
||||
|
@ -108,7 +108,7 @@ void usb_dfu(void)
|
|||
// this case should not happen, but it's not a critical error
|
||||
dfu_state = USB_DFU_STATE_DFU_DNLOAD_IDLE; // indicate flashing can continue
|
||||
}
|
||||
gpio_set_pin_level(LED_SYSTEM, false); // switch LED on to indicate USB DFU can resume
|
||||
gpio_set_pin_level(LED_SYSTEM, true); // switch LED on to indicate USB DFU can resume
|
||||
}
|
||||
if (USB_DFU_STATE_DFU_MANIFEST == dfu_state) { // we can start manifestation (finish flashing)
|
||||
// in theory every DFU files should have a suffix to with a CRC to check the data
|
||||
|
|
Loading…
Reference in New Issue