- CDC: the way responding on the notification element changed
This commit is contained in:
parent
4df8912593
commit
a9d0e99d7b
145
class/cdc.c
145
class/cdc.c
@ -11,7 +11,7 @@
|
||||
#include <cmsis_gcc.h>
|
||||
|
||||
// state
|
||||
static USB_CdcState cdcs = { 0 };
|
||||
static USB_CdcState cdcs = {0};
|
||||
static uint8_t tx_buffer[USB_CDC_PCKT_BUFSIZE];
|
||||
|
||||
#define USB_CDC_FIFO_MEM_SIZE (3072) // FIXME: ez vagy a blocking FIFO bugos
|
||||
@ -19,7 +19,7 @@ static uint8_t tx_buffer[USB_CDC_PCKT_BUFSIZE];
|
||||
static uint8_t fifo_mem[USB_CDC_FIFO_MEM_SIZE];
|
||||
static BFifo fifo;
|
||||
|
||||
void usb_cdc_read_callback(const uint8_t * data, uint32_t size);
|
||||
void usb_cdc_read_callback(const uint8_t *data, uint32_t size);
|
||||
|
||||
void usb_cdc_init(const USB_CdcAssignments *as) {
|
||||
// clear the structure
|
||||
@ -38,81 +38,88 @@ void usb_cdc_init(const USB_CdcAssignments *as) {
|
||||
// initialize buffer
|
||||
bfifo_create(&fifo, fifo_mem, USB_CDC_FIFO_MEM_SIZE);
|
||||
|
||||
// initialize an all-0 interrupt
|
||||
cdcs.interrupt_data = 0;
|
||||
cdcs.interrupt_pending = true;
|
||||
|
||||
// from now on CDC is considered initialized
|
||||
cdcs.initialized = true;
|
||||
}
|
||||
|
||||
//static uint8_t replyBuf[sizeof(USB_Cdc_LineCodingStruct)];
|
||||
// static uint8_t replyBuf[sizeof(USB_Cdc_LineCodingStruct)];
|
||||
|
||||
int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
|
||||
int ret = -1;
|
||||
switch (cbevt->type) {
|
||||
case USB_CBEVT_UNKNOWN_REQ: {
|
||||
switch (cbevt->setup_request->bRequest) {
|
||||
case USB_CDC_SET_LINE_CODING: // set line coding
|
||||
memcpy(&cdcs.line_coding, cbevt->data, sizeof(USB_Cdc_LineCodingStruct));
|
||||
//MSG("%u\n", cdcs.line_coding.dwDTERate);
|
||||
ret = 0;
|
||||
break;
|
||||
case USB_CDC_GET_LINE_CODING: // get line coding
|
||||
cbevt->reply_data = (const uint8_t *) &cdcs.line_coding; // expert move: pass the pointer, no copying
|
||||
cbevt->reply_size = sizeof(USB_Cdc_LineCodingStruct);
|
||||
cbevt->reply_valid = true; // the reply has been set to something valid
|
||||
ret = 0;
|
||||
break;
|
||||
case USB_CDC_SEND_BREAK: // send break
|
||||
// do nothing
|
||||
ret = 0;
|
||||
break;
|
||||
case USB_CDC_SET_CONTROL_LINE_STATE: // set control line state
|
||||
memcpy(&cdcs.control_line_state, cbevt->data, sizeof(USB_Cdc_ControlLineStateStruct));
|
||||
//MSG("%u\n", cdcs.control_line_state.D);
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// send a ZLP reply
|
||||
if (ret != -1) {
|
||||
cbevt->reply_data = NULL;
|
||||
cbevt->reply_size = 0;
|
||||
cbevt->reply_valid = true;
|
||||
}
|
||||
|
||||
case USB_CBEVT_UNKNOWN_REQ: {
|
||||
switch (cbevt->setup_request->bRequest) {
|
||||
case USB_CDC_SET_LINE_CODING: // set line coding
|
||||
memcpy(&cdcs.line_coding, cbevt->data, sizeof(USB_Cdc_LineCodingStruct));
|
||||
// MSG("%u\n", cdcs.line_coding.dwDTERate);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_CBEVT_OUT: {
|
||||
if (cbevt->ep == cdcs.ep_assignments.data_ep) {
|
||||
//MSG("%c\n", cbevt->data[0]);
|
||||
ret = 0;
|
||||
|
||||
usb_cdc_read_callback(cbevt->data, cbevt->size);
|
||||
//usbcore_schedule_transmission(cdcs.ep_assignments.data_ep, cbevt->data, cbevt->size); // echo
|
||||
}
|
||||
case USB_CDC_GET_LINE_CODING: // get line coding
|
||||
cbevt->reply_data = (const uint8_t *)&cdcs.line_coding; // expert move: pass the pointer, no copying
|
||||
cbevt->reply_size = sizeof(USB_Cdc_LineCodingStruct);
|
||||
cbevt->reply_valid = true; // the reply has been set to something valid
|
||||
ret = 0;
|
||||
break;
|
||||
case USB_CDC_SEND_BREAK: // send break
|
||||
// do nothing
|
||||
ret = 0;
|
||||
break;
|
||||
case USB_CDC_SET_CONTROL_LINE_STATE: // set control line state
|
||||
memcpy(&cdcs.control_line_state, cbevt->data, sizeof(USB_Cdc_ControlLineStateStruct));
|
||||
// MSG("%u\n", cdcs.control_line_state.D);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_CBEVT_IN: {
|
||||
if (cbevt->ep == cdcs.ep_assignments.control_ep) { // if notification feeding is requested
|
||||
usbcore_schedule_transmission(cdcs.ep_assignments.control_ep, NULL, 0); // send ZLP
|
||||
ret = 0;
|
||||
} else if (cbevt->ep == cdcs.ep_assignments.data_ep) { // if data are requested
|
||||
//usbcore_schedule_transmission(cdcs.ep_assignments.data_ep, NULL, 0); // send ZLP
|
||||
ret = 0;
|
||||
|
||||
// read from the fifo
|
||||
uint32_t readSize = bfifo_read(&fifo, tx_buffer, USB_CDC_PCKT_BUFSIZE);
|
||||
if (readSize > 0) {
|
||||
uint32_t writeSize = usbcore_schedule_transmission(cdcs.ep_assignments.data_ep, tx_buffer, readSize); // write data acquired from the buffer
|
||||
bfifo_pop(&fifo, writeSize, 0); // pop with no blocking
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// send a ZLP reply
|
||||
if (ret != -1) {
|
||||
cbevt->reply_data = NULL;
|
||||
cbevt->reply_size = 0;
|
||||
cbevt->reply_valid = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_CBEVT_OUT: {
|
||||
if (cbevt->ep == cdcs.ep_assignments.data_ep) {
|
||||
// MSG("%c\n", cbevt->data[0]);
|
||||
ret = 0;
|
||||
|
||||
usb_cdc_read_callback(cbevt->data, cbevt->size);
|
||||
// usbcore_schedule_transmission(cdcs.ep_assignments.data_ep, cbevt->data, cbevt->size); // echo
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_CBEVT_IN: {
|
||||
if (cbevt->ep == cdcs.ep_assignments.control_ep) { // if notification feeding is requested
|
||||
if (cdcs.interrupt_pending) {
|
||||
usbcore_schedule_transmission(cdcs.ep_assignments.control_ep, (const uint8_t *)&(cdcs.interrupt_data), sizeof(uint16_t)); // send ZLP
|
||||
cdcs.interrupt_pending = false;
|
||||
}
|
||||
ret = 0;
|
||||
} else if (cbevt->ep == cdcs.ep_assignments.data_ep) { // if data are requested
|
||||
// usbcore_schedule_transmission(cdcs.ep_assignments.data_ep, NULL, 0); // send ZLP
|
||||
ret = 0;
|
||||
|
||||
// read from the fifo
|
||||
uint32_t readSize = bfifo_read(&fifo, tx_buffer, USB_CDC_PCKT_BUFSIZE);
|
||||
if (readSize > 0) {
|
||||
uint32_t writeSize = usbcore_schedule_transmission(cdcs.ep_assignments.data_ep, tx_buffer, readSize); // write data acquired from the buffer
|
||||
bfifo_pop(&fifo, writeSize, 0); // pop with no blocking
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -122,14 +129,14 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
|
||||
// usb_cdc_process_and_return(cbevt);
|
||||
// }
|
||||
|
||||
void usb_cdc_write(const uint8_t * data, uint32_t size) {
|
||||
void usb_cdc_write(const uint8_t *data, uint32_t size) {
|
||||
if (cdcs.initialized) {
|
||||
bfifo_push_all(&fifo, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void usb_cdc_read_callback(const uint8_t * data, uint32_t size) {
|
||||
(void) data;
|
||||
(void) size;
|
||||
__attribute__((weak)) void usb_cdc_read_callback(const uint8_t *data, uint32_t size) {
|
||||
(void)data;
|
||||
(void)size;
|
||||
return;
|
||||
}
|
@ -50,6 +50,8 @@ typedef struct {
|
||||
USB_CdcAssignments ep_assignments; // endpoint assignments
|
||||
USB_Cdc_LineCodingStruct line_coding; // line coding
|
||||
USB_Cdc_ControlLineStateStruct control_line_state; // control line state
|
||||
uint16_t interrupt_data; // data sent though the next transfer on the notification element
|
||||
bool interrupt_pending; // interrupt data is valid and should be send in the next cycle
|
||||
bool initialized; // CDC is initialized
|
||||
} USB_CdcState;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user