make sure usb buffer occupies whole cache line when DCACHE is enabled for msc,cdc,hid

HIL enable device DMA for p4
This commit is contained in:
hathach 2024-11-21 10:15:30 +07:00
parent 2571889061
commit fa523a5682
No known key found for this signature in database
GPG Key ID: 26FAB84F615C3C52
10 changed files with 105 additions and 103 deletions

View File

@ -8,7 +8,7 @@
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* furnished to do so, subject to the following conditions:aaaaa
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
@ -33,7 +33,7 @@
// #define NEOPIXEL_PIN 48
#define BUTTON_PIN 0
#define BUTTON_PIN 35
#define BUTTON_STATE_ACTIVE 0
// For CI hardware test, to test both device and host on the same HS port with help of

View File

@ -69,8 +69,14 @@ typedef struct {
OSAL_MUTEX_DEF(tx_ff_mutex);
// Endpoint Transfer buffer
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE];
union {
CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE];
TUD_DCACHE_PADDING;
};
union {
CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE];
TUD_DCACHE_PADDING;
};
} cdcd_interface_t;
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char)

View File

@ -53,9 +53,18 @@ typedef struct {
// Note: HID descriptor may be not available from application after enumeration
tusb_hid_descriptor_hid_t const *hid_descriptor;
uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE];
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE];
union {
CFG_TUD_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE];
TUD_DCACHE_PADDING;
};
union {
CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE];
TUD_DCACHE_PADDING;
};
union {
CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE];
TUD_DCACHE_PADDING;
};
} hidd_interface_t;
CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID];

View File

@ -44,8 +44,7 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
enum
{
enum {
MSC_STAGE_CMD = 0,
MSC_STAGE_DATA,
MSC_STAGE_STATUS,
@ -53,11 +52,19 @@ enum
MSC_STAGE_NEED_RESET,
};
typedef struct
{
// TODO optimize alignment
CFG_TUSB_MEM_ALIGN msc_cbw_t cbw;
CFG_TUSB_MEM_ALIGN msc_csw_t csw;
typedef struct {
union {
CFG_TUD_MEM_ALIGN msc_cbw_t cbw;
TUD_DCACHE_PADDING;
};
union {
CFG_TUD_MEM_ALIGN msc_csw_t csw;
TUD_DCACHE_PADDING;
};
union {
CFG_TUD_MEM_ALIGN uint8_t ep_buf[CFG_TUD_MSC_EP_BUFSIZE];
TUD_DCACHE_PADDING;
};
uint8_t itf_num;
uint8_t ep_in;
@ -74,8 +81,7 @@ typedef struct
uint8_t add_sense_qualifier;
}mscd_interface_t;
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static mscd_interface_t _mscd_itf;
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE];
CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN static mscd_interface_t _mscd_itf;
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
@ -86,13 +92,11 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc);
static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc);
static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint32_t xferred_bytes);
TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir)
{
TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir) {
return tu_bit_test(dir, 7);
}
static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc)
{
static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc) {
// Data residue is always = host expect - actual transferred
p_msc->csw.data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len;
@ -100,14 +104,12 @@ static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc)
return usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t));
}
static inline bool prepare_cbw(uint8_t rhport, mscd_interface_t* p_msc)
{
static inline bool prepare_cbw(uint8_t rhport, mscd_interface_t* p_msc) {
p_msc->stage = MSC_STAGE_CMD;
return usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t));
}
static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status)
{
static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status) {
msc_cbw_t const * p_cbw = &p_msc->cbw;
msc_csw_t * p_csw = &p_msc->csw;
@ -116,24 +118,21 @@ static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status
p_msc->stage = MSC_STAGE_STATUS;
// failed but sense key is not set: default to Illegal Request
if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
if (p_msc->sense_key == 0) {
tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
}
// If there is data stage and not yet complete, stall it
if ( p_cbw->total_bytes && p_csw->data_residue )
{
if ( is_data_in(p_cbw->dir) )
{
if (p_cbw->total_bytes && p_csw->data_residue) {
if (is_data_in(p_cbw->dir)) {
usbd_edpt_stall(rhport, p_msc->ep_in);
}
else
{
} else {
usbd_edpt_stall(rhport, p_msc->ep_out);
}
}
}
static inline uint32_t rdwr10_get_lba(uint8_t const command[])
{
static inline uint32_t rdwr10_get_lba(uint8_t const command[]) {
// use offsetof to avoid pointer to the odd/unaligned address
uint32_t const lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba));
@ -141,14 +140,12 @@ static inline uint32_t rdwr10_get_lba(uint8_t const command[])
return tu_ntohl(lba);
}
static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw)
{
static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw) {
uint16_t const block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count));
return tu_ntohs(block_count);
}
static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw)
{
static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) {
// first extract block count in the command
uint16_t const block_count = rdwr10_get_blockcount(cbw);
@ -158,40 +155,28 @@ static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw)
return (uint16_t) (cbw->total_bytes / block_count);
}
uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
{
uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) {
uint8_t status = MSC_CSW_STATUS_PASSED;
uint16_t const block_count = rdwr10_get_blockcount(cbw);
if ( cbw->total_bytes == 0 )
{
if ( block_count )
{
if (cbw->total_bytes == 0) {
if (block_count) {
TU_LOG_DRV(" SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n");
status = MSC_CSW_STATUS_PHASE_ERROR;
}else
{
} else {
// no data transfer, only exist in complaint test suite
}
}else
{
if ( SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir) )
{
} else {
if (SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir)) {
TU_LOG_DRV(" SCSI case 10 (Ho <> Di)\r\n");
status = MSC_CSW_STATUS_PHASE_ERROR;
}
else if ( SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir) )
{
} else if (SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir)) {
TU_LOG_DRV(" SCSI case 8 (Hi <> Do)\r\n");
status = MSC_CSW_STATUS_PHASE_ERROR;
}
else if ( 0 == block_count )
{
} else if (0 == block_count) {
TU_LOG_DRV(" SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n");
status = MSC_CSW_STATUS_FAILED;
}
else if ( cbw->total_bytes / block_count == 0 )
{
status = MSC_CSW_STATUS_FAILED;
} else if (cbw->total_bytes / block_count == 0) {
TU_LOG_DRV(" Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n");
status = MSC_CSW_STATUS_PHASE_ERROR;
}
@ -205,8 +190,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= CFG_TUD_MSC_LOG_LEVEL
TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
{
TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = {
{ .key = SCSI_CMD_TEST_UNIT_READY , .data = "Test Unit Ready" },
{ .key = SCSI_CMD_INQUIRY , .data = "Inquiry" },
{ .key = SCSI_CMD_MODE_SELECT_6 , .data = "Mode_Select 6" },
@ -220,8 +204,7 @@ TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
{ .key = SCSI_CMD_WRITE_10 , .data = "Write10" }
};
TU_ATTR_UNUSED tu_static tu_lookup_table_t const _msc_scsi_cmd_table =
{
TU_ATTR_UNUSED tu_static tu_lookup_table_t const _msc_scsi_cmd_table = {
.count = TU_ARRAY_SIZE(_msc_scsi_cmd_lookup),
.items = _msc_scsi_cmd_lookup
};
@ -462,7 +445,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
// 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length
if ( (p_cbw->total_bytes > 0 ) && !is_data_in(p_cbw->dir) )
{
if (p_cbw->total_bytes > sizeof(_mscd_buf))
if (p_cbw->total_bytes > CFG_TUD_MSC_EP_BUFSIZE)
{
TU_LOG_DRV(" SCSI reject non READ10/WRITE10 with large data\r\n");
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
@ -470,17 +453,17 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
{
// Didn't check for case 9 (Ho > Dn), which requires examining scsi command first
// but it is OK to just receive data then responded with failed status
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, (uint16_t) p_msc->total_len) );
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, p_msc->ep_buf, (uint16_t) p_msc->total_len) );
}
}else
{
// First process if it is a built-in commands
int32_t resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, _mscd_buf, sizeof(_mscd_buf));
int32_t resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, p_msc->ep_buf, CFG_TUD_MSC_EP_BUFSIZE);
// Invoke user callback if not built-in
if ( (resplen < 0) && (p_msc->sense_key == 0) )
{
resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len);
resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, p_msc->ep_buf, (uint16_t) p_msc->total_len);
}
if ( resplen < 0 )
@ -513,7 +496,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
{
// cannot return more than host expect
p_msc->total_len = tu_min32((uint32_t) resplen, p_cbw->total_bytes);
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) p_msc->total_len) );
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, p_msc->ep_buf, (uint16_t) p_msc->total_len) );
}
}
}
@ -522,7 +505,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
case MSC_STAGE_DATA:
TU_LOG_DRV(" SCSI Data [Lun%u]\r\n", p_cbw->lun);
//TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2);
//TU_LOG_MEM(MSC_DEBUG, p_msc->ep_buf, xferred_bytes, 2);
if (SCSI_CMD_READ_10 == p_cbw->command[0])
{
@ -548,7 +531,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
// OUT transfer, invoke callback if needed
if ( !is_data_in(p_cbw->dir) )
{
int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len);
int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, p_msc->ep_buf, (uint16_t) p_msc->total_len);
if ( cb_result < 0 )
{
@ -861,11 +844,11 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz);
// remaining bytes capped at class buffer
int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len);
int32_t nbytes = (int32_t) tu_min32(CFG_TUD_MSC_EP_BUFSIZE, p_cbw->total_bytes-p_msc->xferred_len);
// Application can consume smaller bytes
uint32_t const offset = p_msc->xferred_len % block_sz;
nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_buf, (uint32_t) nbytes);
nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, p_msc->ep_buf, (uint32_t) nbytes);
if ( nbytes < 0 )
{
@ -884,7 +867,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
}
else
{
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) nbytes), );
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, p_msc->ep_buf, (uint16_t) nbytes), );
}
}
@ -908,10 +891,10 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
}
// remaining bytes capped at class buffer
uint16_t nbytes = (uint16_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len);
uint16_t nbytes = (uint16_t) tu_min32(CFG_TUD_MSC_EP_BUFSIZE, p_cbw->total_bytes-p_msc->xferred_len);
// Write10 callback will be called later when usb transfer complete
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, nbytes), );
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, p_msc->ep_buf, nbytes), );
}
// process new data arrived from WRITE10
@ -927,7 +910,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
// Invoke callback to consume new data
uint32_t const offset = p_msc->xferred_len % block_sz;
int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_buf, xferred_bytes);
int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, p_msc->ep_buf, xferred_bytes);
if ( nbytes < 0 )
{
@ -950,7 +933,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
if ( nbytes > 0 )
{
p_msc->xferred_len += (uint16_t) nbytes;
memmove(_mscd_buf, _mscd_buf+nbytes, left_over);
memmove(p_msc->ep_buf, p_msc->ep_buf+nbytes, left_over);
}
// simulate an transfer complete with adjusted parameters --> callback will be invoked with adjusted parameter

View File

@ -58,6 +58,9 @@
// Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111
#define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) )
// DCache padding for variable to occupy full cache line
#define TUD_DCACHE_PADDING uint8_t TU_XSTRCAT(dcache_padding_, _TU_COUNTER_)[CFG_TUD_MEM_DCACHE_ENABLE ? CFG_TUD_MEM_DCACHE_LINE_SIZE : 1]
//--------------------------------------------------------------------+
// Includes
//--------------------------------------------------------------------+

View File

@ -136,7 +136,7 @@
#define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
#define TU_ATTR_PACKED __attribute__ ((packed))
#define TU_ATTR_WEAK __attribute__ ((weak))
// #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f))
// #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
#ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug
#define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
#endif
@ -189,6 +189,7 @@
#define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
#define TU_ATTR_PACKED __attribute__ ((packed))
#define TU_ATTR_WEAK __attribute__ ((weak))
// #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
#define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
#define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
@ -216,6 +217,7 @@
#define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
#define TU_ATTR_PACKED __attribute__ ((packed))
#define TU_ATTR_WEAK __attribute__ ((weak))
// #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
#ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug
#define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
#endif
@ -244,6 +246,7 @@
#define TU_ATTR_SECTION(sec_name)
#define TU_ATTR_PACKED
#define TU_ATTR_WEAK
// #define TU_ATTR_WEAK_ALIAS(f)
#define TU_ATTR_ALWAYS_INLINE
#define TU_ATTR_DEPRECATED(mess)
#define TU_ATTR_UNUSED

View File

@ -54,6 +54,10 @@ enum {
};
typedef struct {
union {
CFG_TUD_MEM_ALIGN uint8_t ep_buf[CFG_TUD_ENDPOINT0_SIZE];
TUD_DCACHE_PADDING;
};
tusb_control_request_t request;
uint8_t* buffer;
uint16_t data_len;
@ -61,17 +65,14 @@ typedef struct {
usbd_control_xfer_cb_t complete_cb;
} usbd_control_xfer_t;
tu_static usbd_control_xfer_t _ctrl_xfer;
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN
tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN static usbd_control_xfer_t _ctrl_xfer;
//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
// Queue ZLP status transaction
static inline bool _status_stage_xact(uint8_t rhport, tusb_control_request_t const* request) {
static inline bool status_stage_xact(uint8_t rhport, tusb_control_request_t const* request) {
// Opposite to endpoint in Data Phase
uint8_t const ep_addr = request->bmRequestType_bit.direction ? EDPT_CTRL_OUT : EDPT_CTRL_IN;
return usbd_edpt_xfer(rhport, ep_addr, NULL, 0);
@ -84,13 +85,13 @@ bool tud_control_status(uint8_t rhport, tusb_control_request_t const* request) {
_ctrl_xfer.total_xferred = 0;
_ctrl_xfer.data_len = 0;
return _status_stage_xact(rhport, request);
return status_stage_xact(rhport, request);
}
// Queue a transaction in Data Stage
// Each transaction has up to Endpoint0's max packet size.
// This function can also transfer an zero-length packet
static bool _data_stage_xact(uint8_t rhport) {
static bool data_stage_xact(uint8_t rhport) {
uint16_t const xact_len = tu_min16(_ctrl_xfer.data_len - _ctrl_xfer.total_xferred,
CFG_TUD_ENDPOINT0_SIZE);
@ -99,11 +100,11 @@ static bool _data_stage_xact(uint8_t rhport) {
if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_IN) {
ep_addr = EDPT_CTRL_IN;
if (xact_len) {
TU_VERIFY(0 == tu_memcpy_s(_usbd_ctrl_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len));
TU_VERIFY(0 == tu_memcpy_s(_ctrl_xfer.ep_buf, CFG_TUD_ENDPOINT0_SIZE, _ctrl_xfer.buffer, xact_len));
}
}
return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _usbd_ctrl_buf : NULL, xact_len);
return usbd_edpt_xfer(rhport, ep_addr, xact_len ? _ctrl_xfer.ep_buf : NULL, xact_len);
}
// Transmit data to/from the control endpoint.
@ -122,10 +123,10 @@ bool tud_control_xfer(uint8_t rhport, tusb_control_request_t const* request, voi
// TU_LOG2(" Control total data length is %u bytes\r\n", _ctrl_xfer.data_len);
// Data stage
TU_ASSERT(_data_stage_xact(rhport));
TU_ASSERT(data_stage_xact(rhport));
} else {
// Status stage
TU_ASSERT(_status_stage_xact(rhport, request));
TU_ASSERT(status_stage_xact(rhport, request));
}
return true;
@ -179,7 +180,7 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
if (_ctrl_xfer.request.bmRequestType_bit.direction == TUSB_DIR_OUT) {
TU_VERIFY(_ctrl_xfer.buffer);
memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
memcpy(_ctrl_xfer.buffer, _ctrl_xfer.ep_buf, xferred_bytes);
TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2);
}
@ -205,7 +206,7 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
if (is_ok) {
// Send status
TU_ASSERT(_status_stage_xact(rhport, &_ctrl_xfer.request));
TU_ASSERT(status_stage_xact(rhport, &_ctrl_xfer.request));
} else {
// Stall both IN and OUT control endpoint
dcd_edpt_stall(rhport, EDPT_CTRL_OUT);
@ -213,7 +214,7 @@ bool usbd_control_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
}
} else {
// More data to transfer
TU_ASSERT(_data_stage_xact(rhport));
TU_ASSERT(data_stage_xact(rhport));
}
return true;

View File

@ -58,11 +58,9 @@ static xfer_ctl_t xfer_status[DWC2_EP_MAX][2];
#define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir])
typedef struct {
CFG_TUD_MEM_ALIGN union {
uint32_t setup_packet[2];
#if CFG_TUD_MEM_DCACHE_ENABLE
uint8_t setup_packet_cache_padding[CFG_TUD_MEM_DCACHE_LINE_SIZE];
#endif
union {
CFG_TUD_MEM_ALIGN uint32_t setup_packet[2];
TUD_DCACHE_PADDING;
};
// EP0 transfers are limited to 1 packet - larger sizes has to be split

View File

@ -252,11 +252,7 @@
#define CFG_TUD_DWC2_SLAVE_ENABLE 1
#endif
// DWC2 controller: use DMA for data transfer
// For processors with data cache enabled, USB endpoint buffer region
// (defined by CFG_TUSB_MEM_SECTION) must be declared as non-cacheable.
// For example, on Cortex-M7 the MPU region can be configured as normal
// non-cacheable, with RASR register value: TEX=1 C=0 B=0 S=0.
// Enable DWC2 DMA for device
#ifndef CFG_TUD_DWC2_DMA_ENABLE
#define CFG_TUD_DWC2_DMA_ENABLE 0
#endif

View File

@ -3,6 +3,9 @@
{
"name": "espressif_p4_function_ev",
"uid": "6055F9F98715",
"build" : {
"flags_on": ["", "CFG_TUD_DWC2_DMA_ENABLE"]
},
"tests": {
"only": ["device/cdc_msc_freertos", "device/hid_composite_freertos", "host/device_info"],
"dev_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002427"}]