فهرست منبع

Rewrite GPIO pin inits

Most of the work was spent rewriting GPIO pin inits and getting
rid of Greenpak code. Some work was done on the sdio sdcard code
but more work needs to be done before the project compiles.

It was found that updating the flash code will not work because
page erases are not support with the current chip. Switching to
sector erasures will most likely fix the issue.
Morio 3 سال پیش
والد
کامیت
7eb4105bdf

+ 64 - 30
lib/ZuluSCSI_platform_GD32F450/ZuluSCSI_platform.cpp

@@ -150,31 +150,42 @@ void azplatform_init()
     rcu_periph_clock_enable(RCU_GPIOD);
     rcu_periph_clock_enable(RCU_GPIOE);
     
-    // Switch to SWD debug port (disable JTAG) to release PB4 as GPIO
-    gpio_af_set(GPIOB, GPIO)
-    gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);    
-
     // SCSI pins.
     // Initialize open drain outputs to high.
     SCSI_RELEASE_OUTPUTS();
-    gpio_init(SCSI_OUT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_DATA_MASK | SCSI_OUT_REQ);
-    gpio_init(SCSI_OUT_IO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_IO_PIN);
-    gpio_init(SCSI_OUT_CD_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_CD_PIN);
-    gpio_init(SCSI_OUT_SEL_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_SEL_PIN);
-    gpio_init(SCSI_OUT_MSG_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_MSG_PIN);
-    gpio_init(SCSI_OUT_RST_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_RST_PIN);
-    gpio_init(SCSI_OUT_BSY_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_BSY_PIN);
-
-    gpio_init(SCSI_IN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_IN_MASK);
-    gpio_init(SCSI_ATN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_ATN_PIN);
-    gpio_init(SCSI_BSY_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_BSY_PIN);
-    gpio_init(SCSI_SEL_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_SEL_PIN);
-    gpio_init(SCSI_ACK_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_ACK_PIN);
-    gpio_init(SCSI_RST_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_RST_PIN);
+    // @TODO Check if the output speed should be set to 200MHZ
+    gpio_mode_set(SCSI_OUT_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_OUT_DATA_MASK | SCSI_OUT_REQ);
+    gpio_output_options_set(SCSI_OUT_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_DATA_MASK | SCSI_OUT_REQ);
+
+    gpio_mode_set(SCSI_OUT_IO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_OUT_IO_PIN);
+    gpio_output_options_set(SCSI_OUT_IO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_IO_PIN);
+
+    gpio_mode_set(SCSI_OUT_CD_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_OUT_CD_PIN);
+    gpio_output_options_set(SCSI_OUT_CD_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_CD_PIN);
+
+    gpio_mode_set(SCSI_OUT_SEL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_OUT_SEL_PIN);
+    gpio_output_options_set(SCSI_OUT_SEL_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_SEL_PIN);
+
+    gpio_mode_set(SCSI_OUT_MSG_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_OUT_MSG_PIN);
+    gpio_output_options_set(SCSI_OUT_MSG_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_MSG_PIN);
+
+    gpio_mode_set(SCSI_OUT_RST_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_OUT_RST_PIN);
+    gpio_output_options_set(SCSI_OUT_RST_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_RST_PIN);
+
+    gpio_mode_set(SCSI_OUT_BSY_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_OUT_BSY_PIN);
+    gpio_output_options_set(SCSI_OUT_BSY_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_BSY_PIN);
+
+    gpio_mode_set(SCSI_IN_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_IN_MASK);
+    gpio_mode_set(SCSI_ATN_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_ATN_PIN);
+    gpio_mode_set(SCSI_BSY_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_BSY_PIN);
+    gpio_mode_set(SCSI_SEL_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_SEL_PIN);
+    gpio_mode_set(SCSI_ACK_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_ACK_PIN);
+    gpio_mode_set(SCSI_RST_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_RST_PIN);
 
     // Terminator enable
     gpio_bit_set(SCSI_TERM_EN_PORT, SCSI_TERM_EN_PIN);
-    gpio_init(SCSI_TERM_EN_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, SCSI_TERM_EN_PIN);
+    gpio_mode_set(SCSI_TERM_EN_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SCSI_TERM_EN_PIN);
+    gpio_output_options_set(SCSI_TERM_EN_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, SCSI_TERM_EN_PIN);
 
 #ifndef SD_USE_SDIO
     // SD card pins using SPI
@@ -184,20 +195,38 @@ void azplatform_init()
     gpio_init(SD_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_MOSI_PIN);
 #else
     // SD card pins using SDIO
-    gpio_init(SD_SDIO_DATA_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_SDIO_D0 | SD_SDIO_D1 | SD_SDIO_D2 | SD_SDIO_D3);
-    gpio_init(SD_SDIO_CLK_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_SDIO_CLK);
-    gpio_init(SD_SDIO_CMD_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SD_SDIO_CMD);
+    gpio_mode_set(SD_SDIO_DATA_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, SD_SDIO_D0 | SD_SDIO_D1 | SD_SDIO_D2 | SD_SDIO_D3);
+    gpio_output_options_set(SD_SDIO_DATA_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SD_SDIO_D0 | SD_SDIO_D1 | SD_SDIO_D2 | SD_SDIO_D3);
+    gpio_af_set(SD_SDIO_DATA_PORT, GPIO_AF_12, SD_SDIO_D0 | SD_SDIO_D1 | SD_SDIO_D2 | SD_SDIO_D3);
+
+    gpio_mode_set(SD_SDIO_CLK_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, SD_SDIO_CLK);
+    gpio_output_options_set(SD_SDIO_CLK_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SD_SDIO_CLK);
+    gpio_af_set(SD_SDIO_CLK_PORT, GPIO_AF_12, SD_SDIO_CLK);
+
+    gpio_mode_set(SD_SDIO_CMD_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, SD_SDIO_CMD);
+    gpio_output_options_set(SD_SDIO_CMD_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SD_SDIO_CMD);
+    gpio_af_set(SD_SDIO_CMD_PORT, GPIO_AF_12, SD_SDIO_CMD);
+
 #endif
 
+    // @TODO confirm dip switch 1 is not longer JTAG NJTRST
+    // Switch to SWD debug port (disable JTAG) to release PB4 as GPIO
+    //gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);   
+
     // DIP switches
-    gpio_init(DIP_PORT, GPIO_MODE_IPD, 0, DIPSW1_PIN | DIPSW2_PIN | DIPSW3_PIN);
+    gpio_mode_set(DIP_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, DIPSW1_PIN | DIPSW2_PIN | DIPSW3_PIN);
+
 
     // LED pins
     gpio_bit_set(LED_PORT, LED_PINS);
-    gpio_init(LED_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, LED_PINS);
-
+    gpio_mode_set(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_PINS);
+    gpio_output_options_set(LED_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED_PINS);
+ 
     // SWO trace pin on PB3
-    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
+    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_3);
+    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
+    gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_3);   
+
 }
 
 void azplatform_late_init()
@@ -227,8 +256,6 @@ void azplatform_late_init()
         azlog("DIPSW1 is ON: enabling Apple quirks by default");
         g_enable_apple_quirks = true;
     }
-
-    greenpak_load_firmware();
 }
 
 /*****************************************/
@@ -405,6 +432,10 @@ void azplatform_reset_watchdog()
 
 bool azplatform_rewrite_flash_page(uint32_t offset, uint8_t buffer[AZPLATFORM_FLASH_PAGE_SIZE])
 {
+    // @TODO rewrite this function for sector erases as page erases aren't available
+    azlog("Flash rewrite not implemented for the GD32F4xx yet.");
+    return false;
+
     if (offset == 0)
     {
         if (buffer[3] != 0x20 || buffer[7] != 0x08)
@@ -419,10 +450,13 @@ bool azplatform_rewrite_flash_page(uint32_t offset, uint8_t buffer[AZPLATFORM_FL
     assert(offset >= AZPLATFORM_BOOTLOADER_SIZE);
     
     fmc_unlock();
-    fmc_bank0_unlock();
+    // @TODO make sure this is no longer needed
+    // fmc_bank0_unlock();
+
 
     fmc_state_enum status;
-    status = fmc_page_erase(FLASH_BASE + offset);
+    // @TODO - rewrite this to do sector errases as page erase is not available for the gd32f450
+    // status = fmc_page_erase(FLASH_BASE + offset);
     if (status != FMC_READY)
     {
         azlog("Erase failed: ", (int)status);

+ 6 - 6
lib/ZuluSCSI_platform_GD32F450/ZuluSCSI_v1_4_gpio.h

@@ -95,8 +95,8 @@
 #define SCSI_SEL_PORT GPIOB
 #define SCSI_SEL_PIN  GPIO_PIN_11
 #define SCSI_SEL_EXTI EXTI_11
-#define SCSI_SEL_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB
-#define SCSI_SEL_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_11
+#define SCSI_SEL_EXTI_SOURCE_PORT EXTI_SOURCE_GPIOB
+#define SCSI_SEL_EXTI_SOURCE_PIN EXTI_SOURCE_PIN11
 #define SCSI_SEL_IRQ EXTI10_15_IRQHandler
 #define SCSI_SEL_IRQn EXTI10_15_IRQn
 
@@ -104,8 +104,8 @@
 #define SCSI_BSY_PORT GPIOB
 #define SCSI_BSY_PIN  GPIO_PIN_10
 #define SCSI_BSY_EXTI EXTI_10
-#define SCSI_BSY_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB
-#define SCSI_BSY_EXTI_SOURCE_PIN  GPIO_PIN_SOURCE_10
+#define SCSI_BSY_EXTI_SOURCE_PORT EXTI_SOURCE_GPIOB
+#define SCSI_BSY_EXTI_SOURCE_PIN  EXTI_SOURCE_PIN10
 #define SCSI_BSY_IRQ  EXTI10_15_IRQHandler
 #define SCSI_BSY_IRQn EXTI10_15_IRQn
 
@@ -113,8 +113,8 @@
 #define SCSI_RST_PORT GPIOB
 #define SCSI_RST_PIN  GPIO_PIN_13
 #define SCSI_RST_EXTI EXTI_13
-#define SCSI_RST_EXTI_SOURCE_PORT GPIO_PORT_SOURCE_GPIOB
-#define SCSI_RST_EXTI_SOURCE_PIN GPIO_PIN_SOURCE_13
+#define SCSI_RST_EXTI_SOURCE_PORT EXTI_SOURCE_GPIOB
+#define SCSI_RST_EXTI_SOURCE_PIN EXTI_SOURCE_PIN13
 #define SCSI_RST_IRQ  EXTI10_15_IRQHandler
 #define SCSI_RST_IRQn EXTI10_15_IRQn
 

+ 24 - 0
lib/ZuluSCSI_platform_GD32F450/gd32_sdio_sdcard.c

@@ -1628,6 +1628,13 @@ uint32_t sd_card_capacity_get(void)
     return capacity;
 }
 
+sd_error_enum sd_card_information_get_short(sdio_card_type_enum *card_type, uint16_t *card_rca)
+{
+    *card_type = cardtype;
+    *card_rca = sd_rca;
+    return SD_OK;
+}
+
 /*!
     \brief      get the detailed information of the SD card based on received CID and CSD
     \param[in]  none
@@ -1826,6 +1833,23 @@ sd_error_enum sd_card_information_get(sd_card_info_struct *pcardinfo)
     return status;
 }
 
+void sd_cid_get(uint8_t *cid)
+{
+    // SdFat expects the data in big endian format.
+    for (int i = 0; i < 16; i++)
+    {
+        cid[i] = (sd_cid[i / 4] >> (24 - (i % 4) * 8)) & 0xFF;
+    }
+}
+
+void sd_csd_get(uint8_t *csd)
+{
+    for (int i = 0; i < 16; i++)
+    {
+        csd[i] = (sd_csd[i / 4] >> (24 - (i % 4) * 8)) & 0xFF;
+    }
+}
+
 /*!
     \brief      check if the command sent error occurs
     \param[in]  none

+ 6 - 0
lib/ZuluSCSI_platform_GD32F450/gd32_sdio_sdcard.h

@@ -222,6 +222,7 @@ sd_error_enum sd_bus_mode_config(uint32_t busmode);
 /* configure the mode of transmission */
 sd_error_enum sd_transfer_mode_config(uint32_t txmode);
 
+typedef void (*sdio_callback_t)(uint32_t bytes_done);
 /* read a block data into a buffer from the specified address of a card */
 sd_error_enum sd_block_read(uint32_t *preadbuffer, uint32_t readaddr, uint16_t blocksize);
 /* read multiple blocks data into a buffer from the specified address of a card */
@@ -252,5 +253,10 @@ sd_transfer_state_enum sd_transfer_state_get(void);
 uint32_t sd_card_capacity_get(void);
 /* get the detailed information of the SD card based on received CID and CSD */
 sd_error_enum sd_card_information_get(sd_card_info_struct *pcardinfo);
+sd_error_enum sd_card_information_get_short(sdio_card_type_enum *card_type, uint16_t *card_rca);
+
+/* Get card information in raw format */
+void sd_cid_get(uint8_t *cid);
+void sd_csd_get(uint8_t *csd);
 
 #endif /* SDCARD_H */

+ 8 - 42
lib/ZuluSCSI_platform_GD32F450/scsiPhy.cpp

@@ -141,26 +141,6 @@ static void selectPhyMode()
     }
 #endif
 
-    // GreenPAK with software write, available on V1.1 with extra chip, 3.5 MB/s
-    if (wanted_mode == PHY_MODE_BEST_AVAILABLE || wanted_mode == PHY_MODE_GREENPAK_PIO)
-    {
-        if (greenpak_is_ready())
-        {
-            g_scsi_phy_mode = PHY_MODE_GREENPAK_PIO;
-        }
-    }
-
-    // GreenPAK with DMA write, available on V1.1 with extra chip
-#ifdef SCSI_ACCEL_DMA_AVAILABLE
-    if (wanted_mode == PHY_MODE_BEST_AVAILABLE || wanted_mode == PHY_MODE_GREENPAK_DMA)
-    {
-        if (greenpak_is_ready())
-        {
-            g_scsi_phy_mode = PHY_MODE_GREENPAK_DMA;
-        }
-    }
-#endif
-
     if (g_scsi_phy_mode != oldmode)
     {
         azlog("SCSI PHY operating mode: ", g_scsi_phy_mode_names[g_scsi_phy_mode]);
@@ -187,10 +167,6 @@ extern "C" void scsiPhyReset(void)
     {
         scsi_accel_timer_dma_init();
     }
-    else if (g_scsi_phy_mode == PHY_MODE_GREENPAK_DMA)
-    {
-        scsi_accel_greenpak_dma_init();
-    }
 }
 
 /************************/
@@ -371,16 +347,8 @@ static void processPollingWrite(uint32_t count)
     }
     else if (count_words * 4 == count)
     {
-        if (g_scsi_phy_mode == PHY_MODE_GREENPAK_PIO)
-        {
-            // GreenPAK PIO accelerated asynchronous transfer
-            scsi_accel_greenpak_send((const uint32_t*)data, count_words, &scsiDev.resetFlag);
-        }
-        else
-        {
-            // Assembler optimized asynchronous transfer
-            scsi_accel_asm_send((const uint32_t*)data, count_words, &scsiDev.resetFlag);
-        }
+        // Assembler optimized asynchronous transfer
+        scsi_accel_asm_send((const uint32_t*)data, count_words, &scsiDev.resetFlag);
     }
     else
     {
@@ -506,11 +474,6 @@ extern "C" void scsiRead(uint8_t* data, uint32_t count, int* parityError)
         // Synchronous data transfer
         scsi_accel_sync_recv(data, count, parityError, &scsiDev.resetFlag);
     }
-    else if (count_words * 4 == count && count_words >= 2 && use_greenpak)
-    {
-        // GreenPAK accelerated receive can handle a multiple of 4 bytes with minimum of 8 bytes.
-        scsi_accel_greenpak_recv((uint32_t*)data, count_words, &scsiDev.resetFlag);
-    }
     else if (count_words * 4 == count && count_words >= 1)
     {
         // Optimized ASM subroutine can handle multiple of 4 bytes with minimum of 4 bytes.
@@ -578,19 +541,22 @@ void SCSI_SEL_IRQ (void)
 static void init_irqs()
 {
     // Falling edge of RST pin
-    gpio_exti_source_select(SCSI_RST_EXTI_SOURCE_PORT, SCSI_RST_EXTI_SOURCE_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);
     exti_init(SCSI_RST_EXTI, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
     NVIC_SetPriority(SCSI_RST_IRQn, 1);
     NVIC_EnableIRQ(SCSI_RST_IRQn);
 
     // Rising edge of BSY pin
-    gpio_exti_source_select(SCSI_BSY_EXTI_SOURCE_PORT, SCSI_BSY_EXTI_SOURCE_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_exti_source_select(SCSI_SEL_EXTI_SOURCE_PORT, SCSI_SEL_EXTI_SOURCE_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);
     NVIC_EnableIRQ(SCSI_SEL_IRQn);

+ 41 - 245
lib/ZuluSCSI_platform_GD32F450/scsi_accel_dma.cpp

@@ -17,11 +17,6 @@ bool scsi_accel_dma_isWriteFinished(const uint8_t* data) { return true; }
 
 #else
 
-static void greenpak_refill_dmabuf();
-static void greenpak_start_dma();
-static void greenpak_stop_dma();
-
-enum greenpak_state_t { GREENPAK_IO1_LOW = 0, GREENPAK_IO1_HIGH, GREENPAK_STOP};
 
 #define DMA_BUF_SIZE 256
 #define DMA_BUF_MASK (DMA_BUF_SIZE - 1)
@@ -34,7 +29,6 @@ static struct {
     uint32_t bytes_app; // Bytes available in application buffer
     uint32_t bytes_dma; // Bytes (words) written so far to DMA buffer
     uint32_t scheduled_dma; // Bytes (words) that DMA data count was last set to
-    greenpak_state_t greenpak_state; // Toggle signal state for greenpak
 
     uint8_t *next_app_buf; // Next buffer from application after current one finishes
     uint32_t next_app_bytes; // Bytes in next buffer
@@ -42,31 +36,32 @@ static struct {
 
 enum scsidma_state_t { SCSIDMA_IDLE = 0, SCSIDMA_WRITE };
 static volatile scsidma_state_t g_scsi_dma_state;
-static bool g_scsi_dma_use_greenpak;
 
 void scsi_accel_timer_dma_init()
 {
     g_scsi_dma_state = SCSIDMA_IDLE;
-    g_scsi_dma_use_greenpak = false;
     rcu_periph_clock_enable(SCSI_TIMER_RCU);
     rcu_periph_clock_enable(SCSI_TIMER_DMA_RCU);
 
     // DMA Channel A: data copy
     // 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 =
     {
         .periph_addr = (uint32_t)&GPIO_BOP(SCSI_OUT_PORT),
-        .periph_memory_width = DMA_PERIPH_WIDTH_32BIT,
-        .memory0_addr = 0, // Filled before transfer
-        .number = DMA_BUF_SIZE,
-        .priority = DMA_PRIORITY_ULTRA_HIGH,
         .periph_inc = DMA_PERIPH_INCREASE_DISABLE,
+        .memory0_addr = 0, // Filled before transfer
         .memory_inc = DMA_MEMORY_INCREASE_ENABLE,
+        .periph_memory_width = DMA_PERIPH_WIDTH_32BIT,
+        // @TODO Check if circular mode is needed or not
+        .circular_mode = DMA_CIRCULAR_MODE_ENABLE,
         .direction = DMA_MEMORY_TO_PERIPH,
-        .circular_mode = DMA_CIRCULAR_MODE_DISABLE
+        .number = DMA_BUF_SIZE,
+        .priority = DMA_PRIORITY_ULTRA_HIGH
     };
-    dma_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA, &gpio_dma_config);
+
+    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);
@@ -74,19 +69,19 @@ 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_parameter_struct timer_dma_config =
+    dma_single_data_parameter_struct timer_dma_config =
     {
         .periph_addr = (uint32_t)&TIMER_SWEVG(SCSI_TIMER),
-        .periph_width = DMA_PERIPHERAL_WIDTH_32BIT,
-        .memory_addr = (uint32_t)&g_scsi_dma.timer_buf,
-        .memory_width = DMA_MEMORY_WIDTH_32BIT,
-        .number = DMA_BUF_SIZE,
-        .priority = DMA_PRIORITY_HIGH,
         .periph_inc = DMA_PERIPH_INCREASE_DISABLE,
+        .memory0_addr = (uint32_t)&g_scsi_dma.timer_buf,
         .memory_inc = DMA_PERIPH_INCREASE_DISABLE,
-        .direction = DMA_MEMORY_TO_PERIPHERAL
+        .periph_memory_width = DMA_PERIPH_WIDTH_32BIT,
+        .circular_mode = DMA_CIRCULAR_MODE_DISABLE,
+        .direction = DMA_MEMORY_TO_PERIPH,
+        .number = DMA_BUF_SIZE,
+        .priority = DMA_PRIORITY_HIGH
     };
-    dma_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, &timer_dma_config);
+    dma_single_data_mode_init(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB, &timer_dma_config);
     NVIC_SetPriority(SCSI_TIMER_DMACHB_IRQn, 2);
     NVIC_EnableIRQ(SCSI_TIMER_DMACHB_IRQn);
 
@@ -111,8 +106,9 @@ void scsi_accel_timer_dma_init()
     TIMER_CH1CV(SCSI_TIMER) = 1; // Copy data when ACK goes low
     TIMER_CH2CV(SCSI_TIMER) = 1; // REQ is low until ACK goes low
     TIMER_CH3CV(SCSI_TIMER) = 2; // Reset timer after ACK goes high & previous DMA is complete
-    gpio_init(SCSI_TIMER_IN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_TIMER_IN_PIN);
 
+    gpio_mode_set(SCSI_TIMER_IN_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, SCSI_TIMER_IN_PIN);
+    gpio_af_set(SCSI_TIMER_IN_PORT, GPIO_AF_3, SCSI_TIMER_IN_PIN);    
     scsi_accel_dma_stopWrite();
 }
 
@@ -121,35 +117,29 @@ static void scsi_dma_gpio_config(bool enable)
 {
     if (enable)
     {
-        gpio_init(SCSI_OUT_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, SCSI_OUT_REQ);
+        gpio_mode_set(SCSI_OUT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, SCSI_OUT_REQ);
+        
+        gpio_mode_set(SCSI_TIMER_OUT_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, SCSI_TIMER_OUT_PIN);
+        // @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);
 
-        if (g_scsi_dma_use_greenpak)
-        {
-            GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO1;
-            GPIO_BOP(SCSI_OUT_PORT) = GREENPAK_PLD_IO2;
-        }
-        else
-        {
-            gpio_init(SCSI_TIMER_OUT_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, SCSI_TIMER_OUT_PIN);
-        }
     }
     else
     {
-        GPIO_BC(SCSI_OUT_PORT) = GREENPAK_PLD_IO2;
-        gpio_init(SCSI_TIMER_OUT_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, SCSI_TIMER_OUT_PIN);
-        gpio_init(SCSI_OUT_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, SCSI_OUT_REQ);
+        // @ 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);
+        
     }
 }
 
 // Convert input bytes into BOP values in the DMA buffer
 static void refill_dmabuf()
 {
-    if (g_scsi_dma_use_greenpak)
-    {
-        greenpak_refill_dmabuf();
-        return;
-    }
-
     // Check how many bytes we have available from the application
     uint32_t count = g_scsi_dma.bytes_app - g_scsi_dma.bytes_dma;
     
@@ -193,11 +183,6 @@ static void refill_dmabuf()
 // Start DMA transfer
 static void start_dma()
 {
-    if (g_scsi_dma_use_greenpak)
-    {
-        greenpak_start_dma();
-        return;
-    }
 
     // Disable channels while configuring
     DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~DMA_CHXCTL_CHEN;
@@ -207,7 +192,7 @@ static void start_dma()
     // Set new buffer address and size
     // CHA / Data channel is in circular mode and always has DMA_BUF_SIZE buffer size.
     // CHB / Update channel limits the number of data.
-    DMA_CHMADDR(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = (uint32_t)g_scsi_dma.dma_buf;
+    DMA_CHM0ADDR(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = (uint32_t)g_scsi_dma.dma_buf;
     DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = DMA_BUF_SIZE;
     uint32_t dma_to_schedule = g_scsi_dma.bytes_app - g_scsi_dma.scheduled_dma;
     DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) = dma_to_schedule;
@@ -218,8 +203,8 @@ static void start_dma()
     TIMER_DMAINTEN(SCSI_TIMER) = TIMER_DMAINTEN_CH1DEN | TIMER_DMAINTEN_CH3DEN;
 
     // Clear and enable interrupt
-    DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_ERR, SCSI_TIMER_DMACHA);
-    DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_ERR, SCSI_TIMER_DMACHB);
+    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;
 
@@ -243,7 +228,6 @@ static void start_dma()
 // Stop DMA transfer
 static void stop_dma()
 {
-    greenpak_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);
@@ -277,7 +261,7 @@ extern "C" void SCSI_TIMER_DMACHA_IRQ()
     //             DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB), " ",
     //             TIMER_CNT(SCSI_TIMER));
 
-    uint32_t intf = DMA_INTF(SCSI_TIMER_DMA);
+    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)
@@ -293,12 +277,12 @@ extern "C" void SCSI_TIMER_DMACHA_IRQ()
             return;
         }
 
-        DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF, SCSI_TIMER_DMACHA);
+        DMA_INTC1(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF, SCSI_TIMER_DMACHA);
         g_scsi_dma.dma_fillto += DMA_BUF_SIZE / 2;
     }
     else if (intf & full_flag)
     {
-        DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHA);
+        DMA_INTC1(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHA);
         g_scsi_dma.dma_fillto += DMA_BUF_SIZE / 2;
     }
 
@@ -314,10 +298,10 @@ 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_INTF(SCSI_TIMER_DMA);
+    uint32_t intf = DMA_INTF0(SCSI_TIMER_DMA);
     if (intf & DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHB))
     {
-        DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHB);
+        DMA_INTC0(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_FTF, SCSI_TIMER_DMACHB);
 
         if (g_scsi_dma.bytes_app > g_scsi_dma.scheduled_dma)
         {
@@ -405,7 +389,6 @@ void scsi_accel_dma_startWrite(const uint8_t* data, uint32_t count, volatile int
     g_scsi_dma.scheduled_dma = 0;
     g_scsi_dma.next_app_buf = NULL;
     g_scsi_dma.next_app_bytes = 0;
-    g_scsi_dma.greenpak_state = GREENPAK_IO1_LOW;
     refill_dmabuf();
     start_dma();
 }
@@ -464,196 +447,9 @@ void scsi_accel_dma_finishWrite(volatile int *resetFlag)
     scsi_accel_dma_stopWrite();
 }
 
-/************************************************/
-/* Functions using external GreenPAK logic chip */
-/************************************************/
-
-void scsi_accel_greenpak_dma_init()
-{
-    g_scsi_dma_state = SCSIDMA_IDLE;
-    g_scsi_dma_use_greenpak = true;
-    rcu_periph_clock_enable(SCSI_TIMER_RCU);
-    rcu_periph_clock_enable(SCSI_TIMER_DMA_RCU);
-
-    // DMA Channel A: data copy
-    // GPIO DMA copies data from memory buffer to GPIO BOP register.
-    // The memory buffer is filled by interrupt routine.
-    dma_parameter_struct gpio_dma_config =
-    {
-        .periph_addr = (uint32_t)&GPIO_BOP(SCSI_OUT_PORT),
-        .periph_width = DMA_PERIPHERAL_WIDTH_32BIT,
-        .memory_addr = (uint32_t)g_scsi_dma.dma_buf,
-        .memory_width = DMA_MEMORY_WIDTH_32BIT,
-        .number = DMA_BUF_SIZE,
-        .priority = DMA_PRIORITY_ULTRA_HIGH,
-        .periph_inc = DMA_PERIPH_INCREASE_DISABLE,
-        .memory_inc = DMA_MEMORY_INCREASE_ENABLE,
-        .direction = DMA_MEMORY_TO_PERIPHERAL
-    };
-    dma_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, 2);
-    NVIC_EnableIRQ(SCSI_TIMER_DMACHA_IRQn);
-    NVIC_DisableIRQ(SCSI_TIMER_DMACHB_IRQn);
-
-    // EXTI channel is used to trigger when we reach end of the transfer.
-    // Because the main DMA is circular and transfer size may not be even
-    // multiple of it, we cannot trigger the end at the DMA interrupt.
-    gpio_exti_source_select(GREENPAK_PLD_IO2_EXTI_SOURCE_PORT, GREENPAK_PLD_IO2_EXTI_SOURCE_PIN);
-    exti_init(GREENPAK_PLD_IO2_EXTI, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
-    exti_interrupt_flag_clear(GREENPAK_PLD_IO2_EXTI);
-    exti_interrupt_disable(GREENPAK_PLD_IO2_EXTI);
-    NVIC_SetPriority(GREENPAK_IRQn, 1);
-    NVIC_EnableIRQ(GREENPAK_IRQn);
-    
-    // Timer is used to trigger DMA requests
-    // OUT_REQ is driven by timer output.
-    // 1. On timer update event, REQ is set low.
-    // 2. When ACK goes low, timer counts and OUT_REQ is set high.
-    //    Simultaneously a DMA request is triggered to write next data to GPIO.
-    // 3. When ACK goes high, a DMA request is triggered to cause timer update event.
-    //    The DMA request priority is set so that 2. always completes before it.
-    TIMER_CTL0(SCSI_TIMER) = 0;
-    TIMER_SMCFG(SCSI_TIMER) = TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_CI0F_ED;
-    TIMER_CAR(SCSI_TIMER) = 1;
-    TIMER_PSC(SCSI_TIMER) = 0;
-    TIMER_DMAINTEN(SCSI_TIMER) = 0;
-    TIMER_CHCTL0(SCSI_TIMER) = 0x6001; // CH0 as input, CH1 as DMA trigger
-    TIMER_CHCTL1(SCSI_TIMER) = 0;
-    TIMER_CHCTL2(SCSI_TIMER) = 0;
-    TIMER_CCHP(SCSI_TIMER) = 0;
-    TIMER_CH1CV(SCSI_TIMER) = 1; // Copy data when ACK goes low
-    gpio_init(SCSI_TIMER_IN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_TIMER_IN_PIN);
-}
-
+// @TODO check if these externs are need without greenpak
 extern const uint32_t g_scsi_out_byte_to_bop_pld1hi[256];
 extern const uint32_t g_scsi_out_byte_to_bop_pld1lo[256];
 
-static void greenpak_refill_dmabuf()
-{
-    if (g_scsi_dma.greenpak_state == GREENPAK_STOP)
-    {
-        // Wait for previous DMA block to end first
-        return;
-    }
-
-    // Check how many bytes we have available from the application
-    uint32_t count = g_scsi_dma.bytes_app - g_scsi_dma.bytes_dma;
-    
-    // Check amount of free space in DMA buffer
-    uint32_t max = g_scsi_dma.dma_fillto - g_scsi_dma.dma_idx;
-    if (count > max) count = max;
-
-    uint8_t *src = g_scsi_dma.app_buf + g_scsi_dma.bytes_dma;
-    uint32_t *dst = g_scsi_dma.dma_buf;
-    uint32_t pos = g_scsi_dma.dma_idx;
-    uint32_t end = pos + count;
-    g_scsi_dma.dma_idx = end;
-    g_scsi_dma.bytes_dma += count;
-    g_scsi_dma.scheduled_dma = g_scsi_dma.bytes_dma;
-
-    if (pos < end && g_scsi_dma.greenpak_state == GREENPAK_IO1_HIGH)
-    {
-        // Fix alignment so that main loop begins with PLD1HI
-        dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1lo[*src++];
-        g_scsi_dma.greenpak_state = GREENPAK_IO1_LOW;
-    }
-
-    while (pos + 4 <= end)
-    {
-        uint32_t input = *(uint32_t*)src;
-        src += 4;
-
-        dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1hi[(input >> 0) & 0xFF];
-        dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1lo[(input >> 8) & 0xFF];
-        dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1hi[(input >> 16) & 0xFF];
-        dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1lo[(input >> 24) & 0xFF];
-    }
-
-    while (pos < end)
-    {
-        if (g_scsi_dma.greenpak_state == GREENPAK_IO1_HIGH)
-        {
-            dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1lo[*src++];
-            g_scsi_dma.greenpak_state = GREENPAK_IO1_LOW;
-        }
-        else
-        {
-            dst[(pos++) & DMA_BUF_MASK] = g_scsi_out_byte_to_bop_pld1hi[*src++];
-            g_scsi_dma.greenpak_state = GREENPAK_IO1_HIGH;
-        }
-    }
-
-    uint32_t remain = g_scsi_dma.dma_fillto - g_scsi_dma.dma_idx;
-    if (!g_scsi_dma.next_app_buf && remain > 0)
-    {
-        // Mark the end of transfer by turning PD2 off
-        dst[(pos++) & DMA_BUF_MASK] = (GREENPAK_PLD_IO2 << 16) | (GREENPAK_PLD_IO1 << 16);
-        g_scsi_dma.dma_idx = pos;
-        g_scsi_dma.greenpak_state = GREENPAK_STOP;
-    }
-}
-
-extern "C" void GREENPAK_IRQ()
-{
-    if (EXTI_PD & GREENPAK_PLD_IO2_EXTI)
-    {
-        EXTI_PD = GREENPAK_PLD_IO2_EXTI;
-
-        if (g_scsi_dma.bytes_app > g_scsi_dma.bytes_dma || g_scsi_dma.next_app_buf)
-        {
-            assert(g_scsi_dma.greenpak_state == GREENPAK_STOP);
-            g_scsi_dma.greenpak_state = GREENPAK_IO1_LOW;
-            // More data is available
-            check_dma_next_buffer();
-            refill_dmabuf();
-            
-            // Continue transferring
-            GPIO_BOP(SCSI_OUT_PORT) = GREENPAK_PLD_IO2;
-            TIMER_SWEVG(SCSI_TIMER) = TIMER_SWEVG_CH1G;
-        }
-        else
-        {
-            stop_dma();
-        }
-    }
-}
-
-static void greenpak_start_dma()
-{
-    // Disable channels while configuring
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) &= ~DMA_CHXCTL_CHEN;
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHB) &= ~DMA_CHXCTL_CHEN;
-    TIMER_CTL0(SCSI_TIMER) = 0;
-
-    // Set buffer address and size
-    DMA_CHMADDR(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = (uint32_t)g_scsi_dma.dma_buf;
-    DMA_CHCNT(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) = DMA_BUF_SIZE;
-
-    // Clear pending DMA events
-    TIMER_DMAINTEN(SCSI_TIMER) = 0;
-    TIMER_DMAINTEN(SCSI_TIMER) = TIMER_DMAINTEN_CH1DEN | TIMER_DMAINTEN_CH3DEN;
-
-    // Clear and enable interrupt
-    DMA_INTC(SCSI_TIMER_DMA) = DMA_FLAG_ADD(DMA_FLAG_HTF | DMA_FLAG_FTF | DMA_FLAG_ERR, SCSI_TIMER_DMACHA);
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_FTFIE | DMA_CHXCTL_HTFIE;
-    exti_interrupt_flag_clear(GREENPAK_PLD_IO2_EXTI);
-    exti_interrupt_enable(GREENPAK_PLD_IO2_EXTI);
-
-    // Enable channels
-    DMA_CHCTL(SCSI_TIMER_DMA, SCSI_TIMER_DMACHA) |= DMA_CHXCTL_CHEN;
-    
-    // Enable timer
-    TIMER_CNT(SCSI_TIMER) = 0;
-    TIMER_CTL0(SCSI_TIMER) |= TIMER_CTL0_CEN;
-
-    // Generate first event
-    TIMER_SWEVG(SCSI_TIMER) = TIMER_SWEVG_CH1G;
-}
-
-static void greenpak_stop_dma()
-{
-    exti_interrupt_disable(GREENPAK_PLD_IO2_EXTI);
-}
 
 #endif

+ 20 - 14
lib/ZuluSCSI_platform_GD32F450/scsi_accel_sync.cpp

@@ -75,23 +75,28 @@ 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_parameter_struct exmc_dma_config =
+    dma_single_data_parameter_struct exmc_dma_config =
     {
         .periph_addr = EXMC_NOR_PSRAM,
-        .periph_width = DMA_PERIPHERAL_WIDTH_16BIT,
-        .memory_addr = (uint32_t)g_sync_dma_buf,
-        .memory_width = DMA_MEMORY_WIDTH_16BIT,
-        .number = 0, // Filled before transfer
-        .priority = DMA_PRIORITY_MEDIUM,
         .periph_inc = DMA_PERIPH_INCREASE_DISABLE,
+        .memory0_addr = (uint32_t)g_sync_dma_buf,
         .memory_inc = DMA_MEMORY_INCREASE_ENABLE,
-        .direction = DMA_PERIPHERAL_TO_MEMORY
+        .periph_memory_width = DMA_PERIPH_WIDTH_16BIT,
+        .circular_mode = DMA_CIRCULAR_MODE_DISABLE,
+        .direction = DMA_PERIPH_TO_MEMORY,
+        .number = 0, // Filled before transfer
+        .priority = DMA_PRIORITY_MEDIUM
     };
-    dma_init(SCSI_EXMC_DMA, SCSI_EXMC_DMACH, &exmc_dma_config);
-    dma_memory_to_memory_enable(SCSI_EXMC_DMA, SCSI_EXMC_DMACH);
+    dma_single_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);
+
+    gpio_mode_set(SCSI_IN_ACK_EXMC_NWAIT_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_IN_ACK_EXMC_NWAIT_PIN);
+    gpio_mode_set(SCSI_TIMER_IN_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, SCSI_TIMER_IN_PIN);
 
-    gpio_init(SCSI_IN_ACK_EXMC_NWAIT_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_IN_ACK_EXMC_NWAIT_PIN);
-    gpio_init(SCSI_TIMER_IN_PORT, GPIO_MODE_IN_FLOATING, 0, SCSI_TIMER_IN_PIN);
+    // @TODO - added this gpio init sequence - figure out if it actually needed
+    gpio_mode_set(SCSI_ACK_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, SCSI_ACK_PIN);
+    gpio_af_set(SCSI_ACK_PORT, GPIO_AF_1, SCSI_ACK_PIN);
 
     // TIMER1 is used to count ACK pulses
     TIMER_CTL0(SCSI_SYNC_TIMER) = 0;
@@ -105,10 +110,11 @@ void scsi_accel_sync_recv(uint8_t *data, uint32_t count, int* parityError, volat
 {
     // Enable EXMC to drive REQ from EXMC_NOE pin
     EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) |= EXMC_SNCTL_NRBKEN;
-    uint32_t oldmode = GPIO_CTL0(SCSI_OUT_REQ_EXMC_NOE_PORT);
+    uint32_t oldmode = GPIO_CTL(SCSI_OUT_REQ_EXMC_NOE_PORT);
+    //@ TODO check if this IDX offset and it multiplicand are correct - GPIO_CTL has a different layout than f20x GPIO_CTL0
     uint32_t newmode = oldmode & ~(0xF << (SCSI_OUT_REQ_EXMC_NOE_IDX * 4));
     newmode |= 0xB << (SCSI_OUT_REQ_EXMC_NOE_IDX * 4);
-    GPIO_CTL0(SCSI_OUT_REQ_EXMC_NOE_PORT) = newmode;
+    GPIO_CTL(SCSI_OUT_REQ_EXMC_NOE_PORT) = newmode;
     
     while (count > 0)
     {
@@ -144,7 +150,7 @@ void scsi_accel_sync_recv(uint8_t *data, uint32_t count, int* parityError, volat
         data = end;
     }
 
-    GPIO_CTL0(SCSI_OUT_REQ_EXMC_NOE_PORT) = oldmode;
+    GPIO_CTL(SCSI_OUT_REQ_EXMC_NOE_PORT) = oldmode;
     EXMC_SNCTL(EXMC_BANK0_NORSRAM_REGION0) &= ~EXMC_SNCTL_NRBKEN;
 }
 

+ 1 - 1
lib/ZuluSCSI_platform_GD32F450/sd_card_sdio.cpp

@@ -1,5 +1,5 @@
 // Driver and interface for accessing SD card in SDIO mode
-// Used on ZuluSCSI v1.1.
+// Used on ZuluSCSI v1.4.
 
 #include "ZuluSCSI_platform.h"