git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2719 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
0847ae54f0
commit
9ab9d1b44b
|
@ -115,14 +115,10 @@ typedef struct {
|
|||
InputQueue iqueue; \
|
||||
/* Output queue.*/ \
|
||||
OutputQueue oqueue; \
|
||||
/* Input buffer 1.*/ \
|
||||
uint8_t ib1[SERIAL_USB_BUFFERS_SIZE]; \
|
||||
/* Input buffer 2.*/ \
|
||||
uint8_t ib2[SERIAL_USB_BUFFERS_SIZE]; \
|
||||
/* Output buffer 1.*/ \
|
||||
uint8_t ob1[SERIAL_USB_BUFFERS_SIZE]; \
|
||||
/* Output buffer 2.*/ \
|
||||
uint8_t ob2[SERIAL_USB_BUFFERS_SIZE]; \
|
||||
/* Input buffer.*/ \
|
||||
uint8_t ib[SERIAL_USB_BUFFERS_SIZE]; \
|
||||
/* Output buffer.*/ \
|
||||
uint8_t ob[SERIAL_USB_BUFFERS_SIZE]; \
|
||||
/* End of the mandatory fields.*/ \
|
||||
/* Current configuration data.*/ \
|
||||
const SerialUSBConfig *config;
|
||||
|
|
|
@ -58,11 +58,12 @@ static USBEndpointState ep0state;
|
|||
* @brief EP0 initialization structure.
|
||||
*/
|
||||
static const USBEndpointConfig ep0config = {
|
||||
EP_TYPE_CTRL,
|
||||
_usb_ep0in,
|
||||
_usb_ep0out,
|
||||
0x40,
|
||||
0x40,
|
||||
EPR_EP_TYPE_CONTROL | EPR_STAT_TX_NAK | EPR_STAT_RX_VALID,
|
||||
0,
|
||||
0x40,
|
||||
0x80
|
||||
};
|
||||
|
@ -178,50 +179,63 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
|
|||
if (epr & EPR_CTR_TX) {
|
||||
/* IN endpoint, transmission.*/
|
||||
EPR_CLEAR_CTR_TX(ep);
|
||||
n = USB_GET_DESCRIPTOR(ep)->TXCOUNT;
|
||||
usbp->ep[ep]->txbuf += n;
|
||||
usbp->ep[ep]->txcnt += n;
|
||||
usbp->ep[ep]->txsize -= n;
|
||||
if (usbp->ep[ep]->txsize > 0) {
|
||||
/* Transfer not completed, there are more packets to send.*/
|
||||
if (usbp->ep[ep]->txsize > epcp->in_maxsize)
|
||||
n = epcp->in_maxsize;
|
||||
else
|
||||
n = usbp->ep[ep]->txsize;
|
||||
write_packet(ep, usbp->ep[ep]->txbuf, n);
|
||||
if (epcp->flags & USB_EP_FLAGS_IN_PACKET_MODE) {
|
||||
/* Packet mode, just invokes the callback.*/
|
||||
(usbp)->ep[ep]->transmitting = FALSE;
|
||||
epcp->in_cb(usbp, ep);
|
||||
}
|
||||
else {
|
||||
/* Transfer completed, invoking the callback, if defined.*/
|
||||
(usbp)->ep[ep]->transmitting = FALSE;
|
||||
if (epcp->in_cb)
|
||||
/* Transaction mode.*/
|
||||
n = USB_GET_DESCRIPTOR(ep)->TXCOUNT;
|
||||
usbp->ep[ep]->txbuf += n;
|
||||
usbp->ep[ep]->txcnt += n;
|
||||
usbp->ep[ep]->txsize -= n;
|
||||
if (usbp->ep[ep]->txsize > 0) {
|
||||
/* Transfer not completed, there are more packets to send.*/
|
||||
if (usbp->ep[ep]->txsize > epcp->in_maxsize)
|
||||
n = epcp->in_maxsize;
|
||||
else
|
||||
n = usbp->ep[ep]->txsize;
|
||||
write_packet(ep, usbp->ep[ep]->txbuf, n);
|
||||
}
|
||||
else {
|
||||
/* Transfer completed, invokes the callback.*/
|
||||
(usbp)->ep[ep]->transmitting = FALSE;
|
||||
epcp->in_cb(usbp, ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (epr & EPR_CTR_RX) {
|
||||
EPR_CLEAR_CTR_RX(ep);
|
||||
/* OUT endpoint, receive.*/
|
||||
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);
|
||||
if (epcp->flags & USB_EP_FLAGS_IN_PACKET_MODE) {
|
||||
/* Packet mode, just invokes the callback.*/
|
||||
(usbp)->ep[ep]->receiving = FALSE;
|
||||
epcp->out_cb(usbp, ep);
|
||||
}
|
||||
else {
|
||||
n = read_packet(ep, usbp->ep[ep]->rxbuf, usbp->ep[ep]->rxsize);
|
||||
usbp->ep[ep]->rxbuf += n;
|
||||
usbp->ep[ep]->rxcnt += n;
|
||||
usbp->ep[ep]->rxsize -= n;
|
||||
usbp->ep[ep]->rxpkts -= 1;
|
||||
if (usbp->ep[ep]->rxpkts > 0) {
|
||||
/* Transfer not completed, there are more packets to receive.*/
|
||||
EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
|
||||
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);
|
||||
}
|
||||
else {
|
||||
/* Transfer completed, invoking the callback, if defined.*/
|
||||
(usbp)->ep[ep]->receiving = FALSE;
|
||||
if (epcp->out_cb)
|
||||
n = read_packet(ep, usbp->ep[ep]->rxbuf, usbp->ep[ep]->rxsize);
|
||||
usbp->ep[ep]->rxbuf += n;
|
||||
usbp->ep[ep]->rxcnt += n;
|
||||
usbp->ep[ep]->rxsize -= n;
|
||||
usbp->ep[ep]->rxpkts -= 1;
|
||||
if (usbp->ep[ep]->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)->ep[ep]->receiving = FALSE;
|
||||
epcp->out_cb(usbp, ep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -357,13 +371,43 @@ void usb_lld_set_address(USBDriver *usbp) {
|
|||
* @notapi
|
||||
*/
|
||||
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
||||
uint16_t nblocks;
|
||||
uint16_t nblocks, epr;
|
||||
stm32_usb_descriptor_t *dp;
|
||||
const USBEndpointConfig *epcp = usbp->ep[ep]->config;
|
||||
|
||||
/* Setting the endpoint type.*/
|
||||
switch (epcp->ep_type) {
|
||||
case EP_TYPE_ISOC:
|
||||
epr = EPR_EP_TYPE_ISO;
|
||||
break;
|
||||
case EP_TYPE_BULK:
|
||||
epr = EPR_EP_TYPE_BULK;
|
||||
break;
|
||||
case EP_TYPE_INTR:
|
||||
epr = EPR_EP_TYPE_INTERRUPT;
|
||||
break;
|
||||
default:
|
||||
epr = EPR_EP_TYPE_CONTROL;
|
||||
}
|
||||
|
||||
/* IN endpoint settings, always in NAK mode initially.*/
|
||||
if (epcp->in_cb)
|
||||
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->flags & USB_EP_FLAGS_IN_PACKET_MODE) {
|
||||
usbp->ep[ep]->receiving = TRUE;
|
||||
epr |= EPR_STAT_RX_VALID;
|
||||
}
|
||||
else
|
||||
epr |= EPR_STAT_RX_NAK;
|
||||
}
|
||||
|
||||
/* EPxR register setup.*/
|
||||
EPR_SET(ep, epcp->epr | ep);
|
||||
EPR_TOGGLE(ep, epcp->epr);
|
||||
EPR_SET(ep, epr | ep);
|
||||
EPR_TOGGLE(ep, epr);
|
||||
|
||||
/* Endpoint size and address initialization.*/
|
||||
if (epcp->out_maxsize > 62)
|
||||
|
|
|
@ -46,6 +46,16 @@
|
|||
*/
|
||||
#define USB_SET_ADDRESS_MODE USB_LATE_SET_ADDRESS
|
||||
|
||||
/**
|
||||
* @brief Enables the packet mode for an IN endpoint.
|
||||
*/
|
||||
#define USB_EP_FLAGS_IN_PACKET_MODE 1
|
||||
|
||||
/**
|
||||
* @brief Enables the packet mode for an OUT endpoint.
|
||||
*/
|
||||
#define USB_EP_FLAGS_OUT_PACKET_MODE 2
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
@ -98,28 +108,39 @@
|
|||
* @note Platform specific restrictions may apply to endpoints.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Type of the endpoint.
|
||||
*/
|
||||
usbeptype_t ep_type;
|
||||
/**
|
||||
* @brief IN endpoint notification callback.
|
||||
* @details This field must be set to @p NULL if the IN endpoint is not
|
||||
* used.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
usbepcallback_t out_cb;
|
||||
/**
|
||||
* @brief IN endpoint maximum packet size.
|
||||
* @details This field must be set to zero if the IN endpoint is not
|
||||
* used.
|
||||
*/
|
||||
uint16_t in_maxsize;
|
||||
/**
|
||||
* @brief OUT endpoint maximum packet size.
|
||||
* @details This field must be set to zero if the OUT endpoint is not
|
||||
* used.
|
||||
*/
|
||||
uint16_t out_maxsize;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief EPxR register initialization value.
|
||||
* @note Do not specify the EA field, leave it to zero.
|
||||
* @bief Endpoint mode flags.
|
||||
*/
|
||||
uint16_t epr;
|
||||
uint16_t flags;
|
||||
/**
|
||||
* @brief Endpoint IN buffer address as offset in the PMA.
|
||||
*/
|
||||
|
|
|
@ -251,11 +251,12 @@ USBEndpointState ep3state;
|
|||
* @brief EP1 initialization structure (IN only).
|
||||
*/
|
||||
static const USBEndpointConfig ep1config = {
|
||||
EP_TYPE_BULK,
|
||||
sduDataTransmitted,
|
||||
NULL,
|
||||
0x0040,
|
||||
0x0000,
|
||||
EPR_EP_TYPE_BULK | EPR_STAT_TX_NAK | EPR_STAT_RX_DIS,
|
||||
USB_EP_FLAGS_IN_PACKET_MODE,
|
||||
0x00C0,
|
||||
0x0000
|
||||
};
|
||||
|
@ -264,11 +265,12 @@ static const USBEndpointConfig ep1config = {
|
|||
* @brief EP2 initialization structure (IN only).
|
||||
*/
|
||||
static const USBEndpointConfig ep2config = {
|
||||
EP_TYPE_INTR,
|
||||
sduInterruptTransmitted,
|
||||
NULL,
|
||||
0x0010,
|
||||
0x0000,
|
||||
EPR_EP_TYPE_INTERRUPT | EPR_STAT_TX_NAK | EPR_STAT_RX_DIS,
|
||||
0,
|
||||
0x0100,
|
||||
0x0000
|
||||
};
|
||||
|
@ -277,11 +279,12 @@ static const USBEndpointConfig ep2config = {
|
|||
* @brief EP3 initialization structure (OUT only).
|
||||
*/
|
||||
static const USBEndpointConfig ep3config = {
|
||||
EP_TYPE_BULK,
|
||||
NULL,
|
||||
sduDataReceived,
|
||||
0x0000,
|
||||
0x0040,
|
||||
EPR_EP_TYPE_BULK | EPR_STAT_TX_DIS | EPR_STAT_RX_VALID,
|
||||
USB_EP_FLAGS_OUT_PACKET_MODE,
|
||||
0x0000,
|
||||
0x0110
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue