Selaa lähdekoodia

Fixed a timing issue with PIO mode

Timer mode doesn't work yet. Corrected the transfer count from the
gd32_sdio_sdcard.cpp file.

The change was:
uint32_t complete = totalnumber_bytes - DMA_CHCNT(DMA1, DMA_CH3) * 4;
to
uint32_t complete = (0xffff - dma_transfer_number_get(DMA1, DMA_CH3)) * 4;

This is because the GD32F450 sets the DMA_CHCNT to 0xFFFF once the
DMA is enabled. Where as the GD32F205 sets the count to how many
transfer are left.
Morio 2 vuotta sitten
vanhempi
sitoutus
bbee4fd527

+ 2 - 1
lib/ZuluSCSI_platform_GD32F205/ZuluSCSI_platform.cpp

@@ -127,7 +127,8 @@ void platform_init()
     if (TPI->ACPR == 0)
     {
         CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
-        TPI->ACPR = SystemCoreClock / 2000000 - 1; // 2 Mbps baudrate for SWO
+        TPI->ACPR = SystemCoreClock / 115200 - 1; // COM port baudrate for SWO
+        // TPI->ACPR = SystemCoreClock / 2000000 - 1; // 2 Mbps baudrate for SWO
         // TPI->ACPR = SystemCoreClock / 30000000 - 1; // 30 Mbps baudrate for SWO
         TPI->SPPR = 2;
         TPI->FFCR = 0x100; // TPIU packet framing disabled

+ 3 - 2
lib/ZuluSCSI_platform_GD32F450/ZuluSCSI_platform.cpp

@@ -123,10 +123,11 @@ void azplatform_init()
 
     // Enable debug output on SWO pin
     DBG_CTL0 |= DBG_CTL0_TRACE_IOEN;
-    if (TPI->ACPR == 0)
+    // if (TPI->ACPR == 0)
     {
         CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
-        TPI->ACPR = SystemCoreClock / 2000000 - 1; // 2 Mbps baudrate for SWO
+        TPI->ACPR = SystemCoreClock / 115200 - 1; // Serial speed baudrate for SWO
+        // TPI->ACPR = SystemCoreClock / 2000000 - 1; // 2 Mbps baudrate for SWO
         // TPI->ACPR = SystemCoreClock / 30000000 - 1; // 30 Mbps baudrate for SWO
         TPI->SPPR = 2;
         TPI->FFCR = 0x100; // TPIU packet framing disabled

+ 1 - 1
lib/ZuluSCSI_platform_GD32F450/ZuluSCSI_platform.h

@@ -48,7 +48,7 @@ static inline void delay_us(unsigned long us)
 static inline void delay_100ns()
 {
 //    asm volatile ("nop \n nop \n nop \n nop \n nop");
-   asm volatile ("nop \n nop \n nop \n nop \n nop \n nop");
+   asm volatile ("nop \n nop \n nop \n nop \n nop");
 }
 
 // Initialize SPI and GPIO configuration

+ 3 - 2
lib/ZuluSCSI_platform_GD32F450/ZuluSCSI_v1_4_gpio.h

@@ -89,8 +89,9 @@
 #define SCSI_OUT_REQ_EXMC_NOE_PIN   GPIO_PIN_4
 #define SCSI_OUT_REQ_EXMC_NOE_IDX   4
 #define SCSI_EXMC_DATA_SHIFT 5
-#define SCSI_EXMC_DMA DMA0
-#define SCSI_EXMC_DMA_RCU RCU_DMA0
+// DMA1 is the only controller that allows memory to memory transfers
+#define SCSI_EXMC_DMA DMA1  
+#define SCSI_EXMC_DMA_RCU RCU_DMA1
 #define SCSI_EXMC_DMACH DMA_CH0
 #define SCSI_SYNC_TIMER TIMER1
 #define SCSI_SYNC_TIMER_RCU RCU_TIMER1

+ 5 - 6
lib/ZuluSCSI_platform_GD32F450/gd32_sdio_sdcard.c

@@ -708,13 +708,12 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint
                 if((uint32_t)(millis() - start) > 1000) {
                     return SD_ERROR;
                 }
-                /* @TODO - figure out how to fix the count or remove call back from this function
-                                if (callback)
+                if (callback)
                 {
-                    uint32_t complete = totalnumber_bytes - DMA_CHCNT(DMA1, DMA_CH3) * 4;
-                        callback(complete);
-               }
-               */
+                    uint32_t complete = (0xffff - dma_transfer_number_get(DMA1, DMA_CH3)) * 4;
+                    callback(complete);
+                }
+               
 
             }
             while((0 == transend) && (SD_OK == transerror)) {

+ 25 - 15
lib/ZuluSCSI_platform_GD32F450/scsi_accel_dma.cpp

@@ -48,20 +48,24 @@ void scsi_accel_timer_dma_init()
     // GPIO DMA copies data from memory buffer to GPIO BOP register.
     // The memory buffer is filled by interrupt routine.
 
-    dma_single_data_parameter_struct gpio_dma_config =
+    dma_multi_data_parameter_struct gpio_dma_config =
     {
         .periph_addr = (uint32_t)&GPIO_BOP(SCSI_OUT_PORT),
+        .periph_width = DMA_PERIPH_WIDTH_32BIT,
         .periph_inc = DMA_PERIPH_INCREASE_DISABLE,
         .memory0_addr = 0, // Filled before transfer
+        .memory_width = DMA_MEMORY_WIDTH_32BIT,
         .memory_inc = DMA_MEMORY_INCREASE_ENABLE,
-        .periph_memory_width = DMA_PERIPH_WIDTH_32BIT,
+        .memory_burst_width = DMA_MEMORY_BURST_SINGLE,
+        .periph_burst_width = DMA_PERIPH_BURST_SINGLE,
+        .critical_value = DMA_FIFO_1_WORD,
         .circular_mode = DMA_CIRCULAR_MODE_ENABLE,
         .direction = DMA_MEMORY_TO_PERIPH,
         .number = DMA_BUF_SIZE,
         .priority = DMA_PRIORITY_ULTRA_HIGH
     };
 
-    dma_single_data_mode_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, &gpio_dma_config);
+    dma_multi_data_mode_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, &gpio_dma_config);
     dma_channel_subperipheral_select(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, SCSI_TIMER_DMACHA_SUB_PERIPH);
     NVIC_SetPriority(SCSI_TIMER_DMACHA_IRQn, 1);
     NVIC_EnableIRQ(SCSI_TIMER_DMACHA_IRQn);
@@ -69,19 +73,24 @@ void scsi_accel_timer_dma_init()
     // DMA Channel B: timer update
     // Timer DMA causes update event to restart timer after
     // GPIO DMA operation is done.
-    dma_single_data_parameter_struct timer_dma_config =
+    dma_multi_data_parameter_struct timer_dma_config =
     {
         .periph_addr = (uint32_t)&TIMER_SWEVG(SCSI_TIMER),
+        .periph_width = DMA_PERIPH_WIDTH_32BIT,
         .periph_inc = DMA_PERIPH_INCREASE_DISABLE,
         .memory0_addr = (uint32_t)&g_scsi_dma.timer_buf,
+        .memory_width = DMA_MEMORY_WIDTH_32BIT,
         .memory_inc = DMA_PERIPH_INCREASE_DISABLE,
-        .periph_memory_width = DMA_PERIPH_WIDTH_32BIT,
+        .memory_burst_width = DMA_MEMORY_BURST_SINGLE,
+        .periph_burst_width = DMA_PERIPH_BURST_SINGLE,
+        .critical_value = DMA_FIFO_1_WORD,
         .circular_mode = DMA_CIRCULAR_MODE_DISABLE,
-        .direction = DMA_MEMORY_TO_PERIPH,
+        .direction = DMA_MEMORY_TO_MEMORY,
         .number = DMA_BUF_SIZE,
         .priority = DMA_PRIORITY_HIGH
+
     };
-    dma_single_data_mode_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, &timer_dma_config);
+    dma_multi_data_mode_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, &timer_dma_config);
     dma_channel_subperipheral_select(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, SCSI_TIMER_DMACHB_SUB_PERIPH);
     NVIC_SetPriority(SCSI_TIMER_DMACHB_IRQn, 2);
     NVIC_EnableIRQ(SCSI_TIMER_DMACHB_IRQn);
@@ -274,17 +283,18 @@ static void check_dma_next_buffer()
 // Convert new data from application buffer to DMA buffer
 extern "C" void SCSI_TIMER_DMACHA_IRQ()
 {
-    azdbg("DMA irq A, counts: ", dma_transfer_number_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA), " ",
-                dma_transfer_number_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ",
-                TIMER_CNT(SCSI_TIMER));
+    // azdbg("DMA irq A, counts: ", dma_transfer_number_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA), " ",
+    //             dma_transfer_number_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ",
+    //             TIMER_CNT(SCSI_TIMER));
 
-    uint32_t intf = DMA_INTF1(SCSI_TIMER_DMA);
+    uint32_t intf0 = DMA_INTF1(SCSI_TIMER_DMA);
+    uint32_t intf1 = DMA_INTF1(SCSI_TIMER_DMA);
 
     if (dma_interrupt_flag_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_FLAG_HTF))
     {
         if (dma_interrupt_flag_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_FLAG_FTF))
         {
-            azlog("ERROR: SCSI DMA overrun: ", intf,
+            azlog("ERROR: SCSI DMA overrun: ", intf0, intf1,
                " bytes_app: ", g_scsi_dma.bytes_app,
                " bytes_dma: ", g_scsi_dma.bytes_dma,
                " dma_idx: ", g_scsi_dma.dma_idx,
@@ -311,9 +321,9 @@ extern "C" void SCSI_TIMER_DMACHA_IRQ()
 // Check if enough data is available to continue DMA transfer
 extern "C" void SCSI_TIMER_DMACHB_IRQ()
 {
-    azdbg("DMA irq B, counts: ", dma_transfer_number_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA), " ",
-                 dma_transfer_number_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ",
-                 TIMER_CNT(SCSI_TIMER));
+    // azdbg("DMA irq B, counts: ", dma_transfer_number_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA), " ",
+    //              dma_transfer_number_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ",
+    //              TIMER_CNT(SCSI_TIMER));
     if (dma_interrupt_flag_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, DMA_FLAG_FTF))
     {
         dma_interrupt_flag_clear(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, DMA_FLAG_FTF);