aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/hal/platforms/STM32/USBv1/usb_lld.c87
-rw-r--r--os/hal/src/usb.c5
-rw-r--r--os/kernel/include/chdebug.h7
-rw-r--r--os/kernel/src/chdebug.c8
-rw-r--r--readme.txt1
-rw-r--r--testhal/STM32F1xx/USB_CDC/main.c2
6 files changed, 58 insertions, 52 deletions
diff --git a/os/hal/platforms/STM32/USBv1/usb_lld.c b/os/hal/platforms/STM32/USBv1/usb_lld.c
index 1041f69da..0d61b68c7 100644
--- a/os/hal/platforms/STM32/USBv1/usb_lld.c
+++ b/os/hal/platforms/STM32/USBv1/usb_lld.c
@@ -174,8 +174,12 @@ static void usb_packet_read_to_queue(stm32_usb_descriptor_t *udp,
iqp->q_wrptr = iqp->q_buffer;
}
- /* Updating queue counter.*/
+ /* Updating queue.*/
+ chSysLockFromIsr();
iqp->q_counter += n;
+ while (notempty(&iqp->q_waiting))
+ chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK;
+ chSysUnlockFromIsr();
}
/**
@@ -240,6 +244,19 @@ static void usb_packet_write_from_queue(stm32_usb_descriptor_t *udp,
if (oqp->q_rdptr >= oqp->q_top)
oqp->q_rdptr = oqp->q_buffer;
}
+
+ /* Updating queue. Note, the lock is done in this unusual way because this
+ function can be called from both ISR and thread context so the kind
+ of lock function to be invoked cannot be decided beforehand.*/
+ port_lock();
+ dbg_enter_lock();
+
+ oqp->q_counter += n;
+ while (notempty(&oqp->q_waiting))
+ chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK;
+
+ dbg_leave_lock();
+ port_unlock();
}
/**
@@ -266,31 +283,6 @@ static void usb_prepare_receive(USBDriver *usbp, usbep_t ep, size_t n) {
usbp->epc[ep]->out_maxsize);
}
-/**
- * @brief Prepares for a transmit transaction on an IN endpoint.
- * @post The endpoint is ready for @p usbStartTransmitI().
- * @note The transmit transaction size is equal to the data contained
- * in the queue.
- *
- * @param[in] usbp pointer to the @p USBDriver object
- * @param[in] ep endpoint number
- * @param[in] n maximum number of bytes to copy
- *
- * @special
- */
-static void usb_prepare_transmit(USBDriver *usbp, usbep_t ep, size_t n) {
- USBInEndpointState *isp = usbp->epc[ep]->in_state;
-
- isp->txsize = n;
- isp->txcnt = 0;
-
- /* Transfer initialization.*/
- if (n > (size_t)usbp->epc[ep]->in_maxsize)
- n = (size_t)usbp->epc[ep]->in_maxsize;
- usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
- isp->mode.linear.txbuf, n);
-}
-
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
@@ -382,9 +374,15 @@ CH_IRQ_HANDLER(Vector90) {
n = epcp->in_maxsize;
else
n = epcp->in_state->txsize;
- usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
- epcp->in_state->mode.linear.txbuf,
- n);
+
+ if (epcp->in_state->txqueued)
+ usb_packet_write_from_queue(USB_GET_DESCRIPTOR(ep),
+ epcp->in_state->mode.queue.txqueue,
+ n);
+ else
+ usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
+ epcp->in_state->mode.linear.txbuf,
+ n);
chSysLockFromIsr();
usb_lld_start_in(usbp, ep);
chSysUnlockFromIsr();
@@ -406,8 +404,15 @@ CH_IRQ_HANDLER(Vector90) {
stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK;
- /* Reads the packet into the linear buffer.*/
- usb_packet_read_to_buffer(udp, epcp->out_state->mode.linear.rxbuf, n);
+ /* Reads the packet into the defined buffer.*/
+ if (epcp->out_state->rxqueued)
+ usb_packet_read_to_queue(udp,
+ epcp->out_state->mode.queue.rxqueue,
+ n);
+ else
+ usb_packet_read_to_buffer(udp,
+ epcp->out_state->mode.linear.rxbuf,
+ n);
/* Transaction data updated.*/
epcp->out_state->mode.linear.rxbuf += n;
@@ -735,6 +740,7 @@ void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep,
/* Transfer initialization.*/
if (n > (size_t)usbp->epc[ep]->in_maxsize)
n = (size_t)usbp->epc[ep]->in_maxsize;
+
usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
isp->mode.linear.txbuf, n);
}
@@ -788,8 +794,9 @@ void usb_lld_prepare_queued_transmit(USBDriver *usbp, usbep_t ep,
/* Transfer initialization.*/
if (n > (size_t)usbp->epc[ep]->in_maxsize)
n = (size_t)usbp->epc[ep]->in_maxsize;
- usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
- isp->mode.linear.txbuf, n);
+
+ usb_packet_write_from_queue(USB_GET_DESCRIPTOR(ep),
+ isp->mode.queue.txqueue, n);
}
/**
@@ -801,13 +808,8 @@ void usb_lld_prepare_queued_transmit(USBDriver *usbp, usbep_t ep,
* @notapi
*/
void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
- USBOutEndpointState *osp = usbp->epc[ep]->out_state;
- if (osp->rxqueued) {
- InputQueue *iqp = osp->mode.queue.rxqueue;
- while (notempty(&iqp->q_waiting))
- chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK;
- }
+ (void)usbp;
EPR_SET_STAT_RX(ep, EPR_STAT_RX_VALID);
}
@@ -821,13 +823,8 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
* @notapi
*/
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
- USBInEndpointState *isp = usbp->epc[ep]->in_state;
- if (isp->txqueued) {
- OutputQueue *oqp = isp->mode.queue.txqueue;
- while (notempty(&oqp->q_waiting))
- chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK;
- }
+ (void)usbp;
EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
}
diff --git a/os/hal/src/usb.c b/os/hal/src/usb.c
index ceae24770..fa79ea0c1 100644
--- a/os/hal/src/usb.c
+++ b/os/hal/src/usb.c
@@ -313,10 +313,11 @@ void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
"usbEnableEndpointI(), #2", "already initialized");
/* Logically enabling the endpoint in the USBDriver structure.*/
-// if (!(epcp->ep_mode & USB_EP_MODE_PACKET)) {
+ if (epcp->in_state != NULL)
memset(epcp->in_state, 0, sizeof(USBInEndpointState));
+ if (epcp->out_state != NULL)
memset(epcp->out_state, 0, sizeof(USBOutEndpointState));
-// }
+
usbp->epc[ep] = epcp;
/* Low level endpoint activation.*/
diff --git a/os/kernel/include/chdebug.h b/os/kernel/include/chdebug.h
index b899233e4..24dce243e 100644
--- a/os/kernel/include/chdebug.h
+++ b/os/kernel/include/chdebug.h
@@ -77,6 +77,8 @@
/*===========================================================================*/
#if !CH_DBG_SYSTEM_STATE_CHECK
+#define dbg_enter_lock()
+#define dbg_leave_lock()
#define dbg_check_disable()
#define dbg_check_suspend()
#define dbg_check_enable()
@@ -88,6 +90,9 @@
#define dbg_check_leave_isr()
#define chDbgCheckClassI();
#define chDbgCheckClassS();
+#else
+#define dbg_enter_lock() (dbg_lock_cnt = 1)
+#define dbg_leave_lock() (dbg_lock_cnt = 0)
#endif
/*===========================================================================*/
@@ -213,6 +218,8 @@ extern char *dbg_panic_msg;
extern "C" {
#endif
#if CH_DBG_SYSTEM_STATE_CHECK
+ extern cnt_t dbg_isr_cnt;
+ extern cnt_t dbg_lock_cnt;
void dbg_check_disable(void);
void dbg_check_suspend(void);
void dbg_check_enable(void);
diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c
index 8d38dcd6e..0bee1b4ea 100644
--- a/os/kernel/src/chdebug.c
+++ b/os/kernel/src/chdebug.c
@@ -108,7 +108,7 @@ void dbg_check_lock(void) {
if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0))
chDbgPanic("SV#4");
- dbg_lock_cnt = 1;
+ dbg_enter_lock();
}
/**
@@ -120,7 +120,7 @@ void dbg_check_unlock(void) {
if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0))
chDbgPanic("SV#5");
- dbg_lock_cnt = 0;
+ dbg_leave_lock();
}
/**
@@ -132,7 +132,7 @@ void dbg_check_lock_from_isr(void) {
if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0))
chDbgPanic("SV#6");
- dbg_lock_cnt = 1;
+ dbg_enter_lock();
}
/**
@@ -144,7 +144,7 @@ void dbg_check_unlock_from_isr(void) {
if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt <= 0))
chDbgPanic("SV#7");
- dbg_lock_cnt = 0;
+ dbg_leave_lock();
}
/**
diff --git a/readme.txt b/readme.txt
index 588b39d15..0c98ab9d6 100644
--- a/readme.txt
+++ b/readme.txt
@@ -145,7 +145,6 @@
- FIX: Fixed various minor documentation errors (bug 3484942)(backported
to 2.4.1).
- NEW: USB implementation for STM32F105/F107/2xx/F4xx devices.
- TODO: Modify the F103 USB driver for the new model.
- NEW: Improved SerialUSB driver using the new queued mode, much smaller
than the previous driver.
- NEW: Improved USB driver model supporting also queues for endpoint I/O,
diff --git a/testhal/STM32F1xx/USB_CDC/main.c b/testhal/STM32F1xx/USB_CDC/main.c
index d4625066f..b1af1b1bd 100644
--- a/testhal/STM32F1xx/USB_CDC/main.c
+++ b/testhal/STM32F1xx/USB_CDC/main.c
@@ -437,6 +437,8 @@ int main(void) {
/*
* Activates the USB driver and then the USB bus pull-up on D+.
*/
+ usbDisconnectBus(serusbcfg.usbp);
+ chThdSleepMilliseconds(1000);
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg);
usbConnectBus(serusbcfg.usbp);