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-d51de3d6d3f4master
parent
d93fdcd424
commit
de202dd376
|
@ -412,9 +412,9 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
||||||
* @param[in] usbp pointer to the @p USBDriver object
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
* @return The current frame number.
|
* @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.
|
* @brief Returns the status of an IN endpoint.
|
||||||
|
@ -454,9 +454,9 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
||||||
* @param[in] ep endpoint number
|
* @param[in] ep endpoint number
|
||||||
* @return Received data size.
|
* @return Received data size.
|
||||||
*
|
*
|
||||||
* @iclass
|
* @xclass
|
||||||
*/
|
*/
|
||||||
#define usbGetReceiveTransactionSizeI(usbp, ep) \
|
#define usbGetReceiveTransactionSizeX(usbp, ep) \
|
||||||
usb_lld_get_transaction_size(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] n number of bytes to be transferred
|
||||||
* @param[in] endcb callback to be invoked after the transfer or @p NULL
|
* @param[in] endcb callback to be invoked after the transfer or @p NULL
|
||||||
*
|
*
|
||||||
* @api
|
* @special
|
||||||
*/
|
*/
|
||||||
#define usbSetupTransfer(usbp, buf, n, endcb) { \
|
#define usbSetupTransfer(usbp, buf, n, endcb) { \
|
||||||
(usbp)->ep0next = (buf); \
|
(usbp)->ep0next = (buf); \
|
||||||
|
@ -580,7 +580,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
||||||
} \
|
} \
|
||||||
osalSysLockFromISR(); \
|
osalSysLockFromISR(); \
|
||||||
osalThreadResumeI(&(usbp)->epc[ep]->out_state->thread, \
|
osalThreadResumeI(&(usbp)->epc[ep]->out_state->thread, \
|
||||||
usbGetReceiveTransactionSizeI(usbp, ep)); \
|
usbGetReceiveTransactionSizeX(usbp, ep)); \
|
||||||
osalSysUnlockFromISR(); \
|
osalSysUnlockFromISR(); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -608,12 +608,10 @@ extern "C" {
|
||||||
const USBEndpointConfig *epcp);
|
const USBEndpointConfig *epcp);
|
||||||
void usbDisableEndpointsI(USBDriver *usbp);
|
void usbDisableEndpointsI(USBDriver *usbp);
|
||||||
void usbReadSetupI(USBDriver *usbp, usbep_t ep, uint8_t *buf);
|
void usbReadSetupI(USBDriver *usbp, usbep_t ep, uint8_t *buf);
|
||||||
void usbPrepareReceive(USBDriver *usbp, usbep_t ep,
|
void usbStartReceiveI(USBDriver *usbp, usbep_t ep,
|
||||||
uint8_t *buf, size_t n);
|
uint8_t *buf, size_t n);
|
||||||
void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
|
void usbStartTransmitI(USBDriver *usbp, usbep_t ep,
|
||||||
const uint8_t *buf, size_t n);
|
const uint8_t *buf, size_t n);
|
||||||
bool usbStartReceiveI(USBDriver *usbp, usbep_t ep);
|
|
||||||
bool usbStartTransmitI(USBDriver *usbp, usbep_t ep);
|
|
||||||
#if USB_USE_WAIT == TRUE
|
#if USB_USE_WAIT == TRUE
|
||||||
msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n);
|
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);
|
msg_t usbTransmit(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n);
|
||||||
|
|
|
@ -369,7 +369,6 @@ static void otg_epin_handler(USBDriver *usbp, usbep_t ep) {
|
||||||
cover the remaining.*/
|
cover the remaining.*/
|
||||||
isp->txsize = isp->totsize - isp->txsize;
|
isp->txsize = isp->totsize - isp->txsize;
|
||||||
isp->txcnt = 0;
|
isp->txcnt = 0;
|
||||||
usb_lld_prepare_transmit(usbp, ep);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
usb_lld_start_in(usbp, ep);
|
usb_lld_start_in(usbp, ep);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
|
@ -415,13 +414,14 @@ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) {
|
||||||
/* Receive transfer complete.*/
|
/* Receive transfer complete.*/
|
||||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
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
|
/* In case the transaction covered only part of the total transfer
|
||||||
then another transaction is immediately started in order to
|
then another transaction is immediately started in order to
|
||||||
cover the remaining.*/
|
cover the remaining.*/
|
||||||
osp->rxsize = osp->totsize - osp->rxsize;
|
osp->rxsize = osp->totsize - osp->rxsize;
|
||||||
osp->rxcnt = 0;
|
osp->rxcnt = 0;
|
||||||
usb_lld_prepare_receive(usbp, ep);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
usb_lld_start_out(usbp, ep);
|
usb_lld_start_out(usbp, ep);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
|
@ -476,7 +476,6 @@ static void otg_isoc_in_failed_handler(USBDriver *usbp) {
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void otg_isoc_out_failed_handler(USBDriver *usbp) {
|
static void otg_isoc_out_failed_handler(USBDriver *usbp) {
|
||||||
usbep_t ep;
|
usbep_t ep;
|
||||||
stm32_otg_t *otgp = usbp->otg;
|
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);
|
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.
|
* @brief Starts a receive operation on an OUT endpoint.
|
||||||
*
|
*
|
||||||
|
@ -1197,7 +1142,28 @@ void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) {
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
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) {
|
if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
|
||||||
/* Odd/even bit toggling for isochronous endpoint.*/
|
/* Odd/even bit toggling for isochronous endpoint.*/
|
||||||
if (usbp->otg->DSTS & DSTS_FNSOF_ODD)
|
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;
|
usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_SODDFRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Starting operation.*/
|
||||||
usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK;
|
usbp->otg->oe[ep].DOEPCTL |= DOEPCTL_EPENA | DOEPCTL_CNAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1218,7 +1185,27 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
|
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) {
|
if ((usbp->epc[ep]->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
|
||||||
/* Odd/even bit toggling.*/
|
/* Odd/even bit toggling.*/
|
||||||
if (usbp->otg->DSTS & DSTS_FNSOF_ODD)
|
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;
|
usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_SODDFRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Starting operation.*/
|
||||||
usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK;
|
usbp->otg->ie[ep].DIEPCTL |= DIEPCTL_EPENA | DIEPCTL_CNAK;
|
||||||
usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep);
|
usbp->otg->DIEPEMPMSK |= DIEPEMPMSK_INEPTXFEM(ep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -540,8 +540,6 @@ extern "C" {
|
||||||
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
|
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep);
|
||||||
usbepstatus_t usb_lld_get_status_out(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_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_out(USBDriver *usbp, usbep_t ep);
|
||||||
void usb_lld_start_in(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);
|
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep);
|
||||||
|
|
|
@ -146,13 +146,8 @@ static void ibnotify(io_buffers_queue_t *bqp) {
|
||||||
uint8_t *buf = ibqGetEmptyBufferI(&sdup->ibqueue);
|
uint8_t *buf = ibqGetEmptyBufferI(&sdup->ibqueue);
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
/* Buffer found, starting a new transaction.*/
|
/* Buffer found, starting a new transaction.*/
|
||||||
osalSysUnlock();
|
usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out,
|
||||||
|
buf, SERIAL_USB_BUFFERS_SIZE);
|
||||||
usbPrepareReceive(sdup->config->usbp, sdup->config->bulk_out,
|
|
||||||
buf, SERIAL_USB_BUFFERS_SIZE);
|
|
||||||
|
|
||||||
osalSysLock();
|
|
||||||
(void) usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -179,12 +174,7 @@ static void obnotify(io_buffers_queue_t *bqp) {
|
||||||
uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
|
uint8_t *buf = obqGetFullBufferI(&sdup->obqueue, &n);
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
/* Buffer found, starting a new transaction.*/
|
/* Buffer found, starting a new transaction.*/
|
||||||
osalSysUnlock();
|
usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
|
||||||
|
|
||||||
usbPrepareTransmit(sdup->config->usbp, sdup->config->bulk_in, buf, n);
|
|
||||||
|
|
||||||
osalSysLock();
|
|
||||||
(void) usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,9 +309,8 @@ void sduConfigureHookI(SerialUSBDriver *sdup) {
|
||||||
|
|
||||||
osalDbgAssert(buf != NULL, "no free buffer");
|
osalDbgAssert(buf != NULL, "no free buffer");
|
||||||
|
|
||||||
usbPrepareReceive(sdup->config->usbp, sdup->config->bulk_out,
|
usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out,
|
||||||
buf, SERIAL_USB_BUFFERS_SIZE);
|
buf, SERIAL_USB_BUFFERS_SIZE);
|
||||||
(void) usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -392,12 +381,7 @@ void sduSOFHookI(SerialUSBDriver *sdup) {
|
||||||
|
|
||||||
osalDbgAssert(buf != NULL, "queue is empty");
|
osalDbgAssert(buf != NULL, "queue is empty");
|
||||||
|
|
||||||
osalSysUnlockFromISR();
|
usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in, buf, n);
|
||||||
|
|
||||||
usbPrepareTransmit(sdup->config->usbp, sdup->config->bulk_in, buf, n);
|
|
||||||
|
|
||||||
osalSysLockFromISR();
|
|
||||||
(void) usbStartTransmitI(sdup->config->usbp, sdup->config->bulk_in);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,13 +415,10 @@ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
|
||||||
/* Checking if there is a buffer ready for transmission.*/
|
/* Checking if there is a buffer ready for transmission.*/
|
||||||
buf = obqGetFullBufferI(&sdup->obqueue, &n);
|
buf = obqGetFullBufferI(&sdup->obqueue, &n);
|
||||||
|
|
||||||
/* Unlocking the critical zone.*/
|
|
||||||
osalSysUnlockFromISR();
|
|
||||||
|
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
/* The endpoint cannot be busy, we are in the context of the callback,
|
/* The endpoint cannot be busy, we are in the context of the callback,
|
||||||
so it is safe to transmit without a check.*/
|
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) &&
|
else if ((usbp->epc[ep]->in_state->txsize > 0U) &&
|
||||||
((usbp->epc[ep]->in_state->txsize &
|
((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
|
size. Otherwise the recipient may expect more data coming soon and
|
||||||
not return buffered data to app. See section 5.8.3 Bulk Transfer
|
not return buffered data to app. See section 5.8.3 Bulk Transfer
|
||||||
Packet Size Constraints of the USB Specification document.*/
|
Packet Size Constraints of the USB Specification document.*/
|
||||||
usbPrepareTransmit(usbp, ep, usbp->setup, 0);
|
usbStartTransmitI(usbp, ep, usbp->setup, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Nothing to transmit.*/
|
/* Nothing to transmit.*/
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Locking again and starting transmission.*/
|
|
||||||
osalSysLockFromISR();
|
|
||||||
(void) usbStartTransmitI(usbp, ep);
|
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +460,7 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) {
|
||||||
|
|
||||||
/* Posting the filled buffer in the queue.*/
|
/* Posting the filled buffer in the queue.*/
|
||||||
ibqPostFullBufferI(&sdup->ibqueue,
|
ibqPostFullBufferI(&sdup->ibqueue,
|
||||||
usbGetReceiveTransactionSizeI(sdup->config->usbp,
|
usbGetReceiveTransactionSizeX(sdup->config->usbp,
|
||||||
sdup->config->bulk_out));
|
sdup->config->bulk_out));
|
||||||
|
|
||||||
/* The endpoint cannot be busy, we are in the context of the callback,
|
/* 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);
|
buf = ibqGetEmptyBufferI(&sdup->ibqueue);
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
/* Buffer found, starting a new transaction.*/
|
/* Buffer found, starting a new transaction.*/
|
||||||
osalSysUnlockFromISR();
|
usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out,
|
||||||
usbPrepareReceive(sdup->config->usbp, sdup->config->bulk_out,
|
buf, SERIAL_USB_BUFFERS_SIZE);
|
||||||
buf, SERIAL_USB_BUFFERS_SIZE);
|
|
||||||
osalSysLockFromISR();
|
|
||||||
(void) usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out);
|
|
||||||
}
|
}
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
}
|
}
|
||||||
|
|
159
os/hal/src/usb.c
159
os/hal/src/usb.c
|
@ -401,22 +401,31 @@ void usbDisableEndpointsI(USBDriver *usbp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
* @brief Starts a receive transaction on an OUT endpoint.
|
||||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
* @note This function is meant to be called from ISR context outside
|
||||||
* @note This function can be called both in ISR and thread context.
|
* critical zones because there is a potentially slow operation
|
||||||
|
* inside.
|
||||||
*
|
*
|
||||||
* @param[in] usbp pointer to the @p USBDriver object
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
* @param[in] ep endpoint number
|
* @param[in] ep endpoint number
|
||||||
* @param[out] buf buffer where to copy the received data
|
* @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;
|
USBOutEndpointState *osp;
|
||||||
|
|
||||||
|
osalDbgCheckClassI();
|
||||||
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
|
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 = usbp->epc[ep]->out_state;
|
||||||
osp->rxbuf = buf;
|
osp->rxbuf = buf;
|
||||||
osp->rxsize = n;
|
osp->rxsize = n;
|
||||||
|
@ -425,29 +434,35 @@ void usbPrepareReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
|
||||||
osp->thread = NULL;
|
osp->thread = NULL;
|
||||||
#endif
|
#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.
|
* @brief Starts a transmit transaction on an IN endpoint.
|
||||||
* @post The endpoint is ready for @p usbStartTransmitI().
|
* @note This function is meant to be called from ISR context outside
|
||||||
* @note This function can be called both in ISR and thread context.
|
* critical zones because there is a potentially slow operation
|
||||||
* @note The queue must contain at least the amount of data specified
|
* inside.
|
||||||
* as transaction size.
|
|
||||||
*
|
*
|
||||||
* @param[in] usbp pointer to the @p USBDriver object
|
* @param[in] usbp pointer to the @p USBDriver object
|
||||||
* @param[in] ep endpoint number
|
* @param[in] ep endpoint number
|
||||||
* @param[in] buf buffer where to fetch the data to be transmitted
|
* @param[in] buf buffer where to fetch the data to be transmitted
|
||||||
* @param[in] n transaction size
|
* @param[in] n transaction size
|
||||||
*
|
*
|
||||||
* @special
|
* @iclass
|
||||||
*/
|
*/
|
||||||
void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
|
void usbStartTransmitI(USBDriver *usbp, usbep_t ep,
|
||||||
const uint8_t *buf, size_t n) {
|
const uint8_t *buf, size_t n) {
|
||||||
USBInEndpointState *isp;
|
USBInEndpointState *isp;
|
||||||
|
|
||||||
|
osalDbgCheckClassI();
|
||||||
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
|
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 = usbp->epc[ep]->in_state;
|
||||||
isp->txbuf = buf;
|
isp->txbuf = buf;
|
||||||
isp->txsize = n;
|
isp->txsize = n;
|
||||||
|
@ -456,63 +471,8 @@ void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
|
||||||
isp->thread = NULL;
|
isp->thread = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
usb_lld_prepare_transmit(usbp, ep);
|
/* Starting transfer.*/
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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);
|
|
||||||
usb_lld_start_in(usbp, ep);
|
usb_lld_start_in(usbp, ep);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
#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
|
* @return The received effective data size, it can be less than
|
||||||
* the amount specified.
|
* the amount specified.
|
||||||
* @retval MSG_RESET operation aborted by a reset.
|
* @retval MSG_RESET driver not in @p USB_ACTIVE state or the operation
|
||||||
* @retval MSG_TIMEOUT operation aborted by a suspend.
|
* has been aborted by an USB reset or a transition to
|
||||||
|
* the @p USB_SUSPENDED state.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
|
msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
|
|
||||||
usbPrepareReceive(usbp, ep, buf, n);
|
|
||||||
|
|
||||||
osalSysLock();
|
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);
|
msg = osalThreadSuspendS(&usbp->epc[ep]->out_state->thread);
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
|
||||||
|
@ -555,18 +520,23 @@ msg_t usbReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval MSG_OK operation performed successfully.
|
* @retval MSG_OK operation performed successfully.
|
||||||
* @retval MSG_RESET operation aborted by a reset.
|
* @retval MSG_RESET driver not in @p USB_ACTIVE state or the operation
|
||||||
* @retval MSG_TIMEOUT operation aborted by a suspend.
|
* has been aborted by an USB reset or a transition to
|
||||||
|
* the @p USB_SUSPENDED state.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
msg_t usbTransmit(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) {
|
msg_t usbTransmit(USBDriver *usbp, usbep_t ep, const uint8_t *buf, size_t n) {
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
|
|
||||||
usbPrepareTransmit(usbp, ep, buf, n);
|
|
||||||
|
|
||||||
osalSysLock();
|
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);
|
msg = osalThreadSuspendS(&usbp->epc[ep]->in_state->thread);
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
|
||||||
|
@ -700,10 +670,10 @@ void _usb_suspend(USBDriver *usbp) {
|
||||||
if (usbp->epc[i] != NULL) {
|
if (usbp->epc[i] != NULL) {
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
if (usbp->epc[i]->in_state != NULL) {
|
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) {
|
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();
|
osalSysUnlockFromISR();
|
||||||
}
|
}
|
||||||
|
@ -787,9 +757,8 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
||||||
if (usbp->ep0n != 0U) {
|
if (usbp->ep0n != 0U) {
|
||||||
/* Starts the transmit phase.*/
|
/* Starts the transmit phase.*/
|
||||||
usbp->ep0state = USB_EP0_TX;
|
usbp->ep0state = USB_EP0_TX;
|
||||||
usbPrepareTransmit(usbp, 0, usbp->ep0next, usbp->ep0n);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
(void) usbStartTransmitI(usbp, 0);
|
usbStartTransmitI(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -797,9 +766,8 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
||||||
packet.*/
|
packet.*/
|
||||||
usbp->ep0state = USB_EP0_WAITING_STS;
|
usbp->ep0state = USB_EP0_WAITING_STS;
|
||||||
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
||||||
usbPrepareReceive(usbp, 0, NULL, 0);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
(void) usbStartReceiveI(usbp, 0);
|
usbStartReceiveI(usbp, 0, NULL, 0);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
#else
|
#else
|
||||||
usb_lld_end_setup(usbp, ep);
|
usb_lld_end_setup(usbp, ep);
|
||||||
|
@ -811,9 +779,8 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
||||||
if (usbp->ep0n != 0U) {
|
if (usbp->ep0n != 0U) {
|
||||||
/* Starts the receive phase.*/
|
/* Starts the receive phase.*/
|
||||||
usbp->ep0state = USB_EP0_RX;
|
usbp->ep0state = USB_EP0_RX;
|
||||||
usbPrepareReceive(usbp, 0, usbp->ep0next, usbp->ep0n);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
(void) usbStartReceiveI(usbp, 0);
|
usbStartReceiveI(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -821,9 +788,8 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
||||||
packet.*/
|
packet.*/
|
||||||
usbp->ep0state = USB_EP0_SENDING_STS;
|
usbp->ep0state = USB_EP0_SENDING_STS;
|
||||||
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
||||||
usbPrepareTransmit(usbp, 0, NULL, 0);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
(void) usbStartTransmitI(usbp, 0);
|
usbStartTransmitI(usbp, 0, NULL, 0);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
#else
|
#else
|
||||||
usb_lld_end_setup(usbp, ep);
|
usb_lld_end_setup(usbp, ep);
|
||||||
|
@ -854,9 +820,8 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
|
||||||
transmitted.*/
|
transmitted.*/
|
||||||
if ((usbp->ep0n < max) &&
|
if ((usbp->ep0n < max) &&
|
||||||
((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0U)) {
|
((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0U)) {
|
||||||
usbPrepareTransmit(usbp, 0, NULL, 0);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
(void) usbStartTransmitI(usbp, 0);
|
usbStartTransmitI(usbp, 0, NULL, 0);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
usbp->ep0state = USB_EP0_WAITING_TX0;
|
usbp->ep0state = USB_EP0_WAITING_TX0;
|
||||||
return;
|
return;
|
||||||
|
@ -866,9 +831,8 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
|
||||||
/* Transmit phase over, receiving the zero sized status packet.*/
|
/* Transmit phase over, receiving the zero sized status packet.*/
|
||||||
usbp->ep0state = USB_EP0_WAITING_STS;
|
usbp->ep0state = USB_EP0_WAITING_STS;
|
||||||
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
||||||
usbPrepareReceive(usbp, 0, NULL, 0);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
(void) usbStartReceiveI(usbp, 0);
|
usbStartReceiveI(usbp, 0, NULL, 0);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
#else
|
#else
|
||||||
usb_lld_end_setup(usbp, ep);
|
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.*/
|
/* Receive phase over, sending the zero sized status packet.*/
|
||||||
usbp->ep0state = USB_EP0_SENDING_STS;
|
usbp->ep0state = USB_EP0_SENDING_STS;
|
||||||
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
||||||
usbPrepareTransmit(usbp, 0, NULL, 0);
|
|
||||||
osalSysLockFromISR();
|
osalSysLockFromISR();
|
||||||
(void) usbStartTransmitI(usbp, 0);
|
usbStartTransmitI(usbp, 0, NULL, 0);
|
||||||
osalSysUnlockFromISR();
|
osalSysUnlockFromISR();
|
||||||
#else
|
#else
|
||||||
usb_lld_end_setup(usbp, ep);
|
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
|
/* Status packet received, it must be zero sized, invoking the callback
|
||||||
if defined.*/
|
if defined.*/
|
||||||
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
#if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW)
|
||||||
if (usbGetReceiveTransactionSizeI(usbp, 0) != 0U) {
|
if (usbGetReceiveTransactionSizeX(usbp, 0) != 0U) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# Compiler options here.
|
# Compiler options here.
|
||||||
ifeq ($(USE_OPT),)
|
ifeq ($(USE_OPT),)
|
||||||
USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
|
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# C specific options here (added to USE_OPT).
|
# C specific options here (added to USE_OPT).
|
||||||
|
|
|
@ -23,8 +23,7 @@
|
||||||
|
|
||||||
#include "usbcfg.h"
|
#include "usbcfg.h"
|
||||||
|
|
||||||
/* Can be measured using dd if=/dev/xxxx of=/dev/null bs=512 count=10000.*/
|
static const uint8_t txbuf[] =
|
||||||
static uint8_t buf[] =
|
|
||||||
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
|
@ -42,8 +41,12 @@ static uint8_t buf[] =
|
||||||
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||||
"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_WORKING_AREA(waWriter, 128);
|
||||||
static THD_FUNCTION(Writer, arg) {
|
static THD_FUNCTION(Writer, arg) {
|
||||||
|
@ -51,13 +54,28 @@ static THD_FUNCTION(Writer, arg) {
|
||||||
(void)arg;
|
(void)arg;
|
||||||
chRegSetThreadName("writer");
|
chRegSetThreadName("writer");
|
||||||
while (true) {
|
while (true) {
|
||||||
if (USBD2.state == USB_ACTIVE) {
|
msg_t msg = usbTransmit(&USBD2, USBD2_DATA_REQUEST_EP,
|
||||||
msg_t msg = usbTransmit(&USBD2, USBD2_DATA_REQUEST_EP,
|
txbuf, sizeof (txbuf) - 1);
|
||||||
buf, sizeof (buf) - 1);
|
if (msg == MSG_RESET)
|
||||||
if (msg == MSG_OK)
|
chThdSleepMilliseconds(500);
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
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(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
|
||||||
chThdCreateStatic(waWriter, sizeof(waWriter), NORMALPRIO, Writer, 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
|
* Normal main() thread activity, in this demo it does nothing except
|
||||||
|
|
Loading…
Reference in New Issue