aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-02-08 06:29:27 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-02-08 06:29:27 +0000
commit9ab9d1b44b1dfc11094faf3da939d35061b53bed (patch)
tree879d7431abdb2155de9b444005448499e757e437
parent0847ae54f0d4f32f87dc47338a5a9903ce6bc3e0 (diff)
downloadChibiOS-9ab9d1b44b1dfc11094faf3da939d35061b53bed.tar.gz
ChibiOS-9ab9d1b44b1dfc11094faf3da939d35061b53bed.tar.bz2
ChibiOS-9ab9d1b44b1dfc11094faf3da939d35061b53bed.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2719 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--os/hal/include/serial_usb.h12
-rw-r--r--os/hal/platforms/STM32/usb_lld.c112
-rw-r--r--os/hal/platforms/STM32/usb_lld.h27
-rw-r--r--testhal/STM32/USB_CDC/main.c9
4 files changed, 112 insertions, 48 deletions
diff --git a/os/hal/include/serial_usb.h b/os/hal/include/serial_usb.h
index 03c075f62..3cfa1441b 100644
--- a/os/hal/include/serial_usb.h
+++ b/os/hal/include/serial_usb.h
@@ -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;
diff --git a/os/hal/platforms/STM32/usb_lld.c b/os/hal/platforms/STM32/usb_lld.c
index e1ba15de5..a95baf45f 100644
--- a/os/hal/platforms/STM32/usb_lld.c
+++ b/os/hal/platforms/STM32/usb_lld.c
@@ -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)
diff --git a/os/hal/platforms/STM32/usb_lld.h b/os/hal/platforms/STM32/usb_lld.h
index d365521ee..d1e3169c2 100644
--- a/os/hal/platforms/STM32/usb_lld.h
+++ b/os/hal/platforms/STM32/usb_lld.h
@@ -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. */
/*===========================================================================*/
@@ -99,27 +109,38 @@
*/
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.
*/
diff --git a/testhal/STM32/USB_CDC/main.c b/testhal/STM32/USB_CDC/main.c
index b55b24892..04fd4d615 100644
--- a/testhal/STM32/USB_CDC/main.c
+++ b/testhal/STM32/USB_CDC/main.c
@@ -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
};