Fixed bug #662.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8531 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
88247bf5e9
commit
ec59801695
|
@ -34,6 +34,8 @@
|
|||
|
||||
#define BTABLE_ADDR 0x0000
|
||||
|
||||
#define EPR_EP_TYPE_IS_ISO(epr) ((epr & EPR_EP_TYPE_MASK) == EPR_EP_TYPE_ISO)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
@ -211,7 +213,6 @@ static void usb_packet_write_from_buffer(stm32_usb_descriptor_t *udp,
|
|||
stm32_usb_pma_t *pmap;
|
||||
|
||||
pmap = USB_ADDR2PTR(udp->TXADDR0);
|
||||
udp->TXCOUNT0 = (stm32_usb_pma_t)n;
|
||||
|
||||
/* Pushing all complete words.*/
|
||||
i = 0;
|
||||
|
@ -251,7 +252,6 @@ static void usb_packet_write_from_queue(stm32_usb_descriptor_t *udp,
|
|||
syssts_t sts;
|
||||
stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->TXADDR0);
|
||||
|
||||
udp->TXCOUNT0 = (stm32_usb_pma_t)n;
|
||||
nhw = n / 2;
|
||||
while (nhw > 0) {
|
||||
stm32_usb_pma_t w;
|
||||
|
@ -368,7 +368,17 @@ OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) {
|
|||
/* IN endpoint, transmission.*/
|
||||
EPR_CLEAR_CTR_TX(ep);
|
||||
|
||||
/* Double buffering is always enabled for isochronous endpoints, and
|
||||
although we overlap the two buffers for simplicity, we still need
|
||||
to read from the right counter. The DTOG_TX bit indicates the buffer
|
||||
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 read the
|
||||
transmitted bytes from the counter of the OTHER buffer, which is
|
||||
where we stored the last transmitted packet.*/
|
||||
transmitted = (size_t)USB_GET_DESCRIPTOR(ep)->TXCOUNT0;
|
||||
if (EPR_EP_TYPE_IS_ISO(epr) && !(epr & EPR_DTOG_TX))
|
||||
transmitted = (size_t)USB_GET_DESCRIPTOR(ep)->TXCOUNT1;
|
||||
|
||||
epcp->in_state->txcnt += transmitted;
|
||||
n = epcp->in_state->txsize - epcp->in_state->txcnt;
|
||||
if (n > 0) {
|
||||
|
@ -376,6 +386,16 @@ OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) {
|
|||
if (n > epcp->in_maxsize)
|
||||
n = epcp->in_maxsize;
|
||||
|
||||
/* Double buffering is always enabled for isochronous endpoints, and
|
||||
although we overlap the two buffers for simplicity, we still need
|
||||
to write to the right counter. The DTOG_TX bit indicates the buffer
|
||||
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.*/
|
||||
USB_GET_DESCRIPTOR(ep)->TXCOUNT0 = (stm32_usb_pma_t)n;
|
||||
if (EPR_EP_TYPE_IS_ISO(epr) && (epr & EPR_DTOG_TX))
|
||||
USB_GET_DESCRIPTOR(ep)->TXCOUNT1 = (stm32_usb_pma_t)n;
|
||||
|
||||
if (epcp->in_state->txqueued)
|
||||
usb_packet_write_from_queue(USB_GET_DESCRIPTOR(ep),
|
||||
epcp->in_state->mode.queue.txqueue,
|
||||
|
@ -405,7 +425,17 @@ OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) {
|
|||
}
|
||||
else {
|
||||
stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
|
||||
|
||||
/* Double buffering is always enabled for isochronous endpoints, and
|
||||
although we overlap the two buffers for simplicity, we still need
|
||||
to read from the right counter. The DTOG_RX bit indicates the buffer
|
||||
that is currently in use by the USB peripheral, that is, the buffer
|
||||
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;
|
||||
|
||||
/* Reads the packet into the defined buffer.*/
|
||||
if (epcp->out_state->rxqueued)
|
||||
|
@ -418,6 +448,7 @@ OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) {
|
|||
n);
|
||||
epcp->out_state->mode.linear.rxbuf += n;
|
||||
}
|
||||
|
||||
/* Transaction data updated.*/
|
||||
epcp->out_state->rxcnt += n;
|
||||
epcp->out_state->rxsize -= n;
|
||||
|
@ -569,9 +600,13 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
|||
stm32_usb_descriptor_t *dp;
|
||||
const USBEndpointConfig *epcp = usbp->epc[ep];
|
||||
|
||||
/* Setting the endpoint type.*/
|
||||
/* Setting the endpoint type. Note that isochronous endpoints cannot be
|
||||
bidirectional because it uses double buffering and both transmit and
|
||||
receive descriptor fields are used for either direction.*/
|
||||
switch (epcp->ep_mode & USB_EP_MODE_TYPE) {
|
||||
case USB_EP_MODE_TYPE_ISOC:
|
||||
osalDbgAssert((epcp->in_cb == NULL) || (epcp->out_cb == NULL),
|
||||
"isochronous EP cannot be IN and OUT");
|
||||
epr = EPR_EP_TYPE_ISO;
|
||||
break;
|
||||
case USB_EP_MODE_TYPE_BULK:
|
||||
|
@ -584,29 +619,48 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
|||
epr = EPR_EP_TYPE_CONTROL;
|
||||
}
|
||||
|
||||
/* IN endpoint initially in NAK mode.*/
|
||||
if (epcp->in_cb != NULL)
|
||||
epr |= EPR_STAT_TX_NAK;
|
||||
|
||||
/* OUT endpoint initially in NAK mode.*/
|
||||
if (epcp->out_cb != NULL)
|
||||
epr |= EPR_STAT_RX_NAK;
|
||||
|
||||
/* EPxR register setup.*/
|
||||
EPR_SET(ep, epr | ep);
|
||||
EPR_TOGGLE(ep, epr);
|
||||
|
||||
/* Endpoint size and address initialization.*/
|
||||
if (epcp->out_maxsize > 62)
|
||||
nblocks = (((((epcp->out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
|
||||
0x8000;
|
||||
else
|
||||
nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10;
|
||||
|
||||
dp = USB_GET_DESCRIPTOR(ep);
|
||||
dp->TXCOUNT0 = 0;
|
||||
dp->RXCOUNT0 = nblocks;
|
||||
dp->TXADDR0 = usb_pm_alloc(usbp, epcp->in_maxsize);
|
||||
dp->RXADDR0 = usb_pm_alloc(usbp, epcp->out_maxsize);
|
||||
|
||||
/* Initial status for isochronous enpoints is valid because disabled and
|
||||
valid are the only legal values. Also since double buffering is used
|
||||
we need to initialize both count/address sets depending on the direction,
|
||||
but since we are not taking advantage of the double buffering, we set both
|
||||
addresses to point to the same PMA.*/
|
||||
if ((epcp->ep_mode & USB_EP_MODE_TYPE) == USB_EP_MODE_TYPE_ISOC) {
|
||||
if (epcp->in_cb != NULL) {
|
||||
epr |= EPR_STAT_TX_VALID;
|
||||
dp->TXCOUNT1 = dp->TXCOUNT0;
|
||||
dp->TXADDR1 = dp->TXADDR0; /* Both buffers overlapped.*/
|
||||
}
|
||||
if (epcp->out_cb != NULL) {
|
||||
epr |= EPR_STAT_RX_VALID;
|
||||
dp->RXCOUNT1 = dp->RXCOUNT0;
|
||||
dp->RXADDR1 = dp->RXADDR0; /* Both buffers overlapped.*/
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Initial status for other endpoint types is NAK.*/
|
||||
if (epcp->in_cb != NULL)
|
||||
epr |= EPR_STAT_TX_NAK;
|
||||
|
||||
if (epcp->out_cb != NULL)
|
||||
epr |= EPR_STAT_RX_NAK;
|
||||
}
|
||||
|
||||
/* EPxR register setup.*/
|
||||
EPR_SET(ep, epr | ep);
|
||||
EPR_TOGGLE(ep, epr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -737,12 +791,23 @@ void usb_lld_prepare_receive(USBDriver *usbp, usbep_t ep) {
|
|||
void usb_lld_prepare_transmit(USBDriver *usbp, usbep_t ep) {
|
||||
size_t n;
|
||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||
uint32_t epr = STM32_USB->EPR[ep];
|
||||
|
||||
/* Transfer initialization.*/
|
||||
n = isp->txsize;
|
||||
if (n > (size_t)usbp->epc[ep]->in_maxsize)
|
||||
n = (size_t)usbp->epc[ep]->in_maxsize;
|
||||
|
||||
/* Double buffering is always enabled for isochronous endpoints, and
|
||||
although we overlap the two buffers for simplicity, we still need
|
||||
to write to the right counter. The DTOG_TX bit indicates the buffer
|
||||
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.*/
|
||||
USB_GET_DESCRIPTOR(ep)->TXCOUNT0 = (stm32_usb_pma_t)n;
|
||||
if (EPR_EP_TYPE_IS_ISO(epr) && (epr & EPR_DTOG_TX))
|
||||
USB_GET_DESCRIPTOR(ep)->TXCOUNT1 = (stm32_usb_pma_t)n;
|
||||
|
||||
if (isp->txqueued)
|
||||
usb_packet_write_from_queue(USB_GET_DESCRIPTOR(ep),
|
||||
isp->mode.queue.txqueue, n);
|
||||
|
|
|
@ -144,6 +144,8 @@
|
|||
(backported to 3.0.3).
|
||||
- HAL: Fixed RTC module loses day of week when converting (bug #664)
|
||||
(backported to 3.0.3).
|
||||
- HAL: Fixed STM32 USBv1 broken isochronous endpoints (bug #662)
|
||||
(backported to 3.0.4).
|
||||
- HAL: Fixed STM32 USBv1 wrong multiplier when calculating descriptor address
|
||||
in BTABLE (bug #661)(backported to 3.0.4 and 2.6.10).
|
||||
- HAL: Fixed STM32 USBv1 does not make use of BTABLE_ADDR define (bug #660)
|
||||
|
|
Loading…
Reference in New Issue