mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-16 14:42:58 +00:00
Merge branch 'CCRX_Port' of https://github.com/Wini-Buh/tinyusb into Wini-Buh-CCRX_Port
This commit is contained in:
commit
fa0936bf58
@ -215,6 +215,8 @@ typedef enum
|
||||
// Class Specific Functional Descriptor (Communication Interface)
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
/// Header Functional Descriptor (Communication Interface)
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
@ -234,14 +236,21 @@ typedef struct TU_ATTR_PACKED
|
||||
uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface
|
||||
}cdc_desc_func_union_t;
|
||||
|
||||
TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
#define cdc_desc_func_union_n_t(no_slave)\
|
||||
TU_PACK_STRUCT_BEGIN \
|
||||
struct TU_ATTR_PACKED { \
|
||||
uint8_t bLength ;\
|
||||
uint8_t bDescriptorType ;\
|
||||
uint8_t bDescriptorSubType ;\
|
||||
uint8_t bControlInterface ;\
|
||||
uint8_t bSubordinateInterface[no_slave] ;\
|
||||
}
|
||||
} \
|
||||
TU_PACK_STRUCT_END
|
||||
|
||||
|
||||
TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
/// Country Selection Functional Descriptor (Communication Interface)
|
||||
typedef struct TU_ATTR_PACKED
|
||||
@ -253,21 +262,28 @@ typedef struct TU_ATTR_PACKED
|
||||
uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country.
|
||||
}cdc_desc_func_country_selection_t;
|
||||
|
||||
TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
#define cdc_desc_func_country_selection_n_t(no_country) \
|
||||
TU_PACK_STRUCT_BEGIN \
|
||||
struct TU_ATTR_PACKED { \
|
||||
uint8_t bLength ;\
|
||||
uint8_t bDescriptorType ;\
|
||||
uint8_t bDescriptorSubType ;\
|
||||
uint8_t iCountryCodeRelDate ;\
|
||||
uint16_t wCountryCode[no_country] ;\
|
||||
}
|
||||
} \
|
||||
TU_PACK_STRUCT_END
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
/// \brief Call Management Functional Descriptor
|
||||
/// \details This functional descriptor describes the processing of calls for the Communications Class interface.
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||
@ -282,8 +298,10 @@ typedef struct TU_ATTR_PACKED
|
||||
|
||||
uint8_t bDataInterface;
|
||||
}cdc_desc_func_call_management_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
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.
|
||||
@ -292,6 +310,7 @@ typedef struct TU_ATTR_PACKED
|
||||
uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection.
|
||||
uint8_t TU_RESERVED : 4;
|
||||
}cdc_acm_capability_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler");
|
||||
|
||||
@ -307,6 +326,7 @@ typedef struct TU_ATTR_PACKED
|
||||
|
||||
/// \brief Direct Line Management Functional Descriptor
|
||||
/// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||
@ -319,6 +339,7 @@ typedef struct TU_ATTR_PACKED
|
||||
uint8_t TU_RESERVED : 5;
|
||||
} bmCapabilities;
|
||||
}cdc_desc_func_direct_line_management_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
/// \brief Telephone Ringer Functional Descriptor
|
||||
/// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface,
|
||||
@ -335,6 +356,7 @@ typedef struct TU_ATTR_PACKED
|
||||
/// \brief Telephone Operational Modes Functional Descriptor
|
||||
/// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by
|
||||
/// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||
@ -347,10 +369,12 @@ typedef struct TU_ATTR_PACKED
|
||||
uint8_t TU_RESERVED : 5;
|
||||
} bmCapabilities;
|
||||
}cdc_desc_func_telephone_operational_modes_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
/// \brief Telephone Call and Line State Reporting Capabilities Descriptor
|
||||
/// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a
|
||||
/// telephone device to report optional call and line states.
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t bLength ; ///< Size of this descriptor in bytes.
|
||||
@ -366,6 +390,7 @@ typedef struct TU_ATTR_PACKED
|
||||
uint32_t TU_RESERVED : 26;
|
||||
} bmCapabilities;
|
||||
}cdc_desc_func_telephone_call_state_reporting_capabilities_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc)
|
||||
{
|
||||
@ -385,12 +410,17 @@ typedef struct TU_ATTR_PACKED
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct");
|
||||
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR.
|
||||
uint16_t half_duplex_carrier_control : 1;
|
||||
uint16_t : 14;
|
||||
} cdc_line_control_state_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");
|
||||
|
||||
|
@ -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,12 @@
|
||||
#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_PACK_STRUCT_BEGIN
|
||||
#define TU_PACK_STRUCT_END
|
||||
|
||||
#define TU_BIT_FIELD_ORDER_BEGIN
|
||||
#define TU_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 +139,33 @@
|
||||
|
||||
#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_PACK_STRUCT_BEGIN _Pragma("pack")
|
||||
#define TU_PACK_STRUCT_END _Pragma("packoption")
|
||||
|
||||
#define TU_BIT_FIELD_ORDER_BEGIN _Pragma("bit_order right")
|
||||
#define TU_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 +192,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
|
||||
|
@ -262,6 +262,8 @@ enum
|
||||
// USB Descriptors
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
/// USB Device Descriptor
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
@ -327,6 +329,7 @@ typedef struct TU_ATTR_PACKED
|
||||
} tusb_desc_interface_t;
|
||||
|
||||
/// USB Endpoint Descriptor
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t bLength ; ///< Size of this descriptor in bytes
|
||||
@ -342,13 +345,19 @@ 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.
|
||||
} tusb_desc_endpoint_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
/// USB Other Speed Configuration Descriptor
|
||||
typedef struct TU_ATTR_PACKED
|
||||
@ -424,6 +433,7 @@ typedef struct TU_ATTR_PACKED
|
||||
} tusb_desc_webusb_url_t;
|
||||
|
||||
// DFU Functional Descriptor
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint8_t bLength;
|
||||
@ -445,10 +455,12 @@ typedef struct TU_ATTR_PACKED
|
||||
uint16_t wTransferSize;
|
||||
uint16_t bcdDFUVersion;
|
||||
} tusb_desc_dfu_functional_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Types
|
||||
*------------------------------------------------------------------*/
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED{
|
||||
union {
|
||||
struct TU_ATTR_PACKED {
|
||||
@ -465,6 +477,9 @@ typedef struct TU_ATTR_PACKED {
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
} tusb_control_request_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct");
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
@ -957,7 +957,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
|
||||
// Use offsetof to avoid pointer to the odd/misaligned address
|
||||
memcpy(&total_len, (uint8_t*) desc_bos + offsetof(tusb_desc_bos_t, wTotalLength), 2);
|
||||
|
||||
return tud_control_xfer(rhport, p_request, (void*) desc_bos, total_len);
|
||||
return tud_control_xfer(rhport, p_request, (void*) desc_bos, tu_le16toh(total_len));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -972,7 +972,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
|
||||
// Use offsetof to avoid pointer to the odd/misaligned address
|
||||
memcpy(&total_len, (uint8_t*) desc_config + offsetof(tusb_desc_configuration_t, wTotalLength), 2);
|
||||
|
||||
return tud_control_xfer(rhport, p_request, (void*) desc_config, total_len);
|
||||
return tud_control_xfer(rhport, p_request, (void*) desc_config, tu_le16toh(total_len));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1150,7 +1150,7 @@ 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_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, tu_le16toh(desc_ep->wMaxPacketSize.size));
|
||||
TU_ASSERT(tu_edpt_number(desc_ep->bEndpointAddress) < DCD_ATTR_ENDPOINT_MAX);
|
||||
|
||||
switch (desc_ep->bmAttributes.xfer)
|
||||
@ -1158,7 +1158,7 @@ bool usbd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep)
|
||||
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);
|
||||
TU_ASSERT(tu_le16toh(desc_ep->wMaxPacketSize.size) <= max_epsize);
|
||||
}
|
||||
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(tu_le16toh(desc_ep->wMaxPacketSize.size) == 512);
|
||||
}else
|
||||
{
|
||||
// TODO Bulk fullspeed can only be 8, 16, 32, 64
|
||||
TU_ASSERT(desc_ep->wMaxPacketSize.size <= 64);
|
||||
TU_ASSERT(tu_le16toh(desc_ep->wMaxPacketSize.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);
|
||||
TU_ASSERT(tu_le16toh(desc_ep->wMaxPacketSize.size) <= max_epsize);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -58,6 +58,7 @@ static usbd_control_xfer_t _ctrl_xfer;
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
|
||||
static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Application API
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -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);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -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,7 @@
|
||||
#define FIFO_REQ_CLR (1u)
|
||||
#define FIFO_COMPLETE (1u<<1)
|
||||
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
@ -104,7 +108,9 @@ typedef struct {
|
||||
};
|
||||
uint16_t TRN;
|
||||
} reg_pipetre_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef union {
|
||||
struct {
|
||||
volatile uint16_t u8: 8;
|
||||
@ -112,7 +118,11 @@ typedef union {
|
||||
};
|
||||
volatile uint16_t u16;
|
||||
} hw_fifo_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
TU_PACK_STRUCT_BEGIN // Start of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
TU_BIT_FIELD_ORDER_BEGIN
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uintptr_t addr; /* the start address of a transfer data buffer */
|
||||
@ -123,10 +133,13 @@ typedef struct TU_ATTR_PACKED
|
||||
uint32_t : 0;
|
||||
};
|
||||
} pipe_state_t;
|
||||
TU_BIT_FIELD_ORDER_END
|
||||
|
||||
TU_PACK_STRUCT_END // End of definition of packed structs (used by the CCRX toolchain)
|
||||
|
||||
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;
|
||||
@ -139,14 +152,23 @@ CFG_TUSB_MEM_SECTION 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 +252,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 +267,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 +290,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 +308,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 +337,11 @@ 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 */
|
||||
#if TU_BYTE_ORDER == TU_BIG_ENDIAN
|
||||
USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | USB_FIFOSEL_BIGEND;
|
||||
#else
|
||||
USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16;
|
||||
#endif
|
||||
while (!(USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX)) ;
|
||||
} else { /* OUT, a byte */
|
||||
USB0.CFIFOSEL.WORD = USB_FIFOSEL_MBW_8;
|
||||
@ -333,7 +353,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 +374,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 +387,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 +416,16 @@ 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 */
|
||||
#if TU_BYTE_ORDER == TU_BIG_ENDIAN
|
||||
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | USB_FIFOSEL_BIGEND;
|
||||
#else
|
||||
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16;
|
||||
while (!(USB0.D0FIFOSEL.BIT.CURPIPE != num)) ;
|
||||
int r = fifo_write(&USB0.D0FIFO.WORD, pipe, mps);
|
||||
#endif
|
||||
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 +445,25 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num)
|
||||
{
|
||||
pipe_state_t *pipe = &_dcd.pipe[num];
|
||||
if (tu_edpt_dir(pipe->ep)) { /* IN */
|
||||
#if TU_BYTE_ORDER == TU_BIG_ENDIAN
|
||||
select_pipe(num, USB_FIFOSEL_MBW_16 | USB_FIFOSEL_BIGEND);
|
||||
#else
|
||||
select_pipe(num, USB_FIFOSEL_MBW_16);
|
||||
#endif
|
||||
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 +472,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 +495,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,7 +525,11 @@ 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 = {
|
||||
#if defined(__CCRX__)
|
||||
.bmRequestType = { 0 }, /* Note: CCRX needs the braces over this struct member */
|
||||
#else
|
||||
.bmRequestType = 0,
|
||||
#endif
|
||||
.bRequest = 5,
|
||||
.wValue = addr,
|
||||
.wIndex = 0,
|
||||
@ -517,7 +556,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 +579,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 +632,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 +738,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 +800,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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user