- auto ZLP reconsidered and removed, ZLP is always appended to transfers featuring a size divisible by max packet size
- EEM tweaked
This commit is contained in:
parent
6406222be3
commit
f6e3d48476
34
class/eem.c
34
class/eem.c
@ -14,16 +14,14 @@
|
|||||||
|
|
||||||
static USB_EemState eems = {0};
|
static USB_EemState eems = {0};
|
||||||
|
|
||||||
static uint8_t netbBuf[USB_EEM_FIFO_SIZE]; // Network bound FIFO memory
|
// static uint8_t netbBuf[USB_EEM_FIFO_SIZE]; // Network bound FIFO memory
|
||||||
static uint8_t hostbBuf[USB_EEM_FIFO_SIZE]; // Host bound FIFO memory
|
static uint8_t hostbBuf[USB_EEM_FIFO_SIZE]; // Host bound FIFO memory
|
||||||
|
|
||||||
#define EEM_EVENT_QUEUE_LENGTH (16)
|
#define EEM_EVENT_QUEUE_LENGTH (16)
|
||||||
#define EEM_FRAME_QUEUE_LENGTH (24)
|
#define EEM_FRAME_QUEUE_LENGTH (8)
|
||||||
#define EEM_PCKT_SIZE (64)
|
#define EEM_PCKT_SIZE (64)
|
||||||
#define EEM_TRANSFER_UNIT (128)
|
#define EEM_TRANSFER_UNIT (128)
|
||||||
|
|
||||||
static uint8_t transferBuffer[EEM_TRANSFER_UNIT]; // transfer buffer
|
|
||||||
|
|
||||||
void usb_eem_thread(void *);
|
void usb_eem_thread(void *);
|
||||||
|
|
||||||
void usb_eem_init(uint8_t data_ep) {
|
void usb_eem_init(uint8_t data_ep) {
|
||||||
@ -37,7 +35,7 @@ void usb_eem_init(uint8_t data_ep) {
|
|||||||
eems.eventQueue = osMessageQueueNew(EEM_EVENT_QUEUE_LENGTH, sizeof(uint8_t), NULL);
|
eems.eventQueue = osMessageQueueNew(EEM_EVENT_QUEUE_LENGTH, sizeof(uint8_t), NULL);
|
||||||
|
|
||||||
// create network bound and host bound FIFOs
|
// create network bound and host bound FIFOs
|
||||||
bfifo_create(&(eems.hostbFifo), netbBuf, USB_EEM_FIFO_SIZE);
|
// bfifo_create(&(eems.hostbFifo), netbBuf, USB_EEM_FIFO_SIZE);
|
||||||
bfifo_create(&(eems.netbFifo), hostbBuf, USB_EEM_FIFO_SIZE);
|
bfifo_create(&(eems.netbFifo), hostbBuf, USB_EEM_FIFO_SIZE);
|
||||||
|
|
||||||
// create queue for hostbound frames
|
// create queue for hostbound frames
|
||||||
@ -47,6 +45,9 @@ void usb_eem_init(uint8_t data_ep) {
|
|||||||
eems.hostbState = EEM_IDLE;
|
eems.hostbState = EEM_IDLE;
|
||||||
eems.netbState = EEM_IDLE;
|
eems.netbState = EEM_IDLE;
|
||||||
|
|
||||||
|
// turn network bound autoarm on
|
||||||
|
eems.netbAutoArm = true;
|
||||||
|
|
||||||
// no EchoResponse is queued
|
// no EchoResponse is queued
|
||||||
eems.echoRespQueued = false;
|
eems.echoRespQueued = false;
|
||||||
|
|
||||||
@ -81,6 +82,11 @@ int usb_eem_process_and_return(USB_CallbackEvent *cbevt) {
|
|||||||
if ((cbevt->ep == eems.data_ep)) { // verify endpoint
|
if ((cbevt->ep == eems.data_ep)) { // verify endpoint
|
||||||
bfifo_push(&(eems.netbFifo), cbevt->data, cbevt->size); // store portion of netbound packet
|
bfifo_push(&(eems.netbFifo), cbevt->data, cbevt->size); // store portion of netbound packet
|
||||||
usb_eem_push_event(EEM_EVT_NETBOUND_PCKT_RECEIVED); // push notification
|
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
|
||||||
|
eems.netbAutoArm = false;
|
||||||
|
cbevt->arm_out_endpoint = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -101,7 +107,7 @@ int usb_eem_process_and_return(USB_CallbackEvent *cbevt) {
|
|||||||
// MSG("---\n");
|
// MSG("---\n");
|
||||||
// }
|
// }
|
||||||
} else { // no data is waiting for transmission
|
} else { // no data is waiting for transmission
|
||||||
usbcore_schedule_transmission(eems.data_ep, NULL, 0); // send ZLP
|
//usbcore_schedule_transmission(eems.data_ep, NULL, 0); // send ZLP
|
||||||
}
|
}
|
||||||
|
|
||||||
// if FIFO is empty or flushed, then send notification
|
// if FIFO is empty or flushed, then send notification
|
||||||
@ -208,6 +214,12 @@ void usb_eem_process_networkbound() {
|
|||||||
// pop data from the packet
|
// pop data from the packet
|
||||||
bfifo_pop(bf, eems.netbFrameSize, 0);
|
bfifo_pop(bf, eems.netbFrameSize, 0);
|
||||||
|
|
||||||
|
// if free size is greater then the size of a single USB packet, then arm the endpoint
|
||||||
|
if ((eems.netbAutoArm == false) && (bfifo_get_free(bf) > EEM_PCKT_SIZE)) {
|
||||||
|
eems.netbAutoArm = true;
|
||||||
|
usbcore_schedule_reception(eems.data_ep, EEM_PCKT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
// MSG("PKT OK! %u\n", eems.netbFrameSize);
|
// MSG("PKT OK! %u\n", eems.netbFrameSize);
|
||||||
|
|
||||||
eems.netbState = EEM_IDLE;
|
eems.netbState = EEM_IDLE;
|
||||||
@ -217,11 +229,6 @@ void usb_eem_process_networkbound() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void usb_eem_process_hostbound() {
|
void usb_eem_process_hostbound() {
|
||||||
// see if there are some packets waiting for transmission
|
|
||||||
if (osMessageQueueGetCount(eems.hostbFrameQ) == 0) {
|
|
||||||
return; // no packets
|
|
||||||
}
|
|
||||||
|
|
||||||
/*// check that forward buffer is indeed empty
|
/*// check that forward buffer is indeed empty
|
||||||
BFifo * bf = &eems.hostbFifo;
|
BFifo * bf = &eems.hostbFifo;
|
||||||
if (bfifo_get_used(bf) > 0) {
|
if (bfifo_get_used(bf) > 0) {
|
||||||
@ -240,6 +247,11 @@ void usb_eem_process_hostbound() {
|
|||||||
// release frame
|
// release frame
|
||||||
dynmem_free(oldEemFrame);
|
dynmem_free(oldEemFrame);
|
||||||
|
|
||||||
|
// see if there are some packets waiting for transmission
|
||||||
|
if (osMessageQueueGetCount(eems.hostbFrameQ) == 0) {
|
||||||
|
return; // no packets
|
||||||
|
}
|
||||||
|
|
||||||
// at this point, we can safely pop from the frame queue, popping will not block,
|
// at this point, we can safely pop from the frame queue, popping will not block,
|
||||||
// and the forward queue is certainly empty
|
// and the forward queue is certainly empty
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include <etherlib/etherlib.h>
|
#include <etherlib/etherlib.h>
|
||||||
|
|
||||||
#define USB_EEM_FIFO_SIZE (2048)
|
#define USB_EEM_FIFO_SIZE (8192)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EEM_ECHO = 0, // Echo
|
EEM_ECHO = 0, // Echo
|
||||||
@ -44,11 +44,12 @@ typedef struct {
|
|||||||
EthInterface * intf; // interface for packet interception and injection
|
EthInterface * intf; // interface for packet interception and injection
|
||||||
uint8_t data_ep; // bulk data in and out endpoint pair
|
uint8_t data_ep; // bulk data in and out endpoint pair
|
||||||
osMessageQueueId_t eventQueue; // event queue
|
osMessageQueueId_t eventQueue; // event queue
|
||||||
BFifo hostbFifo; // Hostbound FIFO
|
// BFifo hostbFifo; // Hostbound FIFO
|
||||||
BFifo netbFifo; // Network bound FIFO
|
BFifo netbFifo; // Network bound FIFO
|
||||||
USB_EemFsmState netbState; // state of host bound operations
|
USB_EemFsmState netbState; // state of host bound operations
|
||||||
uint16_t netbFrameSize; // size of network bound packet
|
uint16_t netbFrameSize; // size of network bound packet
|
||||||
uint16_t netbSizeLeft; // number of bytes expected from the host sending into current network bound packet
|
uint16_t netbSizeLeft; // number of bytes expected from the host sending into current network bound packet
|
||||||
|
bool netbAutoArm; // signal, that the netbound endpoint should be autoarmed or not
|
||||||
USB_EemFsmState hostbState; // state of network bound operations
|
USB_EemFsmState hostbState; // state of network bound operations
|
||||||
osMessageQueueId_t hostbFrameQ; // queue for hostbound message pointers
|
osMessageQueueId_t hostbFrameQ; // queue for hostbound message pointers
|
||||||
USB_EemFrame * hostbFrame; // hostbound frame
|
USB_EemFrame * hostbFrame; // hostbound frame
|
||||||
|
3
usb.c
3
usb.c
@ -215,7 +215,6 @@ void usbcore_process_nonsetup_event(USBDRV_CallbackCompound *cbcpd) {
|
|||||||
cbevt.subtype = USB_CBEVST_IN_REQ;
|
cbevt.subtype = USB_CBEVST_IN_REQ;
|
||||||
}
|
}
|
||||||
cbevt.dir = USB_IN;
|
cbevt.dir = USB_IN;
|
||||||
cbevt.enable_autozlp = true; // by default, enable auto ZLP
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,8 +232,6 @@ void usbcore_process_nonsetup_event(USBDRV_CallbackCompound *cbcpd) {
|
|||||||
if (cbevt.arm_out_endpoint) {
|
if (cbevt.arm_out_endpoint) {
|
||||||
usbdrv_autoarm_OUT_endpoint(cbcpd->ep);
|
usbdrv_autoarm_OUT_endpoint(cbcpd->ep);
|
||||||
}
|
}
|
||||||
} else if (cbevt.dir == USB_IN) {
|
|
||||||
usbdrv_enable_autozlp(cbcpd->ep, cbevt.enable_autozlp); // handle auto ZLP setting
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ typedef struct {
|
|||||||
const uint8_t * reply_data; // reply data
|
const uint8_t * reply_data; // reply data
|
||||||
uint8_t reply_size; // reply size
|
uint8_t reply_size; // reply size
|
||||||
bool arm_out_endpoint; // automatically arm OUT endpoint at the end of the current transmission
|
bool arm_out_endpoint; // automatically arm OUT endpoint at the end of the current transmission
|
||||||
bool enable_autozlp; // enable automatic ZLP transmission based on transfer size
|
|
||||||
} USB_CallbackEvent;
|
} USB_CallbackEvent;
|
||||||
|
|
||||||
#endif /* CORE_USB_USB_CALLBACK_EVENT */
|
#endif /* CORE_USB_USB_CALLBACK_EVENT */
|
||||||
|
180
usb_driver.c
180
usb_driver.c
@ -284,7 +284,6 @@ void usbdrv_build_fifo() {
|
|||||||
if (cfg->is_configured) {
|
if (cfg->is_configured) {
|
||||||
cfg->fifo_size = CEIL4(MAX(USB_MIN_GROSS_TX_FIFO_SIZE, 2 * cfg->max_packet_size)); // correct FIFO size if necessary
|
cfg->fifo_size = CEIL4(MAX(USB_MIN_GROSS_TX_FIFO_SIZE, 2 * cfg->max_packet_size)); // correct FIFO size if necessary
|
||||||
cfg->fifo_address = next_fifo_addr; // store FIFO address
|
cfg->fifo_address = next_fifo_addr; // store FIFO address
|
||||||
cfg->auto_zlp = true; // turn on automatic ZLP appending
|
|
||||||
cfg->zlp_next = false;
|
cfg->zlp_next = false;
|
||||||
// cfg->txp = false; // no transfer is in progress
|
// cfg->txp = false; // no transfer is in progress
|
||||||
next_fifo_addr += cfg->fifo_size; // advance next address
|
next_fifo_addr += cfg->fifo_size; // advance next address
|
||||||
@ -488,14 +487,8 @@ void usbdrv_fetch_received_data(uint8_t ep, uint16_t len) {
|
|||||||
|
|
||||||
// write data to specific endpoint FIFO
|
// write data to specific endpoint FIFO
|
||||||
uint32_t 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_PKTCNT, 1);*/
|
|
||||||
|
|
||||||
// determine if a transmission is in progress or not
|
// determine if a transmission is in progress or not
|
||||||
bool txp = READ_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA);
|
bool txp = READ_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA);
|
||||||
/*if (txp) {
|
|
||||||
return 0;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
uint16_t mps = gs.ep_IN[ep].max_packet_size; // fetch maximum packet size
|
uint16_t mps = gs.ep_IN[ep].max_packet_size; // fetch maximum packet size
|
||||||
|
|
||||||
@ -600,10 +593,6 @@ void usbdrv_autoarm_OUT_endpoint(uint8_t ep) {
|
|||||||
gs.ep_OUT[ep].autoarm = true;
|
gs.ep_OUT[ep].autoarm = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbdrv_enable_autozlp(uint8_t ep, bool en) {
|
|
||||||
gs.ep_IN[ep].auto_zlp = en;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------
|
// ----------------
|
||||||
|
|
||||||
void usbdrv_set_address(uint8_t addr) {
|
void usbdrv_set_address(uint8_t addr) {
|
||||||
@ -774,7 +763,7 @@ void usbdrv_process_event(uint8_t evt_code, USBDRV_EventData *evt_data) {
|
|||||||
// gs.ep_IN[ep].txp = false;
|
// gs.ep_IN[ep].txp = false;
|
||||||
|
|
||||||
// see if a ZLP transmission was queued
|
// see if a ZLP transmission was queued
|
||||||
if (/*gs.ep_IN[ep].auto_zlp && */ gs.ep_IN[ep].zlp_next) {
|
if (gs.ep_IN[ep].zlp_next) {
|
||||||
usbdrv_arm_IN_endpoint(ep, NULL, 0); // send ZLP
|
usbdrv_arm_IN_endpoint(ep, NULL, 0); // send ZLP
|
||||||
} else { // no ZLP
|
} else { // no ZLP
|
||||||
USBMSG("IN [%d]\n", ep);
|
USBMSG("IN [%d]\n", ep);
|
||||||
@ -889,170 +878,3 @@ void OTG_FS_IRQHandler() {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------
|
|
||||||
|
|
||||||
// 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_PKTCNT, 1);*/
|
|
||||||
|
|
||||||
// // determine if a transmission is in progress or not
|
|
||||||
// if (gs.ep_IN[ep].txp) {
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // determine if a transmission is in progress or not
|
|
||||||
// // bool txp = READ_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA); // transmission in progress
|
|
||||||
|
|
||||||
// // transmission may only be commenced if last transmission has concluded
|
|
||||||
// /*if (READ_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA)) {
|
|
||||||
// return 0;
|
|
||||||
// }*/
|
|
||||||
|
|
||||||
// uint16_t mps = gs.ep_IN[ep].max_packet_size; // fetch maximum packet size
|
|
||||||
|
|
||||||
// // determine final write size
|
|
||||||
// uint32_t freeSize = 0;
|
|
||||||
|
|
||||||
// // if (len > 0) { // only poll DTXFSTS if (len > 0) (see datasheet)
|
|
||||||
// freeSize = USBINEP[ep].DTXFSTS * sizeof(uint32_t); // get free transmit buffer size
|
|
||||||
// //}
|
|
||||||
|
|
||||||
// // if (gs.ep_IN[ep].txp && (freeSize == 0)) {
|
|
||||||
// // return 0;
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// uint16_t writeSize = MIN(freeSize, len); // limit transmit size to free size
|
|
||||||
|
|
||||||
// // if transmission is in progress, then remaining transmission bytes also limits transmission size
|
|
||||||
// if (gs.ep_IN[ep].txp) {
|
|
||||||
// uint16_t bytesLeft = USBINEP[ep].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ;
|
|
||||||
// writeSize = MIN(writeSize, bytesLeft);
|
|
||||||
|
|
||||||
// // if this was the last write, then disable Tx empty interrupt
|
|
||||||
// if (bytesLeft <= mps) {
|
|
||||||
// USBD->DIEPEMPMSK &= ~((uint32_t)(1 << ep));
|
|
||||||
// } else { // if not, turn it back on
|
|
||||||
// USBD->DIEPEMPMSK |= ((uint32_t)(1 << ep));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// } else { // if no transmission was in progress, then setup endpoint for transmission
|
|
||||||
// // calculate packet count based on max packet size
|
|
||||||
// uint16_t packet_count = 1; // for ZLPs
|
|
||||||
// if (writeSize > 0) { // if length is nonzero
|
|
||||||
// packet_count = len / mps + (((len % mps) > 0) ? 1 : 0); // a transfer may contain multiple packets
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // set zlp_next if transfer size is integer multiple of max packet size and auto ZLP is on
|
|
||||||
// gs.ep_IN[ep].zlp_next = gs.ep_IN[ep].auto_zlp && (len > 0) && ((len % mps) == 0);
|
|
||||||
|
|
||||||
// // program DIEPTSIZ with transfer length
|
|
||||||
// USBINEP[ep].DIEPTSIZ = /*(packet_count << USB_OTG_DIEPTSIZ_MULCNT_Pos) |*/ (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | len;
|
|
||||||
|
|
||||||
// // enable endpoint and cancel responding NAK
|
|
||||||
// SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK);
|
|
||||||
|
|
||||||
// // enable FIFO empty interrupt, only if further write operations will follow
|
|
||||||
// // DO NOT enable this interrupt source when dealing with EP0!
|
|
||||||
// if ((ep != 0) && (writeSize < len)) {
|
|
||||||
// USBD->DIEPEMPMSK |= (1 << ep);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // set transfer in progress
|
|
||||||
// gs.ep_IN[ep].txp = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // disable ALL USB interrupts to prevent access to specific registers (see errata)
|
|
||||||
// CLEAR_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT);
|
|
||||||
|
|
||||||
// // push full dwords
|
|
||||||
// volatile uint32_t *p = (uint32_t *)USBFIFO(ep);
|
|
||||||
// uint32_t floorlen_dwords = writeSize >> 2;
|
|
||||||
// for (uint16_t i = 0; i < floorlen_dwords; i++) {
|
|
||||||
// uint16_t i0 = 4 * i;
|
|
||||||
// uint32_t dword = data[i0] | (data[i0 + 1] << 8) | (data[i0 + 2] << 16) | (data[i0 + 3] << 24);
|
|
||||||
// p[i] = dword;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // push the remaining partial dword
|
|
||||||
// uint8_t rem_bytes = writeSize & 0b11;
|
|
||||||
// if (rem_bytes > 0) {
|
|
||||||
// uint32_t rem_dword = 0;
|
|
||||||
// uint16_t rem_start = writeSize - rem_bytes;
|
|
||||||
// for (int16_t i = writeSize - 1; i >= rem_start; i--) {
|
|
||||||
// rem_dword = (rem_dword << 8) | data[i];
|
|
||||||
// }
|
|
||||||
// *p = rem_dword;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // unmask USB interrupts
|
|
||||||
// SET_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT);
|
|
||||||
|
|
||||||
// // return with written size
|
|
||||||
// return writeSize;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// EZ MŰKÖDIK, DE CSAK RÖVID TRANSFEREKRE
|
|
||||||
// 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_PKTCNT, 1);*/
|
|
||||||
|
|
||||||
// // determine if a transmission is in progress or not
|
|
||||||
// bool txp = READ_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA);
|
|
||||||
// if (txp) {
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// uint16_t mps = gs.ep_IN[ep].max_packet_size; // fetch maximum packet size
|
|
||||||
|
|
||||||
// // 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
|
|
||||||
// uint16_t packet_count = 1; // for ZLPs
|
|
||||||
// if (writeSize > 0) { // if length is nonzero
|
|
||||||
// packet_count = writeSize / mps + (((writeSize % mps) > 0) ? 1 : 0); // a transfer may contain multiple packets
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // set zlp_next if transfer size is integer multiple of max packet size and auto ZLP is on
|
|
||||||
// gs.ep_IN[ep].zlp_next = gs.ep_IN[ep].auto_zlp && (writeSize > 0) && ((writeSize % mps) == 0);
|
|
||||||
|
|
||||||
// // program DIEPTSIZ with transfer length
|
|
||||||
// USBINEP[ep].DIEPTSIZ = /*(packet_count << USB_OTG_DIEPTSIZ_MULCNT_Pos) |*/ (packet_count << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | writeSize;
|
|
||||||
|
|
||||||
// // enable endpoint and cancel responding NAK
|
|
||||||
// SET_BIT(USBINEP[ep].DIEPCTL, USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK);
|
|
||||||
|
|
||||||
// // set transfer in progress
|
|
||||||
// //gs.ep_IN[ep].txp = true;
|
|
||||||
|
|
||||||
// // disable ALL USB interrupts to prevent access to specific registers (see errata)
|
|
||||||
// CLEAR_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT);
|
|
||||||
|
|
||||||
// // push full dwords
|
|
||||||
// volatile uint32_t *p = (uint32_t *)USBFIFO(ep);
|
|
||||||
// uint32_t floorlen_dwords = writeSize >> 2;
|
|
||||||
// for (uint16_t i = 0; i < floorlen_dwords; i++) {
|
|
||||||
// uint16_t i0 = 4 * i;
|
|
||||||
// uint32_t dword = data[i0] | (data[i0 + 1] << 8) | (data[i0 + 2] << 16) | (data[i0 + 3] << 24);
|
|
||||||
// p[i] = dword;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // push the remaining partial dword
|
|
||||||
// uint8_t rem_bytes = writeSize & 0b11;
|
|
||||||
// if (rem_bytes > 0) {
|
|
||||||
// uint32_t rem_dword = 0;
|
|
||||||
// uint16_t rem_start = writeSize - rem_bytes;
|
|
||||||
// for (int16_t i = writeSize - 1; i >= rem_start; i--) {
|
|
||||||
// rem_dword = (rem_dword << 8) | data[i];
|
|
||||||
// }
|
|
||||||
// *p = rem_dword;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // unmask USB interrupts
|
|
||||||
// SET_BIT(USBG->GAHBCFG, USB_OTG_GAHBCFG_GINT);
|
|
||||||
|
|
||||||
// // return with written size
|
|
||||||
// return writeSize;
|
|
||||||
// }
|
|
@ -35,10 +35,8 @@ typedef struct {
|
|||||||
uint8_t is_configured; // the endpoint is in use
|
uint8_t is_configured; // the endpoint is in use
|
||||||
uint16_t fifo_address; // address in the FIFO
|
uint16_t fifo_address; // address in the FIFO
|
||||||
uint16_t fifo_size; // FIFO size
|
uint16_t fifo_size; // FIFO size
|
||||||
bool8_t auto_zlp; // automatically insert ZLP packets
|
|
||||||
bool8_t zlp_next; // indicates, that ZLP should be transmitted at the end of the current transfer (for IN endpoints)
|
bool8_t zlp_next; // indicates, that ZLP should be transmitted at the end of the current transfer (for IN endpoints)
|
||||||
bool8_t autoarm; // automatically arm endpoint (for OUT endpoints)
|
bool8_t autoarm; // automatically arm endpoint (for OUT endpoints)
|
||||||
//bool8_t txp; // transfer in progress
|
|
||||||
} USBDRV_EpConfig;
|
} USBDRV_EpConfig;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -155,7 +153,6 @@ uint32_t usbdrv_arm_IN_endpoint(uint8_t ep, const uint8_t *data, uint16_t len);
|
|||||||
#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)
|
||||||
uint32_t usbdrv_arm_OUT_endpoint(uint8_t ep, uint8_t size); // arm OUT endpoint, returned with the actual armed size (capped by the max packet size on that endpoint)
|
uint32_t usbdrv_arm_OUT_endpoint(uint8_t ep, uint8_t size); // arm OUT endpoint, returned with the actual armed size (capped by the max packet size on that endpoint)
|
||||||
void usbdrv_autoarm_OUT_endpoint(uint8_t ep); // automatically re-arm OUT endpoint at the and of the current OUT transfer
|
void usbdrv_autoarm_OUT_endpoint(uint8_t ep); // automatically re-arm OUT endpoint at the and of the current OUT transfer
|
||||||
void usbdrv_enable_autozlp(uint8_t ep, bool en); // enable or disable automatic ZLP appending to the transaction
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user