git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8659 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
5f4e2e2389
commit
ac528c28c7
|
@ -1276,7 +1276,7 @@ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
|
|||
* @details This function must be executed by a system thread in order to
|
||||
* make the USB driver work.
|
||||
* @note The data copy part of the driver is implemented in this thread
|
||||
* in order to not perform heavy tasks withing interrupt handlers.
|
||||
* in order to not perform heavy tasks within interrupt handlers.
|
||||
*
|
||||
* @param[in] p pointer to the @p USBDriver object
|
||||
*
|
||||
|
|
|
@ -126,6 +126,7 @@ static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) {
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
__attribute__((noinline))
|
||||
static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) {
|
||||
size_t i, n;
|
||||
stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
|
||||
|
@ -139,9 +140,10 @@ static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) {
|
|||
in which the next received packet will be stored, so we need to
|
||||
read the counter of the OTHER buffer, which is where the last
|
||||
received packet was stored.*/
|
||||
n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK;
|
||||
if (EPR_EP_TYPE_IS_ISO(epr) && !(epr & EPR_DTOG_RX))
|
||||
n = (size_t)udp->RXCOUNT1 & RXCOUNT_COUNT_MASK;
|
||||
else
|
||||
n = (size_t)udp->RXCOUNT0 & RXCOUNT_COUNT_MASK;
|
||||
|
||||
i = n;
|
||||
while (i > 1) {
|
||||
|
@ -183,9 +185,10 @@ static void usb_packet_write_from_buffer(usbep_t ep,
|
|||
that is currently in use by the USB peripheral, that is, the buffer
|
||||
from which the next packet will be sent, so we need to write the
|
||||
counter of that buffer.*/
|
||||
udp->TXCOUNT0 = (stm32_usb_pma_t)n;
|
||||
if (EPR_EP_TYPE_IS_ISO(epr) && (epr & EPR_DTOG_TX))
|
||||
udp->TXCOUNT1 = (stm32_usb_pma_t)n;
|
||||
else
|
||||
udp->TXCOUNT0 = (stm32_usb_pma_t)n;
|
||||
|
||||
while (i > 0) {
|
||||
w = *buf++;
|
||||
|
@ -413,7 +416,17 @@ void usb_lld_start(USBDriver *usbp) {
|
|||
/* Reset procedure enforced on driver start.*/
|
||||
_usb_reset(usbp);
|
||||
}
|
||||
/* Configuration.*/
|
||||
|
||||
#if STM32_USB_USE_PUMP_THREAD && defined(_CHIBIOS_RT_)
|
||||
/* Creates the data pump thread. Note, it is created only once.*/
|
||||
if (usbp->tr == NULL) {
|
||||
usbp->tr = chThdCreateI(usbp->wa_pump, sizeof usbp->wa_pump,
|
||||
STM32_USB_PUMP_THREAD_PRIO,
|
||||
usb_lld_pump, usbp);
|
||||
chThdStartI(usbp->tr);
|
||||
chSchRescheduleS();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -765,6 +778,65 @@ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
|
|||
EPR_SET_STAT_TX(ep, EPR_STAT_TX_NAK);
|
||||
}
|
||||
|
||||
#if STM32_USB_USE_PUMP_THREAD || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief USB data transfer loop.
|
||||
* @details This function must be executed by a system thread in order to
|
||||
* make the USB driver work.
|
||||
* @note The data copy part of the driver is implemented in this thread
|
||||
* in order to not perform heavy tasks within interrupt handlers.
|
||||
*
|
||||
* @param[in] p pointer to the @p USBDriver object
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void usb_lld_pump(void *p) {
|
||||
USBDriver *usbp = (USBDriver *)p;
|
||||
|
||||
#if defined(_CHIBIOS_RT_)
|
||||
chRegSetThreadName("usb_lld_pump");
|
||||
#endif
|
||||
while (true) {
|
||||
usbep_t ep;
|
||||
|
||||
/* Checking if to go to sleep.*/
|
||||
osalSysLock();
|
||||
if ((usbp->state == USB_STOP) && (usbp->pending == 0U)) {
|
||||
osalThreadSuspendS(&usbp->wait);
|
||||
}
|
||||
osalSysUnlock();
|
||||
|
||||
/* Scanning endpoints.*/
|
||||
for (ep = 0; ep <= USB_ENDOPOINTS_NUMBER; ep++) {
|
||||
uint32_t epmask;
|
||||
|
||||
/* Checking of active endpoints.*/
|
||||
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||
if (epcp != NULL) {
|
||||
if (epcp->in_state != NULL) {
|
||||
epmask = (1U << 16U) << ep;
|
||||
if ((usbp->pending & epmask) != 0U) {
|
||||
/* Handling transfer of this IN endpoint.*/
|
||||
|
||||
osalSysLock();
|
||||
usbp->pending &= ~epmask;
|
||||
osalSysUnlock();
|
||||
}
|
||||
epmask = 1U << ep;
|
||||
if ((usbp->pending & epmask) != 0U) {
|
||||
/* Handling transfer of this OUT endpoint.*/
|
||||
|
||||
osalSysLock();
|
||||
usbp->pending &= ~epmask;
|
||||
osalSysUnlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* STM32_USB_USE_PUMP_THREAD */
|
||||
|
||||
#endif /* HAL_USE_USB */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -88,6 +88,30 @@
|
|||
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the use of a thread for data moving.
|
||||
* @details This option improves IRQ handling by performing data moving
|
||||
* from a dedicated internal thread at the cost of increased
|
||||
* footprint.
|
||||
*/
|
||||
#if !defined(STM32_USB_USE_PUMP_THREAD) || defined(__DOXYGEN__)
|
||||
#define STM32_USB_USE_PUMP_THREAD FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Dedicated data pump threads priority.
|
||||
*/
|
||||
#if !defined(STM32_USB_PUMP_THREAD_PRIO) || defined(__DOXYGEN__)
|
||||
#define STM32_USB_PUMP_THREAD_PRIO LOWPRIO
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Dedicated data pump threads stack size.
|
||||
*/
|
||||
#if !defined(STM32_USB_PUMP_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
|
||||
#define STM32_USB_PUMP_THREAD_STACK_SIZE 128
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
@ -360,6 +384,27 @@ struct USBDriver {
|
|||
* @brief Pointer to the next address in the packet memory.
|
||||
*/
|
||||
uint32_t pmnext;
|
||||
#if STM32_USB_USE_PUMP_THREAD || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mask of endpoints to be served by the pump thread.
|
||||
* @note 0..15 for OUT endpoints, 16..31 for IN endpoints.
|
||||
*/
|
||||
uint32_t pending;
|
||||
/**
|
||||
* @brief Pointer to the thread when it is sleeping or @p NULL.
|
||||
*/
|
||||
thread_reference_t wait;
|
||||
#if defined(_CHIBIOS_RT_) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Pointer to the thread once created.
|
||||
*/
|
||||
thread_reference_t tr;
|
||||
/**
|
||||
* @brief Working area for the dedicated data pump thread;
|
||||
*/
|
||||
THD_WORKING_AREA(wa_pump, STM32_USB_PUMP_THREAD_STACK_SIZE);
|
||||
#endif /* _CHIBIOS_RT_ */
|
||||
#endif /* STM32_USB_USE_PUMP_THREAD */
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -450,6 +495,9 @@ extern "C" {
|
|||
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep);
|
||||
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep);
|
||||
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep);
|
||||
#if STM32_USB_USE_PUMP_THREAD
|
||||
void usb_lld_pump(void *p);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue