summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2020-07-01 15:24:39 +0700
committerGitHub <[email protected]>2020-07-01 15:24:39 +0700
commit0c9932440b794fbdc699df6f0601f6febddedfe5 (patch)
treefd4f1e774266d0fb71468adbeaff4818a26180fb
parentea67aee75be289245fba981a772481f46e20b382 (diff)
parent12a145b27db28a55cc99a89487bdd531bc5f950e (diff)
Merge pull request #452 from hathach/fix-dfu-rt
Fix dfu rt
-rw-r--r--examples/device/dfu_rt/src/main.c58
-rw-r--r--src/class/cdc/cdc_device.c2
-rw-r--r--src/class/dfu/dfu_rt_device.c29
3 files changed, 49 insertions, 40 deletions
diff --git a/examples/device/dfu_rt/src/main.c b/examples/device/dfu_rt/src/main.c
index 666d89649..029ff7312 100644
--- a/examples/device/dfu_rt/src/main.c
+++ b/examples/device/dfu_rt/src/main.c
@@ -23,6 +23,19 @@
*
*/
+/* After device is enumerated, run following command
+ *
+ * $ dfu-util -l
+ *
+ * It should be able to list our device as in Runtime mode. Then run
+ *
+ * $ dfu-util -e
+ *
+ * This will send DETTACH command to put device into bootloader. Since this example
+ * is minimal, it doesn't actually go into DFU mode but rather change the LED blinking
+ * pattern to fast rate as indicator.
+ */
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -41,9 +54,9 @@
* - 2500 ms : device is suspended
*/
enum {
- BLINK_DFU_MODE = 1000,
+ BLINK_DFU_MODE = 100,
BLINK_NOT_MOUNTED = 250,
- BLINK_MOUNTED = 0,
+ BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
};
@@ -104,48 +117,19 @@ void tud_dfu_rt_reboot_to_dfu(void)
blink_interval_ms = BLINK_DFU_MODE;
}
-
//--------------------------------------------------------------------+
// BLINKING TASK + Indicator pulse
//--------------------------------------------------------------------+
-
-volatile uint8_t doPulse = false;
-// called from USB context
-void led_indicator_pulse(void) {
- doPulse = true;
-}
-
void led_blinking_task(void)
{
static uint32_t start_ms = 0;
static bool led_state = false;
- if(blink_interval_ms == BLINK_MOUNTED) // Mounted
- {
- if(doPulse)
- {
- led_state = true;
- board_led_write(true);
- start_ms = board_millis();
- doPulse = false;
- }
- else if (led_state == true)
- {
- if ( board_millis() - start_ms < 750) //Spec says blink must be between 500 and 1000 ms.
- {
- return; // not enough time
- }
- led_state = false;
- board_led_write(false);
- }
- }
- else
- {
- // Blink every interval ms
- if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
- start_ms += blink_interval_ms;
- board_led_write(led_state);
- led_state = 1 - led_state; // toggle
- }
+ // Blink every interval ms
+ if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
+ start_ms += blink_interval_ms;
+
+ board_led_write(led_state);
+ led_state = 1 - led_state; // toggle
}
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c
index 9180065c4..4d6e57878 100644
--- a/src/class/cdc/cdc_device.c
+++ b/src/class/cdc/cdc_device.c
@@ -364,7 +364,7 @@ bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request
tud_control_status(rhport, request);
// Invoke callback
- if ( tud_cdc_line_state_cb) tud_cdc_line_state_cb(itf, dtr, rts);
+ if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts);
}
break;
diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c
index 01d4e3490..d4c3ecb62 100644
--- a/src/class/dfu/dfu_rt_device.c
+++ b/src/class/dfu/dfu_rt_device.c
@@ -44,6 +44,14 @@ typedef enum {
DFU_REQUEST_ABORT = 6,
} dfu_requests_t;
+typedef struct TU_ATTR_PACKED
+{
+ uint8_t status;
+ uint8_t poll_timeout[3];
+ uint8_t state;
+ uint8_t istring;
+} dfu_status_t;
+
//--------------------------------------------------------------------+
// USBD Driver API
//--------------------------------------------------------------------+
@@ -88,10 +96,19 @@ bool dfu_rtd_control_complete(uint8_t rhport, tusb_control_request_t const * req
bool dfu_rtd_control_request(uint8_t rhport, tusb_control_request_t const * request)
{
- // Handle class request only
- TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE);
+ // dfu-util will try to claim the interface with SET_INTERFACE request before sending DFU request
+ if ( TUSB_REQ_TYPE_STANDARD == request->bmRequestType_bit.type &&
+ TUSB_REQ_SET_INTERFACE == request->bRequest )
+ {
+ tud_control_status(rhport, request);
+ return true;
+ }
+
+ // Handle class request only from here
+ TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
+
switch ( request->bRequest )
{
case DFU_REQUEST_DETACH:
@@ -99,6 +116,14 @@ bool dfu_rtd_control_request(uint8_t rhport, tusb_control_request_t const * requ
tud_dfu_rt_reboot_to_dfu();
break;
+ case DFU_REQUEST_GETSTATUS:
+ {
+ // status = OK, poll timeout = 0, state = app idle, istring = 0
+ uint8_t status_response[6] = { 0, 0, 0, 0, 0, 0 };
+ tud_control_xfer(rhport, request, status_response, sizeof(status_response));
+ }
+ break;
+
default: return false; // stall unsupported request
}