Change in osmo-asf4-dfu[master]: implement flashing-side of the DFU state machine

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Kévin Redon gerrit-no-reply at lists.osmocom.org
Wed Jan 9 15:05:18 UTC 2019


Kévin Redon has uploaded this change for review. ( https://gerrit.osmocom.org/12508


Change subject: implement flashing-side of the DFU state machine
......................................................................

implement flashing-side of the DFU state machine

the USB-side state machine currently sets the length to 0,
preventing the actual flashing to be tested

Change-Id: I5ed9cc2a22ed5e41bb59a3ce3f21ab098cec48e7
---
M usb_start.c
1 file changed, 69 insertions(+), 17 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-asf4-dfu refs/changes/08/12508/1

diff --git a/usb_start.c b/usb_start.c
index d911db4..0ce8aba 100644
--- a/usb_start.c
+++ b/usb_start.c
@@ -45,15 +45,20 @@
 /** Ctrl endpoint buffer */
 static uint8_t ctrl_buffer[64];
 
+/** Application address in the flash
+ (
+ *  It comes after the bootloader.
+ *  The NVMCTRL allows to reserve space at the beginning of the flash for the bootloader, but only in multiples of 8192 bytes.
+ *  The binary just with the USB stack already uses 8 kB, we reserve 16 kB for the bootloader (giving use a bit of margin for future fixes).
+ */
+#define APPLICATION_ADDR (8192*2)
+
 /**
  * \brief USB DFU Init
  */
 void usb_dfu_init(void)
 {
-	/* usb stack init */
 	usbdc_init(ctrl_buffer);
-
-	/* usbdc_register_funcion inside */
 	dfudf_init();
 
 	usbdc_start(single_desc);
@@ -61,27 +66,74 @@
 }
 
 /**
- * Example of using CDC ACM Function.
- * \note
- * In this example, we will use a PC as a USB host:
- * - Connect the DEBUG USB on XPLAINED board to PC for program download.
- * - Connect the TARGET USB on XPLAINED board to PC for running program.
- * The application will behave as a virtual COM.
- * - Open a HyperTerminal or other COM tools in PC side.
- * - Send out a character or string and it will echo the content received.
+ * \brief reset device
+ */
+static void usb_dfu_reset(const enum usb_event ev, const uint32_t param)
+{
+	(void)param; // not used
+	switch (ev) {
+	case USB_EV_RESET:
+		usbdc_detach(); // make sure we are detached
+		NVIC_SystemReset(); // initiate a system reset
+		break;
+	default:
+		break;
+	}
+	
+}
+
+/**
+ * \brief Enter USB DFU runtime
  */
 void usb_dfu(void)
 {
-	while (!dfudf_is_enabled()) {
-		// wait DFU to be installed
-	};
-
-	while (1) {
+	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
+	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
+			if (dfu_download_length > 0) { // there is some data to be flashed
+				int32_t rc = flash_write(&FLASH_0, APPLICATION_ADDR + dfu_download_progress, dfu_download_data, dfu_download_length); // write downloaded data chunk to flash
+				if (ERR_NONE == rc) {
+					dfu_state = USB_DFU_STATE_DFU_DNLOAD_IDLE; // indicate flashing this block has been completed
+				} else { // there has been a programming error
+					dfu_state = USB_DFU_STATE_DFU_ERROR;
+					if (ERR_BAD_ADDRESS == rc) {
+						dfu_status = USB_DFU_STATUS_ERR_ADDRESS;
+					} else if (ERR_DENIED == rc) {
+						dfu_status = USB_DFU_STATUS_ERR_WRITE;
+					} else {
+						dfu_status = USB_DFU_STATUS_ERR_PROG;
+					}
+				}
+			} else { // there was no data to flash
+				// 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
+		}
+		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
+			// in practice most downloaded files are just the raw binary with DFU suffix
+			dfu_manifestation_complete = true; // we completed flashing and all checks
+			if (usb_dfu_func_desc->bmAttributes & USB_DFU_ATTRIBUTES_MANIFEST_TOLERANT) {
+				dfu_state = USB_DFU_STATE_DFU_MANIFEST_SYNC;
+			} else {
+				dfu_state = USB_DFU_STATE_DFU_MANIFEST_WAIT_RESET;
+			}
+		}
+		if (USB_DFU_STATE_DFU_MANIFEST_WAIT_RESET == dfu_state) {
+			if (usb_dfu_func_desc->bmAttributes & USB_DFU_ATTRIBUTES_WILL_DETACH) {
+				usb_dfu_reset(USB_EV_RESET, 0); // immediately reset
+			} else { // wait for USB reset
+				usb_d_register_callback(USB_D_CB_EVENT, (FUNC_PTR)usb_dfu_reset); // register new USB reset event handler
+			}
+		}
 	}
 }
 
 void usb_init(void)
 {
-
 	usb_dfu_init();
 }

-- 
To view, visit https://gerrit.osmocom.org/12508
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-asf4-dfu
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5ed9cc2a22ed5e41bb59a3ce3f21ab098cec48e7
Gerrit-Change-Number: 12508
Gerrit-PatchSet: 1
Gerrit-Owner: Kévin Redon <kredon at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190109/c5a3e3f3/attachment.htm>


More information about the gerrit-log mailing list