From d140d7c183937dfed7799b55e2f1444c70de680d Mon Sep 17 00:00:00 2001 From: Epagris Date: Tue, 25 Jun 2024 07:17:29 +0200 Subject: [PATCH 1/3] - EEM class indented --- class/eem.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/class/eem.c b/class/eem.c index 03af74c..f666d83 100644 --- a/class/eem.c +++ b/class/eem.c @@ -83,7 +83,7 @@ int usb_eem_process_and_return(USB_CallbackEvent *cbevt) { bfifo_push(&(eems.netbFifo), cbevt->data, cbevt->size); // store portion of netbound packet usb_eem_push_event(EEM_EVT_NETBOUND_PCKT_RECEIVED); // push notification - if (bfifo_get_free(&eems.netbFifo) < EEM_PCKT_SIZE) { // don't autoarm if OUT no more packets can be stored + if (bfifo_get_free(&eems.netbFifo) < EEM_PCKT_SIZE) { // don't autoarm if OUT no more packets can be stored eems.netbAutoArm = false; cbevt->arm_out_endpoint = false; } @@ -91,23 +91,23 @@ int usb_eem_process_and_return(USB_CallbackEvent *cbevt) { break; case USB_CBEVT_IN: - if (cbevt->ep == eems.data_ep) { // verify endpoint number - if ((eems.hostbFrame != NULL) && (eems.hostbFrameIndex < eems.hostbFrameLength)) { // if there's something in the FIFO - uint8_t *readPtr = ((uint8_t *)eems.hostbFrame) + eems.hostbFrameIndex; // calculate read pointer - uint16_t bytesLeft = eems.hostbFrameLength - eems.hostbFrameIndex; // calculate bytes left - uint32_t writeSize = usbcore_schedule_transmission(eems.data_ep, readPtr, bytesLeft); // attempt to schedule transmission - - //bool enableZLP = (bytesLeft < EEM_TRANSFER_UNIT) && ((bytesLeft % EEM_PCKT_SIZE) == 0); // ZLP transmission should be enabled if this was the last write and transfer size is integer multiple of the USB packet size - //cbevt->enable_autozlp = enableZLP; + if (cbevt->ep == eems.data_ep) { // verify endpoint number + if ((eems.hostbFrame != NULL) && (eems.hostbFrameIndex < eems.hostbFrameLength)) { // if there's something in the FIFO + uint8_t *readPtr = ((uint8_t *)eems.hostbFrame) + eems.hostbFrameIndex; // calculate read pointer + uint16_t bytesLeft = eems.hostbFrameLength - eems.hostbFrameIndex; // calculate bytes left + uint32_t writeSize = usbcore_schedule_transmission(eems.data_ep, readPtr, bytesLeft); // attempt to schedule transmission + + // bool enableZLP = (bytesLeft < EEM_TRANSFER_UNIT) && ((bytesLeft % EEM_PCKT_SIZE) == 0); // ZLP transmission should be enabled if this was the last write and transfer size is integer multiple of the USB packet size + // cbevt->enable_autozlp = enableZLP; eems.hostbFrameIndex += writeSize; // advance frame index - //MSG("U: %u T: %u\n", writeSize, bytesLeft); + // MSG("U: %u T: %u\n", writeSize, bytesLeft); // if (eems.hostbFrameIndex >= eems.hostbFrameLength) { // MSG("---\n"); // } - } else { // no data is waiting for transmission - //usbcore_schedule_transmission(eems.data_ep, NULL, 0); // send ZLP + } else { // no data is waiting for transmission + // usbcore_schedule_transmission(eems.data_ep, NULL, 0); // send ZLP } // if FIFO is empty or flushed, then send notification @@ -241,7 +241,7 @@ void usb_eem_process_hostbound() { } // invalidate frame - USB_EemFrame * oldEemFrame = eems.hostbFrame; + USB_EemFrame *oldEemFrame = eems.hostbFrame; eems.hostbFrame = NULL; // release frame @@ -300,6 +300,10 @@ void usb_eem_ethernet_intercept_cb(EthInterface *intf, const RawPckt *rawPckt) { } void usb_eem_set_intf(EthInterface *intf) { + if (!eems.initialized) { + return; + } + eems.intf = intf; // store interface ethinf_set_intercept_callback(intf, usb_eem_ethernet_intercept_cb); // set intercept callback } From 4df891259399a9b7e1ff4143ac40568966f7c2ae Mon Sep 17 00:00:00 2001 From: Epagris Date: Tue, 25 Jun 2024 08:09:54 +0200 Subject: [PATCH 2/3] - InaboF407 working code --- usb_driver.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/usb_driver.c b/usb_driver.c index c8f75e7..16c6024 100644 --- a/usb_driver.c +++ b/usb_driver.c @@ -132,6 +132,9 @@ void usbdrv_init_global_state() { #endif } +// --------------- + + #if defined(USB_STM32H7) #define TOCAL_VALUE (0x00) #define TRDT_VALUE (0x05) @@ -382,11 +385,10 @@ void usbdrv_initial_ep0_setup() { // addresses of specific DIEPTXF registers, addresses from the RM static uint32_t *USB_pDIEPTXF[4] = { - (uint32_t *)(USBG + 0x028), // DIEPTXF0 - (uint32_t *)(USBG + 0x104), // DIEPTXF1 - (uint32_t *)(USBG + 0x108), // DIEPTXF2 - (uint32_t *)(USBG + 0x10C), // DIEPTXF3 - // TODO: HS USB controller has more endpoints + (uint32_t *)(((uint32_t)USBG) + 0x028), // DIEPTXF0 + (uint32_t *)(((uint32_t)USBG) + 0x104), // DIEPTXF1 + (uint32_t *)(((uint32_t)USBG) + 0x108), // DIEPTXF2 + (uint32_t *)(((uint32_t)USBG) + 0x10C), // DIEPTXF3 }; // configure USB endpoint @@ -641,7 +643,7 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) { // arm OUT endpoint uint32_t usbdrv_arm_OUT_endpoint(uint8_t ep, uint8_t size) { - // arm endpoint only if it was not armed before OR if it's the EP0 OUT which is always enabled, but responds NAK after a successful transfer + // arm endpoint only if it was not armed before if (READ_BIT(USBOUTEP[ep].DOEPCTL, USB_OTG_DOEPCTL_EPENA)) { return 0; } From a9d0e99d7b9f1fd06be1291d3126ca405105d135 Mon Sep 17 00:00:00 2001 From: Epagris Date: Thu, 11 Jul 2024 08:05:29 +0200 Subject: [PATCH 3/3] - 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;