reset device when USB CDC ACM data with is set to 5 bits, to restart DFU bootloader
This commit is contained in:
parent
f7d0b5610c
commit
57f3b45f83
|
@ -24,6 +24,7 @@
|
|||
#include <libopencm3/stm32/rcc.h> // real-time control clock library
|
||||
#include <libopencm3/stm32/gpio.h> // general purpose input output library
|
||||
#include <libopencm3/cm3/nvic.h> // interrupt handler
|
||||
#include <libopencm3/cm3/scb.h> // reset utilities
|
||||
#include <libopencmsis/core_cm3.h> // Cortex M3 utilities
|
||||
#include <libopencm3/usb/usbd.h> // USB library
|
||||
#include <libopencm3/usb/cdc.h> // USB CDC library
|
||||
|
@ -206,28 +207,30 @@ static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *
|
|||
switch (req->bRequest) {
|
||||
case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
|
||||
/*
|
||||
* This Linux cdc_acm driver requires this to be implemented
|
||||
bool dtr = (req->wValue & (1 << 0)) ? true : false;
|
||||
bool rts = (req->wValue & (1 << 1)) ? true : false;
|
||||
*/
|
||||
/* this Linux cdc_acm driver requires this to be implemented
|
||||
* even though it's optional in the CDC spec, and we don't
|
||||
* advertise it in the ACM functional descriptor.
|
||||
*/
|
||||
char local_buf[10];
|
||||
struct usb_cdc_notification *notif = (void *)local_buf;
|
||||
|
||||
/* we echo signals back to host as notification. */
|
||||
notif->bmRequestType = 0xA1;
|
||||
notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
|
||||
notif->wValue = 0;
|
||||
notif->wIndex = 0;
|
||||
notif->wLength = 2;
|
||||
local_buf[8] = req->wValue & 3;
|
||||
local_buf[9] = 0;
|
||||
usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10);
|
||||
return 1;
|
||||
}
|
||||
case USB_CDC_REQ_SET_LINE_CODING:
|
||||
// ignore if length is wrong
|
||||
if (*len < sizeof(struct usb_cdc_line_coding)) {
|
||||
return 0;
|
||||
}
|
||||
// get the line coding
|
||||
struct usb_cdc_line_coding *coding = (struct usb_cdc_line_coding *)*buf;
|
||||
/* reset device is the data bits is set to 5
|
||||
* this is used to allowing rebooting the device in DFU mode for reflashing
|
||||
* to reset the device from the host you can use stty --file /dev/ttyACM0 115200 raw cs5
|
||||
*/
|
||||
if (coding->bDataBits==5) {
|
||||
scb_reset_system(); // reset device
|
||||
while (true); // wait for the reset to happen
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -273,7 +276,6 @@ static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep)
|
|||
uint8_t transmitted = usbd_ep_write_packet(usb_device, 0x82, usb_data, usb_length); // try to transmit data
|
||||
tx_i = (tx_i+transmitted)%sizeof(rx_buffer); // update location on buffer
|
||||
tx_used -= transmitted; // update used size
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue