aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-02-05 09:27:20 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-02-05 09:27:20 +0000
commit200f020df922ac84ffc0e0c98c97a193e3180b1f (patch)
treec0be7c7ff21bcd04fad5cacfb30109a0dffad4c4 /os
parentb920ab090fca4c5ccb7142e8332b5ae77f082a79 (diff)
downloadChibiOS-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.h4
-rw-r--r--os/hal/platforms/STM32/usb_lld.c59
-rw-r--r--os/hal/platforms/STM32/usb_lld.h52
-rw-r--r--os/hal/src/usb.c49
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;