aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-08-13 10:14:45 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-08-13 10:14:45 +0000
commitb6b473a6a1fde7e7154dc2f1a2abaa395d526f62 (patch)
treea3cdbacc09481c62a569f8ddeb274b28320b7691 /os/hal/platforms
parent28e7808798ebb9c087d2ba15a0366362a50fea9e (diff)
downloadChibiOS-b6b473a6a1fde7e7154dc2f1a2abaa395d526f62.tar.gz
ChibiOS-b6b473a6a1fde7e7154dc2f1a2abaa395d526f62.tar.bz2
ChibiOS-b6b473a6a1fde7e7154dc2f1a2abaa395d526f62.zip
Performance improvements to the STM32 OTG driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4562 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/platforms')
-rw-r--r--os/hal/platforms/STM32/OTGv1/usb_lld.c67
-rw-r--r--os/hal/platforms/STM32/OTGv1/usb_lld.h6
2 files changed, 47 insertions, 26 deletions
diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.c b/os/hal/platforms/STM32/OTGv1/usb_lld.c
index b4238a8a0..78fc45a71 100644
--- a/os/hal/platforms/STM32/OTGv1/usb_lld.c
+++ b/os/hal/platforms/STM32/OTGv1/usb_lld.c
@@ -85,6 +85,7 @@ static const USBEndpointConfig ep0config = {
0x40,
&ep0_state.in,
&ep0_state.out,
+ 1,
ep0setup_buffer
};
@@ -448,31 +449,43 @@ static void otg_rxfifo_handler(USBDriver *usbp) {
* @notapi
*/
static void otg_txfifo_handler(USBDriver *usbp, usbep_t ep) {
- uint32_t n;
-
- /* Number of bytes remaining in current transaction.*/
- n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt;
- if (n > usbp->epc[ep]->in_maxsize)
- n = usbp->epc[ep]->in_maxsize;
-
- if (usbp->epc[ep]->in_state->txqueued) {
- /* Queue associated.*/
- otg_fifo_write_from_queue(ep,
- usbp->epc[ep]->in_state->mode.queue.txqueue,
- n);
- }
- else {
- /* Linear buffer associated.*/
- otg_fifo_write_from_buffer(ep,
- usbp->epc[ep]->in_state->mode.linear.txbuf,
- n);
- usbp->epc[ep]->in_state->mode.linear.txbuf += n;
- }
- usbp->epc[ep]->in_state->txcnt += n;
- /* Interrupt disabled on transaction end.*/
- if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize)
- OTG->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep);
+ /* The TXFIFO is filled until there is space and data to be transmitted.*/
+ while (TRUE) {
+ uint32_t n;
+
+ /* Number of bytes remaining in current transaction.*/
+ n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt;
+ if (n > usbp->epc[ep]->in_maxsize)
+ n = usbp->epc[ep]->in_maxsize;
+
+ /* Checks if in the TXFIFO there is enough space to accommodate the
+ next packet.*/
+ if (((OTG->ie[ep].DTXFSTS & DTXFSTS_INEPTFSAV_MASK) * 4) < n)
+ return;
+
+ /* Handles the two cases: linear buffer or queue.*/
+ if (usbp->epc[ep]->in_state->txqueued) {
+ /* Queue associated.*/
+ otg_fifo_write_from_queue(ep,
+ usbp->epc[ep]->in_state->mode.queue.txqueue,
+ n);
+ }
+ else {
+ /* Linear buffer associated.*/
+ otg_fifo_write_from_buffer(ep,
+ usbp->epc[ep]->in_state->mode.linear.txbuf,
+ n);
+ usbp->epc[ep]->in_state->mode.linear.txbuf += n;
+ }
+ usbp->epc[ep]->in_state->txcnt += n;
+
+ /* Interrupt disabled on transaction end.*/
+ if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) {
+ OTG->DIEPEMPMSK &= ~DIEPEMPMSK_INEPTXFEM(ep);
+ return;
+ }
+ }
}
/**
@@ -650,8 +663,8 @@ void usb_lld_start(USBDriver *usbp) {
- Full Speed 1.1 PHY.*/
OTG->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_PHYSEL;
- /* Interrupt on TXFIFOs empty.*/
- OTG->GAHBCFG = GAHBCFG_PTXFELVL | GAHBCFG_TXFELVL;
+ /* Interrupts on TXFIFOs half empty.*/
+ OTG->GAHBCFG = 0;
/* 48MHz 1.1 PHY.*/
OTG->DCFG = 0x02200000 | DCFG_PFIVL(0) | DCFG_DSPD_FS11;
@@ -806,6 +819,8 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
if (usbp->epc[ep]->in_cb != NULL) {
/* FIFO allocation for the IN endpoint.*/
fsize = usbp->epc[ep]->in_maxsize / 4;
+ if (usbp->epc[ep]->in_multiplier > 1)
+ fsize *= usbp->epc[ep]->in_multiplier;
OTG->DIEPTXF[ep - 1] = DIEPTXF_INEPTXFD(fsize) |
DIEPTXF_INEPTXSA(otg_ram_alloc(usbp, fsize));
otg_txfifo_flush(ep);
diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.h b/os/hal/platforms/STM32/OTGv1/usb_lld.h
index 8b2903982..30e96c71b 100644
--- a/os/hal/platforms/STM32/OTGv1/usb_lld.h
+++ b/os/hal/platforms/STM32/OTGv1/usb_lld.h
@@ -232,6 +232,12 @@ typedef struct {
USBOutEndpointState *out_state;
/* End of the mandatory fields.*/
/**
+ * @brief Determines the space allocated for the TXFIFO as multiples of
+ * the packet size (@p in_maxsize). Note that zero is interpreted
+ * as one for simplicity and robustness.
+ */
+ uint16_t in_multiplier;
+ /**
* @brief Pointer to a buffer for setup packets.
* @details Setup packets require a dedicated 8-bytes buffer, set this
* field to @p NULL for non-control endpoints.