aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-02-09 16:36:49 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2011-02-09 16:36:49 +0000
commit77934792d53efe99678286bab123c42c546478a7 (patch)
tree19ff302d365627261bf60802d78669e31bda1b76
parent9ab9d1b44b1dfc11094faf3da939d35061b53bed (diff)
downloadChibiOS-77934792d53efe99678286bab123c42c546478a7.tar.gz
ChibiOS-77934792d53efe99678286bab123c42c546478a7.tar.bz2
ChibiOS-77934792d53efe99678286bab123c42c546478a7.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2722 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--boards/GENERIC_SPC563/board.h2
-rw-r--r--os/hal/include/usb.h13
-rw-r--r--os/hal/platforms/SPC56x/hal_lld.h4
-rw-r--r--os/hal/platforms/STM32/usb_lld.c71
-rw-r--r--os/hal/platforms/STM32/usb_lld.h4
-rw-r--r--os/hal/src/serial_usb.c21
-rw-r--r--os/hal/src/usb.c76
7 files changed, 169 insertions, 22 deletions
diff --git a/boards/GENERIC_SPC563/board.h b/boards/GENERIC_SPC563/board.h
index 53c1140ce..0c840175f 100644
--- a/boards/GENERIC_SPC563/board.h
+++ b/boards/GENERIC_SPC563/board.h
@@ -34,7 +34,7 @@
* Board frequencies.
*/
#if !defined(EXTCLK)
-#define EXTCLK 8000000
+#define EXTCLK 12000000
#endif
/*
diff --git a/os/hal/include/usb.h b/os/hal/include/usb.h
index 26c701f52..c6c5d57cf 100644
--- a/os/hal/include/usb.h
+++ b/os/hal/include/usb.h
@@ -76,6 +76,11 @@
#define USB_EARLY_SET_ADDRESS 0
#define USB_LATE_SET_ADDRESS 1
+/**
+ * @brief Returned by some functions to report a busy endpoint.
+ */
+#define USB_ENDPOINT_BUSY ((size_t)0xFFFFFFFF)
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -233,7 +238,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] ep endpoint number
* @return The operation status.
* @retval FALSE Endpoint ready.
- * @retval TRUE Endpoint busy.
+ * @retval TRUE Endpoint transmitting.
*
* @iclass
*/
@@ -246,7 +251,7 @@ typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
* @param[in] ep endpoint number
* @return The operation status.
* @retval FALSE Endpoint ready.
- * @retval TRUE Endpoint busy.
+ * @retval TRUE Endpoint receiving.
*
* @iclass
*/
@@ -282,6 +287,10 @@ extern "C" {
void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
const USBEndpointConfig *epcp);
void usbDisableEndpointsI(USBDriver *usbp);
+ size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n);
+ size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n);
bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n);
bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep,
diff --git a/os/hal/platforms/SPC56x/hal_lld.h b/os/hal/platforms/SPC56x/hal_lld.h
index c61089a38..13dc9a267 100644
--- a/os/hal/platforms/SPC56x/hal_lld.h
+++ b/os/hal/platforms/SPC56x/hal_lld.h
@@ -112,7 +112,7 @@
* @note The effective divider factor is this value plus one.
*/
#if !defined(SPC563_CLK_PREDIV) || defined(__DOXYGEN__)
-#define SPC563_CLK_PREDIV 0
+#define SPC563_CLK_PREDIV 2
#endif
/**
@@ -120,7 +120,7 @@
* @note Must be in range 32...96.
*/
#if !defined(SPC563_CLK_MFD) || defined(__DOXYGEN__)
-#define SPC563_CLK_MFD 40
+#define SPC563_CLK_MFD 80
#endif
/**
diff --git a/os/hal/platforms/STM32/usb_lld.c b/os/hal/platforms/STM32/usb_lld.c
index a95baf45f..62e7caa82 100644
--- a/os/hal/platforms/STM32/usb_lld.c
+++ b/os/hal/platforms/STM32/usb_lld.c
@@ -483,6 +483,77 @@ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
}
/**
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @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
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The received packet size regardless the specified
+ * @p n parameter.
+ * @retval 0 Zero size packet received.
+ *
+ * @notapi
+ */
+size_t usb_lld_read_packet(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+ uint32_t *pmap;
+ stm32_usb_descriptor_t *udp;
+ size_t count;
+
+ (void)usbp;
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->RXADDR);
+ count = udp->RXCOUNT & RXCOUNT_COUNT_MASK;
+ if (n > count)
+ n = count;
+ n = (n + 1) / 2;
+ while (n > 0) {
+ *(uint16_t *)buf = (uint16_t)*pmap++;
+ buf += 2;
+ n--;
+ }
+ EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
+ return count;
+}
+
+/**
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ *
+ * @notapi
+ */
+void usb_lld_write_packet(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+ uint32_t *pmap;
+ stm32_usb_descriptor_t *udp;
+
+ (void)usbp;
+ udp = USB_GET_DESCRIPTOR(ep);
+ pmap = USB_ADDR2PTR(udp->TXADDR);
+ udp->TXCOUNT = n;
+ n = (n + 1) / 2;
+ while (n > 0) {
+ *pmap++ = *(uint16_t *)buf;
+ buf += 2;
+ n--;
+ }
+ EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
+}
+
+/**
* @brief Starts a receive operation on an OUT endpoint.
*
* @param[in] usbp pointer to the @p USBDriver object
diff --git a/os/hal/platforms/STM32/usb_lld.h b/os/hal/platforms/STM32/usb_lld.h
index d1e3169c2..6d131796e 100644
--- a/os/hal/platforms/STM32/usb_lld.h
+++ b/os/hal/platforms/STM32/usb_lld.h
@@ -333,6 +333,10 @@ 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);
+ 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,
+ const uint8_t *buf, size_t n);
void usb_lld_start_out(USBDriver *usbp, usbep_t ep,
uint8_t *buf, size_t n);
void usb_lld_start_in(USBDriver *usbp, usbep_t ep,
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 60976eca2..29aec2650 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -119,9 +119,9 @@ static void inotify(GenericQueue *qp) {
emptied, then a whole packet is loaded in the queue.*/
if (chIQIsEmptyI(&sdup->iqueue)) {
- n = usbReadI(sdup->config->usbp, sdup->config->data_available_ep,
- sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
- if (n > 0) {
+ n = usbReadPacketI(sdup->config->usbp, sdup->config->data_available_ep,
+ sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
+ if (n != USB_ENDPOINT_BUSY) {
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
chSemSetCounterI(&sdup->iqueue.q_sem, n);
}
@@ -137,9 +137,9 @@ static void onotify(GenericQueue *qp) {
/* If there is any data in the output queue then it is sent within a
single packet and the queue is emptied.*/
- n = usbWriteI(sdup->config->usbp, sdup->config->data_request_ep,
- sdup->oqueue.q_buffer, chOQGetFullI(&sdup->oqueue));
- if (n > 0) {
+ n = usbWritePacketI(sdup->config->usbp, sdup->config->data_request_ep,
+ sdup->oqueue.q_buffer, chOQGetFullI(&sdup->oqueue));
+ if (n != USB_ENDPOINT_BUSY) {
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
}
@@ -278,8 +278,8 @@ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
single packet and the queue is emptied.*/
n = chOQGetFullI(&sdup->oqueue);
if (n > 0) {
- n = usbWriteI(usbp, ep, sdup->oqueue.q_buffer, n);
- if (n > 0) {
+ n = usbWritePacketI(usbp, ep, sdup->oqueue.q_buffer, n);
+ if (n != USB_ENDPOINT_BUSY) {
sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
chSemSetCounterI(&sdup->oqueue.q_sem, SERIAL_USB_BUFFERS_SIZE);
chIOAddFlagsI(sdup, IO_OUTPUT_EMPTY);
@@ -302,8 +302,9 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) {
if (chIQIsEmptyI(&sdup->iqueue)) {
size_t n;
- n = usbReadI(usbp, ep, sdup->iqueue.q_buffer, SERIAL_USB_BUFFERS_SIZE);
- if (n > 0) {
+ n = usbReadPacketI(usbp, ep, sdup->iqueue.q_buffer,
+ SERIAL_USB_BUFFERS_SIZE);
+ if (n != USB_ENDPOINT_BUSY) {
sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
chSemSetCounterI(&sdup->iqueue.q_sem, n);
chIOAddFlagsI(sdup, IO_INPUT_AVAILABLE);
diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c
index d0db0ed5c..afec3c645 100644
--- a/os/hal/src/usb.c
+++ b/os/hal/src/usb.c
@@ -338,15 +338,73 @@ void usbDisableEndpointsI(USBDriver *usbp) {
}
/**
+ * @brief Reads a packet from the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @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
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The received packet size regardless the specified
+ * @p n parameter.
+ * @retval USB_ENDPOINT_BUSY Endpoint busy receiving.
+ * @retval 0 Zero size packet received.
+ *
+ * @iclass
+ */
+size_t usbReadPacketI(USBDriver *usbp, usbep_t ep,
+ uint8_t *buf, size_t n) {
+
+ if (usbp->ep[ep]->receiving)
+ return USB_ENDPOINT_BUSY;
+
+ return usb_lld_read_packet(usbp, ep, buf, n);;
+}
+
+/**
+ * @brief Writes a packet to the dedicated packet buffer.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in packet mode.
+ * @post The endpoint is ready to transmit the packet.
+ *
+ * @param[in] usbp pointer to the @p USBDriver object
+ * @param[in] ep endpoint number
+ * @param[in] buf buffer where to fetch the packet data
+ * @param[in] n maximum number of bytes to copy. This value must
+ * not exceed the maximum packet size for this endpoint.
+ * @return The operation status.
+ * @retval USB_ENDPOINT_BUSY Endpoint busy transmitting.
+ * @retval 0 Operation complete.
+ *
+ * @iclass
+ */
+size_t usbWritePacketI(USBDriver *usbp, usbep_t ep,
+ const uint8_t *buf, size_t n) {
+
+ if (usbp->ep[ep]->transmitting)
+ return USB_ENDPOINT_BUSY;
+
+ usb_lld_write_packet(usbp, ep, buf, n);
+ return 0;
+}
+
+/**
* @brief Starts a receive operation on an OUT endpoint.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in transaction mode.
+ * @post The endpoint callback is invoked when the transfer has been
+ * completed.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[out] buf buffer where to copy the endpoint data
- * @param[in] n maximum number of bytes to copy in the buffer
+ * @param[out] buf buffer where to copy the received data
+ * @param[in] n maximum number of bytes to copy
* @return The operation status.
- * @retval FALSE Receive operation started.
- * @retval TRUE Endpoint already receiving.
+ * @retval FALSE Operation complete.
+ * @retval TRUE Endpoint busy receiving.
*
* @iclass
*/
@@ -362,14 +420,18 @@ bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep,
/**
* @brief Starts a transmit operation on an IN endpoint.
+ * @pre In order to use this function he endpoint must have been
+ * initialized in transaction mode.
+ * @post The endpoint callback is invoked when the transfer has been
+ * completed.
*
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number
- * @param[in] buf buffer where to fetch the endpoint data
+ * @param[in] buf buffer where to fetch the data to be transmitted
* @param[in] n maximum number of bytes to copy
* @return The operation status.
- * @retval FALSE Transmit operation started.
- * @retval TRUE Endpoint already transmitting.
+ * @retval FALSE Operation complete.
+ * @retval TRUE Endpoint busy transmitting.
*
* @iclass
*/