فهرست منبع

PIO mode works

PIO mode works now with 512 block transfers.
Morio 2 سال پیش
والد
کامیت
0bb9f21f1a

+ 6 - 6
lib/ZuluSCSI_platform_GD32F450/ZuluSCSI_v1_4_gpio.h

@@ -34,12 +34,12 @@
 #define SCSI_TIMER_IN_PIN GPIO_PIN_6
 #define SCSI_TIMER_DMA DMA1
 #define SCSI_TIMER_DMA_RCU RCU_DMA1
-#define SCSI_TIMER_DMACHA DMA_CH4
-#define SCSI_TIMER_DMACHB DMA_CH1
-#define SCSI_TIMER_DMACHA_IRQ DMA1_Channel4_IRQHandler
-#define SCSI_TIMER_DMACHA_IRQn DMA1_Channel4_IRQn
-#define SCSI_TIMER_DMACHB_IRQ DMA1_Channel1_IRQHandler
-#define SCSI_TIMER_DMACHB_IRQn DMA1_Channel1_IRQn
+#define SCSI_TIMER_DMACHA DMA_CH7
+#define SCSI_TIMER_DMACHB DMA_CH3
+#define SCSI_TIMER_DMACHA_IRQ DMA1_Channel7_IRQHandler
+#define SCSI_TIMER_DMACHA_IRQn DMA1_Channel7_IRQn
+#define SCSI_TIMER_DMACHB_IRQ DMA1_Channel3_IRQHandler
+#define SCSI_TIMER_DMACHB_IRQn DMA1_Channel3_IRQn
 
 // SCSI input data port
 #define SCSI_IN_PORT  GPIOE

+ 9 - 7
lib/ZuluSCSI_platform_GD32F450/gd32_sdio_sdcard.c

@@ -622,7 +622,7 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint
         return status;
     }
 
-    if(blocksnumber > 1) {
+    if(blocksnumber >= 1) {
         if(blocksnumber * blocksize > SD_MAX_DATA_LENGTH) {
             /* exceeds the maximum length */
             status = SD_PARAMETER_INVALID;
@@ -703,17 +703,19 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint
             sdio_interrupt_enable(SDIO_INT_DTCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_RXORE | SDIO_INT_DTEND | SDIO_INT_STBITE);
             sdio_dma_enable();
             dma_receive_config(preadbuffer, totalnumber_bytes);
-
             uint32_t start = millis();
             while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) {
                 if((uint32_t)(millis() - start) > 1000) {
                     return SD_ERROR;
                 }
-                if (callback)
+                /* @TODO - figure out how to fix the count or remove call back from this function
+                                if (callback)
                 {
-                    uint32_t complete = (totalnumber_bytes - DMA_CHCNT(DMA1, DMA_CH3) * 4);
-                    callback(complete);
-                }
+                    uint32_t complete = totalnumber_bytes - DMA_CHCNT(DMA1, DMA_CH3) * 4;
+                        callback(complete);
+               }
+               */
+
             }
             while((0 == transend) && (SD_OK == transerror)) {
                 if (callback)
@@ -2507,7 +2509,7 @@ static void dma_receive_config(uint32_t *dstbuf, uint32_t bufsize)
     dma_struct.periph_addr = (uint32_t)SDIO_FIFO_ADDR;
     dma_struct.memory0_addr = (uint32_t)dstbuf;
     dma_struct.direction = DMA_PERIPH_TO_MEMORY;
-    dma_struct.number = 0;
+    dma_struct.number = bufsize/4;
     dma_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
     dma_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
     dma_struct.periph_width = DMA_PERIPH_WIDTH_32BIT;

+ 11 - 12
lib/ZuluSCSI_platform_GD32F450/scsiPhy.cpp

@@ -22,8 +22,6 @@ static enum {
     PHY_MODE_BEST_AVAILABLE = 0,
     PHY_MODE_PIO = 1,
     PHY_MODE_DMA_TIMER = 2,
-    PHY_MODE_GREENPAK_PIO = 3,
-    PHY_MODE_GREENPAK_DMA = 4
 } g_scsi_phy_mode;
 static const char *g_scsi_phy_mode_names[] = {
     "Unknown", "PIO", "DMA_TIMER" // removing greenpak , "GREENPAK_PIO", "GREENPAK_DMA"
@@ -296,7 +294,6 @@ extern "C" void scsiStartWrite(const uint8_t* data, uint32_t count)
     g_scsi_writereq.use_sync_mode = (g_scsi_phase == DATA_IN && scsiDev.target->syncOffset > 0);
 
     if (g_scsi_phy_mode == PHY_MODE_PIO
-        || g_scsi_phy_mode == PHY_MODE_GREENPAK_PIO
         || g_scsi_writereq.use_sync_mode)
     {
         // Software based bit-banging.
@@ -321,7 +318,7 @@ extern "C" void scsiStartWrite(const uint8_t* data, uint32_t count)
         g_scsi_writereq.data = data;
         g_scsi_writereq.count = count;
     }
-    else if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA)
+    else if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER)
     {
         // Accelerated writes using DMA and timers
         scsi_accel_dma_startWrite(data, count, &scsiDev.resetFlag);
@@ -413,14 +410,13 @@ extern "C" bool scsiIsWriteFinished(const uint8_t *data)
         return isPollingWriteFinished(data);
     }
     
-    if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA)
+    if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER)
     {
         return scsi_accel_dma_isWriteFinished(data);
     }
-    else
-    {
-        return true;
-    }
+    // @TODO this was attached as an else to g_scsi_phy_mode==PHY_MODE_DMA_TIMER, not sure if true should be returned as default
+    return true;
+    
 }
 
 extern "C" void scsiFinishWrite()
@@ -431,7 +427,7 @@ extern "C" void scsiFinishWrite()
         processPollingWrite(g_scsi_writereq.count);
     }
 
-    if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER || g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA)
+    if (g_scsi_phy_mode == PHY_MODE_DMA_TIMER)
     {
         scsi_accel_dma_finishWrite(&scsiDev.resetFlag);
     }
@@ -539,6 +535,9 @@ void SCSI_SEL_IRQ (void)
 
 static void init_irqs()
 {
+    // Enable SYSCFG clock to set EXTI lines
+    rcu_periph_clock_enable(RCU_SYSCFG);
+
     // Falling edge of RST pin
     gpio_mode_set(SCSI_RST_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_RST_PIN);
     syscfg_exti_line_config(SCSI_RST_EXTI_SOURCE_PORT, SCSI_RST_EXTI_SOURCE_PIN);
@@ -547,14 +546,14 @@ static void init_irqs()
     NVIC_EnableIRQ(SCSI_RST_IRQn);
 
     // Rising edge of BSY pin
-    gpio_mode_set(SCSI_BSY_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_BSY_PIN);
+    //gpio_mode_set(SCSI_BSY_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_BSY_PIN);
     syscfg_exti_line_config(SCSI_BSY_EXTI_SOURCE_PORT, SCSI_BSY_EXTI_SOURCE_PIN);
     exti_init(SCSI_BSY_EXTI, EXTI_INTERRUPT, EXTI_TRIG_RISING);
     NVIC_SetPriority(SCSI_BSY_IRQn, 1);
     NVIC_EnableIRQ(SCSI_BSY_IRQn);
 
     // Falling edge of SEL pin
-    gpio_mode_set(SCSI_SEL_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_SEL_PIN);
+    // gpio_mode_set(SCSI_SEL_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_SEL_PIN);
     syscfg_exti_line_config(SCSI_SEL_EXTI_SOURCE_PORT, SCSI_SEL_EXTI_SOURCE_PIN);
     exti_init(SCSI_SEL_EXTI, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
     NVIC_SetPriority(SCSI_SEL_IRQn, 1);

+ 42 - 27
lib/ZuluSCSI_platform_GD32F450/scsi_accel_dma.cpp

@@ -62,7 +62,6 @@ void scsi_accel_timer_dma_init()
     };
 
     dma_single_data_mode_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, &gpio_dma_config);
-    dma_circulation_enable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA);
     NVIC_SetPriority(SCSI_TIMER_DMACHA_IRQn, 1);
     NVIC_EnableIRQ(SCSI_TIMER_DMACHA_IRQn);
 
@@ -123,7 +122,7 @@ static void scsi_dma_gpio_config(bool enable)
         // @TODO determine if the output should be set to 200MHZ instead of 50MHZ
         gpio_output_options_set(SCSI_TIMER_OUT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_TIMER_OUT_PIN);
         // @TODO find if TIMER2_CH3 (AF2) is the correct AF
-        gpio_af_set(SCSI_TIMER_OUT_PORT, GPIO_AF_2, SCSI_TIMER_OUT_PIN);
+        gpio_af_set(SCSI_TIMER_OUT_PORT, GPIO_AF_3, SCSI_TIMER_OUT_PIN);
 
     }
     else
@@ -131,6 +130,7 @@ static void scsi_dma_gpio_config(bool enable)
         // @ DELETE this line shouldn't be needed?
         // GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO2;
         gpio_mode_set(SCSI_TIMER_OUT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_TIMER_OUT_PIN);
+
         gpio_output_options_set(SCSI_OUT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_REQ);
         gpio_mode_set(SCSI_OUT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_OUT_REQ);
         
@@ -203,14 +203,20 @@ static void start_dma()
     TIMER_DMAINTEN(SCSI_TIMER) = TIMER_DMAINTEN_CH1DEN | TIMER_DMAINTEN_CH3DEN;
 
     // Clear and enable interrupt
-    DMA_INTC1(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_FEE, SCSI_TIMER_DMACHA);
-    DMA_INTC0(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_FEE, SCSI_TIMER_DMACHB);
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE;
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_FTFIE;
+    dma_interrupt_flag_clear(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_FEE);
+    // DMA_INTC1(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_FEE, SCSI_TIMER_DMACHA);
+    dma_interrupt_flag_clear(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_FEE);
+    // DMA_INTC0(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_FEE, SCSI_TIMER_DMACHB);
+    dma_interrupt_enable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE);
+    // DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE;
+    dma_interrupt_enable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, DMA_CHXCTL_FTFIE);
+    // DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_FTFIE;
 
     // Enable channels
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_CHEN;
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_CHEN;
+    dma_channel_enable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA);
+    //DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_CHEN;
+    dma_channel_enable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB);
+    //DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_CHEN;
 
     // Make sure REQ is initially high
     TIMER_CNT(SCSI_TIMER) = 16;
@@ -218,7 +224,8 @@ static void start_dma()
     TIMER_CHCTL1(SCSI_TIMER) = 0x6074;
 
     // Enable timer
-    TIMER_CTL0(SCSI_TIMER) |= TIMER_CTL0_CEN;
+    timer_enable(SCSI_TIMER);
+    //TIMER_CTL0(SCSI_TIMER) |= TIMER_CTL0_CEN;
 
     // Generate first events
     TIMER_SWEVG(SCSI_TIMER) = TIMER_SWEVG_CH1G;
@@ -228,11 +235,16 @@ static void start_dma()
 // Stop DMA transfer
 static void stop_dma()
 {
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~DMA_CHXCTL_CHEN;
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN;
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~(DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE);
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_FTFIE;
-    TIMER_CTL0(SCSI_TIMER) &= ~TIMER_CTL0_CEN;
+    dma_channel_disable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA);
+    // DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~DMA_CHXCTL_CHEN;
+    dma_channel_disable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB);
+    // DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN;
+    dma_interrupt_disable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE);
+    // DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~(DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE);
+    dma_interrupt_disable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, DMA_CHXCTL_FTFIE);
+    //DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_FTFIE;
+    timer_disable(SCSI_TIMER);
+    //TIMER_CTL0(SCSI_TIMER) &= ~TIMER_CTL0_CEN;
     g_scsi_dma_state = SCSIDMA_IDLE;
     SCSI_RELEASE_DATA_REQ();
 }
@@ -262,11 +274,10 @@ extern "C" void SCSI_TIMER_DMACHA_IRQ()
     //             TIMER_CNT(SCSI_TIMER));
 
     uint32_t intf = DMA_INTF1(SCSI_TIMER_DMA);
-    const uint32_t half_flag = DMA_FLAG_ADD(DMA_FLAG_HTF, SCSI_TIMER_DMACHA);
-    const uint32_t full_flag = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHA);
-    if (intf & half_flag)
+
+    if (dma_interrupt_flag_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_FLAG_HTF))
     {
-        if (intf & full_flag)
+        if (dma_interrupt_flag_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_FLAG_FTF))
         {
             azlog("ERROR: SCSI DMA overrun: ", intf,
                " bytes_app: ", g_scsi_dma.bytes_app,
@@ -277,12 +288,12 @@ extern "C" void SCSI_TIMER_DMACHA_IRQ()
             return;
         }
 
-        DMA_INTC1(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF, SCSI_TIMER_DMACHA);
+        dma_interrupt_flag_clear(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_FLAG_HTF);
         g_scsi_dma.dma_fillto += DMA_BUF_SIZE / 2;
     }
-    else if (intf & full_flag)
+    else if (dma_interrupt_flag_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_FLAG_FTF))
     {
-        DMA_INTC1(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHA);
+        dma_interrupt_flag_clear(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, DMA_FLAG_FTF);
         g_scsi_dma.dma_fillto += DMA_BUF_SIZE / 2;
     }
 
@@ -292,16 +303,17 @@ extern "C" void SCSI_TIMER_DMACHA_IRQ()
     check_dma_next_buffer();
 }
 
+// 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);
 // Check if enough data is available to continue DMA transfer
 extern "C" void SCSI_TIMER_DMACHB_IRQ()
 {
     // azdbg("DMA irq B, counts: ", DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA), " ",
     //             DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ",
     //             TIMER_CNT(SCSI_TIMER));
-    uint32_t intf = DMA_INTF0(SCSI_TIMER_DMA);
-    if (intf & DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHB))
+    if (dma_interrupt_flag_get(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, DMA_FLAG_FTF))
     {
-        DMA_INTC0(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHB);
+        dma_interrupt_flag_clear(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, DMA_FLAG_FTF);
 
         if (g_scsi_dma.bytes_app > g_scsi_dma.scheduled_dma)
         {
@@ -325,9 +337,12 @@ extern "C" void SCSI_TIMER_DMACHB_IRQ()
 
             // Update the total number of bytes available for DMA
             uint32_t dma_to_schedule = g_scsi_dma.bytes_app - g_scsi_dma.scheduled_dma;
-            DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN;
-            DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) = dma_to_schedule;
-            DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_CHEN;
+            dma_channel_disable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB);
+            // DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN;
+            dma_transfer_number_config(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, dma_to_schedule);
+            // DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) = dma_to_schedule;
+            dma_channel_enable(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB);
+            // DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) |= DMA_CHXCTL_CHEN;
             g_scsi_dma.scheduled_dma += dma_to_schedule;
         }
         else

+ 8 - 4
lib/ZuluSCSI_platform_GD32F450/scsi_accel_sync.cpp

@@ -75,19 +75,23 @@ void scsi_accel_sync_init()
     // DMA used to transfer data from EXMC to RAM
     // DMA is used so that if data transfer fails, we can at least abort by resetting CPU.
     // Accessing EXMC from the CPU directly hangs it totally if ACK pulses are not received.
-    dma_single_data_parameter_struct exmc_dma_config =
+    dma_multi_data_parameter_struct exmc_dma_config =
     {
         .periph_addr = EXMC_NOR_PSRAM,
+        .periph_width = DMA_PERIPH_WIDTH_16BIT,
         .periph_inc = DMA_PERIPH_INCREASE_DISABLE,
         .memory0_addr = (uint32_t)g_sync_dma_buf,
+        .memory_width = DMA_PERIPH_WIDTH_16BIT,
         .memory_inc = DMA_MEMORY_INCREASE_ENABLE,
-        .periph_memory_width = DMA_PERIPH_WIDTH_16BIT,
+        .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_PERIPH_TO_MEMORY,
+        .direction = DMA_MEMORY_TO_MEMORY,
         .number = 0, // Filled before transfer
         .priority = DMA_PRIORITY_MEDIUM
     };
-    dma_single_data_mode_init(SCSI_EXMC_DMA, SCSI_EXMC_DMACH, &exmc_dma_config);
+    dma_multi_data_mode_init(SCSI_EXMC_DMA, SCSI_EXMC_DMACH, &exmc_dma_config);
     // @TODO - figure out how to implement memory to memory DMA transfer
     // dma_memory_to_memory_enable(SCSI_EXMC_DMA, SCSI_EXMC_DMACH);