Merge pull request #859 from Wini-Buh/CCRX_Port

Adaptations for Renesas CCRX toolchain and Rx72N controller performed
This commit is contained in:
Ha Thach 2021-07-29 16:13:13 +07:00 committed by GitHub
commit fa00377d93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 177 additions and 69 deletions

View File

@ -215,6 +215,10 @@ typedef enum
// Class Specific Functional Descriptor (Communication Interface)
//--------------------------------------------------------------------+
// Start of all packed definitions for compiler without per-type packed
TU_ATTR_PACKED_BEGIN
TU_ATTR_BIT_FIELD_ORDER_BEGIN
/// Header Functional Descriptor (Communication Interface)
typedef struct TU_ATTR_PACKED
{
@ -235,7 +239,7 @@ typedef struct TU_ATTR_PACKED
}cdc_desc_func_union_t;
#define cdc_desc_func_union_n_t(no_slave)\
struct TU_ATTR_PACKED { \
struct TU_ATTR_PACKED { \
uint8_t bLength ;\
uint8_t bDescriptorType ;\
uint8_t bDescriptorSubType ;\
@ -254,7 +258,7 @@ typedef struct TU_ATTR_PACKED
}cdc_desc_func_country_selection_t;
#define cdc_desc_func_country_selection_n_t(no_country) \
struct TU_ATTR_PACKED {\
struct TU_ATTR_PACKED { \
uint8_t bLength ;\
uint8_t bDescriptorType ;\
uint8_t bDescriptorSubType ;\
@ -283,7 +287,6 @@ typedef struct TU_ATTR_PACKED
uint8_t bDataInterface;
}cdc_desc_func_call_management_t;
typedef struct TU_ATTR_PACKED
{
uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature.
@ -295,8 +298,8 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler");
/// \brief Abstract Control Management Functional Descriptor
/// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
/// Abstract Control Management Functional Descriptor
/// This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
@ -367,6 +370,7 @@ typedef struct TU_ATTR_PACKED
} bmCapabilities;
}cdc_desc_func_telephone_call_state_reporting_capabilities_t;
// TODO remove
static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc)
{
return p_desc[2];
@ -394,7 +398,8 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");
/** @} */
TU_ATTR_PACKED_END // End of all packed definitions
TU_ATTR_BIT_FIELD_ORDER_END
#ifdef __cplusplus
}

View File

@ -52,6 +52,8 @@
#define TU_VERIFY_STATIC _Static_assert
#elif defined (__cplusplus) && __cplusplus >= 201103L
#define TU_VERIFY_STATIC static_assert
#elif defined(__CCRX__)
#define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(Line, __LINE__)[(const_expr) ? 1 : 0];
#else
#define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) }
#endif
@ -77,6 +79,11 @@
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
#define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used
#define TU_ATTR_PACKED_BEGIN
#define TU_ATTR_PACKED_END
#define TU_ATTR_BIT_FIELD_ORDER_BEGIN
#define TU_ATTR_BIT_FIELD_ORDER_END
// Endian conversion use well-known host to network (big endian) naming
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
@ -101,6 +108,11 @@
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
#define TU_ATTR_USED __attribute__ ((used))
#define TU_ATTR_PACKED_BEGIN
#define TU_ATTR_PACKED_END
#define TU_ATTR_BIT_FIELD_ORDER_BEGIN
#define TU_ATTR_BIT_FIELD_ORDER_END
// __BYTE_ORDER is defined in the TI ARM compiler, but not MSP430 (which is little endian)
#if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) || defined(__MSP430__)
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
@ -122,6 +134,11 @@
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
#define TU_ATTR_USED __attribute__ ((used)) // Function/Variable is meant to be used
#define TU_ATTR_PACKED_BEGIN
#define TU_ATTR_PACKED_END
#define TU_ATTR_BIT_FIELD_ORDER_BEGIN
#define TU_ATTR_BIT_FIELD_ORDER_END
// Endian conversion use well-known host to network (big endian) naming
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
@ -131,6 +148,32 @@
#define TU_BSWAP16(u16) (__iar_builtin_REV16(u16))
#define TU_BSWAP32(u32) (__iar_builtin_REV(u32))
#elif defined(__CCRX__)
#define TU_ATTR_ALIGNED(Bytes)
#define TU_ATTR_SECTION(sec_name)
#define TU_ATTR_PACKED
#define TU_ATTR_WEAK
#define TU_ATTR_ALWAYS_INLINE
#define TU_ATTR_DEPRECATED(mess)
#define TU_ATTR_UNUSED
#define TU_ATTR_USED
#define TU_ATTR_PACKED_BEGIN _Pragma("pack")
#define TU_ATTR_PACKED_END _Pragma("packoption")
#define TU_ATTR_BIT_FIELD_ORDER_BEGIN _Pragma("bit_order right")
#define TU_ATTR_BIT_FIELD_ORDER_END _Pragma("bit_order")
// Endian conversion use well-known host to network (big endian) naming
#if defined(__LIT)
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
#else
#define TU_BYTE_ORDER TU_BIG_ENDIAN
#endif
#define TU_BSWAP16(u16) ((unsigned short)_builtin_revw((unsigned long)u16))
#define TU_BSWAP32(u32) (_builtin_revl(u32))
#else
#error "Compiler attribute porting is required"
#endif
@ -157,11 +200,11 @@
#define tu_htonl(u32) (u32)
#define tu_ntohl(u32) (u32)
#define tu_htole16(u16) (tu_bswap16(u16))
#define tu_le16toh(u16) (tu_bswap16(u16))
#define tu_htole16(u16) (TU_BSWAP16(u16))
#define tu_le16toh(u16) (TU_BSWAP16(u16))
#define tu_htole32(u32) (tu_bswap32(u32))
#define tu_le32toh(u32) (tu_bswap32(u32))
#define tu_htole32(u32) (TU_BSWAP32(u32))
#define tu_le32toh(u32) (TU_BSWAP32(u32))
#else
#error Byte order is undefined

View File

@ -262,6 +262,10 @@ enum
// USB Descriptors
//--------------------------------------------------------------------+
// Start of all packed definitions for compiler without per-type packed
TU_ATTR_PACKED_BEGIN
TU_ATTR_BIT_FIELD_ORDER_BEGIN
/// USB Device Descriptor
typedef struct TU_ATTR_PACKED
{
@ -295,6 +299,8 @@ typedef struct TU_ATTR_PACKED
uint8_t bNumDeviceCaps ; ///< Number of device capability descriptors in the BOS
} tusb_desc_bos_t;
TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct");
/// USB Configuration Descriptor
typedef struct TU_ATTR_PACKED
{
@ -326,6 +332,8 @@ typedef struct TU_ATTR_PACKED
uint8_t iInterface ; ///< Index of string descriptor describing this interface
} tusb_desc_interface_t;
TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct");
/// USB Endpoint Descriptor
typedef struct TU_ATTR_PACKED
{
@ -342,9 +350,14 @@ typedef struct TU_ATTR_PACKED
} bmAttributes ; ///< This field describes the endpoint's attributes when it is configured using the bConfigurationValue. \n Bits 1..0: Transfer Type \n- 00 = Control \n- 01 = Isochronous \n- 10 = Bulk \n- 11 = Interrupt \n If not an isochronous endpoint, bits 5..2 are reserved and must be set to zero. If isochronous, they are defined as follows: \n Bits 3..2: Synchronization Type \n- 00 = No Synchronization \n- 01 = Asynchronous \n- 10 = Adaptive \n- 11 = Synchronous \n Bits 5..4: Usage Type \n- 00 = Data endpoint \n- 01 = Feedback endpoint \n- 10 = Implicit feedback Data endpoint \n- 11 = Reserved \n Refer to Chapter 5 of USB 2.0 specification for more information. \n All other bits are reserved and must be reset to zero. Reserved bits must be ignored by the host.
struct TU_ATTR_PACKED {
#if defined(__CCRX__)
//FIXME the original defined bit field has a problem with the CCRX toolchain, so only a size field is defined
uint16_t size;
#else
uint16_t size : 11; ///< Maximum packet size this endpoint is capable of sending or receiving when this configuration is selected. \n For isochronous endpoints, this value is used to reserve the bus time in the schedule, required for the per-(micro)frame data payloads. The pipe may, on an ongoing basis, actually use less bandwidth than that reserved. The device reports, if necessary, the actual bandwidth used via its normal, non-USB defined mechanisms. \n For all endpoints, bits 10..0 specify the maximum packet size (in bytes). \n For high-speed isochronous and interrupt endpoints: \n Bits 12..11 specify the number of additional transaction opportunities per microframe: \n- 00 = None (1 transaction per microframe) \n- 01 = 1 additional (2 per microframe) \n- 10 = 2 additional (3 per microframe) \n- 11 = Reserved \n Bits 15..13 are reserved and must be set to zero.
uint16_t hs_period_mult : 2;
uint16_t TU_RESERVED : 3;
#endif
}wMaxPacketSize;
uint8_t bInterval ; ///< Interval for polling endpoint for data transfers. Expressed in frames or microframes depending on the device operating speed (i.e., either 1 millisecond or 125 us units). \n- For full-/high-speed isochronous endpoints, this value must be in the range from 1 to 16. The bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$). \n- For full-/low-speed interrupt endpoints, the value of this field may be from 1 to 255. \n- For high-speed interrupt endpoints, the bInterval value is used as the exponent for a \f$ 2^(bInterval-1) \f$ value; e.g., a bInterval of 4 means a period of 8 (\f$ 2^(4-1) \f$) . This value must be from 1 to 16. \n- For high-speed bulk/control OUT endpoints, the bInterval must specify the maximum NAK rate of the endpoint. A value of 0 indicates the endpoint never NAKs. Other values indicate at most 1 NAK each bInterval number of microframes. This value must be in the range from 0 to 255. \n Refer to Chapter 5 of USB 2.0 specification for more information.
@ -449,7 +462,7 @@ typedef struct TU_ATTR_PACKED
/*------------------------------------------------------------------*/
/* Types
*------------------------------------------------------------------*/
typedef struct TU_ATTR_PACKED {
typedef struct TU_ATTR_PACKED{
union {
struct TU_ATTR_PACKED {
uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t.
@ -468,11 +481,9 @@ typedef struct TU_ATTR_PACKED {
TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct");
// TODO move to somewhere suitable
static inline uint8_t bm_request_type(uint8_t direction, uint8_t type, uint8_t recipient)
{
return ((uint8_t) (direction << 7)) | ((uint8_t) (type << 5)) | (recipient);
}
TU_ATTR_PACKED_END // End of all packed definitions
TU_ATTR_BIT_FIELD_ORDER_END
//--------------------------------------------------------------------+
// Endpoint helper

View File

@ -141,11 +141,11 @@
#define DCD_ATTR_ENDPOINT_MAX 7
//------------- Renesas -------------//
#elif TU_CHECK_MCU(RX63X) || TU_CHECK_MCU(RX65X)
#elif TU_CHECK_MCU(RX63X) || TU_CHECK_MCU(RX65X) || TU_CHECK_MCU(RX72N)
#define DCD_ATTR_ENDPOINT_MAX 10
//#elif TU_CHECK_MCU(MM32F327X)
// #define DCD_ATTR_ENDPOINT_MAX not knwon yet
// #define DCD_ATTR_ENDPOINT_MAX not known yet
#else
#warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8"

View File

@ -831,7 +831,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
// Parse interface descriptor
uint8_t const * p_desc = ((uint8_t const*) desc_cfg) + sizeof(tusb_desc_configuration_t);
uint8_t const * desc_end = ((uint8_t const*) desc_cfg) + desc_cfg->wTotalLength;
uint8_t const * desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength);
while( p_desc < desc_end )
{
@ -953,9 +953,8 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
tusb_desc_bos_t const* desc_bos = (tusb_desc_bos_t const*) tud_descriptor_bos_cb();
uint16_t total_len;
// Use offsetof to avoid pointer to the odd/misaligned address
memcpy(&total_len, (uint8_t*) desc_bos + offsetof(tusb_desc_bos_t, wTotalLength), 2);
uint16_t const total_len = tu_le16toh( tu_unaligned_read16((uint8_t*) desc_bos + offsetof(tusb_desc_bos_t, wTotalLength)) );
return tud_control_xfer(rhport, p_request, (void*) desc_bos, total_len);
}
@ -968,9 +967,8 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
tusb_desc_configuration_t const* desc_config = (tusb_desc_configuration_t const*) tud_descriptor_configuration_cb(desc_index);
TU_ASSERT(desc_config);
uint16_t total_len;
// Use offsetof to avoid pointer to the odd/misaligned address
memcpy(&total_len, (uint8_t*) desc_config + offsetof(tusb_desc_configuration_t, wTotalLength), 2);
uint16_t const total_len = tu_le16toh( tu_unaligned_read16((uint8_t*) desc_config + offsetof(tusb_desc_configuration_t, wTotalLength)) );
return tud_control_xfer(rhport, p_request, (void*) desc_config, total_len);
}
@ -1150,15 +1148,17 @@ void usbd_defer_func(osal_task_func_t func, void* param, bool in_isr)
bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep)
{
TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, desc_ep->wMaxPacketSize.size);
TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < DCD_ATTR_ENDPOINT_MAX);
uint16_t const max_packet_size = tu_le16toh(desc_ep->wMaxPacketSize.size);
TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size);
TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < CFG_TUD_ENDPPOINT_MAX);
switch (desc_ep->bmAttributes.xfer)
{
case TUSB_XFER_ISOCHRONOUS:
{
uint16_t const max_epsize = (_usbd_dev.speed == TUSB_SPEED_HIGH ? 1024 : 1023);
TU_ASSERT(desc_ep->wMaxPacketSize.size <= max_epsize);
uint16_t const spec_size = (_usbd_dev.speed == TUSB_SPEED_HIGH ? 1024 : 1023);
TU_ASSERT(max_packet_size <= spec_size);
}
break;
@ -1166,18 +1166,18 @@ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep)
if (_usbd_dev.speed == TUSB_SPEED_HIGH)
{
// Bulk highspeed must be EXACTLY 512
TU_ASSERT(desc_ep->wMaxPacketSize.size == 512);
TU_ASSERT(max_packet_size == 512);
}else
{
// TODO Bulk fullspeed can only be 8, 16, 32, 64
TU_ASSERT(desc_ep->wMaxPacketSize.size <= 64);
TU_ASSERT(max_packet_size <= 64);
}
break;
case TUSB_XFER_INTERRUPT:
{
uint16_t const max_epsize = (_usbd_dev.speed == TUSB_SPEED_HIGH ? 1024 : 64);
TU_ASSERT(desc_ep->wMaxPacketSize.size <= max_epsize);
uint16_t const spec_size = (_usbd_dev.speed == TUSB_SPEED_HIGH ? 1024 : 64);
TU_ASSERT(max_packet_size <= spec_size);
}
break;

View File

@ -100,10 +100,6 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const * request);
// Application return pointer to descriptor
uint8_t const * tud_descriptor_device_cb(void);
// Invoked when received GET BOS DESCRIPTOR request
// Application return pointer to descriptor
TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void);
// Invoked when received GET CONFIGURATION DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint8_t const * tud_descriptor_configuration_cb(uint8_t index);
@ -112,6 +108,10 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index);
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid);
// Invoked when received GET BOS DESCRIPTOR request
// Application return pointer to descriptor
TU_ATTR_WEAK uint8_t const * tud_descriptor_bos_cb(void);
// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
TU_ATTR_WEAK uint8_t const* tud_descriptor_device_qualifier_cb(void);

View File

@ -56,7 +56,6 @@ typedef struct
// Note: The drivers array must be accessible at all time when stack is active
usbd_class_driver_t const* usbd_app_driver_get_cb(uint8_t* driver_count) TU_ATTR_WEAK;
typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
//--------------------------------------------------------------------+

View File

@ -2,6 +2,7 @@
* The MIT License (MIT)
*
* Copyright (c) 2020 Koji Kitayama
* Portions copyrighted (c) 2021 Roland Winistoerfer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -27,7 +28,8 @@
#include "tusb_option.h"
#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \
CFG_TUSB_MCU == OPT_MCU_RX65X)
CFG_TUSB_MCU == OPT_MCU_RX65X || \
CFG_TUSB_MCU == OPT_MCU_RX72N )
#include "device/dcd.h"
#include "iodefine.h"
@ -38,6 +40,7 @@
#define SYSTEM_PRCR_PRKEY (0xA5u<<8)
#define USB_FIFOSEL_TX ((uint16_t)(1u<<5))
#define USB_FIFOSEL_BIGEND ((uint16_t)(1u<<8))
#define USB_FIFOSEL_MBW_8 ((uint16_t)(0u<<10))
#define USB_FIFOSEL_MBW_16 ((uint16_t)(1u<<10))
#define USB_IS0_CTSQ ((uint16_t)(7u))
@ -92,6 +95,10 @@
#define FIFO_REQ_CLR (1u)
#define FIFO_COMPLETE (1u<<1)
// Start of definition of packed structs (used by the CCRX toolchain)
TU_ATTR_PACKED_BEGIN
TU_ATTR_BIT_FIELD_ORDER_BEGIN
typedef struct {
union {
struct {
@ -124,9 +131,12 @@ typedef struct TU_ATTR_PACKED
};
} pipe_state_t;
TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain)
TU_ATTR_BIT_FIELD_ORDER_END
typedef struct
{
pipe_state_t pipe[9];
pipe_state_t pipe[10];
uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */
uint8_t suspended;
} dcd_data_t;
@ -134,19 +144,28 @@ typedef struct
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
CFG_TUSB_MEM_SECTION static dcd_data_t _dcd;
static dcd_data_t _dcd;
static uint32_t disable_interrupt(void)
{
uint32_t pswi;
#if defined(__CCRX__)
pswi = get_psw() & 0x010000;
clrpsw_i();
#else
pswi = __builtin_rx_mvfc(0) & 0x010000;
__builtin_rx_clrpsw('I');
#endif
return pswi;
}
static void enable_interrupt(uint32_t pswi)
{
#if defined(__CCRX__)
set_psw(get_psw() | pswi);
#else
__builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi);
#endif
}
static unsigned find_pipe(unsigned xfer)
@ -230,7 +249,7 @@ static unsigned select_pipe(unsigned num, unsigned attr)
{
USB0.PIPESEL.WORD = num;
USB0.D0FIFOSEL.WORD = num | attr;
while (!(USB0.D0FIFOSEL.BIT.CURPIPE != num)) ;
while (USB0.D0FIFOSEL.BIT.CURPIPE != num) ;
return wait_for_pipe_ready();
}
@ -245,12 +264,6 @@ static int fifo_write(volatile void *fifo, pipe_state_t* pipe, unsigned mps)
hw_fifo_t *reg = (hw_fifo_t*)fifo;
uintptr_t addr = pipe->addr + pipe->length - rem;
if (addr & 1u) {
/* addr is not 2-byte aligned */
reg->u8 = *(const uint8_t *)addr;
++addr;
--len;
}
while (len >= 2) {
reg->u16 = *(const uint16_t *)addr;
addr += 2;
@ -274,11 +287,11 @@ static int fifo_read(volatile void *fifo, pipe_state_t* pipe, unsigned mps, size
if (rem < len) len = rem;
pipe->remaining = rem - len;
hw_fifo_t *reg = (hw_fifo_t*)fifo;
uint8_t *reg = (uint8_t*)fifo; /* byte access is always at base register address */
uintptr_t addr = pipe->addr;
unsigned loop = len;
while (loop--) {
*(uint8_t *)addr = reg->u8;
*(uint8_t *)addr = *reg;
++addr;
}
pipe->addr = addr;
@ -292,7 +305,7 @@ static void process_setup_packet(uint8_t rhport)
uint16_t setup_packet[4];
if (0 == (USB0.INTSTS0.WORD & USB_IS0_VALID)) return;
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR;
setup_packet[0] = USB0.USBREQ.WORD;
setup_packet[0] = tu_le16toh(USB0.USBREQ.WORD);
setup_packet[1] = USB0.USBVAL;
setup_packet[2] = USB0.USBINDX;
setup_packet[3] = USB0.USBLENG;
@ -321,7 +334,7 @@ static bool process_edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer,
pipe_state_t *pipe = &_dcd.pipe[0];
/* configure fifo direction and access unit settings */
if (ep_addr) { /* IN, 2 bytes */
USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16;
USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0);
while (!(USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX)) ;
} else { /* OUT, a byte */
USB0.CFIFOSEL.WORD = USB_FIFOSEL_MBW_8;
@ -333,7 +346,7 @@ static bool process_edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer,
pipe->remaining = total_bytes;
if (ep_addr) { /* IN */
TU_ASSERT(USB0.DCPCTR.BIT.BSTS && (USB0.USBREQ.WORD & 0x80));
if (fifo_write(&USB0.CFIFO.WORD, pipe, 64)) {
if (fifo_write((void*)&USB0.CFIFO.WORD, pipe, 64)) {
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
}
}
@ -354,7 +367,7 @@ static void process_edpt0_bemp(uint8_t rhport)
const unsigned rem = pipe->remaining;
if (rem > 64) {
pipe->remaining = rem - 64;
int r = fifo_write(&USB0.CFIFO.WORD, &_dcd.pipe[0], 64);
int r = fifo_write((void*)&USB0.CFIFO.WORD, &_dcd.pipe[0], 64);
if (r) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
return;
}
@ -367,7 +380,7 @@ static void process_edpt0_bemp(uint8_t rhport)
static void process_edpt0_brdy(uint8_t rhport)
{
size_t len = USB0.CFIFOCTR.BIT.DTLN;
int cplt = fifo_read(&USB0.CFIFO.WORD, &_dcd.pipe[0], 64, len);
int cplt = fifo_read((void*)&USB0.CFIFO.WORD, &_dcd.pipe[0], 64, len);
if (cplt || (len < 64)) {
if (2 != cplt) {
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR;
@ -396,11 +409,12 @@ static bool process_pipe_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer,
USB0.PIPESEL.WORD = num;
const unsigned mps = USB0.PIPEMAXP.WORD;
if (dir) { /* IN */
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16;
while (!(USB0.D0FIFOSEL.BIT.CURPIPE != num)) ;
int r = fifo_write(&USB0.D0FIFO.WORD, pipe, mps);
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0);
while (USB0.D0FIFOSEL.BIT.CURPIPE != num) ;
int r = fifo_write((void*)&USB0.D0FIFO.WORD, pipe, mps);
if (r) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
USB0.D0FIFOSEL.WORD = 0;
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
} else {
volatile reg_pipetre_t *pt = get_pipetre(num);
if (pt) {
@ -420,19 +434,21 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num)
{
pipe_state_t *pipe = &_dcd.pipe[num];
if (tu_edpt_dir(pipe->ep)) { /* IN */
select_pipe(num, USB_FIFOSEL_MBW_16);
select_pipe(num, USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0));
const unsigned mps = USB0.PIPEMAXP.WORD;
unsigned rem = pipe->remaining;
rem -= TU_MIN(rem, mps);
pipe->remaining = rem;
if (rem) {
int r = 0;
r = fifo_write(&USB0.D0FIFO.WORD, pipe, mps);
r = fifo_write((void*)&USB0.D0FIFO.WORD, pipe, mps);
if (r) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
USB0.D0FIFOSEL.WORD = 0;
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
return;
}
USB0.D0FIFOSEL.WORD = 0;
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
pipe->addr = 0;
pipe->remaining = 0;
dcd_event_xfer_complete(rhport, pipe->ep, pipe->length,
@ -441,18 +457,20 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num)
const unsigned ctr = select_pipe(num, USB_FIFOSEL_MBW_8);
const unsigned len = ctr & USB_FIFOCTR_DTLN;
const unsigned mps = USB0.PIPEMAXP.WORD;
int cplt = fifo_read(&USB0.D0FIFO.WORD, pipe, mps, len);
int cplt = fifo_read((void*)&USB0.D0FIFO.WORD, pipe, mps, len);
if (cplt || (len < mps)) {
if (2 != cplt) {
USB0.D0FIFO.WORD = USB_FIFOCTR_BCLR;
}
USB0.D0FIFOSEL.WORD = 0;
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
dcd_event_xfer_complete(rhport, pipe->ep,
pipe->length - pipe->remaining,
XFER_RESULT_SUCCESS, true);
return;
}
USB0.D0FIFOSEL.WORD = 0;
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
}
}
@ -462,7 +480,9 @@ static void process_bus_reset(uint8_t rhport)
USB0.BRDYENB.WORD = 1;
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR;
USB0.D0FIFOSEL.WORD = 0;
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
USB0.D1FIFOSEL.WORD = 0;
while (USB0.D1FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t)(&USB0.PIPE1CTR.WORD));
volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t)(&USB0.PIPE1TRE.WORD));
for (int i = 1; i <= 5; ++i) {
@ -490,12 +510,16 @@ static void process_set_address(uint8_t rhport)
const uint32_t addr = USB0.USBADDR.BIT.USBADDR;
if (!addr) return;
const tusb_control_request_t setup_packet = {
.bmRequestType = 0,
.bRequest = 5,
.wValue = addr,
.wIndex = 0,
.wLength = 0,
};
#if defined(__CCRX__)
.bmRequestType = { 0 }, /* Note: CCRX needs the braces over this struct member */
#else
.bmRequestType = 0,
#endif
.bRequest = TUSB_REQ_SET_ADDRESS,
.wValue = addr,
.wIndex = 0,
.wLength = 0,
};
dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet, true);
}
@ -517,7 +541,13 @@ void dcd_init(uint8_t rhport)
USB0.SYSCFG.BIT.DCFM = 0;
USB0.SYSCFG.BIT.USBE = 1;
USB.DPUSR0R.BIT.FIXPHY0 = 0u; /* USB0 Transceiver Output fixed */
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
USB0.PHYSLEW.LONG = 0x5;
IR(PERIB, INTB185) = 0;
#else
IR(USB0, USBI0) = 0;
#endif
/* Setup default control pipe */
USB0.DCPMAXP.BIT.MXPS = 64;
@ -534,13 +564,21 @@ void dcd_init(uint8_t rhport)
void dcd_int_enable(uint8_t rhport)
{
(void)rhport;
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
IEN(PERIB, INTB185) = 1;
#else
IEN(USB0, USBI0) = 1;
#endif
}
void dcd_int_disable(uint8_t rhport)
{
(void)rhport;
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
IEN(PERIB, INTB185) = 0;
#else
IEN(USB0, USBI0) = 0;
#endif
}
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
@ -579,7 +617,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
const unsigned dir = tu_edpt_dir(ep_addr);
const unsigned xfer = ep_desc->bmAttributes.xfer;
const unsigned mps = ep_desc->wMaxPacketSize.size;
const unsigned mps = tu_le16toh(ep_desc->wMaxPacketSize.size);
if (xfer == TUSB_XFER_ISOCHRONOUS && mps > 256) {
/* USBa supports up to 256 bytes */
return false;
@ -685,8 +723,8 @@ void dcd_int_handler(uint8_t rhport)
(void)rhport;
unsigned is0 = USB0.INTSTS0.WORD;
/* clear bits except VALID */
USB0.INTSTS0.WORD = USB_IS0_VALID;
/* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */
USB0.INTSTS0.WORD = ~((USB_IS0_CTRT | USB_IS0_DVST | USB_IS0_SOFR | USB_IS0_RESM | USB_IS0_VBINT) & is0) | USB_IS0_VALID;
if (is0 & USB_IS0_VBINT) {
if (USB0.INTSTS0.BIT.VBSTS) {
dcd_connect(rhport);
@ -747,13 +785,24 @@ void dcd_int_handler(uint8_t rhport)
if (is0 & USB_IS0_BRDY) {
const unsigned m = USB0.BRDYENB.WORD;
unsigned s = USB0.BRDYSTS.WORD & m;
USB0.BRDYSTS.WORD = 0;
/* clear active bits (don't write 0 to already cleared bits according to the HW manual) */
USB0.BRDYSTS.WORD = ~s;
if (s & 1) {
process_edpt0_brdy(rhport);
s &= ~1;
}
while (s) {
#if defined(__CCRX__)
static const int Mod37BitPosition[] = {
-1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4,
7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5,
20, 8, 19, 18
};
const unsigned num = Mod37BitPosition[(-s & s) % 37];
#else
const unsigned num = __builtin_ctz(s);
#endif
process_pipe_brdy(rhport, num);
s &= ~TU_BIT(num);
}

View File

@ -117,6 +117,7 @@
// Renesas RX
#define OPT_MCU_RX63X 1400 ///< Renesas RX63N/631
#define OPT_MCU_RX65X 1401 ///< Renesas RX65N/RX651
#define OPT_MCU_RX72N 1402 ///< Renesas RX72N
// Mind Motion
#define OPT_MCU_MM32F327X 1500 ///< Mind Motion MM32F327