feature(dcd_dwc2): Added cache synchronization
This commit is contained in:
		@@ -47,20 +47,7 @@
 | 
				
			|||||||
// 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;
 | 
				
			||||||
@@ -361,11 +348,6 @@ 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;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -865,11 +847,6 @@ 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;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -895,9 +872,7 @@ 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,14 +39,6 @@
 | 
				
			|||||||
#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
 | 
				
			||||||
@@ -119,25 +111,6 @@ 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
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user