From a9d0e99d7b9f1fd06be1291d3126ca405105d135 Mon Sep 17 00:00:00 2001 From: Epagris Date: Thu, 11 Jul 2024 08:05:29 +0200 Subject: [PATCH] - CDC: the way responding on the notification element changed --- class/cdc.c | 145 +++++++++++++++++++++++++++------------------------- class/cdc.h | 2 + 2 files changed, 78 insertions(+), 69 deletions(-) diff --git a/class/cdc.c b/class/cdc.c index b4a8346..c7d2927 100644 --- a/class/cdc.c +++ b/class/cdc.c @@ -11,7 +11,7 @@ #include // 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; } \ No newline at end of file diff --git a/class/cdc.h b/class/cdc.h index 82f71df..4abbb28 100644 --- a/class/cdc.h +++ b/class/cdc.h @@ -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;