USB driver API improvements. Revision of the low level drivers.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4284 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
c691408183
commit
25ac1fcadf
|
@ -385,76 +385,6 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
|||
*/
|
||||
#define usbGetReceiveStatusI(usbp, ep) ((usbp)->receiving & (1 << (ep)))
|
||||
|
||||
/**
|
||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized in transaction mode.
|
||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
||||
*
|
||||
* @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 maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define usbPrepareReceive(usbp, ep, buf, n) \
|
||||
usb_lld_prepare_receive(usbp, ep, buf, n)
|
||||
|
||||
/**
|
||||
* @brief Prepares for a transmit transaction on an IN endpoint.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized in transaction mode.
|
||||
* @post The endpoint is ready for @p usbStartTransmitI().
|
||||
*
|
||||
* @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 maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define usbPrepareTransmit(usbp, ep, buf, n) \
|
||||
usb_lld_prepare_transmit(usbp, ep, buf, n)
|
||||
|
||||
/**
|
||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized in transaction mode.
|
||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
||||
* @note The receive transaction size is equal to the space in the queue
|
||||
* rounded to the lower multiple of a packet size. Make sure there
|
||||
* is room for at least one packet in the queue before starting
|
||||
* the receive operation.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] iq input queue to be filled with incoming data
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define usbPrepareQueuedReceive(usbp, ep, iq, n) \
|
||||
usb_lld_prepare_queued_receive(usbp, ep, iq, n)
|
||||
|
||||
/**
|
||||
* @brief Prepares for a transmit transaction on an IN endpoint.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized in transaction mode.
|
||||
* @post The endpoint is ready for @p usbStartTransmitI().
|
||||
* @note The transmit transaction size is equal to the data contained
|
||||
* in the queue.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] oq output queue to be fetched for outgoing data
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define usbPrepareQueuedTransmit(usbp, ep, oq, n) \
|
||||
usb_lld_prepare_queued_transmit(usbp, ep, oq, n)
|
||||
|
||||
/**
|
||||
* @brief Returns the exact size of a receive transaction.
|
||||
* @details The received size can be different from the size specified in
|
||||
|
@ -604,6 +534,14 @@ 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);
|
||||
void usbPrepareQueuedReceive(USBDriver *usbp, usbep_t ep,
|
||||
InputQueue *iqp, size_t n);
|
||||
void usbPrepareQueuedTransmit(USBDriver *usbp, usbep_t ep,
|
||||
OutputQueue *oqp, size_t n);
|
||||
bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep);
|
||||
bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep);
|
||||
bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep);
|
||||
|
|
|
@ -187,61 +187,6 @@ static uint32_t otg_ram_alloc(USBDriver *usbp, size_t size) {
|
|||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
static void otg_prepare_receive(USBDriver *usbp, usbep_t ep, size_t n) {
|
||||
uint32_t pcnt;
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
|
||||
osp->rxsize = n;
|
||||
osp->rxcnt = 0;
|
||||
|
||||
/* Transfer initialization.*/
|
||||
pcnt = (n + usbp->epc[ep]->out_maxsize - 1) / usbp->epc[ep]->out_maxsize;
|
||||
OTG->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) |
|
||||
DOEPTSIZ_XFRSIZ(usbp->epc[ep]->out_maxsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a transmit transaction on an IN endpoint.
|
||||
* @post The endpoint is ready for @p usbStartTransmitI().
|
||||
* @note The transmit transaction size is equal to the data contained
|
||||
* in the queue.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
static void otg_prepare_transmit(USBDriver *usbp, usbep_t ep, size_t n) {
|
||||
uint32_t pcnt;
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
|
||||
isp->txsize = n;
|
||||
isp->txcnt = 0;
|
||||
|
||||
/* Transfer initialization.*/
|
||||
if (n == 0) {
|
||||
/* Special case, sending zero size packet.*/
|
||||
OTG->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0);
|
||||
}
|
||||
else {
|
||||
/* Normal case.*/
|
||||
pcnt = (n + usbp->epc[ep]->in_maxsize - 1) / usbp->epc[ep]->in_maxsize;
|
||||
OTG->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(pcnt) |
|
||||
DIEPTSIZ_XFRSIZ(usbp->epc[ep]->in_state->txsize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pushes a series of words into a FIFO.
|
||||
*
|
||||
|
@ -963,18 +908,19 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
|
|||
*
|
||||
* @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 maximum number of bytes to copy
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep,
|
||||
uint8_t *buf, size_t n) {
|
||||
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep) {
|
||||
uint32_t pcnt;
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
|
||||
osp->rxqueued = FALSE;
|
||||
osp->mode.linear.rxbuf = buf;
|
||||
otg_prepare_receive(usbp, ep, n);
|
||||
/* Transfer initialization.*/
|
||||
pcnt = (osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
|
||||
usbp->epc[ep]->out_maxsize;
|
||||
OTG->oe[ep].DOEPTSIZ = DOEPTSIZ_STUPCNT(3) | DOEPTSIZ_PKTCNT(pcnt) |
|
||||
DOEPTSIZ_XFRSIZ(usbp->epc[ep]->out_maxsize);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -982,64 +928,25 @@ void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep,
|
|||
*
|
||||
* @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 maximum number of bytes to copy
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep,
|
||||
const uint8_t *buf, size_t n) {
|
||||
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) {
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
|
||||
isp->txqueued = FALSE;
|
||||
isp->mode.linear.txbuf = buf;
|
||||
otg_prepare_transmit(usbp, ep, n);
|
||||
}
|
||||
/* Transfer initialization.*/
|
||||
if (isp->txsize == 0) {
|
||||
/* Special case, sending zero size packet.*/
|
||||
OTG->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(1) | DIEPTSIZ_XFRSIZ(0);
|
||||
}
|
||||
else {
|
||||
/* Normal case.*/
|
||||
uint32_t pcnt = (isp->txsize + usbp->epc[ep]->in_maxsize - 1) /
|
||||
usbp->epc[ep]->in_maxsize;
|
||||
OTG->ie[ep].DIEPTSIZ = DIEPTSIZ_PKTCNT(pcnt) |
|
||||
DIEPTSIZ_XFRSIZ(usbp->epc[ep]->in_state->txsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
||||
* @note The receive transaction size is equal to the space in the queue
|
||||
* rounded to the lower multiple of a packet size. Make sure there
|
||||
* is room for at least one packet in the queue before starting
|
||||
* the receive operation.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] iq input queue to be filled with incoming data
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void usb_lld_prepare_queued_receive(USBDriver *usbp, usbep_t ep,
|
||||
InputQueue *iq, size_t n) {
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
|
||||
osp->rxqueued = TRUE;
|
||||
osp->mode.queue.rxqueue = iq;
|
||||
otg_prepare_receive(usbp, ep, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a transmit transaction on an IN endpoint.
|
||||
* @post The endpoint is ready for @p usbStartTransmitI().
|
||||
* @note The transmit transaction size is equal to the data contained
|
||||
* in the queue.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] oq output queue to be fetched for outgoing data
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void usb_lld_prepare_queued_transmit(USBDriver *usbp, usbep_t ep,
|
||||
OutputQueue *oq, size_t n) {
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
|
||||
isp->txqueued = TRUE;
|
||||
isp->mode.queue.txqueue = oq;
|
||||
otg_prepare_transmit(usbp, ep, n);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -397,14 +397,8 @@ 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,
|
||||
uint8_t *buf, size_t n);
|
||||
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep,
|
||||
const uint8_t *buf, size_t n);
|
||||
void usb_lld_prepare_queued_receive(USBDriver *usbp, usbep_t ep,
|
||||
InputQueue *iq, size_t n);
|
||||
void usb_lld_prepare_queued_transmit(USBDriver *usbp, usbep_t ep,
|
||||
OutputQueue *oq, size_t n);
|
||||
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);
|
||||
|
|
|
@ -259,30 +259,6 @@ static void usb_packet_write_from_queue(stm32_usb_descriptor_t *udp,
|
|||
port_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
static void usb_prepare_receive(USBDriver *usbp, usbep_t ep, size_t n) {
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
|
||||
osp->rxsize = n;
|
||||
osp->rxcnt = 0;
|
||||
|
||||
/* Transfer initialization.*/
|
||||
if (osp->rxsize == 0) /* Special case for zero sized packets.*/
|
||||
osp->rxpkts = 1;
|
||||
else
|
||||
osp->rxpkts = (uint16_t)((n + usbp->epc[ep]->out_maxsize - 1) /
|
||||
usbp->epc[ep]->out_maxsize);
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
@ -704,18 +680,18 @@ void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
|
|||
*
|
||||
* @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 maximum number of bytes to copy
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep,
|
||||
uint8_t *buf, size_t n) {
|
||||
void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep) {
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
|
||||
osp->rxqueued = FALSE;
|
||||
osp->mode.linear.rxbuf = buf;
|
||||
usb_prepare_receive(usbp, ep, n);
|
||||
/* Transfer initialization.*/
|
||||
if (osp->rxsize == 0) /* Special case for zero sized packets.*/
|
||||
osp->rxpkts = 1;
|
||||
else
|
||||
osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
|
||||
usbp->epc[ep]->out_maxsize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -728,75 +704,21 @@ void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep,
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep,
|
||||
const uint8_t *buf, size_t n) {
|
||||
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) {
|
||||
size_t n;
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
|
||||
isp->txqueued = FALSE;
|
||||
isp->mode.linear.txbuf = buf;
|
||||
isp->txsize = n;
|
||||
isp->txcnt = 0;
|
||||
|
||||
/* Transfer initialization.*/
|
||||
n = isp->txsize;
|
||||
if (n > (size_t)usbp->epc[ep]->in_maxsize)
|
||||
n = (size_t)usbp->epc[ep]->in_maxsize;
|
||||
|
||||
usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
|
||||
isp->mode.linear.txbuf, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
||||
* @note The receive transaction size is equal to the space in the queue
|
||||
* rounded to the lower multiple of a packet size. Make sure there
|
||||
* is room for at least one packet in the queue before starting
|
||||
* the receive operation.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] iq input queue to be filled with incoming data
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void usb_lld_prepare_queued_receive(USBDriver *usbp, usbep_t ep,
|
||||
InputQueue *iq, size_t n) {
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
|
||||
osp->rxqueued = TRUE;
|
||||
osp->mode.queue.rxqueue = iq;
|
||||
usb_prepare_receive(usbp, ep, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a transmit transaction on an IN endpoint.
|
||||
* @post The endpoint is ready for @p usbStartTransmitI().
|
||||
* @note The transmit transaction size is equal to the data contained
|
||||
* in the queue.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] oq output queue to be fetched for outgoing data
|
||||
* @param[in] n maximum number of bytes to copy
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void usb_lld_prepare_queued_transmit(USBDriver *usbp, usbep_t ep,
|
||||
OutputQueue *oq, size_t n) {
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
|
||||
isp->txqueued = TRUE;
|
||||
isp->mode.queue.txqueue = oq;
|
||||
isp->txsize = n;
|
||||
isp->txcnt = 0;
|
||||
|
||||
/* Transfer initialization.*/
|
||||
if (n > (size_t)usbp->epc[ep]->in_maxsize)
|
||||
n = (size_t)usbp->epc[ep]->in_maxsize;
|
||||
|
||||
usb_packet_write_from_queue(USB_GET_DESCRIPTOR(ep),
|
||||
isp->mode.queue.txqueue, n);
|
||||
if (isp->txqueued)
|
||||
usb_packet_write_from_queue(USB_GET_DESCRIPTOR(ep),
|
||||
isp->mode.queue.txqueue, n);
|
||||
else
|
||||
usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
|
||||
isp->mode.linear.txbuf, n);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -407,14 +407,8 @@ 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,
|
||||
uint8_t *buf, size_t n);
|
||||
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep,
|
||||
const uint8_t *buf, size_t n);
|
||||
void usb_lld_prepare_queued_receive(USBDriver *usbp, usbep_t ep,
|
||||
InputQueue *iq, size_t n);
|
||||
void usb_lld_prepare_queued_transmit(USBDriver *usbp, usbep_t ep,
|
||||
OutputQueue *oq, size_t n);
|
||||
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);
|
||||
|
|
158
os/hal/src/usb.c
158
os/hal/src/usb.c
|
@ -352,6 +352,118 @@ void usbDisableEndpointsI(USBDriver *usbp) {
|
|||
usb_lld_disable_endpoints(usbp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized in transaction mode.
|
||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
||||
* @note This function can be called both in ISR and thread context.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void usbPrepareReceive(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
|
||||
osp->rxqueued = FALSE;
|
||||
osp->mode.linear.rxbuf = buf;
|
||||
osp->rxsize = n;
|
||||
osp->rxcnt = 0;
|
||||
|
||||
usb_lld_prepare_receive(usbp, ep);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a transmit transaction on an IN endpoint.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized in transaction mode.
|
||||
* @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.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
|
||||
const uint8_t *buf, size_t n) {
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
|
||||
isp->txqueued = FALSE;
|
||||
isp->mode.linear.txbuf = buf;
|
||||
isp->txsize = n;
|
||||
isp->txcnt = 0;
|
||||
|
||||
usb_lld_prepare_transmit(usbp, ep);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a receive transaction on an OUT endpoint.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized in transaction mode.
|
||||
* @post The endpoint is ready for @p usbStartReceiveI().
|
||||
* @note This function can be called both in ISR and thread context.
|
||||
* @note The queue must have enough free space to accommodate the
|
||||
* specified transaction size rounded to the next packet size
|
||||
* boundary. For example if the transaction size is 1 and the
|
||||
* packet size is 64 then the queue must have space for at least
|
||||
* 64 bytes.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] iqp input queue to be filled with incoming data
|
||||
* @param[in] n transaction size
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void usbPrepareQueuedReceive(USBDriver *usbp, usbep_t ep,
|
||||
InputQueue *iqp, size_t n) {
|
||||
USBOutEndpointState *osp = usbp->epc[ep]->out_state;
|
||||
|
||||
osp->rxqueued = TRUE;
|
||||
osp->mode.queue.rxqueue = iqp;
|
||||
osp->rxsize = n;
|
||||
osp->rxcnt = 0;
|
||||
|
||||
usb_lld_prepare_receive(usbp, ep);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepares for a transmit transaction on an IN endpoint.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized in transaction mode.
|
||||
* @post The endpoint is ready for @p usbStartTransmitI().
|
||||
* @note This function can be called both in ISR and thread context.
|
||||
* @note The transmit transaction size is equal to the data contained
|
||||
* in the queue.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] oqp output queue to be fetched for outgoing data
|
||||
* @param[in] n transaction size
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void usbPrepareQueuedTransmit(USBDriver *usbp, usbep_t ep,
|
||||
OutputQueue *oqp, size_t n) {
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
|
||||
isp->txqueued = TRUE;
|
||||
isp->mode.queue.txqueue = oqp;
|
||||
isp->txsize = n;
|
||||
isp->txcnt = 0;
|
||||
|
||||
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
|
||||
|
@ -359,6 +471,7 @@ void usbDisableEndpointsI(USBDriver *usbp) {
|
|||
*
|
||||
* @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.
|
||||
|
@ -385,6 +498,7 @@ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep) {
|
|||
*
|
||||
* @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.
|
||||
|
@ -409,6 +523,7 @@ bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep) {
|
|||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval FALSE Endpoint stalled.
|
||||
* @retval TRUE Endpoint busy, not stalled.
|
||||
|
@ -432,6 +547,7 @@ bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep) {
|
|||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval FALSE Endpoint stalled.
|
||||
* @retval TRUE Endpoint busy, not stalled.
|
||||
|
@ -526,15 +642,19 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
|||
if (usbp->ep0n > 0) {
|
||||
/* Starts the transmit phase.*/
|
||||
usbp->ep0state = USB_EP0_TX;
|
||||
usb_lld_prepare_transmit(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||
usb_lld_start_in(usbp, 0);
|
||||
usbPrepareTransmit(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||
chSysLockFromIsr();
|
||||
usbStartTransmitI(usbp, 0);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
else {
|
||||
/* No transmission phase, directly receiving the zero sized status
|
||||
packet.*/
|
||||
usbp->ep0state = USB_EP0_WAITING_STS;
|
||||
usb_lld_prepare_receive(usbp, 0, NULL, 0);
|
||||
usb_lld_start_out(usbp, 0);
|
||||
usbPrepareReceive(usbp, 0, NULL, 0);
|
||||
chSysLockFromIsr();
|
||||
usbStartReceiveI(usbp, 0);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -542,15 +662,19 @@ void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
|||
if (usbp->ep0n > 0) {
|
||||
/* Starts the receive phase.*/
|
||||
usbp->ep0state = USB_EP0_RX;
|
||||
usb_lld_prepare_receive(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||
usb_lld_start_out(usbp, 0);
|
||||
usbPrepareReceive(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||
chSysLockFromIsr();
|
||||
usbStartReceiveI(usbp, 0);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
else {
|
||||
/* No receive phase, directly sending the zero sized status
|
||||
packet.*/
|
||||
usbp->ep0state = USB_EP0_SENDING_STS;
|
||||
usb_lld_prepare_transmit(usbp, 0, NULL, 0);
|
||||
usb_lld_start_in(usbp, 0);
|
||||
usbPrepareTransmit(usbp, 0, NULL, 0);
|
||||
chSysLockFromIsr();
|
||||
usbStartTransmitI(usbp, 0);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -577,15 +701,19 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
|
|||
transmitted.*/
|
||||
if ((usbp->ep0n < max) &&
|
||||
((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0)) {
|
||||
usb_lld_prepare_transmit(usbp, 0, NULL, 0);
|
||||
usb_lld_start_in(usbp, 0);
|
||||
usbPrepareTransmit(usbp, 0, NULL, 0);
|
||||
chSysLockFromIsr();
|
||||
usbStartTransmitI(usbp, 0);
|
||||
chSysUnlockFromIsr();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Transmit phase over, receiving the zero sized status packet.*/
|
||||
usbp->ep0state = USB_EP0_WAITING_STS;
|
||||
usb_lld_prepare_receive(usbp, 0, NULL, 0);
|
||||
usb_lld_start_out(usbp, 0);
|
||||
usbPrepareReceive(usbp, 0, NULL, 0);
|
||||
chSysLockFromIsr();
|
||||
usbStartReceiveI(usbp, 0);
|
||||
chSysUnlockFromIsr();
|
||||
return;
|
||||
case USB_EP0_SENDING_STS:
|
||||
/* Status packet sent, invoking the callback if defined.*/
|
||||
|
@ -622,8 +750,10 @@ void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
|
|||
case USB_EP0_RX:
|
||||
/* Receive phase over, sending the zero sized status packet.*/
|
||||
usbp->ep0state = USB_EP0_SENDING_STS;
|
||||
usb_lld_prepare_transmit(usbp, 0, NULL, 0);
|
||||
usb_lld_start_in(usbp, 0);
|
||||
usbPrepareTransmit(usbp, 0, NULL, 0);
|
||||
chSysLockFromIsr();
|
||||
usbStartTransmitI(usbp, 0);
|
||||
chSysUnlockFromIsr();
|
||||
return;
|
||||
case USB_EP0_WAITING_STS:
|
||||
/* Status packet received, it must be zero sized, invoking the callback
|
||||
|
|
Loading…
Reference in New Issue