Merge pull request #452 from hathach/fix-dfu-rt

Fix dfu rt
This commit is contained in:
Ha Thach 2020-07-01 15:24:39 +07:00 committed by GitHub
commit 0c9932440b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 40 deletions

View File

@ -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
}

View File

@ -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;

View File

@ -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
}