USB synchronous API, to be completed.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8648 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
ae70b0edce
commit
eb0c1ac0c3
|
@ -236,6 +236,14 @@
|
|||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define USB_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
@ -537,10 +545,24 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
#define _usb_isr_invoke_in_cb(usbp, ep) { \
|
||||
(usbp)->transmitting &= ~(1 << (ep)); \
|
||||
(usbp)->epc[ep]->in_cb(usbp, ep); \
|
||||
if ((usbp)->epc[ep]->in_cb != NULL) { \
|
||||
(usbp)->epc[ep]->in_cb(usbp, ep); \
|
||||
} \
|
||||
osalSysLockFromISR(); \
|
||||
osalThreadResumeI(&(usbp)->epc[ep]->in_state->thread, MSG_OK); \
|
||||
osalSysUnlockFromISR(); \
|
||||
}
|
||||
#else
|
||||
#define _usb_isr_invoke_in_cb(usbp, ep) { \
|
||||
(usbp)->transmitting &= ~(1 << (ep)); \
|
||||
if ((usbp)->epc[ep]->in_cb != NULL) { \
|
||||
(usbp)->epc[ep]->in_cb(usbp, ep); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, OUT endpoint event.
|
||||
|
@ -550,10 +572,25 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
#define _usb_isr_invoke_out_cb(usbp, ep) { \
|
||||
(usbp)->receiving &= ~(1 << (ep)); \
|
||||
(usbp)->epc[ep]->out_cb(usbp, ep); \
|
||||
if ((usbp)->epc[ep]->out_cb != NULL) { \
|
||||
(usbp)->epc[ep]->out_cb(usbp, ep); \
|
||||
} \
|
||||
osalSysLockFromISR(); \
|
||||
osalThreadResumeI(&(usbp)->epc[ep]->out_state->thread, \
|
||||
usbGetReceiveTransactionSizeI(usbp, ep)); \
|
||||
osalSysUnlockFromISR(); \
|
||||
}
|
||||
#else
|
||||
#define _usb_isr_invoke_out_cb(usbp, ep) { \
|
||||
(usbp)->receiving &= ~(1 << (ep)); \
|
||||
if ((usbp)->epc[ep]->out_cb != NULL) { \
|
||||
(usbp)->epc[ep]->out_cb(usbp, ep); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -577,6 +614,10 @@ extern "C" {
|
|||
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
|
||||
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);
|
||||
#endif
|
||||
bool usbStallReceiveI(USBDriver *usbp, usbep_t ep);
|
||||
bool usbStallTransmitI(USBDriver *usbp, usbep_t ep);
|
||||
void _usb_reset(USBDriver *usbp);
|
||||
|
|
|
@ -422,9 +422,9 @@ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) {
|
|||
osp->rxsize = osp->totsize - osp->rxsize;
|
||||
osp->rxcnt = 0;
|
||||
usb_lld_prepare_receive(usbp, ep);
|
||||
chSysLockFromISR();
|
||||
osalSysLockFromISR();
|
||||
usb_lld_start_out(usbp, ep);
|
||||
chSysUnlockFromISR();
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
else {
|
||||
/* End on OUT transfer.*/
|
||||
|
@ -1005,7 +1005,7 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
|||
|
||||
/* OUT endpoint activation or deactivation.*/
|
||||
otgp->oe[ep].DOEPTSIZ = 0;
|
||||
if (usbp->epc[ep]->out_cb != NULL) {
|
||||
if (usbp->epc[ep]->out_maxsize != 0) {
|
||||
otgp->oe[ep].DOEPCTL = ctl | DOEPCTL_MPSIZ(usbp->epc[ep]->out_maxsize);
|
||||
otgp->DAINTMSK |= DAINTMSK_OEPM(ep);
|
||||
}
|
||||
|
@ -1016,7 +1016,7 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
|||
|
||||
/* IN endpoint activation or deactivation.*/
|
||||
otgp->ie[ep].DIEPTSIZ = 0;
|
||||
if (usbp->epc[ep]->in_cb != NULL) {
|
||||
if (usbp->epc[ep]->in_maxsize != 0) {
|
||||
/* FIFO allocation for the IN endpoint.*/
|
||||
fsize = usbp->epc[ep]->in_maxsize / 4;
|
||||
if (usbp->epc[ep]->in_multiplier > 1)
|
||||
|
|
|
@ -226,6 +226,12 @@ typedef struct {
|
|||
* @brief Pointer to the transmission linear buffer.
|
||||
*/
|
||||
const uint8_t *txbuf;
|
||||
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waiting thread.
|
||||
*/
|
||||
thread_reference_t thread;
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Total transmit transfer size.
|
||||
|
@ -249,6 +255,12 @@ typedef struct {
|
|||
* @brief Pointer to the receive linear buffer.
|
||||
*/
|
||||
uint8_t *rxbuf;
|
||||
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waiting thread.
|
||||
*/
|
||||
thread_reference_t thread;
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Total transmit transfer size.
|
||||
|
@ -278,14 +290,14 @@ typedef struct {
|
|||
usbepcallback_t setup_cb;
|
||||
/**
|
||||
* @brief IN endpoint notification callback.
|
||||
* @details This field must be set to @p NULL if the IN endpoint is not
|
||||
* used.
|
||||
* @details This field must can be set to @p NULL if callback is not
|
||||
* required.
|
||||
*/
|
||||
usbepcallback_t in_cb;
|
||||
/**
|
||||
* @brief OUT endpoint notification callback.
|
||||
* @details This field must be set to @p NULL if the OUT endpoint is not
|
||||
* used.
|
||||
* @details This field must can be set to @p NULL if callback is not
|
||||
* required.
|
||||
*/
|
||||
usbepcallback_t out_cb;
|
||||
/**
|
||||
|
|
|
@ -345,13 +345,6 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
|
|||
osalDbgAssert(usbp->epc[ep] == NULL, "already initialized");
|
||||
|
||||
/* Logically enabling the endpoint in the USBDriver structure.*/
|
||||
if (epcp->in_state != NULL) {
|
||||
memset(epcp->in_state, 0, sizeof(USBInEndpointState));
|
||||
}
|
||||
if (epcp->out_state != NULL) {
|
||||
memset(epcp->out_state, 0, sizeof(USBOutEndpointState));
|
||||
}
|
||||
|
||||
usbp->epc[ep] = epcp;
|
||||
|
||||
/* Low level endpoint activation.*/
|
||||
|
@ -399,11 +392,17 @@ void usbDisableEndpointsI(USBDriver *usbp) {
|
|||
* @special
|
||||
*/
|
||||
void usbPrepareReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
USBOutEndpointState *osp;
|
||||
|
||||
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
|
||||
|
||||
osp = usbp->epc[ep]->out_state;
|
||||
osp->rxbuf = buf;
|
||||
osp->rxsize = n;
|
||||
osp->rxcnt = 0;
|
||||
#if USB_USE_WAIT == TRUE
|
||||
osp->thread = NULL;
|
||||
#endif
|
||||
|
||||
usb_lld_prepare_receive(usbp, ep);
|
||||
}
|
||||
|
@ -424,11 +423,17 @@ 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) {
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
USBInEndpointState *isp;
|
||||
|
||||
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
|
||||
|
||||
isp = usbp->epc[ep]->in_state;
|
||||
isp->txbuf = buf;
|
||||
isp->txsize = n;
|
||||
isp->txcnt = 0;
|
||||
#if USB_USE_WAIT == TRUE
|
||||
isp->thread = NULL;
|
||||
#endif
|
||||
|
||||
usb_lld_prepare_transmit(usbp, ep);
|
||||
}
|
||||
|
@ -450,7 +455,7 @@ void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
|
|||
bool usbStartReceiveI(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
osalDbgCheckClassI();
|
||||
osalDbgCheck(usbp != NULL);
|
||||
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
|
||||
|
||||
if (usbGetReceiveStatusI(usbp, ep)) {
|
||||
return true;
|
||||
|
@ -478,7 +483,7 @@ bool usbStartReceiveI(USBDriver *usbp, usbep_t ep) {
|
|||
bool usbStartTransmitI(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
osalDbgCheckClassI();
|
||||
osalDbgCheck(usbp != NULL);
|
||||
osalDbgCheck((usbp != NULL) && (ep <= USB_MAX_ENDPOINTS));
|
||||
|
||||
if (usbGetTransmitStatusI(usbp, ep)) {
|
||||
return true;
|
||||
|
@ -489,6 +494,63 @@ bool usbStartTransmitI(USBDriver *usbp, usbep_t ep) {
|
|||
return false;
|
||||
}
|
||||
|
||||
#if (USB_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Performs a receive transaction on an OUT endpoint.
|
||||
*
|
||||
* @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. It is recommended a multiple of
|
||||
* the packet size because the excess is discarded.
|
||||
*
|
||||
* @return The received data effective size, it can be less than
|
||||
* the amount specified.
|
||||
* @retval MSG_RESET operation aborted by a reset.
|
||||
*
|
||||
* @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);
|
||||
msg = osalThreadSuspendS(&usbp->epc[ep]->out_state->thread);
|
||||
osalSysUnlock();
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Performs a transmit transaction on an IN endpoint.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK operation performed successfully.
|
||||
* @retval MSG_RESET operation aborted by a reset.
|
||||
*
|
||||
* @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();
|
||||
usbStartReceiveI(usbp, ep);
|
||||
msg = osalThreadSuspendS(&usbp->epc[ep]->in_state->thread);
|
||||
osalSysUnlock();
|
||||
|
||||
return msg;
|
||||
}
|
||||
#endif /* USB_USE_WAIT == TRUE */
|
||||
|
||||
/**
|
||||
* @brief Stalls an OUT endpoint.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue