- CDC class OS-managed blocking buffer added; - some low-level USB function signatures have been changed

This commit is contained in:
Wiesner András 2024-04-10 23:21:03 +02:00
parent 93a0ff53e6
commit 627e038dbb
6 changed files with 187 additions and 162 deletions

View File

@ -6,9 +6,16 @@
#include "../usb.h" #include "../usb.h"
#include <blocking_io/blocking_fifo.h>
// state // state
static USB_CdcState cdcs; static USB_CdcState cdcs = { 0 };
static uint8_t cdc_buffer[USB_CDC_BUFSIZE]; static uint8_t tx_buffer[USB_CDC_PCKT_BUFSIZE];
#define USB_CDC_FIFO_MEM_SIZE (2048)
static uint8_t fifo_mem[USB_CDC_FIFO_MEM_SIZE];
static BFifo fifo;
void usb_cdc_init(const USB_CdcAssignments *as) { void usb_cdc_init(const USB_CdcAssignments *as) {
// clear the structure // clear the structure
@ -24,10 +31,11 @@ void usb_cdc_init(const USB_CdcAssignments *as) {
// fill-in assigments // fill-in assigments
cdcs.ep_assignments = *as; cdcs.ep_assignments = *as;
// assign buffer pointer // initialize buffer
USB_CdcBuffer * buf = &cdcs.buffer; bfifo_create(&fifo, fifo_mem, USB_CDC_FIFO_MEM_SIZE);
buf->p = cdc_buffer;
buf->size = USB_CDC_BUFSIZE; // from now on CDC is considered initialized
cdcs.initialized = true;
} }
int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) { int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
@ -37,12 +45,12 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
switch (cbevt->setup_request->bRequest) { switch (cbevt->setup_request->bRequest) {
case USB_CDC_SET_LINE_CODING: // set line coding case USB_CDC_SET_LINE_CODING: // set line coding
memcpy(&cdcs.line_coding, cbevt->data, sizeof(USB_Cdc_LineCodingStruct)); memcpy(&cdcs.line_coding, cbevt->data, sizeof(USB_Cdc_LineCodingStruct));
MSG("%u\n", cdcs.line_coding.dwDTERate); //MSG("%u\n", cdcs.line_coding.dwDTERate);
ret = 0; ret = 0;
break; break;
case USB_CDC_SET_CONTROL_LINE_STATE: // set control line state case USB_CDC_SET_CONTROL_LINE_STATE: // set control line state
memcpy(&cdcs.control_line_state, cbevt->data, sizeof(USB_Cdc_ControlLineStateStruct)); memcpy(&cdcs.control_line_state, cbevt->data, sizeof(USB_Cdc_ControlLineStateStruct));
MSG("%u\n", cdcs.control_line_state.D); //MSG("%u\n", cdcs.control_line_state.D);
ret = 0; ret = 0;
break; break;
default: default:
@ -63,6 +71,7 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
if (cbevt->ep == cdcs.ep_assignments.data_ep) { if (cbevt->ep == cdcs.ep_assignments.data_ep) {
//MSG("%c\n", cbevt->data[0]); //MSG("%c\n", cbevt->data[0]);
ret = 0; ret = 0;
usbcore_write(cdcs.ep_assignments.data_ep, cbevt->data, cbevt->size); // echo usbcore_write(cdcs.ep_assignments.data_ep, cbevt->data, cbevt->size); // echo
} }
break; break;
@ -75,7 +84,13 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
} else if (cbevt->ep == cdcs.ep_assignments.data_ep) { // if data are requested } else if (cbevt->ep == cdcs.ep_assignments.data_ep) { // if data are requested
//usbcore_write(cdcs.ep_assignments.data_ep, NULL, 0); // send ZLP //usbcore_write(cdcs.ep_assignments.data_ep, NULL, 0); // send ZLP
ret = 0; ret = 0;
// TODO!!
// read from the fifo
uint32_t readSize = bfifo_read(&fifo, tx_buffer, USB_CDC_PCKT_BUFSIZE);
if (readSize > 0) {
uint32_t writeSize = usbcore_write(cdcs.ep_assignments.data_ep, tx_buffer, readSize); // write data acquired from the buffer
bfifo_pop(&fifo, writeSize, 0); // pop with no blocking
}
} }
} }
@ -86,6 +101,12 @@ int usb_cdc_process_and_return(USB_CallbackEvent *cbevt) {
return ret; return ret;
} }
void usb_event_callback(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);
}
} }

View File

@ -46,17 +46,11 @@ typedef struct {
uint8_t data_ep : 4; // data endpoint uint8_t data_ep : 4; // data endpoint
} USB_CdcAssignments; } USB_CdcAssignments;
typedef struct {
uint32_t size;
uint8_t * p;
uint8_t read_idx, write_idx;
} USB_CdcBuffer;
typedef struct { typedef struct {
USB_CdcAssignments ep_assignments; // endpoint assignments USB_CdcAssignments ep_assignments; // endpoint assignments
USB_CdcBuffer buffer; // buffer
USB_Cdc_LineCodingStruct line_coding; // line coding USB_Cdc_LineCodingStruct line_coding; // line coding
USB_Cdc_ControlLineStateStruct control_line_state; // control line state USB_Cdc_ControlLineStateStruct control_line_state; // control line state
bool initialized; // CDC is initialized
} USB_CdcState; } USB_CdcState;
// ---------------- // ----------------
@ -68,11 +62,12 @@ typedef struct {
// ---------------- // ----------------
#define USB_CDC_BUFSIZE (256) #define USB_CDC_PCKT_BUFSIZE (120)
// ---------------- // ----------------
void usb_cdc_init(const USB_CdcAssignments * as); void usb_cdc_init(const USB_CdcAssignments * as);
int usb_cdc_process_and_return(USB_CallbackEvent * cbevt); int usb_cdc_process_and_return(USB_CallbackEvent * cbevt);
void usb_cdc_write(const uint8_t * data, uint32_t size);
#endif /* CORE_USB_CLASS_CDC */ #endif /* CORE_USB_CLASS_CDC */

4
usb.c
View File

@ -222,6 +222,6 @@ void usbcore_process_nonsetup_event(USBDRV_CallbackCompound *cbcpd) {
} }
} }
void usbcore_write(uint8_t ep, const uint8_t *data, uint16_t size) { uint32_t usbcore_write(uint8_t ep, const uint8_t *data, uint16_t size) {
usbdrv_arm_IN_endpoint(ep, data, size); return usbdrv_arm_IN_endpoint(ep, data, size);
} }

2
usb.h
View File

@ -4,6 +4,6 @@
#include "usb_callback_event.h" #include "usb_callback_event.h"
void usbcore_init(); // initialize USB core void usbcore_init(); // initialize USB core
void usbcore_write(uint8_t ep, const uint8_t *data, uint16_t size); // write data to endpoint uint32_t usbcore_write(uint8_t ep, const uint8_t *data, uint16_t size); // write data to endpoint, return with number of bytes actually written
#endif /* CORE_USB_USB */ #endif /* CORE_USB_USB */

View File

@ -82,6 +82,7 @@ void usbdrv_init() {
usbdrv_initial_ep0_setup(); usbdrv_initial_ep0_setup();
usbdrv_power_and_connect(true); usbdrv_power_and_connect(true);
NVIC_SetPriority(OTG_FS_IRQn, 6);
NVIC_EnableIRQ(OTG_FS_IRQn); NVIC_EnableIRQ(OTG_FS_IRQn);
} }
@ -471,27 +472,31 @@ void usbdrv_fetch_received_data(uint8_t ep, uint16_t len) {
} }
// write data to specific endpoint FIFO // write data to specific endpoint FIFO
void usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) { uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
/*WRITE_FIELD(USBINEP[ep].DIEPTSIZ, USB_OTG_DIEPTSIZ_XFRSIZ, len); /*WRITE_FIELD(USBINEP[ep].DIEPTSIZ, USB_OTG_DIEPTSIZ_XFRSIZ, len);
WRITE_FIELD(USBINEP[ep].DIEPTSIZ, USB_OTG_DIEPTSIZ_PKTCNT, 1);*/ WRITE_FIELD(USBINEP[ep].DIEPTSIZ, USB_OTG_DIEPTSIZ_PKTCNT, 1);*/
// endpoint is already armed // endpoint is already armed
if (gs.ep_IN[ep].task_commenced == USB_EPEVT_ARMED) { // if (gs.ep_IN[ep].task_commenced == USB_EPEVT_ARMED) {
return; // return;
} // }
gs.ep_IN[ep].task_commenced = USB_EPEVT_ARMED; // gs.ep_IN[ep].task_commenced = USB_EPEVT_ARMED;
// determine final write size
uint32_t freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
uint16_t writeSize = MIN(freeSize, len); // limit transmit size to free size
// calculate packet count based on max packet size // calculate packet count based on max packet size
uint16_t mps = gs.ep_IN[ep].max_packet_size; uint16_t mps = gs.ep_IN[ep].max_packet_size;
uint16_t packet_count = 1; // for ZLPs uint16_t packet_count = 1; // for ZLPs
if (len > 0) { // if length is nonzero if (writeSize > 0) { // if length is nonzero
packet_count = len / mps + (((len % mps) > 0) ? 1 : 0); packet_count = writeSize / mps + (((writeSize % mps) > 0) ? 1 : 0);
} }
// TODO: ZLP ending // TODO: ZLP ending
// program DIEPTSIZ with transfer length (TODO: currently only a single transfer!) // program DIEPTSIZ with transfer length (TODO: currently only a single transfer!)
USBINEP[ep].DIEPTSIZ = (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | len; USBINEP[ep].DIEPTSIZ = (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | writeSize;
// enable endpoint and cancel responding NAK // enable endpoint and cancel responding NAK
SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK); SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK);
@ -501,7 +506,7 @@ void usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
// push full dwords // push full dwords
volatile uint32_t *p = (uint32_t *)USBFIFO(ep); volatile uint32_t *p = (uint32_t *)USBFIFO(ep);
uint32_t floorlen_dwords = len >> 2; uint32_t floorlen_dwords = writeSize >> 2;
for (uint16_t i = 0; i < floorlen_dwords; i++) { for (uint16_t i = 0; i < floorlen_dwords; i++) {
uint16_t i0 = 4 * i; uint16_t i0 = 4 * i;
uint32_t dword = data[i0] | (data[i0 + 1] << 8) | (data[i0 + 2] << 16) | (data[i0 + 3] << 24); uint32_t dword = data[i0] | (data[i0 + 1] << 8) | (data[i0 + 2] << 16) | (data[i0 + 3] << 24);
@ -521,6 +526,9 @@ void usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len) {
// unmask USB interrupts // unmask USB interrupts
SET_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT); SET_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT);
// return with written size
return writeSize;
} }
// arm OUT endpoint // arm OUT endpoint
@ -602,151 +610,152 @@ void usbdrv_process_event(uint8_t evt_code, USBDRV_EventData *evt_data) {
} }
switch (gs.state) { switch (gs.state) {
case USB_FSM_INITIAL_WAIT_SPEEDNEG: // wait for speed negotitation to conclude case USB_FSM_INITIAL_WAIT_SPEEDNEG: // wait for speed negotitation to conclude
if (evt_code == USB_EVT_SPEEDNEG_DONE) { if (evt_code == USB_EVT_SPEEDNEG_DONE) {
gs.state = USB_FSM_SETUP_OPERATE; // wait for speed negotiation gs.state = USB_FSM_SETUP_OPERATE; // wait for speed negotiation
}
break;
case USB_FSM_SETUP_OPERATE: { // expect SETUP transactions first, then everything else as well
switch (evt_code) {
case USB_EVT_RECEPTION_DONE: { // reception done
// for (uint32_t i = 0; i < 100000; i++) {
// __NOP();
// }
USBDRV_EventData evt_data = {0};
usbdrv_process_rx_fifo_top(&evt_data); // process rx fifo top
// fetch data if data are available
if ((evt_data.rx.pckt_status == USB_PCKT_STATUS_SETUP_DATA_RECV) ||
(evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV)) {
usbdrv_fetch_received_data(evt_data.rx.ep_num, evt_data.rx.byte_count); // fetch the data
}
// act according to what we have received
if (evt_data.rx.ep_num == 0) { // EP0 special treatment
int stage = -1;
if (evt_data.rx.pckt_status == USB_PCKT_STATUS_SETUP_CPLT) {
stage = UST_SETUP;
USBMSG("--SETUP\n");
} else if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_TRANSFER_CPLT) {
stage = UST_DATA;
// OUT transaction has fired
if (gs.ep_OUT[0].task_commenced == USB_EPEVT_ARMED) {
gs.ep_OUT[0].task_commenced = USB_EPEVT_IDLE;
}
USBMSG("--DATA\n");
}
// process setup packet
if (stage != -1) {
usbcore_process_setup_pckt(gs.rx_buf, gs.rx_buf_level, stage);
}
// SET_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM); // unmask interrupt
} else { // not EP0
if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV) { // TODO maybe the
USBDRV_CallbackCompound cbcpd;
cbcpd.ep = evt_data.rx.ep_num;
cbcpd.dir = USB_OUT;
cbcpd.code = USB_CBC_OUT;
cbcpd.data = gs.rx_buf;
cbcpd.size = gs.rx_buf_level;
usbcore_process_nonsetup_event(&cbcpd);
}
} }
break; break;
case USB_FSM_SETUP_OPERATE: { // expect SETUP transactions }
switch (evt_code) {
case USB_EVT_RECEPTION_DONE: { // reception done
for (uint32_t i = 0; i < 100000; i++) { case USB_EVT_OUT_DONE: { // some OUT operations have finished
__NOP(); for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
if (gs.ep_OUT[ep].is_configured) { // if the endpoint is running
if (READ_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_STUP)) { // setup done
SET_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_STUP);
USBMSG("SETUP\n");
} }
USBDRV_EventData evt_data = {0}; if (READ_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_XFRC)) { // OUT transaction done
usbdrv_process_rx_fifo_top(&evt_data); // process rx fifo top SET_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_XFRC);
USBMSG("OUT\n");
// fetch data if data are available // reset commenced task state
if ((evt_data.rx.pckt_status == USB_PCKT_STATUS_SETUP_DATA_RECV) || if (gs.ep_OUT[ep].task_commenced == USB_EPEVT_ARMED) {
(evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV)) { gs.ep_OUT[ep].task_commenced = USB_EPEVT_IDLE;
usbdrv_fetch_received_data(evt_data.rx.ep_num, evt_data.rx.byte_count); // fetch the data
}
// act according to what we have received
if (evt_data.rx.ep_num == 0) { // EP0 special treatment
int stage = -1;
if (evt_data.rx.pckt_status == USB_PCKT_STATUS_SETUP_CPLT) {
stage = UST_SETUP;
USBMSG("--SETUP\n");
} else if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_TRANSFER_CPLT) {
stage = UST_DATA;
// OUT transaction has fired
if (gs.ep_OUT[0].task_commenced == USB_EPEVT_ARMED) {
gs.ep_OUT[0].task_commenced = USB_EPEVT_IDLE;
}
USBMSG("--DATA\n");
} }
// process setup packet usbdrv_arm_OUT_endpoint(ep, gs.ep_OUT[ep].max_packet_size);
if (stage != -1) {
usbcore_process_setup_pckt(gs.rx_buf, gs.rx_buf_level, stage);
}
//SET_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM); // unmask interrupt
} else { // not EP0
if (evt_data.rx.pckt_status == USB_PCKT_STATUS_OUT_DATA_RECV) { // TODO maybe the
USBDRV_CallbackCompound cbcpd;
cbcpd.ep = evt_data.rx.ep_num;
cbcpd.dir = USB_OUT;
cbcpd.code = USB_CBC_OUT;
cbcpd.data = gs.rx_buf;
cbcpd.size = gs.rx_buf_level;
usbcore_process_nonsetup_event(&cbcpd);
}
}
break;
}
case USB_EVT_OUT_DONE: { // some OUT operations have finished
for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
if (gs.ep_OUT[ep].is_configured) { // if the endpoint is running
if (READ_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_STUP)) { // setup done
SET_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_STUP);
USBMSG("SETUP\n");
}
if (READ_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_XFRC)) { // OUT transaction done
SET_BIT(USBOUTEP[ep].DOEPINT, USB_OTG_DOEPINT_XFRC);
USBMSG("OUT\n");
// reset commenced task state
if (gs.ep_OUT[ep].task_commenced == USB_EPEVT_ARMED) {
gs.ep_OUT[ep].task_commenced = USB_EPEVT_IDLE;
}
usbdrv_arm_OUT_endpoint(ep, gs.ep_OUT[ep].max_packet_size);
}
}
} }
} }
case USB_EVT_IN_DONE: { // some IN operations have finished
// callback compound
USBDRV_CallbackCompound cbcpd;
cbcpd.dir = USB_IN;
cbcpd.data = NULL;
cbcpd.size = 0;
for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
cbcpd.ep = ep;
if (gs.ep_IN[ep].is_configured) { // if the endpoint is running
if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC)) { // timeout done
SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC);
USBMSG("TO\n");
gs.ep_IN[ep].task_commenced = USB_EPEVT_IDLE;
}
if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_XFRC)) { // IN transaction done
SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_XFRC);
// reset commenced task state
if (gs.ep_IN[ep].task_commenced == USB_EPEVT_ARMED) {
gs.ep_IN[ep].task_commenced = USB_EPEVT_IDLE;
}
USBMSG("IN [%d]\n", ep);
cbcpd.code = USB_CBC_IN_DONE;
usbcore_process_nonsetup_event(&cbcpd);
}
if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_ITTXFE)) { // IN endpoint IN token received with Tx FIFO empty interrupt
SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_ITTXFE);
// reset stalled state
if (gs.ep_IN[ep].task_commenced == USB_EPEVT_STALLED) {
usbdrv_stall_endpoint(ep, USB_IN, false);
}
// USBMSG("IN FIFOEMPTY [%d]\n", ep);
cbcpd.code = USB_CBC_IN_FIFOEMPTY;
usbcore_process_nonsetup_event(&cbcpd);
}
}
}
// // set new address if it's already waiting
// if (gs.new_address != 0) {
// WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DAD, gs.new_address);
// gs.new_address = 0;
// USBMSG("ADDR SET\n");
// }
}
default:
break;
} }
break;
}
case USB_EVT_IN_DONE: { // some IN operations have finished
// callback compound
USBDRV_CallbackCompound cbcpd;
cbcpd.dir = USB_IN;
cbcpd.data = NULL;
cbcpd.size = 0;
for (uint8_t ep = 0; ep < USB_NUM_OF_ENDPOINTS; ep++) {
cbcpd.ep = ep;
if (gs.ep_IN[ep].is_configured) { // if the endpoint is running
if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC)) { // timeout done
SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_TOC);
USBMSG("TO\n");
gs.ep_IN[ep].task_commenced = USB_EPEVT_IDLE;
}
if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_XFRC)) { // IN transaction done
SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_XFRC);
// reset commenced task state
if (gs.ep_IN[ep].task_commenced == USB_EPEVT_ARMED) {
gs.ep_IN[ep].task_commenced = USB_EPEVT_IDLE;
}
USBMSG("IN [%d]\n", ep);
cbcpd.code = USB_CBC_IN_DONE;
usbcore_process_nonsetup_event(&cbcpd);
}
if (READ_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_ITTXFE)) { // IN endpoint IN token received with Tx FIFO empty interrupt
SET_BIT(USBINEP[ep].DIEPINT, USB_OTG_DIEPINT_ITTXFE);
// reset stalled state
if (gs.ep_IN[ep].task_commenced == USB_EPEVT_STALLED) {
usbdrv_stall_endpoint(ep, USB_IN, false);
}
// USBMSG("IN FIFOEMPTY [%d]\n", ep);
cbcpd.code = USB_CBC_IN_FIFOEMPTY;
usbcore_process_nonsetup_event(&cbcpd);
}
}
}
// // set new address if it's already waiting
// if (gs.new_address != 0) {
// WRITE_FIELD(USBD->DCFG, USB_OTG_DCFG_DAD, gs.new_address);
// gs.new_address = 0;
// USBMSG("ADDR SET\n");
// }
} }
default: default:
break; break;
}
}
default:
break;
} }
} }
@ -804,7 +813,7 @@ void OTG_FS_IRQHandler() {
if (ints & USB_OTG_GINTSTS_RXFLVL) { if (ints & USB_OTG_GINTSTS_RXFLVL) {
// SET_BIT(USBG->GINTSTS, USB_OTG_GINTSTS_RXFLVL); // clear interrupt // SET_BIT(USBG->GINTSTS, USB_OTG_GINTSTS_RXFLVL); // clear interrupt
USBMSG("RX DONE\n"); USBMSG("RX DONE\n");
//CLEAR_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM); // mask interrupt until processing is done // CLEAR_BIT(USBG->GINTMSK, USB_OTG_GINTMSK_RXFLVLM); // mask interrupt until processing is done
usbdrv_process_event(USB_EVT_RECEPTION_DONE, NULL); // process event usbdrv_process_event(USB_EVT_RECEPTION_DONE, NULL); // process event
// usbdrv_push_event(USB_EVT_RECEPTION_DONE, NULL); // push event // usbdrv_push_event(USB_EVT_RECEPTION_DONE, NULL); // push event
} }

View File

@ -138,7 +138,7 @@ void usbdrv_set_rx_fifo_size(uint16_t size); // set Rx FIFO size
void usbdrv_fetch_received_data(uint8_t ep, uint16_t len); // fetch received data from RX FIFO to receive buffer void usbdrv_fetch_received_data(uint8_t ep, uint16_t len); // fetch received data from RX FIFO to receive buffer
void usbdrv_process_rx_fifo_top(USBDRV_EventData *evt_data); // see what's on top of Rx FIFO void usbdrv_process_rx_fifo_top(USBDRV_EventData *evt_data); // see what's on top of Rx FIFO
void usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len); // write data to specific endpoint FIFO uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len); // write data to specific endpoint FIFO
#define USBDRV_ARM_IN_ZLP(ep) usbdrv_arm_IN_endpoint((ep), NULL, 0) #define USBDRV_ARM_IN_ZLP(ep) usbdrv_arm_IN_endpoint((ep), NULL, 0)
void usbdrv_arm_OUT_endpoint(uint8_t ep, uint8_t size); // arm OUT endpoint void usbdrv_arm_OUT_endpoint(uint8_t ep, uint8_t size); // arm OUT endpoint
bool usbdrv_get_endpoint_interrupt_flag(uint8_t ep, uint8_t dir); // get endpoint interrupt flag bool usbdrv_get_endpoint_interrupt_flag(uint8_t ep, uint8_t dir); // get endpoint interrupt flag