aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-02-28 00:21:45 +0100
committerHarald Welte <laforge@gnumonks.org>2017-02-28 01:10:23 +0100
commit32852bc1d90cd7e27264509c19db47dedd9fac19 (patch)
tree34a22b98fce3617434f3fd46e3e524625f9a1c65
parentedf9c9d32215a044124af229c498502a7a32f389 (diff)
DFU: towards a more complete implementation
* we now actually route the EP0 control requests in DFU mode to the correct handler (weak linker symbols are tricky) * we now actually call code to read/write data from/to RAM/FLASH
-rw-r--r--firmware/apps/dfu/main.c98
-rw-r--r--firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c10
-rw-r--r--firmware/atmel_softpack_libraries/usb/device/dfu/dfu_runtime.c6
-rw-r--r--firmware/libboard/common/include/board_common.h1
-rw-r--r--firmware/libcommon/source/usb.c6
5 files changed, 108 insertions, 13 deletions
diff --git a/firmware/apps/dfu/main.c b/firmware/apps/dfu/main.c
index 9b2facf..af595ac 100644
--- a/firmware/apps/dfu/main.c
+++ b/firmware/apps/dfu/main.c
@@ -4,19 +4,105 @@
#include "usb/common/dfu/usb_dfu.h"
#include "manifest.h"
+#define ALTIF_RAM 0
+#define ALTIF_FLASH 1
+
unsigned int g_unique_id[4];
/*----------------------------------------------------------------------------
* Callbacks
*----------------------------------------------------------------------------*/
-#if 0
-void USBDDriverCallbacks_ConfigurationChanged(uint8_t cfgnum)
+#define RAM_ADDR(offset) (IRAM_ADDR + BOARD_DFU_RAM_SIZE + offset)
+#define FLASH_ADDR(offset) (IFLASH_ADDR + BOARD_DFU_BOOT_SIZE + offset)
+
+#define IFLASH_END ((uint8_t *)IFLASH_ADDR + IFLASH_SIZE)
+#define IRAM_END ((uint8_t *)IRAM_ADDR + IRAM_SIZE)
+
+/* incoming call-back: Host has transfered 'len' bytes (stored at
+ * 'data'), which we shall write to 'offset' into the partition
+ * associated with 'altif'. Guaranted to be les than
+ * BOARD_DFU_PAGE_SIZE */
+int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
+ uint8_t *data, unsigned int len)
{
- TRACE_INFO_WP("cfgChanged%d ", cfgnum);
- simtrace_config = cfgnum;
+ uint32_t addr;
+ int rc;
+
+ printf("dnload(altif=%u, offset=%u, len=%u\n\r", altif, offset, len);
+
+ switch (altif) {
+ case ALTIF_RAM:
+ addr = RAM_ADDR(offset);
+ if (addr > IRAM_ADDR + IRAM_SIZE) {
+ g_dfu.state = DFU_STATE_dfuERROR;
+ g_dfu.status = DFU_STATUS_errADDRESS;
+ return DFU_RET_STALL;
+ }
+ memcpy((void *)addr, data, len);
+ return DFU_RET_ZLP;
+ case ALTIF_FLASH:
+ addr = FLASH_ADDR(offset);
+ if (addr > IFLASH_ADDR + IFLASH_SIZE) {
+ g_dfu.state = DFU_STATE_dfuERROR;
+ g_dfu.status = DFU_STATUS_errADDRESS;
+ return DFU_RET_STALL;
+ }
+ rc = FLASHD_Write(addr, data, len);
+ if (rc != 0) {
+ /* FIXME: set error codes */
+ return DFU_RET_STALL;
+ }
+ return DFU_RET_ZLP;
+ default:
+ /* FIXME: set error codes */
+ TRACE_ERROR("DFU download for unknown AltIf %d\n\r", altif);
+ return DFU_RET_STALL;
+ }
}
-#endif
+
+/* incoming call-back: Host has requested to read back 'req_len' bytes
+ * starting from 'offset' of the firmware * associated with partition
+ * 'altif' */
+int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
+ uint8_t *data, unsigned int req_len)
+{
+ uint32_t addr;
+
+ printf("upload(altif=%u, offset=%u, len=%u)", altif, offset, req_len);
+
+ switch (altif) {
+ case ALTIF_RAM:
+ addr = RAM_ADDR(offset);
+ if (addr > IRAM_ADDR + IRAM_SIZE) {
+ g_dfu.state = DFU_STATE_dfuERROR;
+ g_dfu.status = DFU_STATUS_errADDRESS;
+ return -1;
+ }
+ if ((uint8_t *)addr + req_len > IRAM_END)
+ req_len = IRAM_END - (uint8_t *)addr;
+ memcpy(data, (void *)addr, req_len);
+ break;
+ case ALTIF_FLASH:
+ addr = FLASH_ADDR(offset);
+ if (addr > IFLASH_ADDR + IFLASH_SIZE) {
+ g_dfu.state = DFU_STATE_dfuERROR;
+ g_dfu.status = DFU_STATUS_errADDRESS;
+ return -1;
+ }
+ if ((uint8_t *)addr + req_len > IFLASH_END)
+ req_len = IFLASH_END - (uint8_t *)addr;
+ memcpy(data, (void *)addr, req_len);
+ break;
+ default:
+ TRACE_ERROR("DFU upload for unknown AltIf %d\n\r", altif);
+ /* FIXME: set error codes */
+ return -1;
+ }
+ printf("=%u\r\n", req_len);
+ return req_len;
+}
+
/* returns '1' in case we should break any endless loop */
static void check_exec_dbg_cmd(void)
@@ -70,7 +156,7 @@ extern int main(void)
while (USBD_GetState() < USBD_STATE_CONFIGURED) {
check_exec_dbg_cmd();
-#if 0
+#if 1
if (i >= MAX_USB_ITER * 3) {
TRACE_ERROR("Resetting board (USB could "
"not be configured)\r\n");
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 217ec09..08fda6d 100644
--- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
+++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c
@@ -438,15 +438,18 @@ out:
}
}
+/* we assume the caller has enabled the required clock/PLL for USB */
void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors)
{
/* We already start in DFU idle mode */
g_dfu.state = DFU_STATE_dfuIDLE;
USBDDriver_Initialize(&usbdDriver, pDescriptors, if_altsettings);
-
USBD_Init();
+ USBD_Connect();
//USBD_ConfigureSpeed(1);
+
+ NVIC_EnableIRQ(UDP_IRQn);
}
void USBDFU_SwitchToApp(void)
@@ -464,3 +467,8 @@ void USBDFU_SwitchToApp(void)
//BootIntoApp();
NVIC_SystemReset();
}
+
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ USBDFU_DFU_RequestHandler(request);
+}
diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_runtime.c b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_runtime.c
index 0102650..3bf7aa5 100644
--- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_runtime.c
+++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_runtime.c
@@ -187,3 +187,9 @@ void DFURT_SwitchToDFU(void)
toDFU();
}
+
+void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
+{
+ /* FIXME: integration with CCID control point reqeusts */
+ USBDFU_Runtime_RequestHandler(request);
+}
diff --git a/firmware/libboard/common/include/board_common.h b/firmware/libboard/common/include/board_common.h
index 9943ae1..9a7c8d8 100644
--- a/firmware/libboard/common/include/board_common.h
+++ b/firmware/libboard/common/include/board_common.h
@@ -113,6 +113,7 @@
#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
diff --git a/firmware/libcommon/source/usb.c b/firmware/libcommon/source/usb.c
index 66f1de8..1d37914 100644
--- a/firmware/libcommon/source/usb.c
+++ b/firmware/libcommon/source/usb.c
@@ -821,9 +821,3 @@ void SIMtrace_USB_Initialize(void)
NVIC_EnableIRQ(UDP_IRQn);
}
-
-void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
-{
- /* FIXME: integration with CCID control point reqeusts */
- USBDFU_Runtime_RequestHandler(request);
-}