New USB API finalized, updated OTGv1, USBv1 not yet updated.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8653 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Giovanni Di Sirio 2015-12-28 11:16:40 +00:00
parent d93fdcd424
commit de202dd376
7 changed files with 158 additions and 218 deletions

View File

@ -412,9 +412,9 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] usbp pointer to the @p USBDriver object
* @return The current frame number.
*
* @api
* @xclass
*/
#define usbGetFrameNumber(usbp) usb_lld_get_frame_number(usbp)
#define usbGetFrameNumberX(usbp) usb_lld_get_frame_number(usbp)
/**
* @brief Returns the status of an IN endpoint.
@ -454,9 +454,9 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] ep endpoint number
* @return Received data size.
*
* @iclass
* @xclass
*/
#define usbGetReceiveTransactionSizeI(usbp, ep) \
#define usbGetReceiveTransactionSizeX(usbp, ep) \
usb_lld_get_transaction_size(usbp, ep)
/**
@ -469,7 +469,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] n number of bytes to be transferred
* @param[in] endcb callback to be invoked after the transfer or @p NULL
*
* @api
* @special
*/
#define usbSetupTransfer(usbp, buf, n, endcb) { \
(usbp)->ep0next = (buf); \
@ -580,7 +580,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
} \
osalSysLockFromISR(); \
osalThreadResumeI(&(usbp)->epc[ep]->out_state->thread, \
usbGetReceiveTransactionSizeI(usbp, ep)); \
usbGetReceiveTransactionSizeX(usbp, ep)); \
osalSysUnlockFromISR(); \
}
#else
@ -608,12 +608,10 @@ extern "C" {
const USBEndpointConfig *epcp);
void usbDisableEndpointsI(USBDriver *usbp);
void usbReadSetupI(USBDriver *usbp, usbep_t ep, uint8_t *buf);
void usbPrepareReceive(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n);
void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
const uint8_t *buf, size_t n);
bool usbStartReceiveI(USBDriver *usbp, usbep_t ep);
bool usbStartTransmitI(USBDriver *usbp, usbep_t ep);
void usbStartReceiveI(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n);
void usbStartTransmitI(USBDriver *usbp, usbep_t ep,
const uint8_t *buf, size_t n);
#if USB_USE_WAIT == TRUE
msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n);
msg_t usbTransmit(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n);

View File

@ -369,7 +369,6 @@ static void otg_epin_handler(USBDriver *usbp, usbep_t ep) {
cover the remaining.*/
isp->txsize = isp->totsize - isp->txsize;
isp->txcnt = 0;
usb_lld_prepare_transmit(usbp, ep);
osalSysLockFromISR();
usb_lld_start_in(usbp, ep);
osalSysUnlockFromISR();
@ -415,13 +414,14 @@ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) {
/* Receive transfer complete.*/
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
if (osp->rxsize < osp->totsize) {
/* A short packet always terminates a transaction.*/
if (((osp->rxcnt % usbp->epc[ep]->out_maxsize) == 0) &&
(osp->rxsize < osp->totsize)) {
/* In case the transaction covered only part of the total transfer
then another transaction is immediately started in order to
cover the remaining.*/
osp->rxsize = osp->totsize - osp->rxsize;
osp->rxcnt = 0;
usb_lld_prepare_receive(usbp, ep);
osalSysLockFromISR();
usb_lld_start_out(usbp, ep);
osalSysUnlockFromISR();
@ -476,7 +476,6 @@ static void otg_isoc_in_failed_handler(USBDriver *usbp) {
*
* @notapi
*/
static void otg_isoc_out_failed_handler(USBDriver *usbp) {
usbep_t ep;
stm32_otg_t *otgp = usbp->otg;
@ -1134,60 +1133,6 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
memcpy(buf, usbp->epc[ep]->setup_buf, 8);
}
/**
* @brief Prepares for a receive operation.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep) {
uint32_t pcnt;
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
/* Transfer initialization.*/
osp->totsize = osp->rxsize;
if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE))
osp->rxsize = EP0_MAX_OUTSIZE;
pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
usbp->epc[ep]->out_maxsize;
usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) |
DOEPTSIZ_XFRSIZ(osp->rxsize);
}
/**
* @brief Prepares for a transmit operation.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @notapi
*/
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) {
USBInEndpointState *isp = usbp->epc[ep]->in_state;
/* Transfer initialization.*/
isp->totsize = isp->txsize;
if (isp->txsize == 0) {
/* Special case, sending zero size packet.*/
usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0);
}
else {
if ((ep == 0) && (isp->txsize > EP0_MAX_INSIZE))
isp->txsize = EP0_MAX_INSIZE;
/* Normal case.*/
uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) /
usbp->epc[ep]->in_maxsize;
/* TODO: Support more than one packet per frame for isochronous transfers.*/
usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_MCNT(1) | DIEPTSIZ_PKTCNT(pcnt) |
DIEPTSIZ_XFRSIZ(isp->txsize);
}
}
/**
* @brief Starts a receive operation on an OUT endpoint.
*
@ -1197,7 +1142,28 @@ void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) {
* @notapi
*/
void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
uint32_t pcnt, rxsize;
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
/* Transfer initialization.*/
osp->totsize = osp->rxsize;
if ((ep == 0) && (osp->rxsize > EP0_MAX_OUTSIZE))
osp->rxsize = EP0_MAX_OUTSIZE;
/* Transaction size is rounded to a multiple of packet size because the
following requirement in the RM:
"For OUT transfers, the transfer size field in the endpoint's transfer
size register must be a multiple of the maximum packet size of the
endpoint, adjusted to the Word boundary".*/
pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1U) /
usbp->epc[ep]->out_maxsize;
rxsize = (pcnt * usbp->epc[ep]->out_maxsize + 3U) & 0xFFFFFFFCU;
/*Setting up transaction parameters in DOEPTSIZ.*/
usbp->otg->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) |
DOEPTSIZ_XFRSIZ(rxsize);
/* Special case of isochronous endpoint.*/
if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
/* Odd/even bit toggling for isochronous endpoint.*/
if (usbp->otg->DSTS & DSTS_FNSOF_ODD)
@ -1206,6 +1172,7 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SODDFRM;
}
/* Starting operation.*/
usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK;
}
@ -1218,7 +1185,27 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
* @notapi
*/
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
USBInEndpointState *isp = usbp->epc[ep]->in_state;
/* Transfer initialization.*/
isp->totsize = isp->txsize;
if (isp->txsize == 0) {
/* Special case, sending zero size packet.*/
usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0);
}
else {
if ((ep == 0) && (isp->txsize > EP0_MAX_INSIZE))
isp->txsize = EP0_MAX_INSIZE;
/* Normal case.*/
uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) /
usbp->epc[ep]->in_maxsize;
/* TODO: Support more than one packet per frame for isochronous transfers.*/
usbp->otg->ie[ep].DIEPTSIZ = DIEPTSIZ_MCNT(1) | DIEPTSIZ_PKTCNT(pcnt) |
DIEPTSIZ_XFRSIZ(isp->txsize);
}
/* Special case of isochronous endpoint.*/
if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
/* Odd/even bit toggling.*/
if (usbp->otg->DSTS & DSTS_FNSOF_ODD)
@ -1227,6 +1214,7 @@ void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SODDFRM;
}
/* Starting operation.*/
usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK;
usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep);
}

View File

@ -540,8 +540,6 @@ extern "C" {
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep);
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf);
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep);
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep);
void usb_lld_start_out(USBDriver *usbp, usbep_t ep);
void usb_lld_start_in(USBDriver *usbp, usbep_t ep);
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);

View File

@ -146,13 +146,8 @@ static void ibnotify(io_buffers_queue_t *bqp) {
uint8_t *buf = ibqGetEmptyBufferI(&sdup->ibqueue);
if (buf != NULL) {
/* Buffer found, starting a new transaction.*/
osalSysUnlock();
usbPrepareReceive(sdup->config->usbp, sdup->config->bulk_out,
buf, SERIAL_USB_BUFFERS_SIZE);
osalSysLock();
(void) usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out);
usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out,
buf, SERIAL_USB_BUFFERS_SIZE);
}
}
}
@ -179,12 +174,7 @@ static void obnotify(io_buffers_queue_t *bqp) {
uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
if (buf != NULL) {
/* Buffer found, starting a new transaction.*/
osalSysUnlock();
usbPrepareTransmit(sdup->config->usbp, sdup->config->bulk_in, buf, n);
osalSysLock();
(void) usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in);
usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
}
}
}
@ -319,9 +309,8 @@ void sduConfigureHookI(SerialUSBDriver *sdup) {
osalDbgAssert(buf != NULL, "no free buffer");
usbPrepareReceive(sdup->config->usbp, sdup->config->bulk_out,
buf, SERIAL_USB_BUFFERS_SIZE);
(void) usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out);
usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out,
buf, SERIAL_USB_BUFFERS_SIZE);
}
/**
@ -392,12 +381,7 @@ void sduSOFHookI(SerialUSBDriver *sdup) {
osalDbgAssert(buf != NULL, "queue is empty");
osalSysUnlockFromISR();
usbPrepareTransmit(sdup->config->usbp, sdup->config->bulk_in, buf, n);
osalSysLockFromISR();
(void) usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in);
usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
}
}
@ -431,13 +415,10 @@ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
/* Checking if there is a buffer ready for transmission.*/
buf = obqGetFullBufferI(&sdup->obqueue, &n);
/* Unlocking the critical zone.*/
osalSysUnlockFromISR();
if (buf != NULL) {
/* The endpoint cannot be busy, we are in the context of the callback,
so it is safe to transmit without a check.*/
usbPrepareTransmit(usbp, ep, buf, n);
usbStartTransmitI(usbp, ep, buf, n);
}
else if ((usbp->epc[ep]->in_state->txsize > 0U) &&
((usbp->epc[ep]->in_state->txsize &
@ -446,17 +427,13 @@ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
size. Otherwise the recipient may expect more data coming soon and
not return buffered data to app. See section 5.8.3 Bulk Transfer
Packet Size Constraints of the USB Specification document.*/
usbPrepareTransmit(usbp, ep, usbp->setup, 0);
usbStartTransmitI(usbp, ep, usbp->setup, 0);
}
else {
/* Nothing to transmit.*/
return;
}
/* Locking again and starting transmission.*/
osalSysLockFromISR();
(void) usbStartTransmitI(usbp, ep);
osalSysUnlockFromISR();
}
@ -483,7 +460,7 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) {
/* Posting the filled buffer in the queue.*/
ibqPostFullBufferI(&sdup->ibqueue,
usbGetReceiveTransactionSizeI(sdup->config->usbp,
usbGetReceiveTransactionSizeX(sdup->config->usbp,
sdup->config->bulk_out));
/* The endpoint cannot be busy, we are in the context of the callback,
@ -492,11 +469,8 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) {
buf = ibqGetEmptyBufferI(&sdup->ibqueue);
if (buf != NULL) {
/* Buffer found, starting a new transaction.*/
osalSysUnlockFromISR();
usbPrepareReceive(sdup->config->usbp, sdup->config->bulk_out,
buf, SERIAL_USB_BUFFERS_SIZE);
osalSysLockFromISR();
(void) usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out);
usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out,
buf, SERIAL_USB_BUFFERS_SIZE);
}
osalSysUnlockFromISR();
}

View File

@ -401,22 +401,31 @@ void usbDisableEndpointsI(USBDriver *usbp) {
}
/**
* @brief Prepares for a receive transaction on an OUT endpoint.
* @post The endpoint is ready for @p usbStartReceiveI().
* @note This function can be called both in ISR and thread context.
* @brief Starts a receive transaction on an OUT endpoint.
* @note This function is meant to be called from ISR context outside
* critical zones because there is a potentially slow operation
* inside.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
* @param[out] buf buffer where to copy the received data
* @param[in] n transaction size
* @param[in] n transaction size. It is recommended a multiple of
* the packet size because the excess is discarded.
*
* @special
* @iclass
*/
void usbPrepareReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
void usbStartReceiveI(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n) {
USBOutEndpointState *osp;
osalDbgCheckClassI();
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
osalDbgAssert(!usbGetReceiveStatusI(usbp, ep), "already receiving");
/* Marking the endpoint as active.*/
usbp->receiving |= (uint16_t)((unsigned)1U << (unsigned)ep);
/* Setting up the transfer.*/
osp = usbp->epc[ep]->out_state;
osp->rxbuf = buf;
osp->rxsize = n;
@ -425,29 +434,35 @@ void usbPrepareReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
osp->thread = NULL;
#endif
usb_lld_prepare_receive(usbp, ep);
/* Starting transfer.*/
usb_lld_start_out(usbp, ep);
}
/**
* @brief Prepares for a transmit transaction on an IN endpoint.
* @post The endpoint is ready for @p usbStartTransmitI().
* @note This function can be called both in ISR and thread context.
* @note The queue must contain at least the amount of data specified
* as transaction size.
* @brief Starts a transmit transaction on an IN endpoint.
* @note This function is meant to be called from ISR context outside
* critical zones because there is a potentially slow operation
* inside.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
* @param[in] buf buffer where to fetch the data to be transmitted
* @param[in] n transaction size
*
* @special
* @iclass
*/
void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
const uint8_t *buf, size_t n) {
void usbStartTransmitI(USBDriver *usbp, usbep_t ep,
const uint8_t *buf, size_t n) {
USBInEndpointState *isp;
osalDbgCheckClassI();
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
osalDbgAssert(!usbGetTransmitStatusI(usbp, ep), "already transmitting");
/* Marking the endpoint as active.*/
usbp->transmitting |= (uint16_t)((unsigned)1U << (unsigned)ep);
/* Setting up the transfer.*/
isp = usbp->epc[ep]->in_state;
isp->txbuf = buf;
isp->txsize = n;
@ -456,63 +471,8 @@ void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
isp->thread = NULL;
#endif
usb_lld_prepare_transmit(usbp, ep);
}
/**
* @brief Starts a receive transaction on an OUT endpoint.
* @post The endpoint callback is invoked when the transfer has been
* completed.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @return The operation status.
* @retval false Operation started successfully.
* @retval true Endpoint busy, operation not started.
*
* @iclass
*/
bool usbStartReceiveI(USBDriver *usbp, usbep_t ep) {
osalDbgCheckClassI();
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
if (usbGetReceiveStatusI(usbp, ep)) {
return true;
}
usbp->receiving |= (uint16_t)((unsigned)1U << (unsigned)ep);
usb_lld_start_out(usbp, ep);
return false;
}
/**
* @brief Starts a transmit transaction on an IN endpoint.
* @post The endpoint callback is invoked when the transfer has been
* completed.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
*
* @return The operation status.
* @retval false Operation started successfully.
* @retval true Endpoint busy, operation not started.
*
* @iclass
*/
bool usbStartTransmitI(USBDriver *usbp, usbep_t ep) {
osalDbgCheckClassI();
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
if (usbGetTransmitStatusI(usbp, ep)) {
return true;
}
usbp->transmitting |= (uint16_t)((unsigned)1U << (unsigned)ep);
/* Starting transfer.*/
usb_lld_start_in(usbp, ep);
return false;
}
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
@ -527,18 +487,23 @@ bool usbStartTransmitI(USBDriver *usbp, usbep_t ep) {
*
* @return The received effective data size, it can be less than
* the amount specified.
* @retval MSG_RESET operation aborted by a reset.
* @retval MSG_TIMEOUT operation aborted by a suspend.
* @retval MSG_RESET driver not in @p USB_ACTIVE state or the operation
* has been aborted by an USB reset or a transition to
* the @p USB_SUSPENDED state.
*
* @api
*/
msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
msg_t msg;
usbPrepareReceive(usbp, ep, buf, n);
osalSysLock();
usbStartReceiveI(usbp, ep);
if (usbGetDriverStateI(usbp) != USB_ACTIVE) {
osalSysUnlock();
return MSG_RESET;
}
usbStartReceiveI(usbp, ep, buf, n);
msg = osalThreadSuspendS(&usbp->epc[ep]->out_state->thread);
osalSysUnlock();
@ -555,18 +520,23 @@ msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
*
* @return The operation status.
* @retval MSG_OK operation performed successfully.
* @retval MSG_RESET operation aborted by a reset.
* @retval MSG_TIMEOUT operation aborted by a suspend.
* @retval MSG_RESET driver not in @p USB_ACTIVE state or the operation
* has been aborted by an USB reset or a transition to
* the @p USB_SUSPENDED state.
*
* @api
*/
msg_t usbTransmit(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) {
msg_t msg;
usbPrepareTransmit(usbp, ep, buf, n);
osalSysLock();
usbStartTransmitI(usbp, ep);
if (usbGetDriverStateI(usbp) != USB_ACTIVE) {
osalSysUnlock();
return MSG_RESET;
}
usbStartTransmitI(usbp, ep, buf, n);
msg = osalThreadSuspendS(&usbp->epc[ep]->in_state->thread);
osalSysUnlock();
@ -700,10 +670,10 @@ void _usb_suspend(USBDriver *usbp) {
if (usbp->epc[i] != NULL) {
osalSysLockFromISR();
if (usbp->epc[i]->in_state != NULL) {
osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_TIMEOUT);
osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET);
}
if (usbp->epc[i]->out_state != NULL) {
osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_TIMEOUT);
osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET);
}
osalSysUnlockFromISR();
}
@ -787,9 +757,8 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
if (usbp->ep0n != 0U) {
/* Starts the transmit phase.*/
usbp->ep0state = USB_EP0_TX;
usbPrepareTransmit(usbp, 0, usbp->ep0next, usbp->ep0n);
osalSysLockFromISR();
(void) usbStartTransmitI(usbp, 0);
usbStartTransmitI(usbp, 0, usbp->ep0next, usbp->ep0n);
osalSysUnlockFromISR();
}
else {
@ -797,9 +766,8 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
packet.*/
usbp->ep0state = USB_EP0_WAITING_STS;
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
usbPrepareReceive(usbp, 0, NULL, 0);
osalSysLockFromISR();
(void) usbStartReceiveI(usbp, 0);
usbStartReceiveI(usbp, 0, NULL, 0);
osalSysUnlockFromISR();
#else
usb_lld_end_setup(usbp, ep);
@ -811,9 +779,8 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
if (usbp->ep0n != 0U) {
/* Starts the receive phase.*/
usbp->ep0state = USB_EP0_RX;
usbPrepareReceive(usbp, 0, usbp->ep0next, usbp->ep0n);
osalSysLockFromISR();
(void) usbStartReceiveI(usbp, 0);
usbStartReceiveI(usbp, 0, usbp->ep0next, usbp->ep0n);
osalSysUnlockFromISR();
}
else {
@ -821,9 +788,8 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
packet.*/
usbp->ep0state = USB_EP0_SENDING_STS;
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
usbPrepareTransmit(usbp, 0, NULL, 0);
osalSysLockFromISR();
(void) usbStartTransmitI(usbp, 0);
usbStartTransmitI(usbp, 0, NULL, 0);
osalSysUnlockFromISR();
#else
usb_lld_end_setup(usbp, ep);
@ -854,9 +820,8 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
transmitted.*/
if ((usbp->ep0n < max) &&
((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0U)) {
usbPrepareTransmit(usbp, 0, NULL, 0);
osalSysLockFromISR();
(void) usbStartTransmitI(usbp, 0);
usbStartTransmitI(usbp, 0, NULL, 0);
osalSysUnlockFromISR();
usbp->ep0state = USB_EP0_WAITING_TX0;
return;
@ -866,9 +831,8 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
/* Transmit phase over, receiving the zero sized status packet.*/
usbp->ep0state = USB_EP0_WAITING_STS;
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
usbPrepareReceive(usbp, 0, NULL, 0);
osalSysLockFromISR();
(void) usbStartReceiveI(usbp, 0);
usbStartReceiveI(usbp, 0, NULL, 0);
osalSysUnlockFromISR();
#else
usb_lld_end_setup(usbp, ep);
@ -919,9 +883,8 @@ void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
/* Receive phase over, sending the zero sized status packet.*/
usbp->ep0state = USB_EP0_SENDING_STS;
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
usbPrepareTransmit(usbp, 0, NULL, 0);
osalSysLockFromISR();
(void) usbStartTransmitI(usbp, 0);
usbStartTransmitI(usbp, 0, NULL, 0);
osalSysUnlockFromISR();
#else
usb_lld_end_setup(usbp, ep);
@ -931,7 +894,7 @@ void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
/* Status packet received, it must be zero sized, invoking the callback
if defined.*/
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
if (usbGetReceiveTransactionSizeI(usbp, 0) != 0U) {
if (usbGetReceiveTransactionSizeX(usbp, 0) != 0U) {
break;
}
#endif

View File

@ -5,7 +5,7 @@
# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
endif
# C specific options here (added to USE_OPT).

View File

@ -23,8 +23,7 @@
#include "usbcfg.h"
/* Can be measured using dd if=/dev/xxxx of=/dev/null bs=512 count=10000.*/
static uint8_t buf[] =
static const uint8_t txbuf[] =
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
@ -42,8 +41,12 @@ static uint8_t buf[] =
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
static uint8_t rxbuf[1024];
/*
* Red LED blinker thread, times are in milliseconds.
* USB writer. This thread writes data to the USB at maximum rate.
* Can be measured using:
* dd if=/dev/xxxx of=/dev/null bs=512 count=10000
*/
static THD_WORKING_AREA(waWriter, 128);
static THD_FUNCTION(Writer, arg) {
@ -51,13 +54,28 @@ static THD_FUNCTION(Writer, arg) {
(void)arg;
chRegSetThreadName("writer");
while (true) {
if (USBD2.state == USB_ACTIVE) {
msg_t msg = usbTransmit(&USBD2, USBD2_DATA_REQUEST_EP,
buf, sizeof (buf) - 1);
if (msg == MSG_OK)
continue;
}
chThdSleepMilliseconds(500);
msg_t msg = usbTransmit(&USBD2, USBD2_DATA_REQUEST_EP,
txbuf, sizeof (txbuf) - 1);
if (msg == MSG_RESET)
chThdSleepMilliseconds(500);
}
}
/*
* USB reader. This thread reads data from the USB at maximum rate.
* Can be measured using:
* dd if=bigfile of=/dev/xxx bs=512 count=10000
*/
static THD_WORKING_AREA(waReader, 128);
static THD_FUNCTION(Reader, arg) {
(void)arg;
chRegSetThreadName("reader");
while (true) {
msg_t msg = usbReceive(&USBD2, USBD2_DATA_AVAILABLE_EP,
rxbuf, sizeof (rxbuf) - 1);
if (msg == MSG_RESET)
chThdSleepMilliseconds(500);
}
}
@ -116,6 +134,7 @@ int main(void) {
*/
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
chThdCreateStatic(waWriter, sizeof(waWriter), NORMALPRIO, Writer, NULL);
chThdCreateStatic(waReader, sizeof(waReader), NORMALPRIO, Reader, NULL);
/*
* Normal main() thread activity, in this demo it does nothing except