aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--firmware/Makefile2
-rw-r--r--firmware/apps/dfu/main.c35
-rw-r--r--firmware/apps/dfu/usb_strings.txt1
-rw-r--r--firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c13
-rw-r--r--firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h3
-rw-r--r--firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c29
-rw-r--r--firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c17
-rw-r--r--firmware/libboard/common/include/board_common.h5
-rw-r--r--firmware/libboard/common/source/board_cstartup_gnu.c7
9 files changed, 92 insertions, 20 deletions
diff --git a/firmware/Makefile b/firmware/Makefile
index 5c7aa92..bdca6e5 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -41,7 +41,7 @@ APP ?= dfu
# Defines which are the available memory targets for the SAM3S-EK board.
ifeq ($(APP), dfu)
-MEMORIES ?= flash
+MEMORIES ?= flash dfu
else
MEMORIES ?= dfu
endif
diff --git a/firmware/apps/dfu/main.c b/firmware/apps/dfu/main.c
index 5aafc7c..2e80884 100644
--- a/firmware/apps/dfu/main.c
+++ b/firmware/apps/dfu/main.c
@@ -26,8 +26,15 @@
#include <osmocom/core/timer.h>
+/* USB alternate interface index used to identify which partition to flash */
+/** USB alternate interface index indicating RAM partition */
#define ALTIF_RAM 0
+/** USB alternate interface index indicating flash partition */
+#if defined(ENVIRONMENT_flash)
#define ALTIF_FLASH 1
+#elif defined(ENVIRONMENT_dfu)
+#define ALTIF_FLASH 2
+#endif
unsigned int g_unique_id[4];
/* remember if the watchdog has been configured in the main loop so we can kick it in the ISR */
@@ -44,10 +51,18 @@ static const Pin pinsLeds[] = { PINS_LEDS } ;
*----------------------------------------------------------------------------*/
#define RAM_ADDR(offset) (IRAM_ADDR + BOARD_DFU_RAM_SIZE + offset)
+#if defined(ENVIRONMENT_flash)
#define FLASH_ADDR(offset) (IFLASH_ADDR + BOARD_DFU_BOOT_SIZE + offset)
+#elif defined(ENVIRONMENT_dfu)
+#define FLASH_ADDR(offset) (IFLASH_ADDR + offset)
+#endif
-#define IFLASH_END ((uint8_t *)IFLASH_ADDR + IFLASH_SIZE)
-#define IRAM_END ((uint8_t *)IRAM_ADDR + IRAM_SIZE)
+#define IRAM_END ((uint8_t *)IRAM_ADDR + IRAM_SIZE)
+#if defined(ENVIRONMENT_flash)
+#define IFLASH_END ((uint8_t *)IFLASH_ADDR + IFLASH_SIZE)
+#elif defined(ENVIRONMENT_dfu)
+#define IFLASH_END ((uint8_t *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE)
+#endif
/* incoming call-back: Host has transferred 'len' bytes (stored at
* 'data'), which we shall write to 'offset' into the partition
@@ -90,7 +105,11 @@ int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
break;
case ALTIF_FLASH:
addr = FLASH_ADDR(offset);
+#if defined(ENVIRONMENT_flash)
if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + IFLASH_SIZE) {
+#elif defined(ENVIRONMENT_dfu)
+ if (addr < IFLASH_ADDR || addr + len >= IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
+#endif
g_dfu->state = DFU_STATE_dfuERROR;
g_dfu->status = DFU_STATUS_errADDRESS;
rc = DFU_RET_STALL;
@@ -281,12 +300,12 @@ extern int main(void)
TRACE_INFO("DFU bootloader start reason: ");
switch (USBDFU_OverrideEnterDFU()) {
case 0:
- /* 0 normally means that there is no override, but we are in the bootloader,
- * thus the first check in board_cstartup_gnu did return something else than 0.
- * this can only be g_dfu->magic which is erased when the segment are
- * relocated, which happens in board_cstartup_gnu just after USBDFU_OverrideEnterDFU.
- * no static variable can be used to store this case since this will also be overwritten
- */
+ if (SCB->VTOR < IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
+ TRACE_INFO_WP("unknown\n\r");
+ } else {
+ TRACE_INFO_WP("DFU is the main application\n\r");
+ }
+ break;
case 1:
TRACE_INFO_WP("DFU switch requested by main application\n\r");
break;
diff --git a/firmware/apps/dfu/usb_strings.txt b/firmware/apps/dfu/usb_strings.txt
index f1c79bc..4a58cb8 100644
--- a/firmware/apps/dfu/usb_strings.txt
+++ b/firmware/apps/dfu/usb_strings.txt
@@ -3,3 +3,4 @@ PRODUCT_STRING
DFU (Device Firmware Upgrade)
RAM
Flash (Application Partition)
+Flash (Bootloader Partition)
diff --git a/firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c b/firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
index ac2595c..1ebab5b 100644
--- a/firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
+++ b/firmware/atmel_softpack_libraries/libchip_sam3s/source/USBD_HAL.c
@@ -1171,12 +1171,19 @@ void USBD_IrqHandler(void)
/* if we are currently in the DFU bootloader, and we are beyond
* the MANIFEST stage, we shall switch to the normal
* application */
- if (g_dfu->past_manifest)
+ if (g_dfu->past_manifest) {
+#if defined(ENVIRONMENT_flash)
USBDFU_SwitchToApp();
+#elif defined(ENVIRONMENT_dfu)
+ USBDFU_SwitchToDFU();
+#endif
+ }
+
#else
/* if we are currently in the main application, and we are in
- * appDETACH state, switch into the DFU bootloader */
- if (g_dfu->state == DFU_STATE_appDETACH)
+ * appDETACH state or past downloading, switch into the DFU bootloader.
+ */
+ if (g_dfu->state == DFU_STATE_appDETACH || g_dfu->state == DFU_STATE_dfuMANIFEST)
DFURT_SwitchToDFU();
#endif /* APPLICATION_dfu */
#endif /* BOARD_USB_DFU */
diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
index 7354696..5bd8684 100644
--- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
+++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
@@ -124,6 +124,9 @@ void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors);
/* USBD tells us to switch from DFU mode to application mode */
void USBDFU_SwitchToApp(void);
+/* USBD tells us to switch from to DFU mode */
+void USBDFU_SwitchToDFU(void);
+
/* Return values to be used by USBDFU_handle_{dn,up}load */
#define DFU_RET_NOTHING 0
#define DFU_RET_ZLP 1
diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
index ebbe070..faebc13 100644
--- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
+++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c
@@ -19,9 +19,10 @@ enum {
STR_MANUF = 1,
STR_PROD,
STR_CONFIG,
+ // strings for the first alternate interface (e.g. DFU)
_STR_FIRST_ALT,
// serial string
- STR_SERIAL = (_STR_FIRST_ALT+BOARD_DFU_NUM_IF),
+ STR_SERIAL = (_STR_FIRST_ALT + BOARD_DFU_NUM_IF),
// version string (on additional interface)
VERSION_CONF_STR,
VERSION_STR,
@@ -29,6 +30,25 @@ enum {
STRING_DESC_CNT,
};
+/* string used to replace one of both DFU flash partition atlsettings */
+static const unsigned char usb_string_notavailable[] = {
+ USBStringDescriptor_LENGTH(13),
+ USBGenericDescriptor_STRING,
+ USBStringDescriptor_UNICODE('n'),
+ USBStringDescriptor_UNICODE('o'),
+ USBStringDescriptor_UNICODE('t'),
+ USBStringDescriptor_UNICODE(' '),
+ USBStringDescriptor_UNICODE('a'),
+ USBStringDescriptor_UNICODE('v'),
+ USBStringDescriptor_UNICODE('a'),
+ USBStringDescriptor_UNICODE('i'),
+ USBStringDescriptor_UNICODE('l'),
+ USBStringDescriptor_UNICODE('a'),
+ USBStringDescriptor_UNICODE('b'),
+ USBStringDescriptor_UNICODE('l'),
+ USBStringDescriptor_UNICODE('e'),
+};
+
/* USB string for the serial (using 128-bit device ID) */
static unsigned char usb_string_serial[] = {
USBStringDescriptor_LENGTH(32),
@@ -121,7 +141,7 @@ static const USBDeviceDescriptor fsDevice = {
.bNumEndpoints = 0, \
.bInterfaceClass = 0xfe, \
.bInterfaceSubClass = 1, \
- .iInterface = (_STR_FIRST_ALT+ALT), \
+ .iInterface = (_STR_FIRST_ALT + ALT), \
.bInterfaceProtocol = 2, \
}
@@ -180,6 +200,11 @@ void set_usb_serial_str(void)
for (i = 0; i < ARRAY_SIZE(usb_strings) && i < ARRAY_SIZE(usb_strings_extended); i++) {
usb_strings_extended[i] = usb_strings[i];
}
+#if defined(ENVIRONMENT_dfu)
+ usb_strings_extended[_STR_FIRST_ALT + 1] = usb_string_notavailable;
+#elif defined(ENVIRONMENT_flash)
+ usb_strings_extended[_STR_FIRST_ALT + 2] = usb_string_notavailable;
+#endif
usb_strings_extended[STR_SERIAL] = usb_string_serial;
usb_strings_extended[VERSION_CONF_STR] = usb_string_version_conf;
usb_strings_extended[VERSION_STR] = usb_string_version;
diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
index 1cca7ab..cfb9f63 100644
--- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
+++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
@@ -43,7 +43,7 @@ static unsigned char if_altsettings[1];
/** structure containing the DFU state and magic value to know if DFU or application should be started */
__dfudata struct dfudata _g_dfu = {
- .state = DFU_STATE_appIDLE,
+ .state = DFU_STATE_dfuIDLE,
.past_manifest = 0,
.total_bytes = 0,
};
@@ -463,7 +463,20 @@ void USBDFU_SwitchToApp(void)
/* make sure the MAGIC is not set to enter DFU again */
g_dfu->magic = 0;
- printf("switching to app\r\n");
+ /* disconnect from USB to ensure re-enumeration */
+ USBD_Disconnect();
+
+ /* disable any interrupts during transition */
+ __disable_irq();
+
+ /* Tell the hybrid to execute FTL JUMP! */
+ NVIC_SystemReset();
+}
+
+void USBDFU_SwitchToDFU(void)
+{
+ /* make sure the MAGIC is not set to enter DFU again */
+ g_dfu->magic = USB_DFU_MAGIC;
/* disconnect from USB to ensure re-enumeration */
USBD_Disconnect();
diff --git a/firmware/libboard/common/include/board_common.h b/firmware/libboard/common/include/board_common.h
index dd21e4b..7c4b908 100644
--- a/firmware/libboard/common/include/board_common.h
+++ b/firmware/libboard/common/include/board_common.h
@@ -112,10 +112,13 @@
#define BOARD_USB_UDP
#define BOARD_USB_DFU
+
+
#define BOARD_DFU_BOOT_SIZE (16 * 1024)
#define BOARD_DFU_RAM_SIZE (2 * 1024)
#define BOARD_DFU_PAGE_SIZE 512
-#define BOARD_DFU_NUM_IF 2
+/** number of DFU interfaces (used to flash specific partitions) */
+#define BOARD_DFU_NUM_IF 3
extern void board_exec_dbg_cmd(int ch);
extern void board_main_top(void);
diff --git a/firmware/libboard/common/source/board_cstartup_gnu.c b/firmware/libboard/common/source/board_cstartup_gnu.c
index e82a2fb..d548a30 100644
--- a/firmware/libboard/common/source/board_cstartup_gnu.c
+++ b/firmware/libboard/common/source/board_cstartup_gnu.c
@@ -126,7 +126,7 @@ IntFunc exception_table[] = {
IrqHandlerNotUsed /* 35 not used */
};
-#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
+#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu) && defined(ENVIRONMENT_flash)
#include "usb/device/dfu/dfu.h"
static void BootIntoApp(void)
{
@@ -159,8 +159,9 @@ void ResetException( void )
LowLevelInit() ;
-#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu)
- if (!USBDFU_OverrideEnterDFU()) {
+#if defined(BOARD_USB_DFU) && defined(APPLICATION_dfu) && defined(ENVIRONMENT_flash)
+ // boot application if there is not DFU override
+ if (!USBDFU_OverrideEnterDFU() && SCB->VTOR < IFLASH_ADDR + BOARD_DFU_BOOT_SIZE) {
UART_Exit();
__disable_irq();
BootIntoApp();