mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
feature(dcd_dwc2): Added cache synchronization
This commit is contained in:
parent
9e674d4fae
commit
b8d31a59ee
@ -47,7 +47,20 @@
|
|||||||
// MACRO TYPEDEF CONSTANT ENUM
|
// MACRO TYPEDEF CONSTANT ENUM
|
||||||
//--------------------------------------------------------------------+
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#ifdef DWC2_MEM_CACHE_LINE_SIZE
|
||||||
|
CFG_TUD_MEM_SECTION struct {
|
||||||
|
union {
|
||||||
|
uint32_t data[2];
|
||||||
|
uint8_t buffer[DWC2_MEM_CACHE_LINE_SIZE];
|
||||||
|
};
|
||||||
|
} _cache_aligned_setup_packet;
|
||||||
|
|
||||||
|
#define _setup_packet _cache_aligned_setup_packet.data
|
||||||
|
#define _sizeof_setup_packet() DWC2_MEM_CACHE_LINE_SIZE
|
||||||
|
#else
|
||||||
static CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2];
|
static CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2];
|
||||||
|
#define _sizeof_setup_packet() sizeof(_setup_packet)
|
||||||
|
#endif // DWC2_MEM_CACHE_LINE_SIZE
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t* buffer;
|
uint8_t* buffer;
|
||||||
@ -348,6 +361,11 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
|
|||||||
|
|
||||||
const bool is_dma = dma_device_enabled(dwc2);
|
const bool is_dma = dma_device_enabled(dwc2);
|
||||||
if(is_dma) {
|
if(is_dma) {
|
||||||
|
if (dir == TUSB_DIR_IN && total_bytes != 0) {
|
||||||
|
// CACHE HINT
|
||||||
|
// The xfer->buffer has new data for Host, move it to memory for DMA to transfer it
|
||||||
|
dcd_dcache_clean(xfer->buffer, total_bytes);
|
||||||
|
}
|
||||||
dep->diepdma = (uintptr_t) xfer->buffer;
|
dep->diepdma = (uintptr_t) xfer->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,6 +865,11 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
|
|||||||
|
|
||||||
if (doepint_bm.setup_phase_done) {
|
if (doepint_bm.setup_phase_done) {
|
||||||
dma_setup_prepare(rhport);
|
dma_setup_prepare(rhport);
|
||||||
|
// CACHE HINT
|
||||||
|
// When cache is enabled, _setup_packet must have cache line size alignment
|
||||||
|
// and there should be no valuable data in memory after.
|
||||||
|
// Thus, specific struct is used as a buffer for setup packet data
|
||||||
|
dcd_dcache_invalidate((uint8_t*) _setup_packet, _sizeof_setup_packet());
|
||||||
dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true);
|
dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -872,7 +895,9 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
|
|||||||
if(epnum == 0 && xfer->total_len == 0) {
|
if(epnum == 0 && xfer->total_len == 0) {
|
||||||
dma_setup_prepare(rhport);
|
dma_setup_prepare(rhport);
|
||||||
}
|
}
|
||||||
|
// CACHE HINT
|
||||||
|
// Some data has been received by DMA, fetch the data from memory to cache
|
||||||
|
dcd_dcache_invalidate(xfer->buffer, xfer->total_len);
|
||||||
dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
|
dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,14 @@
|
|||||||
#include "soc/periph_defs.h"
|
#include "soc/periph_defs.h"
|
||||||
#include "soc/usb_wrap_struct.h"
|
#include "soc/usb_wrap_struct.h"
|
||||||
|
|
||||||
|
#if (CFG_TUD_DWC2_DMA_ENABLE && SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE)
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_cache.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#define DWC2_MEM_CACHE_LINE_SIZE CONFIG_CACHE_L1_CACHE_LINE_SIZE
|
||||||
|
#endif // SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
|
||||||
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||||
#define DWC2_FS_REG_BASE 0x60080000UL
|
#define DWC2_FS_REG_BASE 0x60080000UL
|
||||||
#define DWC2_EP_MAX 7
|
#define DWC2_EP_MAX 7
|
||||||
@ -111,6 +119,25 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint
|
|||||||
// maybe usb_utmi_hal_disable()
|
// maybe usb_utmi_hal_disable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (CFG_TUD_DWC2_DMA_ENABLE && SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE)
|
||||||
|
void dcd_dcache_clean(void const* addr, uint32_t data_size) {
|
||||||
|
int flags = ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED;
|
||||||
|
if (addr != NULL && data_size) {
|
||||||
|
esp_err_t ret = esp_cache_msync((void *) addr, data_size, flags);
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dcd_dcache_invalidate(void const* addr, uint32_t data_size) {
|
||||||
|
int flags = ESP_CACHE_MSYNC_FLAG_DIR_M2C;
|
||||||
|
if (addr != NULL && data_size) {
|
||||||
|
data_size = (data_size < DWC2_MEM_CACHE_LINE_SIZE)? DWC2_MEM_CACHE_LINE_SIZE : data_size;
|
||||||
|
esp_err_t ret = esp_cache_msync((void *) addr, data_size, flags);
|
||||||
|
assert(ret == ESP_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // CFG_TUD_DWC2_DMA_ENABLE && SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user