aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2015-12-28 11:16:40 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2015-12-28 11:16:40 +0000
commitde202dd376ea3109e21f535554647689dda23c7b (patch)
treee7247994911999dc69ab1755346057df768309bb /os/hal/src
parentd93fdcd424c049078009119940d0042bb229ed38 (diff)
downloadChibiOS-de202dd376ea3109e21f535554647689dda23c7b.tar.gz
ChibiOS-de202dd376ea3109e21f535554647689dda23c7b.tar.bz2
ChibiOS-de202dd376ea3109e21f535554647689dda23c7b.zip
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
Diffstat (limited to 'os/hal/src')
-rw-r--r--os/hal/src/serial_usb.c48
-rw-r--r--os/hal/src/usb.c159
2 files changed, 72 insertions, 135 deletions
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index a5e8247a8..d4525c52f 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -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();
}
diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c
index b6813c381..4f52424fb 100644
--- a/os/hal/src/usb.c
+++ b/os/hal/src/usb.c
@@ -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