mirror of
https://github.com/hathach/tinyusb.git
synced 2026-03-19 05:55:03 +00:00
dcd/samx7x: synchronize DMA and cache options
Signed-off-by: HiFiPhile <admin@hifiphile.com>
This commit is contained in:
@ -172,6 +172,10 @@
|
||||
#define TUP_RHPORT_HIGHSPEED 1
|
||||
#define TUD_ENDPOINT_ONE_DIRECTION_ONLY
|
||||
|
||||
// Enable dcache if DMA is enabled
|
||||
#define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_SAMX7X_DMA_ENABLE
|
||||
#define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32
|
||||
|
||||
#elif TU_CHECK_MCU(OPT_MCU_PIC32MZ)
|
||||
#define TUP_DCD_ENDPOINT_MAX 8
|
||||
#define TUD_ENDPOINT_ONE_DIRECTION_ONLY
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
|
||||
#include "device/dcd.h"
|
||||
#include "sam.h"
|
||||
#include "common_usb_regs.h"
|
||||
#include "samx7x_common.h"
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
@ -87,18 +87,22 @@ static const tusb_desc_endpoint_t ep0_desc =
|
||||
.wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE,
|
||||
};
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void CleanInValidateCache(uint32_t *addr, int32_t size)
|
||||
{
|
||||
if (SCB->CCR & SCB_CCR_DC_Msk)
|
||||
{
|
||||
SCB_CleanInvalidateDCache_by_Addr(addr, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
#if CFG_TUD_MEM_DCACHE_ENABLE
|
||||
bool dcd_dcache_clean(const void* addr, uint32_t data_size) {
|
||||
TU_VERIFY(addr && data_size);
|
||||
return samx7x_dcache_clean(addr, data_size);
|
||||
}
|
||||
|
||||
bool dcd_dcache_invalidate(const void* addr, uint32_t data_size) {
|
||||
TU_VERIFY(addr && data_size);
|
||||
return samx7x_dcache_invalidate(addr, data_size);
|
||||
}
|
||||
|
||||
bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
|
||||
TU_VERIFY(addr && data_size);
|
||||
return samx7x_dcache_clean_invalidate(addr, data_size);
|
||||
}
|
||||
#endif
|
||||
//------------------------------------------------------------------
|
||||
// Device API
|
||||
//------------------------------------------------------------------
|
||||
@ -255,7 +259,7 @@ static void dcd_ep_handler(uint8_t ep_ix)
|
||||
memcpy(xfer->buffer + xfer->queued_len, ptr, count);
|
||||
} else
|
||||
{
|
||||
tu_fifo_write_n(xfer->fifo, ptr, count);
|
||||
tu_hwfifo_read_to_fifo(ptr, xfer->fifo, count, NULL);
|
||||
}
|
||||
xfer->queued_len = (uint16_t)(xfer->queued_len + count);
|
||||
}
|
||||
@ -309,7 +313,7 @@ static void dcd_ep_handler(uint8_t ep_ix)
|
||||
{
|
||||
memcpy(xfer->buffer + xfer->queued_len, ptr, count);
|
||||
} else {
|
||||
tu_fifo_write_n(xfer->fifo, ptr, count);
|
||||
tu_hwfifo_read_to_fifo(ptr, xfer->fifo, count, NULL);
|
||||
}
|
||||
xfer->queued_len = (uint16_t)(xfer->queued_len + count);
|
||||
}
|
||||
@ -362,6 +366,7 @@ static void dcd_dma_handler(uint8_t ep_ix)
|
||||
dcd_event_xfer_complete(0, 0x80 + ep_ix, count, XFER_RESULT_SUCCESS, true);
|
||||
} else
|
||||
{
|
||||
dcd_dcache_invalidate(xfer->buffer, xfer->total_len);
|
||||
dcd_event_xfer_complete(0, ep_ix, count, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
}
|
||||
@ -588,7 +593,7 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix)
|
||||
}
|
||||
else
|
||||
{
|
||||
tu_fifo_read_n(xfer->fifo, ptr, len);
|
||||
tu_hwfifo_write_from_fifo(ptr, xfer->fifo, len, NULL);
|
||||
}
|
||||
__DSB();
|
||||
__ISB();
|
||||
@ -623,35 +628,18 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
|
||||
|
||||
if (EP_DMA_SUPPORT(epnum) && total_bytes != 0)
|
||||
{
|
||||
// Force the CPU to flush the buffer. We increase the size by 32 because the call aligns the
|
||||
// address to 32-byte boundaries.
|
||||
CleanInValidateCache((uint32_t*) tu_align((uint32_t) buffer, 4), total_bytes + 31);
|
||||
uint32_t udd_dma_ctrl = total_bytes << DEVDMACONTROL_BUFF_LENGTH_Pos;
|
||||
if (dir == TUSB_DIR_OUT)
|
||||
{
|
||||
udd_dma_ctrl |= DEVDMACONTROL_END_TR_IT | DEVDMACONTROL_END_TR_EN;
|
||||
} else {
|
||||
udd_dma_ctrl |= DEVDMACONTROL_END_B_EN;
|
||||
dcd_dcache_clean(xfer->buffer, total_bytes);
|
||||
}
|
||||
USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)buffer;
|
||||
udd_dma_ctrl |= DEVDMACONTROL_END_BUFFIT | DEVDMACONTROL_CHANN_ENB;
|
||||
// Disable IRQs to have a short sequence
|
||||
// between read of EOT_STA and DMA enable
|
||||
uint32_t irq_state = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
if (!(USB_REG->DEVDMA[epnum - 1].DEVDMASTATUS & DEVDMASTATUS_END_TR_ST))
|
||||
{
|
||||
USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl;
|
||||
USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1);
|
||||
__set_PRIMASK(irq_state);
|
||||
return true;
|
||||
}
|
||||
__set_PRIMASK(irq_state);
|
||||
|
||||
// Here a ZLP has been received
|
||||
// and the DMA transfer must be not started.
|
||||
// It is the end of transfer
|
||||
return false;
|
||||
USB_REG->DEVDMA[epnum - 1].DEVDMACONTROL = udd_dma_ctrl;
|
||||
USB_REG->DEVIER = DEVIER_DMA_1 << (epnum - 1);
|
||||
} else
|
||||
{
|
||||
if (dir == TUSB_DIR_OUT)
|
||||
|
||||
@ -2098,7 +2098,72 @@ typedef struct
|
||||
#define FIFO_RAM_ADDR 0xA0100000u
|
||||
|
||||
// Errata: The DMA feature is not available for Pipe/Endpoint 7
|
||||
#define EP_DMA_SUPPORT(epnum) (epnum >= 1 && epnum <= 6)
|
||||
#define EP_DMA_SUPPORT(epnum) (epnum >= 1 && epnum <= 6 && CFG_TUD_SAMX7X_DMA_ENABLE)
|
||||
|
||||
//------------- DCache -------------//
|
||||
#if CFG_TUD_MEM_DCACHE_ENABLE || CFG_TUH_MEM_DCACHE_ENABLE
|
||||
|
||||
typedef struct {
|
||||
uintptr_t start;
|
||||
uintptr_t end;
|
||||
} mem_region_t;
|
||||
|
||||
// Can be used to define additional uncached regions
|
||||
#ifndef CFG_SAMX7X_MEM_UNCACHED_REGIONS
|
||||
#define CFG_SAMX7X_MEM_UNCACHED_REGIONS
|
||||
#endif
|
||||
|
||||
static mem_region_t uncached_regions[] = {
|
||||
// DTCM
|
||||
{.start = 0x20000000, .end = 0x203fffff},
|
||||
CFG_SAMX7X_MEM_UNCACHED_REGIONS
|
||||
};
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t round_up_to_cache_line_size(uint32_t size) {
|
||||
if (size & (CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT-1)) {
|
||||
size = (size & ~(CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT-1)) + CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool is_cache_mem(uintptr_t addr) {
|
||||
if (0 == (SCB->CCR & SCB_CCR_DC_Msk)) {
|
||||
return false; // D-Cache is disabled
|
||||
}
|
||||
for (unsigned int i = 0; i < TU_ARRAY_SIZE(uncached_regions); i++) {
|
||||
if (uncached_regions[i].start <= addr && addr <= uncached_regions[i].end) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_clean(void const* addr, uint32_t data_size) {
|
||||
const uintptr_t addr32 = (uintptr_t) addr;
|
||||
if (is_cache_mem(addr32)) {
|
||||
data_size = round_up_to_cache_line_size(data_size);
|
||||
SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_invalidate(void const* addr, uint32_t data_size) {
|
||||
const uintptr_t addr32 = (uintptr_t) addr;
|
||||
if (is_cache_mem(addr32)) {
|
||||
data_size = round_up_to_cache_line_size(data_size);
|
||||
SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool samx7x_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
|
||||
const uintptr_t addr32 = (uintptr_t) addr;
|
||||
if (is_cache_mem(addr32)) {
|
||||
data_size = round_up_to_cache_line_size(data_size);
|
||||
SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else // TODO : SAM3U
|
||||
|
||||
@ -394,6 +394,24 @@
|
||||
// odd byte with byte access
|
||||
#endif
|
||||
|
||||
//------- Microchip SAMX7X -------//
|
||||
// DMA mode for device
|
||||
#ifndef CFG_TUD_SAMX7X_DMA_ENABLE
|
||||
#ifndef CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT
|
||||
#define CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT 0
|
||||
#endif
|
||||
|
||||
#define CFG_TUD_SAMX7X_DMA_ENABLE CFG_TUD_SAMX7X_DMA_ENABLE_DEFAULT
|
||||
#endif
|
||||
|
||||
#if (CFG_TUSB_MCU == OPT_MCU_SAMX7X)
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4
|
||||
#define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS
|
||||
#define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS
|
||||
#define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// RootHub Mode detection
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user