Simplified USBv1 driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8656 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
32f4a2999d
commit
01e18c68be
|
@ -122,44 +122,71 @@ static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) {
|
||||||
*
|
*
|
||||||
* @param[in] udp pointer to a @p stm32_usb_descriptor_t
|
* @param[in] udp pointer to a @p stm32_usb_descriptor_t
|
||||||
* @param[out] buf buffer where to copy the packet data
|
* @param[out] buf buffer where to copy the packet data
|
||||||
* @param[in] n maximum number of bytes to copy. This value must
|
* @return The size of the receivee packet.
|
||||||
* not exceed the maximum packet size for this endpoint.
|
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
static void usb_packet_read_to_buffer(stm32_usb_descriptor_t *udp,
|
static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) {
|
||||||
uint8_t *buf, size_t n) {
|
size_t i, n;
|
||||||
|
stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
|
||||||
stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->RXADDR0);
|
stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->RXADDR0);
|
||||||
|
uint32_t epr = STM32_USB->EPR[ep];
|
||||||
|
|
||||||
while (n > 1) {
|
/* 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;
|
||||||
|
|
||||||
|
i = n;
|
||||||
|
while (i > 1) {
|
||||||
uint32_t w = *pmap++;
|
uint32_t w = *pmap++;
|
||||||
*buf++ = (uint8_t)w;
|
*buf++ = (uint8_t)w;
|
||||||
*buf++ = (uint8_t)(w >> 8);
|
*buf++ = (uint8_t)(w >> 8);
|
||||||
n -= 2;
|
i -= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n > 0) {
|
if (i > 0) {
|
||||||
*buf = (uint8_t)*pmap;
|
*buf = (uint8_t)*pmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Writes to a dedicated packet buffer.
|
* @brief Writes to a dedicated packet buffer.
|
||||||
*
|
*
|
||||||
* @param[in] udp pointer to a @p stm32_usb_descriptor_t
|
* @param[in] ep endpoint number
|
||||||
* @param[in] buf buffer where to fetch the packet data
|
* @param[in] buf buffer where to fetch the packet data
|
||||||
* @param[in] n maximum number of bytes to copy. This value must
|
* @param[in] n maximum number of bytes to copy. This value must
|
||||||
* not exceed the maximum packet size for this endpoint.
|
* not exceed the maximum packet size for this endpoint.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
static void usb_packet_write_from_buffer(stm32_usb_descriptor_t *udp,
|
static void usb_packet_write_from_buffer(usbep_t ep,
|
||||||
const uint8_t *buf,
|
const uint8_t *buf,
|
||||||
size_t n) {
|
size_t n) {
|
||||||
|
stm32_usb_descriptor_t *udp = USB_GET_DESCRIPTOR(ep);
|
||||||
stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->TXADDR0);
|
stm32_usb_pma_t *pmap = USB_ADDR2PTR(udp->TXADDR0);
|
||||||
|
uint32_t epr = STM32_USB->EPR[ep];
|
||||||
uint32_t w;
|
uint32_t w;
|
||||||
int i = (int)n;
|
int i = (int)n;
|
||||||
|
|
||||||
|
/* 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.*/
|
||||||
|
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;
|
||||||
|
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
w = *buf++;
|
w = *buf++;
|
||||||
w |= *buf++ << 8;
|
w |= *buf++ << 8;
|
||||||
|
@ -204,21 +231,9 @@ static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) {
|
||||||
if (n > epcp->in_maxsize)
|
if (n > epcp->in_maxsize)
|
||||||
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;
|
|
||||||
|
|
||||||
/* Writes the packet from the defined buffer.*/
|
/* Writes the packet from the defined buffer.*/
|
||||||
epcp->in_state->txbuf += transmitted;
|
epcp->in_state->txbuf += transmitted;
|
||||||
usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
|
usb_packet_write_from_buffer(ep, epcp->in_state->txbuf, n);
|
||||||
epcp->in_state->txbuf,
|
|
||||||
n);
|
|
||||||
|
|
||||||
/* Starting IN operation.*/
|
/* Starting IN operation.*/
|
||||||
EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
|
EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
|
||||||
|
@ -237,23 +252,8 @@ static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) {
|
||||||
_usb_isr_invoke_setup_cb(usbp, ep);
|
_usb_isr_invoke_setup_cb(usbp, ep);
|
||||||
}
|
}
|
||||||
else {
|
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.*/
|
/* Reads the packet into the defined buffer.*/
|
||||||
usb_packet_read_to_buffer(udp,
|
n = usb_packet_read_to_buffer(ep, epcp->out_state->rxbuf);
|
||||||
epcp->out_state->rxbuf,
|
|
||||||
n);
|
|
||||||
epcp->out_state->rxbuf += n;
|
epcp->out_state->rxbuf += n;
|
||||||
|
|
||||||
/* Transaction data updated.*/
|
/* Transaction data updated.*/
|
||||||
|
@ -688,25 +688,13 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
|
||||||
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
|
void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
|
||||||
size_t n;
|
size_t n;
|
||||||
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
USBInEndpointState *isp = usbp->epc[ep]->in_state;
|
||||||
uint32_t epr = STM32_USB->EPR[ep];
|
|
||||||
|
|
||||||
/* Transfer initialization.*/
|
/* Transfer initialization.*/
|
||||||
n = isp->txsize;
|
n = isp->txsize;
|
||||||
if (n > (size_t)usbp->epc[ep]->in_maxsize)
|
if (n > (size_t)usbp->epc[ep]->in_maxsize)
|
||||||
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
|
usb_packet_write_from_buffer(ep, isp->txbuf, n);
|
||||||
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;
|
|
||||||
|
|
||||||
usb_packet_write_from_buffer(USB_GET_DESCRIPTOR(ep),
|
|
||||||
isp->txbuf, n);
|
|
||||||
|
|
||||||
EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
|
EPR_SET_STAT_TX(ep, EPR_STAT_TX_VALID);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue