diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-02-05 09:27:20 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-02-05 09:27:20 +0000 |
commit | 200f020df922ac84ffc0e0c98c97a193e3180b1f (patch) | |
tree | c0be7c7ff21bcd04fad5cacfb30109a0dffad4c4 /os | |
parent | b920ab090fca4c5ccb7142e8332b5ae77f082a79 (diff) | |
download | ChibiOS-200f020df922ac84ffc0e0c98c97a193e3180b1f.tar.gz ChibiOS-200f020df922ac84ffc0e0c98c97a193e3180b1f.tar.bz2 ChibiOS-200f020df922ac84ffc0e0c98c97a193e3180b1f.zip |
USB rework, step 1.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2708 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r-- | os/hal/include/usb.h | 4 | ||||
-rw-r--r-- | os/hal/platforms/STM32/usb_lld.c | 59 | ||||
-rw-r--r-- | os/hal/platforms/STM32/usb_lld.h | 52 | ||||
-rw-r--r-- | os/hal/src/usb.c | 49 |
4 files changed, 122 insertions, 42 deletions
diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h index e6fc8b868..9f0d95837 100644 --- a/os/hal/include/usb.h +++ b/os/hal/include/usb.h @@ -313,8 +313,8 @@ extern "C" { void usbObjectInit(USBDriver *usbp);
void usbStart(USBDriver *usbp, const USBConfig *config);
void usbStop(USBDriver *usbp);
- void usbEnableEndpointI(USBDriver *usbp, usbep_t ep,
- const USBEndpointConfig *epcp);
+ void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
+ const USBEndpointConfig *epcp);
void _usb_reset(USBDriver *usbp);
void _usb_ep0in(USBDriver *usbp, usbep_t ep);
void _usb_ep0out(USBDriver *usbp, usbep_t ep);
diff --git a/os/hal/platforms/STM32/usb_lld.c b/os/hal/platforms/STM32/usb_lld.c index 91be0f625..3fe6771ea 100644 --- a/os/hal/platforms/STM32/usb_lld.c +++ b/os/hal/platforms/STM32/usb_lld.c @@ -25,6 +25,8 @@ * @{
*/
+#include <string.h>
+
#include "ch.h"
#include "hal.h"
#include "usb.h"
@@ -42,10 +44,20 @@ USBDriver USBD1;
#endif
+
+/*===========================================================================*/
+/* Driver local variables. */
+/*===========================================================================*/
+
+/**
+ * @brief EP0 state.
+ */
+static USBEndpointState ep0state;
+
/**
* @brief EP0 initialization structure.
*/
-const USBEndpointConfig usb_lld_ep0config = {
+static const USBEndpointConfig ep0config = {
_usb_ep0in,
_usb_ep0out,
0x40,
@@ -56,10 +68,6 @@ const USBEndpointConfig usb_lld_ep0config = { };
/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
@@ -112,18 +120,19 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) { while (istr & ISTR_CTR) {
uint32_t ep;
uint32_t epr = STM32_USB->EPR[ep = istr & ISTR_EP_ID_MASK];
+ const USBEndpointConfig *epcp = usbp->usb_ep[ep]->uep_config;
if (epr & EPR_CTR_TX) {
/* IN endpoint, transmission.*/
EPR_CLEAR_CTR_TX(ep);
- if (usbp->usb_epc[ep]->uepc_in_cb)
- usbp->usb_epc[ep]->uepc_in_cb(usbp, ep);
+ if (epcp->uepc_in_cb)
+ epcp->uepc_in_cb(usbp, ep);
}
if (epr & EPR_CTR_RX) {
/* OUT endpoint, receive.*/
EPR_CLEAR_CTR_RX(ep);
- if (usbp->usb_epc[ep]->uepc_out_cb)
- usbp->usb_epc[ep]->uepc_out_cb(usbp, ep);
+ if (epcp->uepc_out_cb)
+ epcp->uepc_out_cb(usbp, ep);
}
istr = STM32_USB->ISTR;
}
@@ -228,6 +237,12 @@ void usb_lld_reset(USBDriver *usbp) { if (usbp->usb_config->uc_sof_cb != NULL)
cntr |= CNTR_SOFM;
STM32_USB->CNTR = cntr;
+
+ /* EP0 initialization.*/
+ memset(&ep0state, 0, sizeof ep0state);
+ ep0state.uep_config = &ep0config;
+ usbp->usb_ep[0] = &ep0state;
+ usb_lld_init_endpoint(usbp, 0);
}
/**
@@ -240,6 +255,7 @@ void usb_lld_reset(USBDriver *usbp) { */
void usb_lld_set_address(USBDriver *usbp, uint8_t addr) {
+ (void)usbp;
STM32_USB->DADDR = (uint32_t)addr | DADDR_EF;
}
@@ -248,14 +264,13 @@ void usb_lld_set_address(USBDriver *usbp, uint8_t addr) { *
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[in] epcp the endpoint configuration
*
* @notapi
*/
-void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep,
- const USBEndpointConfig *epcp) {
+void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
uint16_t nblocks;
stm32_usb_descriptor_t *dp;
+ const USBEndpointConfig *epcp = usbp->usb_ep[ep]->uep_config;
/* EPxR register setup.*/
EPR_SET(ep, epcp->uepc_epr | ep);
@@ -263,7 +278,8 @@ void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep, /* Endpoint size and address initialization.*/
if (epcp->uepc_out_maxsize > 62)
- nblocks = (((((epcp->uepc_out_maxsize - 1) | 0x1f) + 1) / 32) << 10) | 0x8000;
+ nblocks = (((((epcp->uepc_out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
+ 0x8000;
else
nblocks = ((((epcp->uepc_out_maxsize - 1) | 1) + 1) / 2) << 10;
dp = USB_GET_DESCRIPTOR(ep);
@@ -271,9 +287,6 @@ void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep, dp->RXCOUNT = nblocks;
dp->TXADDR = epcp->uepc_inaddr;
dp->RXADDR = epcp->uepc_outaddr;
-
- /* Logically enabling the endpoint in the USBDriver structure.*/
- usbp->usb_epc[ep] = epcp;
}
/**
@@ -286,6 +299,7 @@ void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep, void usb_lld_disable_endpoints(USBDriver *usbp) {
unsigned i;
+ (void)usbp;
for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) {
EPR_TOGGLE(i, 0);
EPR_SET(i, 0);
@@ -306,6 +320,7 @@ void usb_lld_disable_endpoints(USBDriver *usbp) { */
size_t usb_lld_get_readable(USBDriver *usbp, usbep_t ep) {
+ (void)usbp;
if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_NAK)
return 0;
return (size_t)(USB_GET_DESCRIPTOR(ep)->RXCOUNT & RXCOUNT_COUNT_MASK);
@@ -331,6 +346,7 @@ size_t usb_lld_read(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) { stm32_usb_descriptor_t *udp;
size_t count;
+ (void)usbp;
if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_NAK)
return 0;
@@ -363,7 +379,7 @@ size_t usb_lld_get_writeable(USBDriver *usbp, usbep_t ep) { if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_NAK)
return 0;
- return (size_t)usbp->usb_epc[ep]->uepc_in_maxsize;
+ return (size_t)usbp->usb_ep[ep]->uep_config->uepc_in_maxsize;
}
/**
@@ -388,6 +404,7 @@ size_t usb_lld_write(USBDriver *usbp, usbep_t ep, stm32_usb_descriptor_t *udp;
size_t count;
+ (void)usbp;
if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_NAK)
return 0;
@@ -414,6 +431,7 @@ size_t usb_lld_write(USBDriver *usbp, usbep_t ep, */
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
+ (void)usbp;
switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) {
case EPR_STAT_TX_DIS:
return EP_STATUS_DISABLED;
@@ -434,6 +452,7 @@ 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)usbp;
switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) {
case EPR_STAT_RX_DIS:
return EP_STATUS_DISABLED;
@@ -454,6 +473,7 @@ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) { */
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
+ (void)usbp;
EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL);
}
@@ -467,6 +487,7 @@ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) { */
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
+ (void)usbp;
EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL);
}
@@ -480,6 +501,8 @@ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) { */
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
+ (void)usbp;
+
/* Makes sure to not put to NAK an endpoint that is already
transferring.*/
if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID)
@@ -496,6 +519,8 @@ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) { */
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
+ (void)usbp;
+
/* Makes sure to not put to NAK an endpoint that is already
transferring.*/
if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID)
diff --git a/os/hal/platforms/STM32/usb_lld.h b/os/hal/platforms/STM32/usb_lld.h index af306d8a5..e21bbecd2 100644 --- a/os/hal/platforms/STM32/usb_lld.h +++ b/os/hal/platforms/STM32/usb_lld.h @@ -125,6 +125,49 @@ typedef struct { uint16_t uepc_outaddr;
} USBEndpointConfig;
+
+/**
+ * @brief Type of an endpoint state structure.
+ */
+typedef struct {
+ /**
+ * @brief Configuration associated to the endpoint.
+ */
+ const USBEndpointConfig *uep_config;
+ /**
+ * @brief Pointer to the transmission buffer.
+ */
+ const uint8_t *uep_txbuf;
+ /**
+ * @brief Pointer to the receive buffer.
+ */
+ uint8_t *uep_rxbuf;
+ /**
+ * @brief Requested transmit transfer size.
+ */
+ size_t uep_txsize;
+ /**
+ * @brief Requested receive transfer size.
+ */
+ size_t uep_rxsize;
+ /**
+ * @brief Transmitted bytes so far.
+ */
+ size_t uep_txcnt;
+ /**
+ * @brief Received bytes so far.
+ */
+ size_t uep_rxcnt;
+ /**
+ * @brief @p TRUE if transmitting else @p FALSE.
+ */
+ uint8_t uep_transmitting;
+ /**
+ * @brief @p TRUE if receiving else @p FALSE.
+ */
+ uint8_t uep_receiving;
+} USBEndpointState;
+
/**
* @brief Type of an USB driver configuration structure.
*/
@@ -172,7 +215,7 @@ struct USBDriver { /**
* @brief Active endpoints configurations.
*/
- const USBEndpointConfig *usb_epc[USB_MAX_ENDPOINTS + 1];
+ USBEndpointState *usb_ep[USB_MAX_ENDPOINTS + 1];
/**
* @brief Endpoint 0 state.
*/
@@ -251,6 +294,10 @@ extern USBDriver USBD1; extern const USBEndpointConfig usb_lld_ep0config;
#endif
+#if !defined(__DOXYGEN__)
+extern USBEndpointState usb_lld_ep0state;
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -259,8 +306,7 @@ extern "C" { void usb_lld_stop(USBDriver *usbp);
void usb_lld_reset(USBDriver *usbp);
void usb_lld_set_address(USBDriver *usbp, uint8_t addr);
- void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep,
- const USBEndpointConfig *epcp);
+ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
void usb_lld_disable_endpoints(USBDriver *usbp);
size_t usb_lld_get_readable(USBDriver *usbp, usbep_t ep);
size_t usb_lld_read(USBDriver *usbp, usbep_t ep,
diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c index c89d5a8e9..3cc076443 100644 --- a/os/hal/src/usb.c +++ b/os/hal/src/usb.c @@ -25,6 +25,8 @@ * @{
*/
+#include <string.h>
+
#include "ch.h"
#include "hal.h"
#include "usb.h"
@@ -75,8 +77,8 @@ static void start_rx_ep0(USBDriver *usbp) { /* Determines the maximum amount that can be received using a
single packet.*/
- if (usbp->usb_ep0n > usb_lld_ep0config.uepc_out_maxsize)
- usbp->usb_ep0lastsize = usb_lld_ep0config.uepc_out_maxsize;
+ if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_out_maxsize)
+ usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_out_maxsize;
else
usbp->usb_ep0lastsize = usbp->usb_ep0n;
usbp->usb_ep0state = USB_EP0_RX;
@@ -102,8 +104,8 @@ static void start_tx_ep0(USBDriver *usbp) { /* Determines the maximum amount that can be transmitted using a
single packet.*/
- if (usbp->usb_ep0n > usb_lld_ep0config.uepc_in_maxsize)
- usbp->usb_ep0lastsize = usb_lld_ep0config.uepc_in_maxsize;
+ if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize)
+ usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_in_maxsize;
else
usbp->usb_ep0lastsize = usbp->usb_ep0n;
@@ -294,14 +296,16 @@ void usbObjectInit(USBDriver *usbp) { * @api
*/
void usbStart(USBDriver *usbp, const USBConfig *config) {
+ unsigned i;
chDbgCheck((usbp != NULL) && (config != NULL), "usbStart");
chSysLock();
chDbgAssert((usbp->usb_state == USB_STOP) || (usbp->usb_state == USB_READY),
- "usbStart(), #1",
- "invalid state");
+ "usbStart(), #1", "invalid state");
usbp->usb_config = config;
+ for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
+ usbp->usb_ep[i] = NULL;
usb_lld_start(usbp);
usbp->usb_state = USB_READY;
chSysUnlock();
@@ -336,23 +340,26 @@ void usbStop(USBDriver *usbp) { *
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
+ * @param[out] epp pointer to an endpoint state descriptor structure
* @param[in] epcp the endpoint configuration
*
* @iclass
*/
-void usbEnableEndpointI(USBDriver *usbp, usbep_t ep,
- const USBEndpointConfig *epcp) {
+void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
+ const USBEndpointConfig *epcp) {
chDbgAssert(usbp->usb_state == USB_ACTIVE,
"usbEnableEndpointI(), #1", "invalid state");
- chDbgAssert(usbp->usb_epc[ep] != NULL,
- "usbEnableEndpointI(), #2", "already enabled");
+ chDbgAssert(usbp->usb_ep[ep] != NULL,
+ "usbEnableEndpointI(), #2", "already initialized");
/* Logically enabling the endpoint in the USBDriver structure.*/
- usbp->usb_epc[ep] = epcp;
+ memset(epp, 0, sizeof(USBEndpointState));
+ epp->uep_config = epcp;
+ usbp->usb_ep[ep] = epp;
/* Low level endpoint activation.*/
- usb_lld_enable_endpoint(usbp, ep, epcp);
+ usb_lld_init_endpoint(usbp, ep);
}
/**
@@ -373,7 +380,7 @@ void usbDisableEndpointsI(USBDriver *usbp) { "usbDisableEndpointsI(), #1", "invalid state");
for (i = 1; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_epc[i] = NULL;
+ usbp->usb_ep[i] = NULL;
/* Low level endpoints deactivation.*/
usb_lld_disable_endpoints(usbp);
@@ -396,7 +403,7 @@ void _usb_reset(USBDriver *usbp) { /* Invalidates all endpoints into the USBDriver structure.*/
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
- usbp->usb_epc[i] = NULL;
+ usbp->usb_ep[i] = NULL;
/* EP0 state machine initialization.*/
usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
@@ -404,9 +411,9 @@ void _usb_reset(USBDriver *usbp) { /* Low level reset.*/
usb_lld_reset(usbp);
- /* Low level endpoint zero activation.*/
- usbp->usb_epc[0] = &usb_lld_ep0config;
- usb_lld_enable_endpoint(usbp, 0, &usb_lld_ep0config);
+ /* Endpoint zero initialization.*/
+/* usbp->usb_ep[0].uep_config = &usb_lld_ep0config;
+ usb_lld_init_endpoint(usbp, 0, &usb_lld_ep0config);*/
}
/**
@@ -432,11 +439,13 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) { when a packet has been sent with size less than the maximum packet
size.*/
if ((usbp->usb_ep0max == 0) ||
- (usbp->usb_ep0lastsize < usb_lld_ep0config.uepc_in_maxsize))
+ (usbp->usb_ep0lastsize < usbp->usb_ep[0]->uep_config->uepc_in_maxsize))
usbp->usb_ep0state = USB_EP0_WAITING_STS;
else {
- usbp->usb_ep0lastsize = usbp->usb_ep0n > usb_lld_ep0config.uepc_in_maxsize ?
- usb_lld_ep0config.uepc_in_maxsize : usbp->usb_ep0n;
+ usbp->usb_ep0lastsize =
+ usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize ?
+ usbp->usb_ep[0]->uep_config->uepc_in_maxsize :
+ usbp->usb_ep0n;
usb_lld_write(usbp, 0, usbp->usb_ep0next, usbp->usb_ep0lastsize);
}
return;
|