USB improvements.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2815 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
310fd0745e
commit
3d50b5c9e0
|
@ -395,6 +395,86 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
|||
(usbp)->ep0endcb = (endcb); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a setup packet from the dedicated packet buffer.
|
||||
* @details This function must be invoked in the context of the @p setup_cb
|
||||
* callback in order to read the received setup packet.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized as a control endpoint.
|
||||
* @post The endpoint is ready to accept another packet.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[out] buf buffer where to copy the packet data
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define usbReadSetup(usbp, ep, buf) usb_lld_read_setup(usbp, ep, buf)
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, usb event callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_event_cb(usbp, evt) { \
|
||||
if (((usbp)->config->event_cb) != NULL) \
|
||||
(usbp)->config->event_cb(usbp, evt); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, SOF callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_sof_cb(usbp) { \
|
||||
if (((usbp)->config->sof_cb) != NULL) \
|
||||
(usbp)->config->sof_cb(usbp); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, setup packet callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_setup_cb(usbp, ep) { \
|
||||
(usbp)->epc[ep]->setup_cb(usbp, ep); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, IN endpoint callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_in_cb(usbp, ep) { \
|
||||
(usbp)->transmitting &= ~(1 << (ep)); \
|
||||
(usbp)->epc[ep]->in_cb(usbp, ep); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, OUT endpoint event.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_out_cb(usbp, ep) { \
|
||||
(usbp)->receiving &= ~(1 << (ep)); \
|
||||
(usbp)->epc[ep]->out_cb(usbp, ep); \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
@ -409,6 +489,7 @@ extern "C" {
|
|||
void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
|
||||
const USBEndpointConfig *epcp);
|
||||
void usbDisableEndpointsI(USBDriver *usbp);
|
||||
void usbReadSetupI(USBDriver *usbp, usbep_t ep, uint8_t *buf);
|
||||
size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
|
||||
uint8_t *buf, size_t n);
|
||||
size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
|
||||
|
@ -420,6 +501,7 @@ extern "C" {
|
|||
bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep);
|
||||
bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep);
|
||||
void _usb_reset(USBDriver *usbp);
|
||||
void _usb_ep0setup(USBDriver *usbp, usbep_t ep);
|
||||
void _usb_ep0in(USBDriver *usbp, usbep_t ep);
|
||||
void _usb_ep0out(USBDriver *usbp, usbep_t ep);
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -68,6 +68,7 @@ static union {
|
|||
*/
|
||||
static const USBEndpointConfig ep0config = {
|
||||
USB_EP_MODE_TYPE_CTRL | USB_EP_MODE_TRANSACTION,
|
||||
_usb_ep0setup,
|
||||
_usb_ep0in,
|
||||
_usb_ep0out,
|
||||
0x40,
|
||||
|
@ -193,16 +194,14 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
|
|||
/* USB bus reset condition handling.*/
|
||||
if (istr & ISTR_RESET) {
|
||||
_usb_reset(usbp);
|
||||
if (usbp->config->event_cb)
|
||||
usbp->config->event_cb(usbp, USB_EVENT_RESET);
|
||||
_usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET);
|
||||
STM32_USB->ISTR = ~ISTR_RESET;
|
||||
}
|
||||
|
||||
/* USB bus SUSPEND condition handling.*/
|
||||
if (istr & ISTR_SUSP) {
|
||||
STM32_USB->CNTR |= CNTR_FSUSP;
|
||||
if (usbp->config->event_cb)
|
||||
usbp->config->event_cb(usbp, USB_EVENT_SUSPEND);
|
||||
_usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND);
|
||||
#if STM32_USB_LOW_POWER_ON_SUSPEND
|
||||
STM32_USB->CNTR |= CNTR_LP_MODE;
|
||||
#endif
|
||||
|
@ -214,8 +213,7 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
|
|||
uint32_t fnr = STM32_USB->FNR;
|
||||
if (!(fnr & FNR_RXDP)) {
|
||||
STM32_USB->CNTR &= ~CNTR_FSUSP;
|
||||
if (usbp->config->event_cb)
|
||||
usbp->config->event_cb(usbp, USB_EVENT_WAKEUP);
|
||||
_usb_isr_invoke_event_cb(usbp, USB_EVENT_WAKEUP);
|
||||
}
|
||||
#if STM32_USB_LOW_POWER_ON_SUSPEND
|
||||
else {
|
||||
|
@ -229,8 +227,7 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
|
|||
|
||||
/* SOF handling.*/
|
||||
if (istr & ISTR_SOF) {
|
||||
if (usbp->config->sof_cb)
|
||||
usbp->config->sof_cb(usbp);
|
||||
_usb_isr_invoke_sof_cb(usbp);
|
||||
STM32_USB->ISTR = ~ISTR_SOF;
|
||||
}
|
||||
|
||||
|
@ -245,8 +242,7 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
|
|||
EPR_CLEAR_CTR_TX(ep);
|
||||
if (epcp->ep_mode & USB_EP_MODE_PACKET) {
|
||||
/* Packet mode, just invokes the callback.*/
|
||||
(usbp)->transmitting &= ~(1 << ep);
|
||||
epcp->in_cb(usbp, ep);
|
||||
_usb_isr_invoke_in_cb(usbp, ep);
|
||||
}
|
||||
else {
|
||||
/* Transaction mode.*/
|
||||
|
@ -264,43 +260,36 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
|
|||
}
|
||||
else {
|
||||
/* Transfer completed, invokes the callback.*/
|
||||
(usbp)->transmitting &= ~(1 << ep);
|
||||
epcp->in_cb(usbp, ep);
|
||||
_usb_isr_invoke_in_cb(usbp, ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (epr & EPR_CTR_RX) {
|
||||
EPR_CLEAR_CTR_RX(ep);
|
||||
/* OUT endpoint, receive.*/
|
||||
if (epcp->ep_mode & USB_EP_MODE_PACKET) {
|
||||
if (epr & EPR_SETUP) {
|
||||
/* Setup packets handling, setup packets are handled using a
|
||||
specific callback.*/
|
||||
_usb_isr_invoke_setup_cb(usbp, ep);
|
||||
}
|
||||
else if (epcp->ep_mode & USB_EP_MODE_PACKET) {
|
||||
/* Packet mode, just invokes the callback.*/
|
||||
(usbp)->receiving &= ~(1 << ep);
|
||||
epcp->out_cb(usbp, ep);
|
||||
_usb_isr_invoke_out_cb(usbp, ep);
|
||||
}
|
||||
else {
|
||||
/* Transaction mode.*/
|
||||
if ((epr & EPR_SETUP) && (ep == 0)) {
|
||||
/* Special case, setup packet for EP0, enforcing a reset of the
|
||||
EP0 state machine for robustness.*/
|
||||
usbp->ep0state = USB_EP0_WAITING_SETUP;
|
||||
read_packet(0, usbp->setup, 8);
|
||||
epcp->out_cb(usbp, ep);
|
||||
n = read_packet(ep, epcp->out_state->rxbuf, epcp->out_state->rxsize);
|
||||
epcp->out_state->rxbuf += n;
|
||||
epcp->out_state->rxcnt += n;
|
||||
epcp->out_state->rxsize -= n;
|
||||
epcp->out_state->rxpkts -= 1;
|
||||
if (epcp->out_state->rxpkts > 0) {
|
||||
/* Transfer not completed, there are more packets to receive.*/
|
||||
EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
|
||||
}
|
||||
else {
|
||||
n = read_packet(ep, epcp->out_state->rxbuf, epcp->out_state->rxsize);
|
||||
epcp->out_state->rxbuf += n;
|
||||
epcp->out_state->rxcnt += n;
|
||||
epcp->out_state->rxsize -= n;
|
||||
epcp->out_state->rxpkts -= 1;
|
||||
if (epcp->out_state->rxpkts > 0) {
|
||||
/* Transfer not completed, there are more packets to receive.*/
|
||||
EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
|
||||
}
|
||||
else {
|
||||
/* Transfer completed, invokes the callback.*/
|
||||
(usbp)->receiving &= ~(1 << ep);
|
||||
epcp->out_cb(usbp, ep);
|
||||
}
|
||||
/* Transfer completed, invokes the callback.*/
|
||||
_usb_isr_invoke_out_cb(usbp, ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,12 +441,12 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
|||
}
|
||||
|
||||
/* IN endpoint settings, always in NAK mode initially.*/
|
||||
if (epcp->in_cb)
|
||||
if (epcp->in_cb != NULL)
|
||||
epr |= EPR_STAT_TX_NAK;
|
||||
|
||||
/* OUT endpoint settings. If the endpoint is in packet mode then it must
|
||||
start ready to accept data else it must start in NAK mode.*/
|
||||
if (epcp->out_cb) {
|
||||
if (epcp->out_cb != NULL) {
|
||||
if (epcp->ep_mode & USB_EP_MODE_PACKET) {
|
||||
usbp->receiving |= (1 << ep);
|
||||
epr |= EPR_STAT_RX_VALID;
|
||||
|
@ -553,6 +542,35 @@ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a setup packet from the dedicated packet buffer.
|
||||
* @details This function must be invoked in the context of the @p setup_cb
|
||||
* callback in order to read the received setup packet.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized as a control endpoint.
|
||||
* @post The endpoint is ready to accept another packet.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[out] buf buffer where to copy the packet data
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
|
||||
uint32_t *pmap;
|
||||
stm32_usb_descriptor_t *udp;
|
||||
uint32_t n;
|
||||
|
||||
(void)usbp;
|
||||
udp = USB_GET_DESCRIPTOR(ep);
|
||||
pmap = USB_ADDR2PTR(udp->RXADDR);
|
||||
for (n = 0; n < 4; n++) {
|
||||
*(uint16_t *)buf = (uint16_t)*pmap++;
|
||||
buf += 2;
|
||||
}
|
||||
EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a packet from the dedicated packet buffer.
|
||||
* @pre In order to use this function he endpoint must have been
|
||||
|
|
|
@ -149,6 +149,17 @@ typedef struct {
|
|||
* @brief Type and mode of the endpoint.
|
||||
*/
|
||||
uint32_t ep_mode;
|
||||
/**
|
||||
* @brief Setup packet notification callback.
|
||||
* @details This callback is invoked when a setup packet has been
|
||||
* received.
|
||||
* @post The application must immediately call @p usbReadPacket() in
|
||||
* order to access the received packet.
|
||||
* @note This field is only valid for @p USB_EP_MODE_TYPE_CTRL
|
||||
* endpoints, it should be set to @p NULL for other endpoint
|
||||
* types.
|
||||
*/
|
||||
usbepcallback_t setup_cb;
|
||||
/**
|
||||
* @brief IN endpoint notification callback.
|
||||
* @details This field must be set to @p NULL if the IN endpoint is not
|
||||
|
@ -359,6 +370,7 @@ extern "C" {
|
|||
void usb_lld_disable_endpoints(USBDriver *usbp);
|
||||
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);
|
||||
size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep,
|
||||
uint8_t *buf, size_t n);
|
||||
void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
|
||||
|
|
140
os/hal/src/usb.c
140
os/hal/src/usb.c
|
@ -58,8 +58,7 @@ static void set_address(USBDriver *usbp) {
|
|||
|
||||
usbp->address = usbp->setup[2];
|
||||
usb_lld_set_address(usbp);
|
||||
if (usbp->config->event_cb)
|
||||
usbp->config->event_cb(usbp, USB_EVENT_ADDRESS);
|
||||
_usb_isr_invoke_event_cb(usbp, USB_EVENT_ADDRESS);
|
||||
usbp->state = USB_SELECTED;
|
||||
}
|
||||
|
||||
|
@ -137,8 +136,7 @@ static bool_t default_handler(USBDriver *usbp) {
|
|||
usbp->state = USB_SELECTED;
|
||||
else
|
||||
usbp->state = USB_ACTIVE;
|
||||
if (usbp->config->event_cb)
|
||||
usbp->config->event_cb(usbp, USB_EVENT_CONFIGURED);
|
||||
_usb_isr_invoke_event_cb(usbp, USB_EVENT_CONFIGURED);
|
||||
usbSetupTransfer(usbp, NULL, 0, NULL);
|
||||
return TRUE;
|
||||
case USB_RTYPE_RECIPIENT_INTERFACE | (USB_REQ_GET_STATUS << 8):
|
||||
|
@ -526,6 +524,77 @@ void _usb_reset(USBDriver *usbp) {
|
|||
usb_lld_reset(usbp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default EP0 SETUP callback.
|
||||
* @details This function is used by the low level driver as default handler
|
||||
* for EP0 SETUP events.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number, always zero
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _usb_ep0setup(USBDriver *usbp, usbep_t ep) {
|
||||
size_t max;
|
||||
|
||||
usbp->ep0state = USB_EP0_WAITING_SETUP;
|
||||
usbReadSetup(usbp, ep, usbp->setup);
|
||||
|
||||
/* First verify if the application has an handler installed for this
|
||||
request.*/
|
||||
if (!(usbp->config->requests_hook_cb) ||
|
||||
!(usbp->config->requests_hook_cb(usbp))) {
|
||||
/* Invoking the default handler, if this fails then stalls the
|
||||
endpoint zero as error.*/
|
||||
if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) ||
|
||||
!default_handler(usbp)) {
|
||||
/* Error response, the state machine goes into an error state, the low
|
||||
level layer will have to reset it to USB_EP0_WAITING_SETUP after
|
||||
receiving a SETUP packet.*/
|
||||
usb_lld_stall_in(usbp, 0);
|
||||
usb_lld_stall_out(usbp, 0);
|
||||
_usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
|
||||
usbp->ep0state = USB_EP0_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer preparation. The request handler must have populated
|
||||
correctly the fields ep0next, ep0n and ep0endcb using the macro
|
||||
usbSetupTransfer().*/
|
||||
max = usb_lld_fetch_word(&usbp->setup[6]);
|
||||
/* The transfer size cannot exceed the specified amount.*/
|
||||
if (usbp->ep0n > max)
|
||||
usbp->ep0n = max;
|
||||
if ((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) {
|
||||
/* IN phase.*/
|
||||
if (usbp->ep0n > 0) {
|
||||
/* Starts the transmit phase.*/
|
||||
usbp->ep0state = USB_EP0_TX;
|
||||
usb_lld_start_in(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||
}
|
||||
else {
|
||||
/* No transmission phase, directly receiving the zero sized status
|
||||
packet.*/
|
||||
usbp->ep0state = USB_EP0_WAITING_STS;
|
||||
usb_lld_start_out(usbp, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* OUT phase.*/
|
||||
if (usbp->ep0n > 0) {
|
||||
/* Starts the receive phase.*/
|
||||
usbp->ep0state = USB_EP0_RX;
|
||||
usb_lld_start_out(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||
}
|
||||
else {
|
||||
/* No receive phase, directly sending the zero sized status
|
||||
packet.*/
|
||||
usbp->ep0state = USB_EP0_SENDING_STS;
|
||||
usb_lld_start_in(usbp, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default EP0 IN callback.
|
||||
* @details This function is used by the low level driver as default handler
|
||||
|
@ -558,7 +627,7 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
|
|||
return;
|
||||
case USB_EP0_SENDING_STS:
|
||||
/* Status packet sent, invoking the callback if defined.*/
|
||||
if (usbp->ep0endcb)
|
||||
if (usbp->ep0endcb != NULL)
|
||||
usbp->ep0endcb(usbp);
|
||||
usbp->ep0state = USB_EP0_WAITING_SETUP;
|
||||
return;
|
||||
|
@ -570,8 +639,7 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
|
|||
receiving a SETUP packet.*/
|
||||
usb_lld_stall_in(usbp, 0);
|
||||
usb_lld_stall_out(usbp, 0);
|
||||
if (usbp->config->event_cb)
|
||||
usbp->config->event_cb(usbp, USB_EVENT_STALLED);
|
||||
_usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
|
||||
usbp->ep0state = USB_EP0_ERROR;
|
||||
}
|
||||
|
||||
|
@ -586,62 +654,9 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
|
|||
* @notapi
|
||||
*/
|
||||
void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
|
||||
size_t max;
|
||||
|
||||
(void)ep;
|
||||
switch (usbp->ep0state) {
|
||||
case USB_EP0_WAITING_SETUP:
|
||||
/* SETUP packet handling. The setup packet is expected to be already
|
||||
placed into the setup[8] field of the USBDriver structure, the low
|
||||
level layer has to take care of this.*/
|
||||
|
||||
/* First verify if the application has an handler installed for this
|
||||
request.*/
|
||||
if (!(usbp->config->requests_hook_cb) ||
|
||||
!(usbp->config->requests_hook_cb(usbp))) {
|
||||
/* Invoking the default handler, if this fails then stalls the
|
||||
endpoint zero as error.*/
|
||||
if (((usbp->setup[0] & USB_RTYPE_TYPE_MASK) != USB_RTYPE_TYPE_STD) ||
|
||||
!default_handler(usbp))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Transfer preparation. The request handler must have populated
|
||||
correctly the fields ep0next, ep0n and ep0endcb using the macro
|
||||
usbSetupTransfer().*/
|
||||
max = usb_lld_fetch_word(&usbp->setup[6]);
|
||||
/* The transfer size cannot exceed the specified amount.*/
|
||||
if (usbp->ep0n > max)
|
||||
usbp->ep0n = max;
|
||||
if ((usbp->setup[0] & USB_RTYPE_DIR_MASK) == USB_RTYPE_DIR_DEV2HOST) {
|
||||
/* IN phase.*/
|
||||
if (usbp->ep0n > 0) {
|
||||
/* Starts the transmit phase.*/
|
||||
usbp->ep0state = USB_EP0_TX;
|
||||
usb_lld_start_in(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||
}
|
||||
else {
|
||||
/* No transmission phase, directly receiving the zero sized status
|
||||
packet.*/
|
||||
usbp->ep0state = USB_EP0_WAITING_STS;
|
||||
usb_lld_start_out(usbp, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* OUT phase.*/
|
||||
if (usbp->ep0n > 0) {
|
||||
/* Starts the receive phase.*/
|
||||
usbp->ep0state = USB_EP0_RX;
|
||||
usb_lld_start_out(usbp, 0, usbp->ep0next, usbp->ep0n);
|
||||
}
|
||||
else {
|
||||
/* No receive phase, directly sending the zero sized status
|
||||
packet.*/
|
||||
usbp->ep0state = USB_EP0_SENDING_STS;
|
||||
usb_lld_start_in(usbp, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case USB_EP0_RX:
|
||||
/* Receive phase over, sending the zero sized status packet.*/
|
||||
usbp->ep0state = USB_EP0_SENDING_STS;
|
||||
|
@ -652,7 +667,7 @@ void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
|
|||
if defined.*/
|
||||
if (usbGetReceiveTransactionSizeI(usbp, 0) != 0)
|
||||
break;
|
||||
if (usbp->ep0endcb)
|
||||
if (usbp->ep0endcb != NULL)
|
||||
usbp->ep0endcb(usbp);
|
||||
usbp->ep0state = USB_EP0_WAITING_SETUP;
|
||||
return;
|
||||
|
@ -664,8 +679,7 @@ void _usb_ep0out(USBDriver *usbp, usbep_t ep) {
|
|||
receiving a SETUP packet.*/
|
||||
usb_lld_stall_in(usbp, 0);
|
||||
usb_lld_stall_out(usbp, 0);
|
||||
if (usbp->config->event_cb)
|
||||
usbp->config->event_cb(usbp, USB_EVENT_STALLED);
|
||||
_usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED);
|
||||
usbp->ep0state = USB_EP0_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -203,6 +203,24 @@ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a setup packet from the dedicated packet buffer.
|
||||
* @details This function must be invoked in the context of the @p setup_cb
|
||||
* callback in order to read the received setup packet.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized as a control endpoint.
|
||||
* @post The endpoint is ready to accept another packet.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[out] buf buffer where to copy the packet data
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a packet from the dedicated packet buffer.
|
||||
* @pre In order to use this function he endpoint must have been
|
||||
|
|
|
@ -282,6 +282,7 @@ extern "C" {
|
|||
void usb_lld_disable_endpoints(USBDriver *usbp);
|
||||
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);
|
||||
size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep,
|
||||
uint8_t *buf, size_t n);
|
||||
void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
|
||||
|
|
|
@ -73,6 +73,8 @@
|
|||
*** 2.3.1 ***
|
||||
- FIX: Fixed invalid assertion in adcConvert() (bug 3205410)(backported
|
||||
to 2.2.3).
|
||||
- NEW: Improved setup packets handling in the USB driver through a specific
|
||||
callback.
|
||||
- OPT: Simplified Serial over USB driver configuration.
|
||||
- CHANGE: Removed all the prefixes from the structure/union field names
|
||||
in the HAL subsystem.
|
||||
|
|
|
@ -224,6 +224,7 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp,
|
|||
*/
|
||||
static const USBEndpointConfig ep1config = {
|
||||
USB_EP_MODE_TYPE_BULK | USB_EP_MODE_PACKET,
|
||||
NULL,
|
||||
sduDataTransmitted,
|
||||
NULL,
|
||||
0x0040,
|
||||
|
@ -237,6 +238,7 @@ static const USBEndpointConfig ep1config = {
|
|||
*/
|
||||
static const USBEndpointConfig ep2config = {
|
||||
USB_EP_MODE_TYPE_INTR | USB_EP_MODE_PACKET,
|
||||
NULL,
|
||||
sduInterruptTransmitted,
|
||||
NULL,
|
||||
0x0010,
|
||||
|
@ -251,6 +253,7 @@ static const USBEndpointConfig ep2config = {
|
|||
static const USBEndpointConfig ep3config = {
|
||||
USB_EP_MODE_TYPE_BULK | USB_EP_MODE_PACKET,
|
||||
NULL,
|
||||
NULL,
|
||||
sduDataReceived,
|
||||
0x0000,
|
||||
0x0040,
|
||||
|
|
Loading…
Reference in New Issue