Compiles but not tested and there are known errors. ISOC part not yet enabled.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15075 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-11-14 10:30:33 +00:00
parent 2a27797871
commit 8ba8bd3f72
2 changed files with 97 additions and 79 deletions

View File

@ -32,10 +32,6 @@
/* Driver local definitions. */ /* Driver local definitions. */
/*===========================================================================*/ /*===========================================================================*/
#define BTABLE_ADDR 0x0000
#define EPR_EP_TYPE_IS_ISO(bits) ((bits & EPR_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS)
/** /**
* @brief Returns an endpoint descriptor pointer. * @brief Returns an endpoint descriptor pointer.
*/ */
@ -221,19 +217,22 @@ static uint32_t usb_pm_alloc(USBDriver *usbp, size_t size) {
/** /**
* @brief Reads from a dedicated packet buffer. * @brief Reads from a dedicated packet buffer.
* *
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number * @param[in] ep endpoint number
* @param[out] buf buffer where to copy the packet data * @param[out] buf buffer where to copy the packet data
* @return The size of the receivee packet. * @return The size of the receivee packet.
* *
* @notapi * @notapi
*/ */
static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) { static size_t usb_packet_read_to_buffer(USBDriver *usbp,
usbep_t ep,
uint8_t *buf) {
size_t i, n; size_t i, n;
uint32_t w; uint32_t w;
USB_DRD_PMABuffDescTypeDef *udp = USB_GET_DESCRIPTOR(ep); USB_DRD_PMABuffDescTypeDef *udp = USB_GET_DESCRIPTOR(ep);
uint32_t *pmap = USB_GET_RX_BUFFER(udp); uint32_t *pmap = USB_GET_RX_BUFFER(udp);
#if STM32_USB_USE_ISOCHRONOUS #if STM32_USB_USE_ISOCHRONOUS
uint32_t epr = STM32_USB->CHEPR[ep]; uint32_t epr = usbp->usb->CHEPR[ep];
/* Double buffering is always enabled for isochronous endpoints, and /* Double buffering is always enabled for isochronous endpoints, and
although we overlap the two buffers for simplicity, we still need although we overlap the two buffers for simplicity, we still need
@ -249,6 +248,8 @@ static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) {
n = USB_GET_RX_COUNT0(udp); n = USB_GET_RX_COUNT0(udp);
} }
#else #else
(void)usbp;
n = USB_GET_RX_COUNT0(udp); n = USB_GET_RX_COUNT0(udp);
#endif #endif
@ -311,6 +312,7 @@ static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) {
/** /**
* @brief Writes to a dedicated packet buffer. * @brief Writes to a dedicated packet buffer.
* *
* @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number * @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
@ -318,7 +320,8 @@ static size_t usb_packet_read_to_buffer(usbep_t ep, uint8_t *buf) {
* *
* @notapi * @notapi
*/ */
static void usb_packet_write_from_buffer(usbep_t ep, static void usb_packet_write_from_buffer(USBDriver *usbp,
usbep_t ep,
const uint8_t *buf, const uint8_t *buf,
size_t n) { size_t n) {
USB_DRD_PMABuffDescTypeDef *udp = USB_GET_DESCRIPTOR(ep); USB_DRD_PMABuffDescTypeDef *udp = USB_GET_DESCRIPTOR(ep);
@ -326,7 +329,7 @@ static void usb_packet_write_from_buffer(usbep_t ep,
int i = (int)n; int i = (int)n;
#if STM32_USB_USE_ISOCHRONOUS #if STM32_USB_USE_ISOCHRONOUS
uint32_t epr = STM32_USB->CHEPR[ep]; uint32_t epr = usbp->usb->CHEPR[ep];
/* Double buffering is always enabled for isochronous endpoints, and /* Double buffering is always enabled for isochronous endpoints, and
although we overlap the two buffers for simplicity, we still need although we overlap the two buffers for simplicity, we still need
@ -341,6 +344,8 @@ static void usb_packet_write_from_buffer(usbep_t ep,
USB_SET_TX_COUNT0(udp, n); USB_SET_TX_COUNT0(udp, n);
} }
#else #else
(void)usbp;
USB_SET_TX_COUNT0(udp, n); USB_SET_TX_COUNT0(udp, n);
#endif #endif
@ -395,16 +400,17 @@ static void usb_packet_write_from_buffer(usbep_t ep,
* @brief Common ISR code, serves the EP-related interrupts. * @brief Common ISR code, serves the EP-related interrupts.
* *
* @param[in] usbp pointer to the @p USBDriver object * @param[in] usbp pointer to the @p USBDriver object
* @param[in] ep endpoint number * @param[in] istr ISTR register value to consider
* *
* @notapi * @notapi
*/ */
static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) { static void usb_serve_endpoints(USBDriver *usbp, uint32_t istr) {
size_t n; size_t n;
uint32_t ep = istr & USB_ISTR_IDN_Msk;
uint32_t chepr = usbp->usb->CHEPR[ep]; uint32_t chepr = usbp->usb->CHEPR[ep];
const USBEndpointConfig *epcp = usbp->epc[ep]; const USBEndpointConfig *epcp = usbp->epc[ep];
if (chepr & USB_EP_VTTX) { if ((istr & USB_ISTR_DIR) == 0U) {
/* IN endpoint, transmission.*/ /* IN endpoint, transmission.*/
USBInEndpointState *isp = epcp->in_state; USBInEndpointState *isp = epcp->in_state;
@ -420,7 +426,7 @@ static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) {
/* Writes the packet from the defined buffer.*/ /* Writes the packet from the defined buffer.*/
isp->txbuf += isp->txlast; isp->txbuf += isp->txlast;
isp->txlast = n; isp->txlast = n;
usb_packet_write_from_buffer(ep, isp->txbuf, n); usb_packet_write_from_buffer(usbp, ep, isp->txbuf, n);
/* Starting IN operation.*/ /* Starting IN operation.*/
CHEPR_SET_STATTX(usbp, ep, USB_EP_TX_VALID); CHEPR_SET_STATTX(usbp, ep, USB_EP_TX_VALID);
@ -430,7 +436,7 @@ static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) {
_usb_isr_invoke_in_cb(usbp, ep); _usb_isr_invoke_in_cb(usbp, ep);
} }
} }
if (chepr & USB_EP_VTRX) { else {
/* OUT endpoint, receive.*/ /* OUT endpoint, receive.*/
CHEPR_CLEAR_VTRX(usbp, ep); CHEPR_CLEAR_VTRX(usbp, ep);
@ -444,7 +450,7 @@ static void usb_serve_endpoints(USBDriver *usbp, uint32_t ep) {
USBOutEndpointState *osp = epcp->out_state; USBOutEndpointState *osp = epcp->out_state;
/* Reads the packet into the defined buffer.*/ /* Reads the packet into the defined buffer.*/
n = usb_packet_read_to_buffer(ep, osp->rxbuf); n = usb_packet_read_to_buffer(usbp, ep, osp->rxbuf);
osp->rxbuf += n; osp->rxbuf += n;
/* Transaction data updated.*/ /* Transaction data updated.*/
@ -485,10 +491,10 @@ OSAL_IRQ_HANDLER(STM32_USB1_HP_HANDLER) {
OSAL_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
/* Endpoint events handling.*/ /* Endpoint events handling.*/
istr = STM32_USB->ISTR; istr = usbp->usb->ISTR;
while (istr & USB_ISTR_SOF) { while ((istr & USB_ISTR_SOF) != 0U) {
usb_serve_endpoints(usbp, istr & USB_ISTR_IDN_Msk); usb_serve_endpoints(usbp, istr);
istr = STM32_USB->ISTR; istr = usbp->usb->ISTR;
} }
OSAL_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
@ -507,54 +513,53 @@ OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) {
OSAL_IRQ_PROLOGUE(); OSAL_IRQ_PROLOGUE();
istr = STM32_USB->ISTR; /* Reading interrupt sources and atomically clearing them.*/
istr = usbp->usb->ISTR;
usbp->usb->ISTR = ~istr;
/* USB bus reset condition handling.*/ /* USB bus reset condition handling.*/
if (istr & USB_ISTR_RESET) { if (istr & USB_ISTR_RESET) {
STM32_USB->ISTR = ~USB_ISTR_RESET;
_usb_reset(usbp); _usb_reset(usbp);
} }
/* USB bus SUSPEND condition handling.*/ /* USB bus SUSPEND condition handling.*/
if (istr & USB_ISTR_SUSP) { if ((istr & USB_ISTR_SUSP) != 0U) {
STM32_USB->CNTR |= USB_CNTR_SUSPEN; usbp->usb->CNTR |= USB_CNTR_SUSPEN;
#if STM32_USB_LOW_POWER_ON_SUSPEND #if STM32_USB_LOW_POWER_ON_SUSPEND
STM32_USB->CNTR |= USB_CNTR_LP_MODE; usbp->usb->CNTR |= USB_CNTR_LP_MODE;
#endif #endif
STM32_USB->ISTR = ~USB_ISTR_SUSP;
_usb_suspend(usbp); _usb_suspend(usbp);
} }
/* USB bus WAKEUP condition handling.*/ /* USB bus WAKEUP condition handling.*/
if (istr & USB_ISTR_WKUP) { if ((istr & USB_ISTR_WKUP) != 0U) {
uint32_t fnr = STM32_USB->FNR; uint32_t fnr = usbp->usb->FNR;
if (!(fnr & USB_FNR_RXDP)) { if ((fnr & USB_FNR_RXDP) == 0U) {
STM32_USB->CNTR &= ~USB_CNTR_SUSPEN;
_usb_wakeup(usbp); _usb_wakeup(usbp);
} }
#if STM32_USB_LOW_POWER_ON_SUSPEND #if STM32_USB_LOW_POWER_ON_SUSPEND
else { else {
/* Just noise, going back in SUSPEND mode, reference manual 22.4.5, /* Just noise, going back in SUSPEND mode, reference manual 22.4.5,
table 169.*/ table 169.*/
STM32_USB->CNTR |= USB_CNTR_LP_MODE; usbp->usb->CNTR |= USB_CNTR_LP_MODE;
} }
#endif #endif
STM32_USB->ISTR = ~USB_ISTR_WKUP;
} }
/* SOF handling.*/ /* SOF handling.*/
if (istr & USB_ISTR_SOF) { if ((istr & USB_ISTR_SOF) != 0U) {
_usb_isr_invoke_sof_cb(usbp); _usb_isr_invoke_sof_cb(usbp);
STM32_USB->ISTR = ~USB_ISTR_SOF; }
/* ERR handling.*/
if ((istr & USB_ISTR_ERR) != 0U) {
/* CHTODO */
} }
/* Endpoint events handling.*/ /* Endpoint events handling.*/
while (istr & USB_ISTR_SOF) { while ((istr & USB_ISTR_SOF) != 0U) {
usb_serve_endpoints(usbp, istr & USB_ISTR_IDN_Msk); usb_serve_endpoints(usbp, istr);
istr = STM32_USB->ISTR; istr = usbp->usb->ISTR;
} }
OSAL_IRQ_EPILOGUE(); OSAL_IRQ_EPILOGUE();
@ -596,14 +601,18 @@ void usb_lld_start(USBDriver *usbp) {
/* USB clock enabled.*/ /* USB clock enabled.*/
rccEnableUSB(true); rccEnableUSB(true);
rccResetUSB();
/* Powers up the transceiver while holding the USB in reset state.*/ /* Powers up the transceiver while holding the USB in reset state.*/
STM32_USB->CNTR = USB_CNTR_L2RES; usbp->usb->CNTR = USB_CNTR_USBRST;
/* Enabling the USB IRQ vectors, this also gives enough time to allow /* Enabling the USB IRQ vectors, this also gives enough time to allow
the transceiver power up (1uS).*/ the transceiver power up (1uS).*/
#if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER #if STM32_USB1_HP_NUMBER != STM32_USB1_LP_NUMBER
nvicEnableVector(STM32_USB1_HP_NUMBER, STM32_USB_USB1_HP_IRQ_PRIORITY); nvicEnableVector(STM32_USB1_HP_NUMBER, STM32_USB_USB1_HP_IRQ_PRIORITY);
#endif #endif
nvicEnableVector(STM32_USB1_LP_NUMBER, STM32_USB_USB1_LP_IRQ_PRIORITY); nvicEnableVector(STM32_USB1_LP_NUMBER, STM32_USB_USB1_LP_IRQ_PRIORITY);
/* Releases the USB reset.*/ /* Releases the USB reset.*/
STM32_USB->CNTR = 0; STM32_USB->CNTR = 0;
} }
@ -648,7 +657,6 @@ void usb_lld_reset(USBDriver *usbp) {
uint32_t cntr; uint32_t cntr;
/* Post reset initialization.*/ /* Post reset initialization.*/
STM32_USB->BTABLE = BTABLE_ADDR;
STM32_USB->ISTR = 0; STM32_USB->ISTR = 0;
STM32_USB->DADDR = USB_DADDR_EF; STM32_USB->DADDR = USB_DADDR_EF;
cntr = /* USB_CNTR_ESOFM | */ USB_CNTR_RESETM | USB_CNTR_SUSPM | cntr = /* USB_CNTR_ESOFM | */ USB_CNTR_RESETM | USB_CNTR_SUSPM |
@ -688,7 +696,7 @@ void usb_lld_set_address(USBDriver *usbp) {
* @notapi * @notapi
*/ */
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) { void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
uint16_t epr; uint32_t chepr;
USB_DRD_PMABuffDescTypeDef *dp; USB_DRD_PMABuffDescTypeDef *dp;
const USBEndpointConfig *epcp = usbp->epc[ep]; const USBEndpointConfig *epcp = usbp->epc[ep];
@ -700,28 +708,27 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
#if STM32_USB_USE_ISOCHRONOUS #if STM32_USB_USE_ISOCHRONOUS
osalDbgAssert((epcp->in_state == NULL) || (epcp->out_state == NULL), osalDbgAssert((epcp->in_state == NULL) || (epcp->out_state == NULL),
"isochronous EP cannot be IN and OUT"); "isochronous EP cannot be IN and OUT");
epr = USB_EP_ISOCHRONOUS; chepr = USB_EP_ISOCHRONOUS;
break; break;
#else #else
osalDbgAssert(false, "isochronous support disabled"); osalDbgAssert(false, "isochronous support disabled");
#endif #endif
/* Falls through.*/ /* Falls through.*/
case USB_EP_MODE_TYPE_BULK: case USB_EP_MODE_TYPE_BULK:
epr = USB_EP_BULK; chepr = USB_EP_BULK;
break; break;
case USB_EP_MODE_TYPE_INTR: case USB_EP_MODE_TYPE_INTR:
epr = USB_EP_INTERRUPT; chepr = USB_EP_INTERRUPT;
break; break;
default: default:
epr = USB_EP_CONTROL; chepr = USB_EP_CONTROL;
} }
dp = USB_GET_DESCRIPTOR(ep); dp = USB_GET_DESCRIPTOR(ep);
/* IN endpoint handling.*/ /* IN endpoint handling.*/
if (epcp->in_state != NULL) { if (epcp->in_state != NULL) {
dp->TXCOUNT0 = 0; dp->TXBD = usb_pm_alloc(usbp, epcp->in_maxsize);
dp->TXADDR0 = usb_pm_alloc(usbp, epcp->in_maxsize);
#if STM32_USB_USE_ISOCHRONOUS #if STM32_USB_USE_ISOCHRONOUS
if (epr == USB_EP_ISOCHRONOUS) { if (epr == USB_EP_ISOCHRONOUS) {
@ -733,22 +740,23 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
epr |= USB_EP_TX_NAK; epr |= USB_EP_TX_NAK;
} }
#else #else
epr |= USB_EP_TX_NAK; chepr |= USB_EP_TX_NAK;
#endif #endif
} }
/* OUT endpoint handling.*/ /* OUT endpoint handling.*/
if (epcp->out_state != NULL) { if (epcp->out_state != NULL) {
uint16_t nblocks; uint32_t nblocks;
/* Endpoint size and address initialization.*/ /* Endpoint size and address initialization.*/
if (epcp->out_maxsize > 62) if (epcp->out_maxsize > 62U) {
nblocks = (((((epcp->out_maxsize - 1) | 0x1f) + 1) / 32) << 10) | nblocks = ((((((uint32_t)epcp->out_maxsize - 1U) | 0x1FU) + 1U) / 32U) << 26) |
0x8000; 0x80000000U;
else }
nblocks = ((((epcp->out_maxsize - 1) | 1) + 1) / 2) << 10; else {
dp->RXCOUNT0 = nblocks; nblocks = (((((uint32_t)epcp->out_maxsize - 1U) | 1U) + 1U) / 2U) << 26;
dp->RXADDR0 = usb_pm_alloc(usbp, epcp->out_maxsize); }
dp->RXBD = nblocks | usb_pm_alloc(usbp, epcp->out_maxsize);
#if STM32_USB_USE_ISOCHRONOUS #if STM32_USB_USE_ISOCHRONOUS
if (epr == USB_EP_ISOCHRONOUS) { if (epr == USB_EP_ISOCHRONOUS) {
@ -760,22 +768,22 @@ void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
epr |= USB_EP_RX_NAK; epr |= USB_EP_RX_NAK;
} }
#else #else
epr |= USB_EP_RX_NAK; chepr |= USB_EP_RX_NAK;
#endif #endif
} }
/* Resetting the data toggling bits for this endpoint.*/ /* Resetting the data toggling bits for this endpoint.*/
if (STM32_USB->CHEPR[ep] & USB_EP_DTOG_RX) { if (usbp->usb->CHEPR[ep] & USB_EP_DTOG_RX) {
epr |= USB_EP_DTOG_RX; chepr |= USB_EP_DTOG_RX;
} }
if (STM32_USB->CHEPR[ep] & USB_EP_DTOG_TX) { if (usbp->usb->CHEPR[ep] & USB_EP_DTOG_TX) {
epr |= USB_EP_DTOG_TX; chepr |= USB_EP_DTOG_TX;
} }
/* EPxR register setup.*/ /* CHEPxR register cleared and initialized.*/
EPR_SET(ep, epr | ep); usbp->usb->CHEPR[ep] = usbp->usb->CHEPR[ep];
EPR_TOGGLE(ep, epr); usbp->usb->CHEPR[ep] = chepr;
} }
/** /**
@ -792,9 +800,11 @@ void usb_lld_disable_endpoints(USBDriver *usbp) {
usb_pm_reset(usbp); usb_pm_reset(usbp);
/* Disabling all endpoints.*/ /* Disabling all endpoints.*/
for (i = 1; i <= USB_ENDPOINTS_NUMBER; i++) { for (i = 1U; i <= (unsigned)USB_ENDPOINTS_NUMBER; i++) {
EPR_TOGGLE(i, 0);
EPR_SET(i, 0); /* Clearing all toggle bits then zeroing the rest.*/
usbp->usb->CHEPR[i] = usbp->usb->CHEPR[i];
usbp->usb->CHEPR[i] = 0U;
} }
} }
@ -863,13 +873,13 @@ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
* @notapi * @notapi
*/ */
void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) { void usb_lld_read_setup(USBDriver *usbp, usbep_t ep, uint8_t *buf) {
stm32_usb_pma_t *pmap; uint32_t *pmap;
USB_DRD_PMABuffDescTypeDef *udp; USB_DRD_PMABuffDescTypeDef *udp;
uint32_t n; uint32_t n;
(void)usbp; (void)usbp;
udp = USB_GET_DESCRIPTOR(ep); udp = USB_GET_DESCRIPTOR(ep);
pmap = USB_ADDR2PTR(udp->RXADDR0); pmap = USB_GET_RX_BUFFER(udp);
for (n = 0; n < 4; n++) { for (n = 0; n < 4; n++) {
*(uint16_t *)(void *)buf = (uint16_t)*pmap++; *(uint16_t *)(void *)buf = (uint16_t)*pmap++;
buf += 2; buf += 2;
@ -894,7 +904,7 @@ void usb_lld_start_out(USBDriver *usbp, usbep_t ep) {
osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) / osp->rxpkts = (uint16_t)((osp->rxsize + usbp->epc[ep]->out_maxsize - 1) /
usbp->epc[ep]->out_maxsize); usbp->epc[ep]->out_maxsize);
CHEPR_SET_STATRX(ep, USB_EP_RX_VALID); CHEPR_SET_STATRX(usbp, ep, USB_EP_RX_VALID);
} }
/** /**
@ -915,9 +925,9 @@ void usb_lld_start_in(USBDriver *usbp, usbep_t ep) {
n = (size_t)usbp->epc[ep]->in_maxsize; n = (size_t)usbp->epc[ep]->in_maxsize;
isp->txlast = n; isp->txlast = n;
usb_packet_write_from_buffer(ep, isp->txbuf, n); usb_packet_write_from_buffer(usbp, ep, isp->txbuf, n);
CHEPR_SET_STATTX(ep, USB_EP_TX_VALID); CHEPR_SET_STATTX(usbp, ep, USB_EP_TX_VALID);
} }
/** /**
@ -932,7 +942,7 @@ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
(void)usbp; (void)usbp;
EPR_SET_STAT_RX(ep, USB_EP_RX_STALL); CHEPR_SET_STATRX(usbp, ep, USB_EP_RX_STALL);
} }
/** /**
@ -947,7 +957,7 @@ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
(void)usbp; (void)usbp;
EPR_SET_STAT_TX(ep, USB_EP_TX_STALL); CHEPR_SET_STATTX(usbp, ep, USB_EP_TX_STALL);
} }
/** /**
@ -964,8 +974,9 @@ void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
/* Makes sure to not put to NAK an endpoint that is already /* Makes sure to not put to NAK an endpoint that is already
transferring.*/ transferring.*/
if ((STM32_USB->CHEPR[ep] & USB_CHEP_RX_STRX_Msk) != USB_EP_RX_VALID ) if ((STM32_USB->CHEPR[ep] & USB_CHEP_RX_STRX_Msk) != USB_EP_RX_VALID) {
EPR_SET_STAT_RX(ep, USB_EP_RX_NAK); CHEPR_SET_STATRX(usbp, ep, USB_EP_RX_NAK);
}
} }
/** /**
@ -982,8 +993,9 @@ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
/* Makes sure to not put to NAK an endpoint that is already /* Makes sure to not put to NAK an endpoint that is already
transferring.*/ transferring.*/
if ((STM32_USB->CHEPR[ep] & USB_CHEP_TX_STTX_Msk ) != USB_EP_TX_VALID) if ((STM32_USB->CHEPR[ep] & USB_CHEP_TX_STTX_Msk ) != USB_EP_TX_VALID) {
EPR_SET_STAT_TX(ep, USB_EP_TX_NAK ); CHEPR_SET_STATTX(usbp, ep, USB_EP_TX_NAK );
}
} }
#endif /* HAL_USE_USB */ #endif /* HAL_USE_USB */

View File

@ -31,10 +31,16 @@
/* Driver constants. */ /* Driver constants. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Number of the available endpoints.
* @details This value does not include the endpoint 0 which is always present.
*/
#define USB_ENDPOINTS_NUMBER 7
/** /**
* @brief Maximum endpoint address. * @brief Maximum endpoint address.
*/ */
#define USB_MAX_ENDPOINTS 8 #define USB_MAX_ENDPOINTS USB_ENDPOINTS_NUMBER
/** /**
* @brief Status stage handling method. * @brief Status stage handling method.