USB rework, step 1.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2708 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
b920ab090f
commit
200f020df9
|
@ -313,8 +313,8 @@ extern "C" {
|
|||
void usbObjectInit(USBDriver *usbp);
|
||||
void usbStart(USBDriver *usbp, const USBConfig *config);
|
||||
void usbStop(USBDriver *usbp);
|
||||
void usbEnableEndpointI(USBDriver *usbp, usbep_t ep,
|
||||
const USBEndpointConfig *epcp);
|
||||
void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
|
||||
const USBEndpointConfig *epcp);
|
||||
void _usb_reset(USBDriver *usbp);
|
||||
void _usb_ep0in(USBDriver *usbp, usbep_t ep);
|
||||
void _usb_ep0out(USBDriver *usbp, usbep_t ep);
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "usb.h"
|
||||
|
@ -42,10 +44,20 @@
|
|||
USBDriver USBD1;
|
||||
#endif
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EP0 state.
|
||||
*/
|
||||
static USBEndpointState ep0state;
|
||||
|
||||
/**
|
||||
* @brief EP0 initialization structure.
|
||||
*/
|
||||
const USBEndpointConfig usb_lld_ep0config = {
|
||||
static const USBEndpointConfig ep0config = {
|
||||
_usb_ep0in,
|
||||
_usb_ep0out,
|
||||
0x40,
|
||||
|
@ -55,10 +67,6 @@ const USBEndpointConfig usb_lld_ep0config = {
|
|||
0x80
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
@ -112,18 +120,19 @@ CH_IRQ_HANDLER(USB_LP_IRQHandler) {
|
|||
while (istr & ISTR_CTR) {
|
||||
uint32_t ep;
|
||||
uint32_t epr = STM32_USB->EPR[ep = istr & ISTR_EP_ID_MASK];
|
||||
const USBEndpointConfig *epcp = usbp->usb_ep[ep]->uep_config;
|
||||
|
||||
if (epr & EPR_CTR_TX) {
|
||||
/* IN endpoint, transmission.*/
|
||||
EPR_CLEAR_CTR_TX(ep);
|
||||
if (usbp->usb_epc[ep]->uepc_in_cb)
|
||||
usbp->usb_epc[ep]->uepc_in_cb(usbp, ep);
|
||||
if (epcp->uepc_in_cb)
|
||||
epcp->uepc_in_cb(usbp, ep);
|
||||
}
|
||||
if (epr & EPR_CTR_RX) {
|
||||
/* OUT endpoint, receive.*/
|
||||
EPR_CLEAR_CTR_RX(ep);
|
||||
if (usbp->usb_epc[ep]->uepc_out_cb)
|
||||
usbp->usb_epc[ep]->uepc_out_cb(usbp, ep);
|
||||
if (epcp->uepc_out_cb)
|
||||
epcp->uepc_out_cb(usbp, ep);
|
||||
}
|
||||
istr = STM32_USB->ISTR;
|
||||
}
|
||||
|
@ -228,6 +237,12 @@ void usb_lld_reset(USBDriver *usbp) {
|
|||
if (usbp->usb_config->uc_sof_cb != NULL)
|
||||
cntr |= CNTR_SOFM;
|
||||
STM32_USB->CNTR = cntr;
|
||||
|
||||
/* EP0 initialization.*/
|
||||
memset(&ep0state, 0, sizeof ep0state);
|
||||
ep0state.uep_config = &ep0config;
|
||||
usbp->usb_ep[0] = &ep0state;
|
||||
usb_lld_init_endpoint(usbp, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -240,6 +255,7 @@ void usb_lld_reset(USBDriver *usbp) {
|
|||
*/
|
||||
void usb_lld_set_address(USBDriver *usbp, uint8_t addr) {
|
||||
|
||||
(void)usbp;
|
||||
STM32_USB->DADDR = (uint32_t)addr | DADDR_EF;
|
||||
}
|
||||
|
||||
|
@ -248,14 +264,13 @@ void usb_lld_set_address(USBDriver *usbp, uint8_t addr) {
|
|||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[in] epcp the endpoint configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep,
|
||||
const USBEndpointConfig *epcp) {
|
||||
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep) {
|
||||
uint16_t nblocks;
|
||||
stm32_usb_descriptor_t *dp;
|
||||
const USBEndpointConfig *epcp = usbp->usb_ep[ep]->uep_config;
|
||||
|
||||
/* EPxR register setup.*/
|
||||
EPR_SET(ep, epcp->uepc_epr | ep);
|
||||
|
@ -263,7 +278,8 @@ void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep,
|
|||
|
||||
/* Endpoint size and address initialization.*/
|
||||
if (epcp->uepc_out_maxsize > 62)
|
||||
nblocks = (((((epcp->uepc_out_maxsize - 1) | 0x1f) + 1) / 32) << 10) | 0x8000;
|
||||
nblocks = (((((epcp->uepc_out_maxsize - 1) | 0x1f) + 1) / 32) << 10) |
|
||||
0x8000;
|
||||
else
|
||||
nblocks = ((((epcp->uepc_out_maxsize - 1) | 1) + 1) / 2) << 10;
|
||||
dp = USB_GET_DESCRIPTOR(ep);
|
||||
|
@ -271,9 +287,6 @@ void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep,
|
|||
dp->RXCOUNT = nblocks;
|
||||
dp->TXADDR = epcp->uepc_inaddr;
|
||||
dp->RXADDR = epcp->uepc_outaddr;
|
||||
|
||||
/* Logically enabling the endpoint in the USBDriver structure.*/
|
||||
usbp->usb_epc[ep] = epcp;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,6 +299,7 @@ void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep,
|
|||
void usb_lld_disable_endpoints(USBDriver *usbp) {
|
||||
unsigned i;
|
||||
|
||||
(void)usbp;
|
||||
for (i = 1; i <= USB_ENDOPOINTS_NUMBER; i++) {
|
||||
EPR_TOGGLE(i, 0);
|
||||
EPR_SET(i, 0);
|
||||
|
@ -306,6 +320,7 @@ void usb_lld_disable_endpoints(USBDriver *usbp) {
|
|||
*/
|
||||
size_t usb_lld_get_readable(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
(void)usbp;
|
||||
if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_NAK)
|
||||
return 0;
|
||||
return (size_t)(USB_GET_DESCRIPTOR(ep)->RXCOUNT & RXCOUNT_COUNT_MASK);
|
||||
|
@ -331,6 +346,7 @@ size_t usb_lld_read(USBDriver *usbp, usbep_t ep, uint8_t *buf, size_t n) {
|
|||
stm32_usb_descriptor_t *udp;
|
||||
size_t count;
|
||||
|
||||
(void)usbp;
|
||||
if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_NAK)
|
||||
return 0;
|
||||
|
||||
|
@ -363,7 +379,7 @@ size_t usb_lld_get_writeable(USBDriver *usbp, usbep_t ep) {
|
|||
|
||||
if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_NAK)
|
||||
return 0;
|
||||
return (size_t)usbp->usb_epc[ep]->uepc_in_maxsize;
|
||||
return (size_t)usbp->usb_ep[ep]->uep_config->uepc_in_maxsize;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -388,6 +404,7 @@ size_t usb_lld_write(USBDriver *usbp, usbep_t ep,
|
|||
stm32_usb_descriptor_t *udp;
|
||||
size_t count;
|
||||
|
||||
(void)usbp;
|
||||
if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_NAK)
|
||||
return 0;
|
||||
|
||||
|
@ -414,6 +431,7 @@ size_t usb_lld_write(USBDriver *usbp, usbep_t ep,
|
|||
*/
|
||||
usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
(void)usbp;
|
||||
switch (STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) {
|
||||
case EPR_STAT_TX_DIS:
|
||||
return EP_STATUS_DISABLED;
|
||||
|
@ -434,6 +452,7 @@ usbepstatus_t usb_lld_get_status_in(USBDriver *usbp, usbep_t ep) {
|
|||
*/
|
||||
usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
(void)usbp;
|
||||
switch (STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) {
|
||||
case EPR_STAT_RX_DIS:
|
||||
return EP_STATUS_DISABLED;
|
||||
|
@ -454,6 +473,7 @@ usbepstatus_t usb_lld_get_status_out(USBDriver *usbp, usbep_t ep) {
|
|||
*/
|
||||
void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
(void)usbp;
|
||||
EPR_SET_STAT_TX(ep, EPR_STAT_TX_STALL);
|
||||
}
|
||||
|
||||
|
@ -467,6 +487,7 @@ void usb_lld_stall_in(USBDriver *usbp, usbep_t ep) {
|
|||
*/
|
||||
void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
(void)usbp;
|
||||
EPR_SET_STAT_RX(ep, EPR_STAT_RX_STALL);
|
||||
}
|
||||
|
||||
|
@ -480,6 +501,8 @@ void usb_lld_stall_out(USBDriver *usbp, usbep_t ep) {
|
|||
*/
|
||||
void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
/* Makes sure to not put to NAK an endpoint that is already
|
||||
transferring.*/
|
||||
if ((STM32_USB->EPR[ep] & EPR_STAT_TX_MASK) != EPR_STAT_TX_VALID)
|
||||
|
@ -496,6 +519,8 @@ void usb_lld_clear_in(USBDriver *usbp, usbep_t ep) {
|
|||
*/
|
||||
void usb_lld_clear_out(USBDriver *usbp, usbep_t ep) {
|
||||
|
||||
(void)usbp;
|
||||
|
||||
/* Makes sure to not put to NAK an endpoint that is already
|
||||
transferring.*/
|
||||
if ((STM32_USB->EPR[ep] & EPR_STAT_RX_MASK) != EPR_STAT_RX_VALID)
|
||||
|
|
|
@ -125,6 +125,49 @@ typedef struct {
|
|||
uint16_t uepc_outaddr;
|
||||
} USBEndpointConfig;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Type of an endpoint state structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Configuration associated to the endpoint.
|
||||
*/
|
||||
const USBEndpointConfig *uep_config;
|
||||
/**
|
||||
* @brief Pointer to the transmission buffer.
|
||||
*/
|
||||
const uint8_t *uep_txbuf;
|
||||
/**
|
||||
* @brief Pointer to the receive buffer.
|
||||
*/
|
||||
uint8_t *uep_rxbuf;
|
||||
/**
|
||||
* @brief Requested transmit transfer size.
|
||||
*/
|
||||
size_t uep_txsize;
|
||||
/**
|
||||
* @brief Requested receive transfer size.
|
||||
*/
|
||||
size_t uep_rxsize;
|
||||
/**
|
||||
* @brief Transmitted bytes so far.
|
||||
*/
|
||||
size_t uep_txcnt;
|
||||
/**
|
||||
* @brief Received bytes so far.
|
||||
*/
|
||||
size_t uep_rxcnt;
|
||||
/**
|
||||
* @brief @p TRUE if transmitting else @p FALSE.
|
||||
*/
|
||||
uint8_t uep_transmitting;
|
||||
/**
|
||||
* @brief @p TRUE if receiving else @p FALSE.
|
||||
*/
|
||||
uint8_t uep_receiving;
|
||||
} USBEndpointState;
|
||||
|
||||
/**
|
||||
* @brief Type of an USB driver configuration structure.
|
||||
*/
|
||||
|
@ -172,7 +215,7 @@ struct USBDriver {
|
|||
/**
|
||||
* @brief Active endpoints configurations.
|
||||
*/
|
||||
const USBEndpointConfig *usb_epc[USB_MAX_ENDPOINTS + 1];
|
||||
USBEndpointState *usb_ep[USB_MAX_ENDPOINTS + 1];
|
||||
/**
|
||||
* @brief Endpoint 0 state.
|
||||
*/
|
||||
|
@ -251,6 +294,10 @@ extern USBDriver USBD1;
|
|||
extern const USBEndpointConfig usb_lld_ep0config;
|
||||
#endif
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern USBEndpointState usb_lld_ep0state;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -259,8 +306,7 @@ extern "C" {
|
|||
void usb_lld_stop(USBDriver *usbp);
|
||||
void usb_lld_reset(USBDriver *usbp);
|
||||
void usb_lld_set_address(USBDriver *usbp, uint8_t addr);
|
||||
void usb_lld_enable_endpoint(USBDriver *usbp, usbep_t ep,
|
||||
const USBEndpointConfig *epcp);
|
||||
void usb_lld_init_endpoint(USBDriver *usbp, usbep_t ep);
|
||||
void usb_lld_disable_endpoints(USBDriver *usbp);
|
||||
size_t usb_lld_get_readable(USBDriver *usbp, usbep_t ep);
|
||||
size_t usb_lld_read(USBDriver *usbp, usbep_t ep,
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "usb.h"
|
||||
|
@ -75,8 +77,8 @@ static void start_rx_ep0(USBDriver *usbp) {
|
|||
|
||||
/* Determines the maximum amount that can be received using a
|
||||
single packet.*/
|
||||
if (usbp->usb_ep0n > usb_lld_ep0config.uepc_out_maxsize)
|
||||
usbp->usb_ep0lastsize = usb_lld_ep0config.uepc_out_maxsize;
|
||||
if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_out_maxsize)
|
||||
usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_out_maxsize;
|
||||
else
|
||||
usbp->usb_ep0lastsize = usbp->usb_ep0n;
|
||||
usbp->usb_ep0state = USB_EP0_RX;
|
||||
|
@ -102,8 +104,8 @@ static void start_tx_ep0(USBDriver *usbp) {
|
|||
|
||||
/* Determines the maximum amount that can be transmitted using a
|
||||
single packet.*/
|
||||
if (usbp->usb_ep0n > usb_lld_ep0config.uepc_in_maxsize)
|
||||
usbp->usb_ep0lastsize = usb_lld_ep0config.uepc_in_maxsize;
|
||||
if (usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize)
|
||||
usbp->usb_ep0lastsize = usbp->usb_ep[0]->uep_config->uepc_in_maxsize;
|
||||
else
|
||||
usbp->usb_ep0lastsize = usbp->usb_ep0n;
|
||||
|
||||
|
@ -294,14 +296,16 @@ void usbObjectInit(USBDriver *usbp) {
|
|||
* @api
|
||||
*/
|
||||
void usbStart(USBDriver *usbp, const USBConfig *config) {
|
||||
unsigned i;
|
||||
|
||||
chDbgCheck((usbp != NULL) && (config != NULL), "usbStart");
|
||||
|
||||
chSysLock();
|
||||
chDbgAssert((usbp->usb_state == USB_STOP) || (usbp->usb_state == USB_READY),
|
||||
"usbStart(), #1",
|
||||
"invalid state");
|
||||
"usbStart(), #1", "invalid state");
|
||||
usbp->usb_config = config;
|
||||
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
|
||||
usbp->usb_ep[i] = NULL;
|
||||
usb_lld_start(usbp);
|
||||
usbp->usb_state = USB_READY;
|
||||
chSysUnlock();
|
||||
|
@ -336,23 +340,26 @@ void usbStop(USBDriver *usbp) {
|
|||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[out] epp pointer to an endpoint state descriptor structure
|
||||
* @param[in] epcp the endpoint configuration
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void usbEnableEndpointI(USBDriver *usbp, usbep_t ep,
|
||||
const USBEndpointConfig *epcp) {
|
||||
void usbInitEndpointI(USBDriver *usbp, usbep_t ep, USBEndpointState *epp,
|
||||
const USBEndpointConfig *epcp) {
|
||||
|
||||
chDbgAssert(usbp->usb_state == USB_ACTIVE,
|
||||
"usbEnableEndpointI(), #1", "invalid state");
|
||||
chDbgAssert(usbp->usb_epc[ep] != NULL,
|
||||
"usbEnableEndpointI(), #2", "already enabled");
|
||||
chDbgAssert(usbp->usb_ep[ep] != NULL,
|
||||
"usbEnableEndpointI(), #2", "already initialized");
|
||||
|
||||
/* Logically enabling the endpoint in the USBDriver structure.*/
|
||||
usbp->usb_epc[ep] = epcp;
|
||||
memset(epp, 0, sizeof(USBEndpointState));
|
||||
epp->uep_config = epcp;
|
||||
usbp->usb_ep[ep] = epp;
|
||||
|
||||
/* Low level endpoint activation.*/
|
||||
usb_lld_enable_endpoint(usbp, ep, epcp);
|
||||
usb_lld_init_endpoint(usbp, ep);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -373,7 +380,7 @@ void usbDisableEndpointsI(USBDriver *usbp) {
|
|||
"usbDisableEndpointsI(), #1", "invalid state");
|
||||
|
||||
for (i = 1; i <= USB_MAX_ENDPOINTS; i++)
|
||||
usbp->usb_epc[i] = NULL;
|
||||
usbp->usb_ep[i] = NULL;
|
||||
|
||||
/* Low level endpoints deactivation.*/
|
||||
usb_lld_disable_endpoints(usbp);
|
||||
|
@ -396,7 +403,7 @@ void _usb_reset(USBDriver *usbp) {
|
|||
|
||||
/* Invalidates all endpoints into the USBDriver structure.*/
|
||||
for (i = 0; i <= USB_MAX_ENDPOINTS; i++)
|
||||
usbp->usb_epc[i] = NULL;
|
||||
usbp->usb_ep[i] = NULL;
|
||||
|
||||
/* EP0 state machine initialization.*/
|
||||
usbp->usb_ep0state = USB_EP0_WAITING_SETUP;
|
||||
|
@ -404,9 +411,9 @@ void _usb_reset(USBDriver *usbp) {
|
|||
/* Low level reset.*/
|
||||
usb_lld_reset(usbp);
|
||||
|
||||
/* Low level endpoint zero activation.*/
|
||||
usbp->usb_epc[0] = &usb_lld_ep0config;
|
||||
usb_lld_enable_endpoint(usbp, 0, &usb_lld_ep0config);
|
||||
/* Endpoint zero initialization.*/
|
||||
/* usbp->usb_ep[0].uep_config = &usb_lld_ep0config;
|
||||
usb_lld_init_endpoint(usbp, 0, &usb_lld_ep0config);*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -432,11 +439,13 @@ void _usb_ep0in(USBDriver *usbp, usbep_t ep) {
|
|||
when a packet has been sent with size less than the maximum packet
|
||||
size.*/
|
||||
if ((usbp->usb_ep0max == 0) ||
|
||||
(usbp->usb_ep0lastsize < usb_lld_ep0config.uepc_in_maxsize))
|
||||
(usbp->usb_ep0lastsize < usbp->usb_ep[0]->uep_config->uepc_in_maxsize))
|
||||
usbp->usb_ep0state = USB_EP0_WAITING_STS;
|
||||
else {
|
||||
usbp->usb_ep0lastsize = usbp->usb_ep0n > usb_lld_ep0config.uepc_in_maxsize ?
|
||||
usb_lld_ep0config.uepc_in_maxsize : usbp->usb_ep0n;
|
||||
usbp->usb_ep0lastsize =
|
||||
usbp->usb_ep0n > usbp->usb_ep[0]->uep_config->uepc_in_maxsize ?
|
||||
usbp->usb_ep[0]->uep_config->uepc_in_maxsize :
|
||||
usbp->usb_ep0n;
|
||||
usb_lld_write(usbp, 0, usbp->usb_ep0next, usbp->usb_ep0lastsize);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -232,6 +232,21 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EP1 state.
|
||||
*/
|
||||
USBEndpointState ep1state;
|
||||
|
||||
/**
|
||||
* @brief EP2 state.
|
||||
*/
|
||||
USBEndpointState ep2state;
|
||||
|
||||
/**
|
||||
* @brief EP3 state.
|
||||
*/
|
||||
USBEndpointState ep3state;
|
||||
|
||||
/**
|
||||
* @brief EP1 initialization structure (IN only).
|
||||
*/
|
||||
|
@ -284,9 +299,9 @@ static void usb_event(USBDriver *usbp, usbevent_t event) {
|
|||
case USB_EVENT_CONFIGURED:
|
||||
/* Enables the endpoints specified into the configuration.*/
|
||||
chSysLock();
|
||||
usbEnableEndpointI(usbp, DATA_REQUEST_EP, &ep1config);
|
||||
usbEnableEndpointI(usbp, INTERRUPT_REQUEST_EP, &ep2config);
|
||||
usbEnableEndpointI(usbp, DATA_AVAILABLE_EP, &ep3config);
|
||||
usbInitEndpointI(usbp, DATA_REQUEST_EP, &ep1state, &ep1config);
|
||||
usbInitEndpointI(usbp, INTERRUPT_REQUEST_EP, &ep2state, &ep2config);
|
||||
usbInitEndpointI(usbp, DATA_AVAILABLE_EP, &ep3state, &ep3config);
|
||||
chSysUnlock();
|
||||
return;
|
||||
case USB_EVENT_SUSPEND:
|
||||
|
|
Loading…
Reference in New Issue