Adaptations for Renesas CCRX toolchain and Rx72N controller performed

This commit is contained in:
Wini-Buh 2021-05-29 21:23:39 +02:00
parent 4e2684f23a
commit b4f092ec74
13 changed files with 543 additions and 73 deletions

View File

@ -216,6 +216,7 @@ typedef enum
//--------------------------------------------------------------------+
/// Header Functional Descriptor (Communication Interface)
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
@ -223,8 +224,10 @@ typedef struct TU_ATTR_PACKED
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUNC_DESC_
uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal
}cdc_desc_func_header_t;
TU_PACK_STRUCT_END
/// Union Functional Descriptor (Communication Interface)
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
@ -233,17 +236,21 @@ typedef struct TU_ATTR_PACKED
uint8_t bControlInterface ; ///< Interface number of Communication Interface
uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface
}cdc_desc_func_union_t;
TU_PACK_STRUCT_END
#define cdc_desc_func_union_n_t(no_slave)\
struct TU_ATTR_PACKED { \
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
/// Country Selection Functional Descriptor (Communication Interface)
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
@ -252,15 +259,18 @@ typedef struct TU_ATTR_PACKED
uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
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
#define cdc_desc_func_country_selection_n_t(no_country) \
struct TU_ATTR_PACKED {\
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
@ -268,22 +278,28 @@ typedef struct TU_ATTR_PACKED
/// \brief Call Management Functional Descriptor
/// \details This functional descriptor describes the processing of calls for the Communications Class interface.
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
TU_BIT_FIELD_ORDER_BEGIN
struct {
uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface.
uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself.
uint8_t TU_RESERVED : 6;
} bmCapabilities;
TU_BIT_FIELD_ORDER_END
uint8_t bDataInterface;
}cdc_desc_func_call_management_t;
TU_PACK_STRUCT_END
TU_PACK_STRUCT_BEGIN
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,11 +308,14 @@ 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_PACK_STRUCT_END
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
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
@ -304,25 +323,31 @@ typedef struct TU_ATTR_PACKED
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
cdc_acm_capability_t bmCapabilities ;
}cdc_desc_func_acm_t;
TU_PACK_STRUCT_END
/// \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_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
TU_BIT_FIELD_ORDER_BEGIN
struct {
uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit.
uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State.
uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time.
uint8_t TU_RESERVED : 5;
} bmCapabilities;
TU_BIT_FIELD_ORDER_END
}cdc_desc_func_direct_line_management_t;
TU_PACK_STRUCT_END
/// \brief Telephone Ringer Functional Descriptor
/// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface,
/// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
@ -331,31 +356,38 @@ typedef struct TU_ATTR_PACKED
uint8_t bRingerVolSteps ;
uint8_t bNumRingerPatterns ;
}cdc_desc_func_telephone_ringer_t;
TU_PACK_STRUCT_END
/// \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_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
TU_BIT_FIELD_ORDER_BEGIN
struct {
uint8_t simple_mode : 1;
uint8_t standalone_mode : 1;
uint8_t computer_centric_mode : 1;
uint8_t TU_RESERVED : 5;
} bmCapabilities;
TU_BIT_FIELD_ORDER_END
}cdc_desc_func_telephone_operational_modes_t;
TU_PACK_STRUCT_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_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
TU_BIT_FIELD_ORDER_BEGIN
struct {
uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone
uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states.
@ -365,7 +397,9 @@ typedef struct TU_ATTR_PACKED
uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification
uint32_t TU_RESERVED : 26;
} bmCapabilities;
TU_BIT_FIELD_ORDER_END
}cdc_desc_func_telephone_call_state_reporting_capabilities_t;
TU_PACK_STRUCT_END
static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc)
{
@ -375,6 +409,7 @@ static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc)
//--------------------------------------------------------------------+
// Requests
//--------------------------------------------------------------------+
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint32_t bit_rate;
@ -382,15 +417,20 @@ typedef struct TU_ATTR_PACKED
uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space
uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16
} cdc_line_coding_t;
TU_PACK_STRUCT_END
TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct");
TU_PACK_STRUCT_BEGIN
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
TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");

View File

@ -31,6 +31,15 @@
#include "cdc_device.h"
#include "device/usbd_pvt.h"
#if defined(TU_HAS_NO_ATTR_WEAK)
static void (*const MAKE_WEAK_FUNC(tud_cdc_rx_cb))(uint8_t) = TUD_CDC_RX_CB;
static void (*const MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb))(uint8_t, char) = TUD_CDC_RX_WANTED_CB;
static void (*const MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb))(uint8_t) = TUD_CDC_TX_COMPLETE_CB;
static void (*const MAKE_WEAK_FUNC(tud_cdc_line_state_cb))(uint8_t, bool, bool) = TUD_CDC_LINE_STATE_CB;
static void (*const MAKE_WEAK_FUNC(tud_cdc_line_coding_cb))(uint8_t, cdc_line_coding_t const*) = TUD_CDC_LINE_CODING_CB;
static void (*const MAKE_WEAK_FUNC(tud_cdc_send_break_cb))(uint8_t, uint16_t) = TUD_CDC_SEND_BREAK_CB;
#endif
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
@ -359,7 +368,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
}
else if ( stage == CONTROL_STAGE_ACK)
{
if ( tud_cdc_line_coding_cb ) tud_cdc_line_coding_cb(itf, &p_cdc->line_coding);
if ( MAKE_WEAK_FUNC(tud_cdc_line_coding_cb) ) MAKE_WEAK_FUNC(tud_cdc_line_coding_cb)(itf, &p_cdc->line_coding);
}
break;
@ -394,7 +403,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
TU_LOG2(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts);
// Invoke callback
if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts);
if ( MAKE_WEAK_FUNC(tud_cdc_line_state_cb) ) MAKE_WEAK_FUNC(tud_cdc_line_state_cb)(itf, dtr, rts);
}
break;
case CDC_REQUEST_SEND_BREAK:
@ -405,7 +414,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
else if (stage == CONTROL_STAGE_ACK)
{
TU_LOG2(" Send Break\r\n");
if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue);
if ( MAKE_WEAK_FUNC(tud_cdc_send_break_cb) ) MAKE_WEAK_FUNC(tud_cdc_send_break_cb)(itf, request->wValue);
}
break;
@ -436,19 +445,19 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
tu_fifo_write_n(&p_cdc->rx_ff, &p_cdc->epout_buf, xferred_bytes);
// Check for wanted char and invoke callback if needed
if ( tud_cdc_rx_wanted_cb && (((signed char) p_cdc->wanted_char) != -1) )
if ( MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb) && (((signed char) p_cdc->wanted_char) != -1) )
{
for ( uint32_t i = 0; i < xferred_bytes; i++ )
{
if ( (p_cdc->wanted_char == p_cdc->epout_buf[i]) && !tu_fifo_empty(&p_cdc->rx_ff) )
{
tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char);
MAKE_WEAK_FUNC(tud_cdc_rx_wanted_cb)(itf, p_cdc->wanted_char);
}
}
}
// invoke receive callback (if there is still data)
if (tud_cdc_rx_cb && !tu_fifo_empty(&p_cdc->rx_ff) ) tud_cdc_rx_cb(itf);
if (MAKE_WEAK_FUNC(tud_cdc_rx_cb) && !tu_fifo_empty(&p_cdc->rx_ff) ) MAKE_WEAK_FUNC(tud_cdc_rx_cb)(itf);
// prepare for OUT transaction
_prep_out_transaction(p_cdc);
@ -460,7 +469,7 @@ bool cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_
if ( ep_addr == p_cdc->ep_in )
{
// invoke transmit callback to possibly refill tx fifo
if ( tud_cdc_tx_complete_cb ) tud_cdc_tx_complete_cb(itf);
if ( MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb) ) MAKE_WEAK_FUNC(tud_cdc_tx_complete_cb)(itf);
if ( 0 == tud_cdc_n_write_flush(itf) )
{

View File

@ -130,6 +130,7 @@ static inline bool tud_cdc_write_clear (void);
// Application Callback API (weak is optional)
//--------------------------------------------------------------------+
#if !defined(TU_HAS_NO_ATTR_WEAK)
// Invoked when received new data
TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf);
@ -148,6 +149,62 @@ TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p
// Invoked when received send break
TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms);
#else
#if ADD_WEAK_FUNC_TUD_CDC_RX_CB
#define TUD_CDC_RX_CB tud_cdc_rx_cb
#endif
#ifndef TUD_CDC_RX_CB
#define TUD_CDC_RX_CB NULL
#else
extern void TUD_CDC_RX_CB(uint8_t itf);
#endif
#if ADD_WEAK_FUNC_TUD_CDC_RX_WANTED_CB
#define TUD_CDC_RX_WANTED_CB tud_cdc_rx_wanted_cb
#endif
#ifndef TUD_CDC_RX_WANTED_CB
#define TUD_CDC_RX_WANTED_CB NULL
#else
extern void TUD_CDC_RX_WANTED_CB(uint8_t itf, char wanted_char);
#endif
#if ADD_WEAK_FUNC_TUD_CDC_TX_COMPLETE_CB
#define TUD_CDC_TX_COMPLETE_CB tud_cdc_tx_complete_cb
#endif
#ifndef TUD_CDC_TX_COMPLETE_CB
#define TUD_CDC_TX_COMPLETE_CB NULL
#else
extern void TUD_CDC_TX_COMPLETE_CB(uint8_t itf);
#endif
#if ADD_WEAK_FUNC_TUD_CDC_LINE_STATE_CB
#define TUD_CDC_LINE_STATE_CB tud_cdc_line_state_cb
#endif
#ifndef TUD_CDC_LINE_STATE_CB
#define TUD_CDC_LINE_STATE_CB NULL
#else
extern void TUD_CDC_LINE_STATE_CB(uint8_t itf, bool dtr, bool rts);
#endif
#if ADD_WEAK_FUNC_TUD_CDC_LINE_CODING_CB
#define TUD_CDC_LINE_CODING_CB tud_cdc_line_coding_cb
#endif
#ifndef TUD_CDC_LINE_CODING_CB
#define TUD_CDC_LINE_CODING_CB NULL
#else
extern void TUD_CDC_LINE_CODING_CB(uint8_t itf, cdc_line_coding_t const* p_line_coding);
#endif
#if ADD_WEAK_FUNC_TUD_CDC_SEND_BREAK_CB
#define TUD_CDC_SEND_BREAK_CB tud_cdc_send_break_cb
#endif
#ifndef TUD_CDC_SEND_BREAK_CB
#define TUD_CDC_SEND_BREAK_CB NULL
#else
extern void TUD_CDC_SEND_BREAK_CB(uint8_t itf, uint16_t duration_ms);
#endif
#endif
//--------------------------------------------------------------------+
// Inline Functions
//--------------------------------------------------------------------+

View File

@ -48,6 +48,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
@ -62,6 +64,9 @@
// Compiler porting with Attribute and Endian
//--------------------------------------------------------------------+
// define the standard definition of this macro to construct a "weak" function name
#define MAKE_WEAK_FUNC(func_name) func_name
// TODO refactor since __attribute__ is supported across many compiler
#if defined(__GNUC__)
#define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
@ -73,9 +78,17 @@
#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
#define TU_ENDIAN_LITTLE_BEGIN
#define TU_ENDIAN_LITTLE_END
#else
#define TU_BYTE_ORDER TU_BIG_ENDIAN
#endif
@ -123,6 +136,77 @@
#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
#define TU_ENDIAN_LITTLE_BEGIN
#define TU_ENDIAN_LITTLE_END
#else
#define TU_BYTE_ORDER TU_BIG_ENDIAN
#define TU_ENDIAN_LITTLE_BEGIN _Pragma("endian little")
#define TU_ENDIAN_LITTLE_END _Pragma("endian")
#endif
#define TU_BSWAP16(u16) ((unsigned short)_builtin_revw((unsigned long)u16))
#define TU_BSWAP32(u32) (_builtin_revl(u32))
/* activate the "aligned" emulation, because this toolchain does not know
the aligned attribute (or something similar yet) */
#define TU_HAS_NO_ATTR_ALIGNED
/* activate the "weak" function emulation, because this toolchain does not
know the weak attribute (or something similar yet) */
#define TU_HAS_NO_ATTR_WEAK
// make sure to define away the standard definition of this macro
#undef MAKE_WEAK_FUNC
// Helper macro to construct a "weak" function name
#define MAKE_WEAK_FUNC(func_name) weak_ ## func_name
#if defined(TU_HAS_NO_ATTR_WEAK)
// "Weak function" emulation defined in cdc_device.h
#define ADD_WEAK_FUNC_TUD_CDC_RX_CB 0
#define ADD_WEAK_FUNC_TUD_CDC_RX_WANTED_CB 0
#define ADD_WEAK_FUNC_TUD_CDC_TX_COMPLETE_CB 0
#define ADD_WEAK_FUNC_TUD_CDC_LINE_STATE_CB 0
#define ADD_WEAK_FUNC_TUD_CDC_LINE_CODING_CB 0
#define ADD_WEAK_FUNC_TUD_CDC_SEND_BREAK_CB 0
// "Weak function" emulation defined in usbd_pvt.h
#define ADD_WEAK_FUNC_USBD_APP_DRIVER_GET_CB 0
// "Weak function" emulation defined in usbd.h
#define ADD_WEAK_FUNC_TUD_DESCRIPTOR_BOS_CB 0
#define ADD_WEAK_FUNC_TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB 0
#define ADD_WEAK_FUNC_TUD_MOUNT_CB 0
#define ADD_WEAK_FUNC_TUD_UMOUNT_CB 0
#define ADD_WEAK_FUNC_TUD_SUSPEND_CB 0
#define ADD_WEAK_FUNC_TUD_RESUME_CB 0
#define ADD_WEAK_FUNC_TUD_VENDOR_CONTROL_XFER_CB 0
// "Weak function" emulation defined in dcd.h
#define ADD_WEAK_FUNC_DCD_EDPT0_STATUS_COMPLETE 0
#define ADD_WEAK_FUNC_DCD_EDPT_CLOSE 0
#define ADD_WEAK_FUNC_DCD_EDPT_XFER_FIFO 0
#endif
#else
#error "Compiler attribute porting is required"
#endif
@ -149,11 +233,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

@ -263,6 +263,7 @@ enum
//--------------------------------------------------------------------+
/// USB Device Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
@ -283,10 +284,12 @@ typedef struct TU_ATTR_PACKED
uint8_t bNumConfigurations ; ///< Number of possible configurations.
} tusb_desc_device_t;
TU_PACK_STRUCT_END
TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct");
// USB Binary Device Object Store (BOS) Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes
@ -294,8 +297,10 @@ typedef struct TU_ATTR_PACKED
uint16_t wTotalLength ; ///< Total length of data returned for this descriptor
uint8_t bNumDeviceCaps ; ///< Number of device capability descriptors in the BOS
} tusb_desc_bos_t;
TU_PACK_STRUCT_END
/// USB Configuration Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes
@ -308,10 +313,10 @@ typedef struct TU_ATTR_PACKED
uint8_t bmAttributes ; ///< Configuration characteristics \n D7: Reserved (set to one)\n D6: Self-powered \n D5: Remote Wakeup \n D4...0: Reserved (reset to zero) \n D7 is reserved and must be set to one for historical reasons. \n A device configuration that uses power from the bus and a local source reports a non-zero value in bMaxPower to indicate the amount of bus power required and sets D6. The actual power source at runtime may be determined using the GetStatus(DEVICE) request (see USB 2.0 spec Section 9.4.5). \n If a device configuration supports remote wakeup, D5 is set to one.
uint8_t bMaxPower ; ///< Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational. Expressed in 2 mA units (i.e., 50 = 100 mA).
} tusb_desc_configuration_t;
TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9, "size is not correct");
TU_PACK_STRUCT_END
/// USB Interface Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes
@ -325,8 +330,10 @@ typedef struct TU_ATTR_PACKED
uint8_t bInterfaceProtocol ; ///< Protocol code (assigned by the USB). \n These codes are qualified by the value of the bInterfaceClass and the bInterfaceSubClass fields. If an interface supports class-specific requests, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use a class-specific protocol on this interface. \li If this field is set to FFH, the device uses a vendor-specific protocol for this interface.
uint8_t iInterface ; ///< Index of string descriptor describing this interface
} tusb_desc_interface_t;
TU_PACK_STRUCT_END
/// USB Endpoint Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes
@ -334,23 +341,32 @@ typedef struct TU_ATTR_PACKED
uint8_t bEndpointAddress ; ///< The address of the endpoint on the USB device described by this descriptor. The address is encoded as follows: \n Bit 3...0: The endpoint number \n Bit 6...4: Reserved, reset to zero \n Bit 7: Direction, ignored for control endpoints 0 = OUT endpoint 1 = IN endpoint.
TU_BIT_FIELD_ORDER_BEGIN
struct TU_ATTR_PACKED {
uint8_t xfer : 2;
uint8_t sync : 2;
uint8_t usage : 2;
uint8_t : 2;
} 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.
TU_BIT_FIELD_ORDER_END
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_PACK_STRUCT_END
/// USB Other Speed Configuration Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of descriptor
@ -363,8 +379,10 @@ typedef struct TU_ATTR_PACKED
uint8_t bmAttributes ; ///< Same as Configuration descriptor
uint8_t bMaxPower ; ///< Same as Configuration descriptor
} tusb_desc_other_speed_t;
TU_PACK_STRUCT_END
/// USB Device Qualifier Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of descriptor
@ -378,8 +396,10 @@ typedef struct TU_ATTR_PACKED
uint8_t bNumConfigurations ; ///< Number of Other-speed Configurations
uint8_t bReserved ; ///< Reserved for future use, must be zero
} tusb_desc_device_qualifier_t;
TU_PACK_STRUCT_END
/// USB Interface Association Descriptor (IAD ECN)
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of descriptor
@ -394,16 +414,20 @@ typedef struct TU_ATTR_PACKED
uint8_t iFunction ; ///< Index of the string descriptor describing the interface association.
} tusb_desc_interface_assoc_t;
TU_PACK_STRUCT_END
// USB String Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes
uint8_t bDescriptorType ; ///< Descriptor Type
uint16_t unicode_string[];
} tusb_desc_string_t;
TU_PACK_STRUCT_END
// USB Binary Device Object Store (BOS)
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength;
@ -413,8 +437,10 @@ typedef struct TU_ATTR_PACKED
uint8_t PlatformCapabilityUUID[16];
uint8_t CapabilityData[];
} tusb_desc_bos_platform_t;
TU_PACK_STRUCT_END
// USB WebuSB URL Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength;
@ -422,14 +448,17 @@ typedef struct TU_ATTR_PACKED
uint8_t bScheme;
char url[];
} tusb_desc_webusb_url_t;
TU_PACK_STRUCT_END
// DFU Functional Descriptor
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uint8_t bLength;
uint8_t bDescriptorType;
union {
TU_BIT_FIELD_ORDER_BEGIN
struct TU_ATTR_PACKED {
uint8_t bitCanDnload : 1;
uint8_t bitCanUpload : 1;
@ -437,6 +466,7 @@ typedef struct TU_ATTR_PACKED
uint8_t bitWillDetach : 1;
uint8_t reserved : 4;
} bmAttributes;
TU_BIT_FIELD_ORDER_END
uint8_t bAttributes;
};
@ -445,17 +475,21 @@ typedef struct TU_ATTR_PACKED
uint16_t wTransferSize;
uint16_t bcdDFUVersion;
} tusb_desc_dfu_functional_t;
TU_PACK_STRUCT_END
/*------------------------------------------------------------------*/
/* Types
*------------------------------------------------------------------*/
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED{
union {
TU_BIT_FIELD_ORDER_BEGIN
struct TU_ATTR_PACKED {
uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t.
uint8_t type : 2; ///< Request type tusb_request_type_t.
uint8_t direction : 1; ///< Direction type. tusb_dir_t
} bmRequestType_bit;
TU_BIT_FIELD_ORDER_END
uint8_t bmRequestType;
};
@ -465,6 +499,7 @@ typedef struct TU_ATTR_PACKED{
uint16_t wIndex;
uint16_t wLength;
} tusb_control_request_t;
TU_PACK_STRUCT_END
TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct");

View File

@ -116,24 +116,54 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK;
// Endpoint API
//--------------------------------------------------------------------+
#if !defined(TU_HAS_NO_ATTR_WEAK)
// Invoked when a control transfer's status stage is complete.
// May help DCD to prepare for next control transfer, this API is optional.
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK;
// Configure endpoint's registers according to descriptor
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
// Close an endpoint.
// Since it is weak, caller must TU_ASSERT this function's existence before calling it.
void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK;
// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
// Submit an transfer using fifo, When complete dcd_event_xfer_complete() is invoked to notify the stack
// This API is optional, may be useful for register-based for transferring data.
bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) TU_ATTR_WEAK;
#else
#if ADD_WEAK_FUNC_DCD_EDPT0_STATUS_COMPLETE
#define DCD_EDPT0_STATUS_COMPLETE dcd_edpt0_status_complete
#endif
#ifndef DCD_EDPT0_STATUS_COMPLETE
#define DCD_EDPT0_STATUS_COMPLETE NULL
#else
extern void DCD_EDPT0_STATUS_COMPLETE(uint8_t rhport, tusb_control_request_t const * request);
#endif
#if ADD_WEAK_FUNC_DCD_EDPT_CLOSE
#define DCD_EDPT_CLOSE dcd_edpt_close
#endif
#ifndef DCD_EDPT_CLOSE
#define DCD_EDPT_CLOSE NULL
#else
extern void DCD_EDPT_CLOSE(uint8_t rhport, uint8_t ep_addr);
#endif
#if ADD_WEAK_FUNC_DCD_EDPT_XFER_FIFO
#define DCD_EDPT_XFER_FIFO dcd_edpt_xfer_fifo
#endif
#ifndef DCD_EDPT_XFER_FIFO
#define DCD_EDPT_XFER_FIFO NULL
#else
extern void DCD_EDPT_XFER_FIFO(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes);
#endif
#endif
// Configure endpoint's registers according to descriptor
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
// Stall endpoint
void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);

View File

@ -33,6 +33,19 @@
#include "device/usbd_pvt.h"
#include "device/dcd.h"
#if defined(TU_HAS_NO_ATTR_WEAK)
static uint8_t const* (*const MAKE_WEAK_FUNC(tud_descriptor_bos_cb))(void) = TUD_DESCRIPTOR_BOS_CB;
static uint8_t const* (*const MAKE_WEAK_FUNC(tud_descriptor_device_qualifier_cb))(void) = TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB;
static void (*const MAKE_WEAK_FUNC(tud_mount_cb))(void) = TUD_MOUNT_CB;
static void (*const MAKE_WEAK_FUNC(tud_umount_cb))(void) = TUD_UMOUNT_CB;
static void (*const MAKE_WEAK_FUNC(tud_suspend_cb))(_Bool) = TUD_SUSPEND_CB;
static void (*const MAKE_WEAK_FUNC(tud_resume_cb))(void) = TUD_RESUME_CB;
static _Bool (*const MAKE_WEAK_FUNC(tud_vendor_control_xfer_cb))(uint8_t, uint8_t, tusb_control_request_t const *) = TUD_RESUME_CB;
static usbd_class_driver_t const* (*const MAKE_WEAK_FUNC(usbd_app_driver_get_cb))(uint8_t*) = USBD_APP_DRIVER_GET_CB;
static bool (*const MAKE_WEAK_FUNC(dcd_edpt_xfer_fifo))(uint8_t, uint8_t, tu_fifo_t *, uint16_t) = DCD_EDPT_XFER_FIFO;
static void (*const MAKE_WEAK_FUNC(dcd_edpt_close))(uint8_t, uint8_t) = DCD_EDPT_CLOSE;
#endif
#ifndef CFG_TUD_TASK_QUEUE_SZ
#define CFG_TUD_TASK_QUEUE_SZ 16
#endif
@ -50,6 +63,8 @@ enum { DRVID_INVALID = 0xFFu };
typedef struct
{
TU_PACK_STRUCT_BEGIN
TU_BIT_FIELD_ORDER_BEGIN
struct TU_ATTR_PACKED
{
volatile uint8_t connected : 1;
@ -60,6 +75,8 @@ typedef struct
uint8_t remote_wakeup_support : 1; // configuration descriptor's attribute
uint8_t self_powered : 1; // configuration descriptor's attribute
};
TU_BIT_FIELD_ORDER_END
TU_PACK_STRUCT_END
volatile uint8_t cfg_num; // current active configuration (0x00 is not configured)
uint8_t speed;
@ -67,6 +84,8 @@ typedef struct
uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid)
uint8_t ep2drv[CFG_TUD_EP_MAX][2]; // map endpoint to driver ( 0xff is invalid )
TU_PACK_STRUCT_BEGIN
TU_BIT_FIELD_ORDER_BEGIN
struct TU_ATTR_PACKED
{
volatile bool busy : 1;
@ -75,6 +94,8 @@ typedef struct
// TODO merge ep2drv here, 4-bit should be sufficient
}ep_status[CFG_TUD_EP_MAX][2];
TU_BIT_FIELD_ORDER_END
TU_PACK_STRUCT_END
}usbd_device_t;
@ -236,7 +257,7 @@ static uint8_t _app_driver_count = 0;
static inline usbd_class_driver_t const * get_driver(uint8_t drvid)
{
// Application drivers
if ( usbd_app_driver_get_cb )
if ( MAKE_WEAK_FUNC(usbd_app_driver_get_cb) )
{
if ( drvid < _app_driver_count ) return &_app_driver[drvid];
drvid -= _app_driver_count;
@ -408,9 +429,9 @@ bool tud_init (uint8_t rhport)
TU_ASSERT(_usbd_q);
// Get application driver if available
if ( usbd_app_driver_get_cb )
if ( MAKE_WEAK_FUNC(usbd_app_driver_get_cb) )
{
_app_driver = usbd_app_driver_get_cb(&_app_driver_count);
_app_driver = MAKE_WEAK_FUNC(usbd_app_driver_get_cb)(&_app_driver_count);
}
// Init class drivers
@ -501,7 +522,7 @@ void tud_task (void)
usbd_reset(event.rhport);
// invoke callback
if (tud_umount_cb) tud_umount_cb();
if (MAKE_WEAK_FUNC(tud_umount_cb)) MAKE_WEAK_FUNC(tud_umount_cb)();
break;
case DCD_EVENT_SETUP_RECEIVED:
@ -557,12 +578,12 @@ void tud_task (void)
case DCD_EVENT_SUSPEND:
TU_LOG2("\r\n");
if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en);
if (MAKE_WEAK_FUNC(tud_suspend_cb)) MAKE_WEAK_FUNC(tud_suspend_cb)(_usbd_dev.remote_wakeup_en);
break;
case DCD_EVENT_RESUME:
TU_LOG2("\r\n");
if (tud_resume_cb) tud_resume_cb();
if (MAKE_WEAK_FUNC(tud_resume_cb)) MAKE_WEAK_FUNC(tud_resume_cb)();
break;
case DCD_EVENT_SOF:
@ -609,10 +630,10 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// Vendor request
if ( p_request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR )
{
TU_VERIFY(tud_vendor_control_xfer_cb);
TU_VERIFY(MAKE_WEAK_FUNC(tud_vendor_control_xfer_cb));
usbd_control_set_complete_callback(tud_vendor_control_xfer_cb);
return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request);
usbd_control_set_complete_callback(MAKE_WEAK_FUNC(tud_vendor_control_xfer_cb));
return MAKE_WEAK_FUNC(tud_vendor_control_xfer_cb)(rhport, CONTROL_STAGE_SETUP, p_request);
}
#if CFG_TUSB_DEBUG >= 2
@ -831,7 +852,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 )
{
@ -892,7 +913,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
}
// invoke callback
if (tud_mount_cb) tud_mount_cb();
if (MAKE_WEAK_FUNC(tud_mount_cb)) MAKE_WEAK_FUNC(tud_mount_cb)();
return true;
}
@ -949,15 +970,15 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
TU_LOG2(" BOS\r\n");
// requested by host if USB > 2.0 ( i.e 2.1 or 3.x )
if (!tud_descriptor_bos_cb) return false;
if (!MAKE_WEAK_FUNC(tud_descriptor_bos_cb)) return false;
tusb_desc_bos_t const* desc_bos = (tusb_desc_bos_t const*) tud_descriptor_bos_cb();
tusb_desc_bos_t const* desc_bos = (tusb_desc_bos_t const*)MAKE_WEAK_FUNC(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);
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 +993,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;
@ -995,9 +1016,9 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
// Host sends this request to ask why our device with USB BCD from 2.0
// but is running at Full/Low Speed. If not highspeed capable stall this request,
// otherwise return the descriptor that could work in highspeed mode
if ( tud_descriptor_device_qualifier_cb )
if (MAKE_WEAK_FUNC(tud_descriptor_device_qualifier_cb))
{
uint8_t const* desc_qualifier = tud_descriptor_device_qualifier_cb();
uint8_t const* desc_qualifier = MAKE_WEAK_FUNC(tud_descriptor_device_qualifier_cb)();
TU_ASSERT(desc_qualifier);
// first byte of descriptor is its size
@ -1165,18 +1186,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;
@ -1285,7 +1306,7 @@ bool usbd_edpt_iso_xfer(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
// and usbd task can preempt and clear the busy
_usbd_dev.ep_status[epnum][dir].busy = true;
if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes))
if (MAKE_WEAK_FUNC(dcd_edpt_xfer_fifo)(rhport, ep_addr, ff, total_bytes))
{
TU_LOG2("OK\r\n");
return true;
@ -1348,10 +1369,10 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr)
*/
void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr)
{
TU_ASSERT(dcd_edpt_close, /**/);
TU_ASSERT(MAKE_WEAK_FUNC(dcd_edpt_close), /**/);
TU_LOG2(" CLOSING Endpoint: 0x%02X\r\n", ep_addr);
dcd_edpt_close(rhport, ep_addr);
MAKE_WEAK_FUNC(dcd_edpt_close(rhport, ep_addr));
return;
}

View File

@ -103,10 +103,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);
@ -115,6 +111,11 @@ 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);
#if !defined(TU_HAS_NO_ATTR_WEAK)
// 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);
@ -135,6 +136,71 @@ TU_ATTR_WEAK void tud_resume_cb(void);
// Invoked when received control request with VENDOR TYPE
TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
#else
#if ADD_WEAK_FUNC_TUD_DESCRIPTOR_BOS_CB
#define TUD_DESCRIPTOR_BOS_CB tud_descriptor_bos_cb
#endif
#ifndef TUD_DESCRIPTOR_BOS_CB
#define TUD_DESCRIPTOR_BOS_CB NULL
#else
extern uint8_t const* TUD_DESCRIPTOR_BOS_CB(void);
#endif
#if ADD_WEAK_FUNC_TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB
#define TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB tud_descriptor_device_qualifier_cb
#endif
#ifndef TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB
#define TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB NULL
#else
extern uint8_t const* TUD_DESCRIPTOR_DEVICE_QUALIFIER_CB(void);
#endif
#if ADD_WEAK_FUNC_TUD_MOUNT_CB
#define TUD_MOUNT_CB tud_mount_cb
#endif
#ifndef TUD_MOUNT_CB
#define TUD_MOUNT_CB NULL
#else
extern void TUD_MOUNT_CB(void);
#endif
#if ADD_WEAK_FUNC_TUD_UMOUNT_CB
#define TUD_UMOUNT_CB tud_umount_cb
#endif
#ifndef TUD_UMOUNT_CB
#define TUD_UMOUNT_CB NULL
#else
extern void TUD_UMOUNT_CB(void);
#endif
#if ADD_WEAK_FUNC_TUD_SUSPEND_CB
#define TUD_SUSPEND_CB tud_suspend_cb
#endif
#ifndef TUD_SUSPEND_CB
#define TUD_SUSPEND_CB NULL
#else
extern void TUD_SUSPEND_CB(bool remote_wakeup_en);
#endif
#if ADD_WEAK_FUNC_TUD_RESUME_CB
#define TUD_RESUME_CB tud_resume_cb
#endif
#ifndef TUD_RESUME_CB
#define TUD_RESUME_CB NULL
#else
extern void TUD_RESUME_CB(void);
#endif
#if ADD_WEAK_FUNC_TUD_VENDOR_CONTROL_XFER_CB
#define TUD_VENDOR_CONTROL_XFER_CB tud_vendor_control_xfer_cb
#endif
#ifndef TUD_VENDOR_CONTROL_XFER_CB
#define TUD_VENDOR_CONTROL_XFER_CB NULL
#else
extern bool TUD_VENDOR_CONTROL_XFER_CB(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
#endif
#endif
//--------------------------------------------------------------------+
// Binary Device Object Store (BOS) Descriptor Templates
//--------------------------------------------------------------------+

View File

@ -36,6 +36,10 @@
extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback);
#endif
#if defined(TU_HAS_NO_ATTR_WEAK)
static void (*const MAKE_WEAK_FUNC(dcd_edpt0_status_complete))(uint8_t, tusb_control_request_t const *) = DCD_EDPT0_STATUS_COMPLETE;
#endif
enum
{
EDPT_CTRL_OUT = 0x00,
@ -55,8 +59,17 @@ typedef struct
static usbd_control_xfer_t _ctrl_xfer;
#if defined(TU_HAS_NO_ATTR_ALIGNED)
// Helper union to overcome the lack of the alignment attribute/pragma
static union {
uint16_t : (sizeof(uint16_t) * 8); // Alignment of at least the size of the used type
uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
} Align_usbd_ctrl_buf_;
static uint8_t *_usbd_ctrl_buf = (uint8_t*)&Align_usbd_ctrl_buf_;
#else
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
#endif
//--------------------------------------------------------------------+
// Application API
@ -171,7 +184,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
TU_ASSERT(0 == xferred_bytes);
// invoke optional dcd hook if available
if (dcd_edpt0_status_complete) dcd_edpt0_status_complete(rhport, &_ctrl_xfer.request);
if (MAKE_WEAK_FUNC(dcd_edpt0_status_complete)) MAKE_WEAK_FUNC(dcd_edpt0_status_complete)(rhport, &_ctrl_xfer.request);
if (_ctrl_xfer.complete_cb)
{

View File

@ -51,10 +51,21 @@ typedef struct
void (* sof ) (uint8_t rhport); /* optional */
} usbd_class_driver_t;
#if !defined(TU_HAS_NO_ATTR_WEAK)
// Invoked when initializing device stack to get additional class drivers.
// Can optionally implemented by application to extend/overwrite class driver support.
// 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;
#else
#if ADD_WEAK_FUNC_USBD_APP_DRIVER_GET_CB
#define USBD_APP_DRIVER_GET_CB usbd_app_driver_get_cb
#endif
#ifndef USBD_APP_DRIVER_GET_CB
#define USBD_APP_DRIVER_GET_CB NULL
#else
extern usbd_class_driver_t const* USBD_APP_DRIVER_GET_CB(uint8_t* driver_count);
#endif
#endif
typedef bool (*usbd_control_xfer_cb_t)(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);

View File

@ -51,6 +51,7 @@ static inline void osal_task_delay(uint32_t msec)
typedef StaticSemaphore_t osal_semaphore_def_t;
typedef SemaphoreHandle_t osal_semaphore_t;
#if (configSUPPORT_STATIC_ALLOCATION == 1) //FIXME Only static API supported
static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
{
return xSemaphoreCreateBinaryStatic(semdef);
@ -76,6 +77,7 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
return res != 0;
}
}
#endif
static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
{
@ -96,7 +98,12 @@ typedef SemaphoreHandle_t osal_mutex_t;
static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{
#if (configSUPPORT_STATIC_ALLOCATION == 0) //FIXME Only static API supported
(void)mdef;
return xSemaphoreCreateMutex();
#else
return xSemaphoreCreateMutexStatic(mdef);
#endif
}
static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
@ -131,7 +138,11 @@ typedef QueueHandle_t osal_queue_t;
static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
#if defined(__Tx36V5_Maincard__)
return xQueueCreate(qdef->depth, qdef->item_sz);
#else
return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq);
#endif
}
static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
@ -139,6 +150,19 @@ static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
return xQueueReceive(qhdl, data, portMAX_DELAY);
}
#if defined(__Tx36V5_Maincard__)
extern BaseType_t UsbTaskWoken;
static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
{
if (!in_isr) {
return(xQueueSendToBack(qhdl, data, OSAL_TIMEOUT_WAIT_FOREVER));
} else {
BaseType_t res = xQueueSendToBackFromISR(qhdl, data, &UsbTaskWoken);
return(res != 0);
}
}
#else
static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
{
if ( !in_isr )
@ -159,6 +183,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
return res != 0;
}
}
#endif
static inline bool osal_queue_empty(osal_queue_t qhdl)
{

View File

@ -26,7 +26,7 @@
#include "tusb_option.h"
#if TUSB_OPT_DEVICE_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X )
#if TUSB_OPT_DEVICE_ENABLED && (( CFG_TUSB_MCU == OPT_MCU_RX63X ) || ( CFG_TUSB_MCU == OPT_MCU_RX72N ))
#include "device/dcd.h"
#include "iodefine.h"
@ -38,6 +38,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))
@ -91,39 +92,47 @@
typedef struct {
union {
TU_BIT_FIELD_ORDER_BEGIN
struct {
uint16_t : 8;
uint16_t TRCLR: 1;
uint16_t TRENB: 1;
uint16_t : 0;
};
TU_BIT_FIELD_ORDER_END
uint16_t TRE;
};
uint16_t TRN;
} reg_pipetre_t;
typedef union {
TU_BIT_FIELD_ORDER_BEGIN
struct {
volatile uint16_t u8: 8;
volatile uint16_t : 0;
};
TU_BIT_FIELD_ORDER_END
volatile uint16_t u16;
} hw_fifo_t;
TU_PACK_STRUCT_BEGIN
typedef struct TU_ATTR_PACKED
{
uintptr_t addr; /* the start address of a transfer data buffer */
uint16_t length; /* the number of bytes in the buffer */
uint16_t remaining; /* the number of bytes remaining in the buffer */
TU_BIT_FIELD_ORDER_BEGIN
struct {
uint32_t ep : 8; /* an assigned endpoint address */
uint32_t : 0;
};
TU_BIT_FIELD_ORDER_END
} pipe_state_t;
TU_PACK_STRUCT_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 */
} dcd_data_t;
@ -135,14 +144,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)
@ -226,7 +244,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();
}
@ -270,11 +288,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,6 +310,13 @@ static void process_setup_packet(uint8_t rhport)
setup_packet[1] = USB0.USBVAL;
setup_packet[2] = USB0.USBINDX;
setup_packet[3] = USB0.USBLENG;
#if TU_BYTE_ORDER==TU_BIG_ENDIAN
#if defined(__CCRX__)
setup_packet[0] = tu_le16toh(setup_packet[0]);
#else
//FIXME needs to implemented for other tool chains
#endif
#endif
USB0.INTSTS0.WORD = ~USB_IS0_VALID;
dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet[0], true);
}
@ -317,7 +342,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;
@ -329,7 +358,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;
}
}
@ -350,7 +379,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;
}
@ -363,7 +392,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;
@ -392,11 +421,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) {
@ -416,19 +450,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,
@ -437,18 +477,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 */
}
}
@ -458,7 +500,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) {
@ -485,13 +529,22 @@ static void process_set_address(uint8_t rhport)
{
const uint32_t addr = USB0.USBADDR.BIT.USBADDR;
if (!addr) return;
#if defined(__CCRX__)
tusb_control_request_t setup_packet;
setup_packet.bmRequestType = 0;
setup_packet.bRequest = 5;
setup_packet.wValue = addr;
setup_packet.wIndex = 0;
setup_packet.wLength = 0;
#else
const tusb_control_request_t setup_packet = {
.bmRequestType = 0,
.bRequest = 5,
.wValue = addr,
.wIndex = 0,
.wLength = 0,
};
.bmRequestType = 0,
.bRequest = 5,
.wValue = addr,
.wIndex = 0,
.wLength = 0,
};
#endif
dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet, true);
}
@ -513,7 +566,13 @@ void dcd_init(uint8_t rhport)
USB0.SYSCFG.BIT.DCFM = 0;
USB0.SYSCFG.BIT.USBE = 1;
USB0.PHYSLEW.LONG = 0x5;
USB.DPUSR0R.BIT.FIXPHY0 = 0u; /* USB0 Transceiver Output fixed */
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
IR(PERIB, INTB185) = 0;
#else
IR(USB0, USBI0) = 0;
#endif
/* Setup default control pipe */
USB0.DCPMAXP.BIT.MXPS = 64;
@ -529,13 +588,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)
@ -574,7 +641,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;
@ -680,8 +747,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);
@ -720,13 +787,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

@ -112,6 +112,7 @@
// Renesas RX
#define OPT_MCU_RX63X 1400 ///< Renesas RX63N/631
#define OPT_MCU_RX72N 1401 ///< Renesas RX72N
/** @} */