rename ep_num to ep_idx, minor clean up

This commit is contained in:
hathach 2023-02-28 17:11:59 +07:00
parent 8db462bf6e
commit ffdc100cb9
4 changed files with 223 additions and 206 deletions

View File

@ -1495,17 +1495,19 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
} }
#if USE_ISO_EP_ALLOCATION #if USE_ISO_EP_ALLOCATION
#if CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_ENABLE_EP_IN
uint8_t ep_in = 0; uint8_t ep_in = 0;
uint16_t ep_in_size = 0; uint16_t ep_in_size = 0;
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
uint8_t ep_out = 0; uint8_t ep_out = 0;
uint16_t ep_out_size = 0; uint16_t ep_out_size = 0;
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
uint8_t ep_fb = 0; uint8_t ep_fb = 0;
#endif #endif
uint8_t const *p_desc = _audiod_fct[i].p_desc; uint8_t const *p_desc = _audiod_fct[i].p_desc;
uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN; uint8_t const *p_desc_end = p_desc + _audiod_fct[i].desc_length - TUD_AUDIO_DESC_IAD_LEN;
@ -1516,28 +1518,28 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc; tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) p_desc;
if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) if (desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS)
{ {
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
// Explicit feedback EP // Explicit feedback EP
if (desc_ep->bmAttributes.usage == 1) if (desc_ep->bmAttributes.usage == 1)
{ {
ep_fb = desc_ep->bEndpointAddress; ep_fb = desc_ep->bEndpointAddress;
} }
#endif #endif
// Data EP // Data EP
if (desc_ep->bmAttributes.usage == 0) if (desc_ep->bmAttributes.usage == 0)
{ {
if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN)
{ {
#if CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_ENABLE_EP_IN
ep_in = desc_ep->bEndpointAddress; ep_in = desc_ep->bEndpointAddress;
ep_in_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_in_size); ep_in_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_in_size);
#endif #endif
} else } else
{ {
#if CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_ENABLE_EP_OUT
ep_out = desc_ep->bEndpointAddress; ep_out = desc_ep->bEndpointAddress;
ep_out_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_out_size); ep_out_size = TU_MAX(tu_edpt_packet_size(desc_ep), ep_out_size);
#endif #endif
} }
} }
@ -1546,26 +1548,28 @@ uint16_t audiod_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uin
p_desc = tu_desc_next(p_desc); p_desc = tu_desc_next(p_desc);
} }
#if CFG_TUD_AUDIO_ENABLE_EP_IN #if CFG_TUD_AUDIO_ENABLE_EP_IN
if (ep_in) if (ep_in)
{ {
usbd_edpt_iso_alloc(rhport, ep_in, ep_in_size); usbd_edpt_iso_alloc(rhport, ep_in, ep_in_size);
} }
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
if (ep_out) if (ep_out)
{ {
usbd_edpt_iso_alloc(rhport, ep_out, ep_out_size); usbd_edpt_iso_alloc(rhport, ep_out, ep_out_size);
} }
#endif #endif
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
if (ep_fb) if (ep_fb)
{ {
usbd_edpt_iso_alloc(rhport, ep_fb, 4); usbd_edpt_iso_alloc(rhport, ep_fb, 4);
} }
#endif #endif
#endif #endif // USE_ISO_EP_ALLOCATION
break; break;
} }
@ -1628,18 +1632,19 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
if (audio->ep_in_as_intf_num == itf) if (audio->ep_in_as_intf_num == itf)
{ {
audio->ep_in_as_intf_num = 0; audio->ep_in_as_intf_num = 0;
#if !USE_ISO_EP_ALLOCATION #if !USE_ISO_EP_ALLOCATION
usbd_edpt_close(rhport, audio->ep_in); usbd_edpt_close(rhport, audio->ep_in);
#endif #endif
// Clear FIFOs, since data is no longer valid // Clear FIFOs, since data is no longer valid
#if !CFG_TUD_AUDIO_ENABLE_ENCODING #if !CFG_TUD_AUDIO_ENABLE_ENCODING
tu_fifo_clear(&audio->ep_in_ff); tu_fifo_clear(&audio->ep_in_ff);
#else #else
for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++)
{ {
tu_fifo_clear(&audio->tx_supp_ff[cnt]); tu_fifo_clear(&audio->tx_supp_ff[cnt]);
} }
#endif #endif
// Invoke callback - can be used to stop data sampling // Invoke callback - can be used to stop data sampling
if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request));
@ -1647,24 +1652,25 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
audio->ep_in = 0; // Necessary? audio->ep_in = 0; // Necessary?
} }
#endif #endif // CFG_TUD_AUDIO_ENABLE_EP_IN
#if CFG_TUD_AUDIO_ENABLE_EP_OUT #if CFG_TUD_AUDIO_ENABLE_EP_OUT
if (audio->ep_out_as_intf_num == itf) if (audio->ep_out_as_intf_num == itf)
{ {
audio->ep_out_as_intf_num = 0; audio->ep_out_as_intf_num = 0;
#if !USE_ISO_EP_ALLOCATION #if !USE_ISO_EP_ALLOCATION
usbd_edpt_close(rhport, audio->ep_out); usbd_edpt_close(rhport, audio->ep_out);
#endif #endif
// Clear FIFOs, since data is no longer valid // Clear FIFOs, since data is no longer valid
#if !CFG_TUD_AUDIO_ENABLE_DECODING #if !CFG_TUD_AUDIO_ENABLE_DECODING
tu_fifo_clear(&audio->ep_out_ff); tu_fifo_clear(&audio->ep_out_ff);
#else #else
for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++)
{ {
tu_fifo_clear(&audio->rx_supp_ff[cnt]); tu_fifo_clear(&audio->rx_supp_ff[cnt]);
} }
#endif #endif
// Invoke callback - can be used to stop data sampling // Invoke callback - can be used to stop data sampling
if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request)); if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request));
@ -1672,15 +1678,15 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
audio->ep_out = 0; // Necessary? audio->ep_out = 0; // Necessary?
// Close corresponding feedback EP // Close corresponding feedback EP
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
#if !USE_ISO_EP_ALLOCATION #if !USE_ISO_EP_ALLOCATION
usbd_edpt_close(rhport, audio->ep_fb); usbd_edpt_close(rhport, audio->ep_fb);
#endif #endif
audio->ep_fb = 0; audio->ep_fb = 0;
tu_memclr(&audio->feedback, sizeof(audio->feedback)); tu_memclr(&audio->feedback, sizeof(audio->feedback));
#endif #endif
} }
#endif #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT
// Save current alternative interface setting // Save current alternative interface setting
audio->alt_setting[idxItf] = alt; audio->alt_setting[idxItf] = alt;
@ -1724,11 +1730,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
audio->ep_in_sz = tu_edpt_packet_size(desc_ep); audio->ep_in_sz = tu_edpt_packet_size(desc_ep);
// If software encoding is enabled, parse for the corresponding parameters - doing this here means only AS interfaces with EPs get scanned for parameters // If software encoding is enabled, parse for the corresponding parameters - doing this here means only AS interfaces with EPs get scanned for parameters
#if CFG_TUD_AUDIO_ENABLE_ENCODING #if CFG_TUD_AUDIO_ENABLE_ENCODING
audiod_parse_for_AS_params(audio, p_desc_parse_for_params, p_desc_end, itf); audiod_parse_for_AS_params(audio, p_desc_parse_for_params, p_desc_end, itf);
// Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap
#if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING #if CFG_TUD_AUDIO_ENABLE_TYPE_I_ENCODING
const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / audio->n_bytes_per_sampe_tx) * audio->n_bytes_per_sampe_tx); const uint16_t active_fifo_depth = (uint16_t) ((audio->tx_supp_ff_sz_max / audio->n_bytes_per_sampe_tx) * audio->n_bytes_per_sampe_tx);
for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++) for (uint8_t cnt = 0; cnt < audio->n_tx_supp_ff; cnt++)
{ {
@ -1736,9 +1742,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
} }
audio->n_ff_used_tx = audio->n_channels_tx / audio->n_channels_per_ff_tx; audio->n_ff_used_tx = audio->n_channels_tx / audio->n_channels_per_ff_tx;
TU_ASSERT( audio->n_ff_used_tx <= audio->n_tx_supp_ff ); TU_ASSERT( audio->n_ff_used_tx <= audio->n_tx_supp_ff );
#endif #endif
#endif
#endif
// Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded
// It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there
@ -1755,11 +1760,11 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
audio->ep_out_as_intf_num = itf; audio->ep_out_as_intf_num = itf;
audio->ep_out_sz = tu_edpt_packet_size(desc_ep); audio->ep_out_sz = tu_edpt_packet_size(desc_ep);
#if CFG_TUD_AUDIO_ENABLE_DECODING #if CFG_TUD_AUDIO_ENABLE_DECODING
audiod_parse_for_AS_params(audio, p_desc_parse_for_params, p_desc_end, itf); audiod_parse_for_AS_params(audio, p_desc_parse_for_params, p_desc_end, itf);
// Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap // Reconfigure size of support FIFOs - this is necessary to avoid samples to get split in case of a wrap
#if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING #if CFG_TUD_AUDIO_ENABLE_TYPE_I_DECODING
const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sampe_rx) * audio->n_bytes_per_sampe_rx; const uint16_t active_fifo_depth = (audio->rx_supp_ff_sz_max / audio->n_bytes_per_sampe_rx) * audio->n_bytes_per_sampe_rx;
for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++) for (uint8_t cnt = 0; cnt < audio->n_rx_supp_ff; cnt++)
{ {
@ -1767,18 +1772,18 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
} }
audio->n_ff_used_rx = audio->n_channels_rx / audio->n_channels_per_ff_rx; audio->n_ff_used_rx = audio->n_channels_rx / audio->n_channels_per_ff_rx;
TU_ASSERT( audio->n_ff_used_rx <= audio->n_rx_supp_ff ); TU_ASSERT( audio->n_ff_used_rx <= audio->n_rx_supp_ff );
#endif #endif
#endif #endif
// Prepare for incoming data // Prepare for incoming data
#if USE_LINEAR_BUFFER_RX #if USE_LINEAR_BUFFER_RX
TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false); TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false);
#else #else
TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz), false); TU_VERIFY(usbd_edpt_xfer_fifo(rhport, audio->ep_out, &audio->ep_out_ff, audio->ep_out_sz), false);
#endif #endif
} }
#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1) // Check if usage is explicit data feedback
{ {
audio->ep_fb = ep_addr; audio->ep_fb = ep_addr;
@ -1787,7 +1792,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
// Enable SOF interrupt if callback is implemented // Enable SOF interrupt if callback is implemented
if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true); if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true);
} }
#endif #endif
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT
foundEPs += 1; foundEPs += 1;
@ -1838,7 +1843,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
default: break; default: break;
} }
} }
#endif #endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
// We are done - abort loop // We are done - abort loop
break; break;

View File

@ -1384,12 +1384,10 @@ bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packe
{ {
rhport = _usbd_rhport; rhport = _usbd_rhport;
TU_ASSERT(dcd_edpt_iso_alloc);
TU_ASSERT(tu_edpt_number(ep_addr) < CFG_TUD_ENDPPOINT_MAX); TU_ASSERT(tu_edpt_number(ep_addr) < CFG_TUD_ENDPPOINT_MAX);
if (dcd_edpt_iso_alloc) return dcd_edpt_iso_alloc(rhport, ep_addr, largest_packet_size);
return dcd_edpt_iso_alloc(rhport, ep_addr, largest_packet_size);
else
return false;
} }
bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep)
@ -1399,18 +1397,14 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep
uint8_t const epnum = tu_edpt_number(desc_ep->bEndpointAddress); uint8_t const epnum = tu_edpt_number(desc_ep->bEndpointAddress);
uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress);
TU_ASSERT(dcd_edpt_iso_activate);
TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX); TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX);
TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed)); TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed));
if (dcd_edpt_iso_activate) _usbd_dev.ep_status[epnum][dir].stalled = false;
{ _usbd_dev.ep_status[epnum][dir].busy = false;
_usbd_dev.ep_status[epnum][dir].stalled = false; _usbd_dev.ep_status[epnum][dir].claimed = false;
_usbd_dev.ep_status[epnum][dir].busy = false; return dcd_edpt_iso_activate(rhport, desc_ep);
_usbd_dev.ep_status[epnum][dir].claimed = false;
return dcd_edpt_iso_activate(rhport, desc_ep);
}
else
return false;
} }
#endif #endif

View File

@ -6,7 +6,7 @@
* Portions: * Portions:
* Copyright (c) 2016 STMicroelectronics * Copyright (c) 2016 STMicroelectronics
* Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2019 Ha Thach (tinyusb.org)
* Copyright (c) 2022 Simon Küppers (skuep) * Copyright (c) 2022 Simon Küppers (skuep)
* Copyright (c) 2022 HiFiPhile * Copyright (c) 2022 HiFiPhile
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
@ -159,6 +159,10 @@ TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_LENGTH))<=(PMA_LEN
TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes");
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
// One of these for every EP IN & OUT, uses a bit of RAM.... // One of these for every EP IN & OUT, uses a bit of RAM....
typedef struct typedef struct
{ {
@ -169,21 +173,9 @@ typedef struct
uint16_t pma_ptr; uint16_t pma_ptr;
uint16_t max_packet_size; uint16_t max_packet_size;
uint16_t pma_alloc_size; uint16_t pma_alloc_size;
uint8_t epnum; uint8_t ep_idx; // index for USB_EPnR register
} xfer_ctl_t; } xfer_ctl_t;
static xfer_ctl_t xfer_status[MAX_EP_COUNT][2];
TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t ep_addr)
{
uint8_t epnum = tu_edpt_number(ep_addr);
uint8_t dir = tu_edpt_dir(ep_addr);
// Fix -Werror=null-dereference
TU_ASSERT(epnum < MAX_EP_COUNT, &xfer_status[0][0]);
return &xfer_status[epnum][dir];
}
// EP allocator // EP allocator
typedef struct typedef struct
{ {
@ -192,12 +184,18 @@ typedef struct
bool allocated[2]; bool allocated[2];
} ep_alloc_t; } ep_alloc_t;
static xfer_ctl_t xfer_status[MAX_EP_COUNT][2];
static ep_alloc_t ep_alloc_status[STFSDEV_EP_COUNT]; static ep_alloc_t ep_alloc_status[STFSDEV_EP_COUNT];
static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6];
static uint8_t remoteWakeCountdown; // When wake is requested static uint8_t remoteWakeCountdown; // When wake is requested
//--------------------------------------------------------------------+
// Prototypes
//--------------------------------------------------------------------+
// into the stack. // into the stack.
static void dcd_handle_bus_reset(void); static void dcd_handle_bus_reset(void);
static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix); static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix);
@ -217,6 +215,20 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN
static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes); static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes);
static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes); static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes);
//--------------------------------------------------------------------+
// Inline helper
//--------------------------------------------------------------------+
TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t* xfer_ctl_ptr(uint32_t ep_addr)
{
uint8_t epnum = tu_edpt_number(ep_addr);
uint8_t dir = tu_edpt_dir(ep_addr);
// Fix -Werror=null-dereference
TU_ASSERT(epnum < MAX_EP_COUNT, &xfer_status[0][0]);
return &xfer_status[epnum][dir];
}
// Using a function due to better type checks // Using a function due to better type checks
// This seems better than having to do type casts everywhere else // This seems better than having to do type casts everywhere else
TU_ATTR_ALWAYS_INLINE static inline void reg16_clear_bits(__IO uint16_t *reg, uint16_t mask) { TU_ATTR_ALWAYS_INLINE static inline void reg16_clear_bits(__IO uint16_t *reg, uint16_t mask) {
@ -228,6 +240,10 @@ TU_ATTR_ALWAYS_INLINE static inline void clear_istr_bits(uint16_t mask) {
USB->ISTR = ~mask; USB->ISTR = ~mask;
} }
//--------------------------------------------------------------------+
// Controller API
//--------------------------------------------------------------------+
void dcd_init (uint8_t rhport) void dcd_init (uint8_t rhport)
{ {
/* Clocks should already be enabled */ /* Clocks should already be enabled */
@ -825,6 +841,7 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
{ {
return i; return i;
} }
// If EP of current direction is not allocated // If EP of current direction is not allocated
// Except for ISO endpoint, both direction should be free // Except for ISO endpoint, both direction should be free
if(!ep_alloc_status[i].allocated[dir] && if(!ep_alloc_status[i].allocated[dir] &&
@ -886,14 +903,14 @@ static void dcd_ep_free(uint8_t ep_addr)
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
{ {
(void)rhport; (void)rhport;
uint8_t const epnum = dcd_ep_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer); uint8_t const ep_idx = dcd_ep_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer);
uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc);
const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size);
uint16_t pma_addr; uint16_t pma_addr;
uint32_t wType; uint32_t wType;
TU_ASSERT(epnum < STFSDEV_EP_COUNT); TU_ASSERT(ep_idx < STFSDEV_EP_COUNT);
TU_ASSERT(buffer_size <= 1024); TU_ASSERT(buffer_size <= 1024);
// Set type // Set type
@ -916,8 +933,8 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc
TU_ASSERT(false); TU_ASSERT(false);
} }
pcd_set_eptype(USB, epnum, wType); pcd_set_eptype(USB, ep_idx, wType);
pcd_set_ep_address(USB, epnum, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress));
// Be normal, for now, instead of only accepting zero-byte packets (on control endpoint) // Be normal, for now, instead of only accepting zero-byte packets (on control endpoint)
// or being double-buffered (bulk endpoints) // or being double-buffered (bulk endpoints)
pcd_clear_ep_kind(USB,0); pcd_clear_ep_kind(USB,0);
@ -928,37 +945,37 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc
if( (dir == TUSB_DIR_IN) || (wType == USB_EP_ISOCHRONOUS) ) if( (dir == TUSB_DIR_IN) || (wType == USB_EP_ISOCHRONOUS) )
{ {
*pcd_ep_tx_address_ptr(USB, epnum) = pma_addr; *pcd_ep_tx_address_ptr(USB, ep_idx) = pma_addr;
pcd_set_ep_tx_bufsize(USB, epnum, buffer_size); pcd_set_ep_tx_bufsize(USB, ep_idx, buffer_size);
pcd_clear_tx_dtog(USB, epnum); pcd_clear_tx_dtog(USB, ep_idx);
} }
if( (dir == TUSB_DIR_OUT) || (wType == USB_EP_ISOCHRONOUS) ) if( (dir == TUSB_DIR_OUT) || (wType == USB_EP_ISOCHRONOUS) )
{ {
*pcd_ep_rx_address_ptr(USB, epnum) = pma_addr; *pcd_ep_rx_address_ptr(USB, ep_idx) = pma_addr;
pcd_set_ep_rx_bufsize(USB, epnum, buffer_size); pcd_set_ep_rx_bufsize(USB, ep_idx, buffer_size);
pcd_clear_rx_dtog(USB, epnum); pcd_clear_rx_dtog(USB, ep_idx);
} }
/* Enable endpoint */ /* Enable endpoint */
if (dir == TUSB_DIR_IN) if (dir == TUSB_DIR_IN)
{ {
if(wType == USB_EP_ISOCHRONOUS) { if(wType == USB_EP_ISOCHRONOUS) {
pcd_set_ep_tx_status(USB, epnum, USB_EP_TX_DIS); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS);
} else { } else {
pcd_set_ep_tx_status(USB, epnum, USB_EP_TX_NAK); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK);
} }
} else } else
{ {
if(wType == USB_EP_ISOCHRONOUS) { if(wType == USB_EP_ISOCHRONOUS) {
pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_DIS); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS);
} else { } else {
pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_NAK); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK);
} }
} }
xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size;
xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->epnum = epnum; xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx = ep_idx;
return true; return true;
} }
@ -981,16 +998,16 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
(void)rhport; (void)rhport;
xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr);
uint8_t const epnum = xfer->epnum; uint8_t const ep_idx = xfer->ep_idx;
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
if(dir == TUSB_DIR_IN) if(dir == TUSB_DIR_IN)
{ {
pcd_set_ep_tx_status(USB, epnum, USB_EP_TX_DIS); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS);
} }
else else
{ {
pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_DIS); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS);
} }
dcd_ep_free(ep_addr); dcd_ep_free(ep_addr);
@ -1004,19 +1021,19 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
TU_ASSERT(largest_packet_size <= 1024); TU_ASSERT(largest_packet_size <= 1024);
uint8_t const epnum = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS);
const uint16_t buffer_size = pcd_aligned_buffer_size(largest_packet_size); const uint16_t buffer_size = pcd_aligned_buffer_size(largest_packet_size);
/* Create a packet memory buffer area. For isochronous endpoints, /* Create a packet memory buffer area. For isochronous endpoints,
* use the same buffer as the double buffer, essentially disabling double buffering */ * use the same buffer as the double buffer, essentially disabling double buffering */
uint16_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size); uint16_t pma_addr = dcd_pma_alloc(ep_addr, buffer_size);
xfer_ctl_ptr(ep_addr)->epnum = epnum; xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx;
pcd_set_eptype(USB, epnum, USB_EP_ISOCHRONOUS); pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS);
*pcd_ep_tx_address_ptr(USB, epnum) = pma_addr; *pcd_ep_tx_address_ptr(USB, ep_idx) = pma_addr;
*pcd_ep_rx_address_ptr(USB, epnum) = pma_addr; *pcd_ep_rx_address_ptr(USB, ep_idx) = pma_addr;
return true; return true;
} }
@ -1024,30 +1041,30 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet
bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
{ {
(void)rhport; (void)rhport;
uint8_t const epnum = xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->epnum; uint8_t const ep_idx = xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->ep_idx;
uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc);
const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size);
/* Disable endpoint */ /* Disable endpoint */
if(dir == TUSB_DIR_IN) if(dir == TUSB_DIR_IN)
{ {
pcd_set_ep_tx_status(USB, epnum, USB_EP_TX_DIS); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS);
} }
else else
{ {
pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_DIS); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS);
} }
pcd_set_ep_address(USB, epnum, tu_edpt_number(p_endpoint_desc->bEndpointAddress)); pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress));
// Be normal, for now, instead of only accepting zero-byte packets (on control endpoint) // Be normal, for now, instead of only accepting zero-byte packets (on control endpoint)
// or being double-buffered (bulk endpoints) // or being double-buffered (bulk endpoints)
pcd_clear_ep_kind(USB,0); pcd_clear_ep_kind(USB,0);
pcd_set_ep_tx_bufsize(USB, epnum, buffer_size); pcd_set_ep_tx_bufsize(USB, ep_idx, buffer_size);
pcd_set_ep_rx_bufsize(USB, epnum, buffer_size); pcd_set_ep_rx_bufsize(USB, ep_idx, buffer_size);
pcd_clear_tx_dtog(USB, epnum); pcd_clear_tx_dtog(USB, ep_idx);
pcd_clear_rx_dtog(USB, epnum); pcd_clear_rx_dtog(USB, ep_idx);
xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size;
@ -1093,8 +1110,8 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
(void) rhport; (void) rhport;
xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr);
uint8_t const epnum = xfer->epnum; uint8_t const ep_idx = xfer->ep_idx;
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
xfer->buffer = buffer; xfer->buffer = buffer;
xfer->ff = NULL; xfer->ff = NULL;
@ -1105,22 +1122,22 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
{ {
// A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid // A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid
// buffer for the control endpoint. // buffer for the control endpoint.
if (epnum == 0 && buffer == NULL) if (ep_idx == 0 && buffer == NULL)
{ {
xfer->buffer = (uint8_t*)_setup_packet; xfer->buffer = (uint8_t*)_setup_packet;
} }
if(total_bytes > xfer->max_packet_size) if(total_bytes > xfer->max_packet_size)
{ {
pcd_set_ep_rx_bufsize(USB,epnum,xfer->max_packet_size); pcd_set_ep_rx_bufsize(USB,ep_idx,xfer->max_packet_size);
} else { } else {
pcd_set_ep_rx_bufsize(USB,epnum,total_bytes); pcd_set_ep_rx_bufsize(USB,ep_idx,total_bytes);
} }
pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_VALID); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID);
} }
else // IN else // IN
{ {
dcd_transmit_packet(xfer,epnum); dcd_transmit_packet(xfer,ep_idx);
} }
return true; return true;
} }
@ -1130,7 +1147,7 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
(void) rhport; (void) rhport;
xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr);
uint8_t const epnum = xfer->epnum; uint8_t const epnum = xfer->ep_idx;
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
xfer->buffer = NULL; xfer->buffer = NULL;
@ -1160,16 +1177,16 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
(void)rhport; (void)rhport;
xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr);
uint8_t const epnum = xfer->epnum; uint8_t const ep_idx = xfer->ep_idx;
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
if (dir == TUSB_DIR_IN) if (dir == TUSB_DIR_IN)
{ // IN { // IN
pcd_set_ep_tx_status(USB, epnum, USB_EP_TX_STALL); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_STALL);
} }
else else
{ // OUT { // OUT
pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_STALL); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_STALL);
} }
} }
@ -1178,25 +1195,25 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
(void)rhport; (void)rhport;
xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr); xfer_ctl_t * xfer = xfer_ctl_ptr(ep_addr);
uint8_t const epnum = xfer->epnum; uint8_t const ep_idx = xfer->ep_idx;
uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr);
if (dir == TUSB_DIR_IN) if (dir == TUSB_DIR_IN)
{ // IN { // IN
if (pcd_get_eptype(USB, epnum) != USB_EP_ISOCHRONOUS) { if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) {
pcd_set_ep_tx_status(USB, epnum, USB_EP_TX_NAK); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK);
} }
/* Reset to DATA0 if clearing stall condition. */ /* Reset to DATA0 if clearing stall condition. */
pcd_clear_tx_dtog(USB, epnum); pcd_clear_tx_dtog(USB, ep_idx);
} }
else else
{ // OUT { // OUT
if (pcd_get_eptype(USB, epnum) != USB_EP_ISOCHRONOUS) { if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) {
pcd_set_ep_rx_status(USB, epnum, USB_EP_RX_NAK); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK);
} }
/* Reset to DATA0 if clearing stall condition. */ /* Reset to DATA0 if clearing stall condition. */
pcd_clear_rx_dtog(USB, epnum); pcd_clear_rx_dtog(USB, ep_idx);
} }
} }
@ -1318,7 +1335,7 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN
*dstVal++ = ((temp >> 8) & 0xFF); *dstVal++ = ((temp >> 8) & 0xFF);
} }
if (wNBytes % 2) if (wNBytes & 0x01)
{ {
temp = *pdwVal; temp = *pdwVal;
pdwVal += PMA_STRIDE; pdwVal += PMA_STRIDE;

View File

@ -120,9 +120,9 @@
static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR;
// prototypes // prototypes
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum); TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx);
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum); TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx);
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wRegValue); TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue);
/* Aligned buffer size according to hardware */ /* Aligned buffer size according to hardware */
TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size)
@ -138,71 +138,71 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t si
} }
/* SetENDPOINT */ /* SetENDPOINT */
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wRegValue) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue)
{ {
__O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpNum*2u); __O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
*reg = (uint16_t)wRegValue; *reg = (uint16_t)wRegValue;
} }
/* GetENDPOINT */ /* GetENDPOINT */
TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpNum) { TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) {
__I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpNum*2u); __I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
return *reg; return *reg;
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wType) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= (uint32_t)USB_EP_T_MASK; regVal &= (uint32_t)USB_EP_T_MASK;
regVal |= wType; regVal |= wType;
regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high
pcd_set_endpoint(USBx, bEpNum, regVal); pcd_set_endpoint(USBx, bEpIdx, regVal);
} }
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EP_T_FIELD; regVal &= USB_EP_T_FIELD;
return regVal; return regVal;
} }
/** /**
* @brief Clears bit CTR_RX / CTR_TX in the endpoint register. * @brief Clears bit CTR_RX / CTR_TX in the endpoint register.
* @param USBx USB peripheral instance register address. * @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number. * @param bEpIdx Endpoint Number.
* @retval None * @retval None
*/ */
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EPREG_MASK; regVal &= USB_EPREG_MASK;
regVal &= ~USB_EP_CTR_RX; regVal &= ~USB_EP_CTR_RX;
regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0) regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0)
pcd_set_endpoint(USBx, bEpNum, regVal); pcd_set_endpoint(USBx, bEpIdx, regVal);
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EPREG_MASK; regVal &= USB_EPREG_MASK;
regVal &= ~USB_EP_CTR_TX; regVal &= ~USB_EP_CTR_TX;
regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0)
pcd_set_endpoint(USBx, bEpNum,regVal); pcd_set_endpoint(USBx, bEpIdx,regVal);
} }
/** /**
* @brief gets counter of the tx buffer. * @brief gets counter of the tx buffer.
* @param USBx USB peripheral instance register address. * @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number. * @param bEpIdx Endpoint Number.
* @retval Counter value * @retval Counter value
*/ */
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
__I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpNum); __I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx);
return *regPtr & 0x3ffU; return *regPtr & 0x3ffU;
} }
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
__I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpNum); __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx);
return *regPtr & 0x3ffU; return *regPtr & 0x3ffU;
} }
@ -229,17 +229,17 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_cnt_reg(__O uint16_t * pdwRe
/** /**
* @brief Sets address in an endpoint register. * @brief Sets address in an endpoint register.
* @param USBx USB peripheral instance register address. * @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number. * @param bEpIdx Endpoint Number.
* @param bAddr Address. * @param bAddr Address.
* @retval None * @retval None
*/ */
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t bAddr) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EPREG_MASK; regVal &= USB_EPREG_MASK;
regVal |= bAddr; regVal |= bAddr;
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
pcd_set_endpoint(USBx, bEpNum,regVal); pcd_set_endpoint(USBx, bEpIdx,regVal);
} }
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x)
@ -250,47 +250,47 @@ TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_Type
} }
// Pointers to the PMA table entries (using the ARM address space) // Pointers to the PMA table entries (using the ARM address space)
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_address_ptr(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_address_ptr(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 0u); return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u);
} }
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 1u); return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u);
} }
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_address_ptr(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_address_ptr(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 2u); return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u);
} }
TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
return pcd_btable_word_ptr(USBx,(bEpNum)*4u + 3u); return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u);
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount)
{ {
__IO uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpNum); __IO uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx);
*reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU);
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount)
{ {
__IO uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpNum); __IO uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx);
*reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU);
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_bufsize(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount)
{ {
__IO uint16_t *pdwReg = pcd_ep_tx_cnt_ptr((USBx),(bEpNum)); __IO uint16_t *pdwReg = pcd_ep_tx_cnt_ptr((USBx),(bEpIdx));
wCount = pcd_aligned_buffer_size(wCount); wCount = pcd_aligned_buffer_size(wCount);
pcd_set_ep_cnt_reg(pdwReg, wCount); pcd_set_ep_cnt_reg(pdwReg, wCount);
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_bufsize(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_bufsize(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount)
{ {
__IO uint16_t *pdwReg = pcd_ep_rx_cnt_ptr((USBx),(bEpNum)); __IO uint16_t *pdwReg = pcd_ep_rx_cnt_ptr((USBx),(bEpIdx));
wCount = pcd_aligned_buffer_size(wCount); wCount = pcd_aligned_buffer_size(wCount);
pcd_set_ep_cnt_reg(pdwReg, wCount); pcd_set_ep_cnt_reg(pdwReg, wCount);
} }
@ -298,13 +298,13 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_bufsize(USB_TypeDef * USB
/** /**
* @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @brief sets the status for tx transfer (bits STAT_TX[1:0]).
* @param USBx USB peripheral instance register address. * @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number. * @param bEpIdx Endpoint Number.
* @param wState new state * @param wState new state
* @retval None * @retval None
*/ */
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wState) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EPTX_DTOGMASK; regVal &= USB_EPTX_DTOGMASK;
/* toggle first bit ? */ /* toggle first bit ? */
@ -319,20 +319,20 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx
} }
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
pcd_set_endpoint(USBx, bEpNum, regVal); pcd_set_endpoint(USBx, bEpIdx, regVal);
} /* pcd_set_ep_tx_status */ } /* pcd_set_ep_tx_status */
/** /**
* @brief sets the status for rx transfer (bits STAT_TX[1:0]) * @brief sets the status for rx transfer (bits STAT_TX[1:0])
* @param USBx USB peripheral instance register address. * @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number. * @param bEpIdx Endpoint Number.
* @param wState new state * @param wState new state
* @retval None * @retval None
*/ */
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wState) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EPRX_DTOGMASK; regVal &= USB_EPRX_DTOGMASK;
/* toggle first bit ? */ /* toggle first bit ? */
@ -347,12 +347,12 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx
} }
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
pcd_set_endpoint(USBx, bEpNum, regVal); pcd_set_endpoint(USBx, bEpIdx, regVal);
} /* pcd_set_ep_rx_status */ } /* pcd_set_ep_rx_status */
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
return (regVal & USB_EPRX_STAT) >> (12u); return (regVal & USB_EPRX_STAT) >> (12u);
} /* pcd_get_ep_rx_status */ } /* pcd_get_ep_rx_status */
@ -360,71 +360,71 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef *
/** /**
* @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
* @param USBx USB peripheral instance register address. * @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number. * @param bEpIdx Endpoint Number.
* @retval None * @retval None
*/ */
TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EPREG_MASK; regVal &= USB_EPREG_MASK;
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX;
pcd_set_endpoint(USBx, bEpNum, regVal); pcd_set_endpoint(USBx, bEpIdx, regVal);
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EPREG_MASK; regVal &= USB_EPREG_MASK;
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX;
pcd_set_endpoint(USBx, bEpNum, regVal); pcd_set_endpoint(USBx, bEpIdx, regVal);
} }
/** /**
* @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register.
* @param USBx USB peripheral instance register address. * @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number. * @param bEpIdx Endpoint Number.
* @retval None * @retval None
*/ */
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
if((regVal & USB_EP_DTOG_RX) != 0) if((regVal & USB_EP_DTOG_RX) != 0)
{ {
pcd_rx_dtog(USBx,bEpNum); pcd_rx_dtog(USBx,bEpIdx);
} }
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
if((regVal & USB_EP_DTOG_TX) != 0) if((regVal & USB_EP_DTOG_TX) != 0)
{ {
pcd_tx_dtog(USBx,bEpNum); pcd_tx_dtog(USBx,bEpIdx);
} }
} }
/** /**
* @brief set & clear EP_KIND bit. * @brief set & clear EP_KIND bit.
* @param USBx USB peripheral instance register address. * @param USBx USB peripheral instance register address.
* @param bEpNum Endpoint Number. * @param bEpIdx Endpoint Number.
* @retval None * @retval None
*/ */
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal |= USB_EP_KIND; regVal |= USB_EP_KIND;
regVal &= USB_EPREG_MASK; regVal &= USB_EPREG_MASK;
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
pcd_set_endpoint(USBx, bEpNum, regVal); pcd_set_endpoint(USBx, bEpIdx, regVal);
} }
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpNum) TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx)
{ {
uint32_t regVal = pcd_get_endpoint(USBx, bEpNum); uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
regVal &= USB_EPKIND_MASK; regVal &= USB_EPKIND_MASK;
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
pcd_set_endpoint(USBx, bEpNum, regVal); pcd_set_endpoint(USBx, bEpIdx, regVal);
} }
// This checks if the device has "LPM" // This checks if the device has "LPM"
@ -438,6 +438,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, u
USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED )
// Number of endpoints in hardware // Number of endpoints in hardware
// TODO should use TUP_DCD_ENDPOINT_MAX
#define STFSDEV_EP_COUNT (8u) #define STFSDEV_EP_COUNT (8u)
#endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */ #endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */