Search This Blog

Apr 24, 2013

FATFs DMA support



We have request to add DMA support in FATFs to improve SD read/write performance.
1.       Add DMA descriptor structures in circurlar_buffer.c
        +SI32_DMADESC_A_Type dma_desc[SI32_DMACTRL_NUM_CHANNELS + SI32_DMADESC_ALT_STRIDE]  __attribute__ ((aligned SI32_DMADESC_PRI_ALIGN));
15        +
16        +
17        +void DMA_initialize(void)
18        +{
19        +    // Setup and enable the DMA controller and DMAXBAR
20        +    SI32_DMACTRL_A_write_baseptr(SI32_DMACTRL_0, (uint32_t)dma_desc);
21        +    SI32_DMACTRL_A_enable_module(SI32_DMACTRL_0);
22        +}
23        +
2.       Enable DMA clock and module in gCLKCTRL.c.
old        new        
...        ...        @@ -44,5 +44,7 @@ void CLKCTRL_setup_default_mode_clock_gates(void)
44        44                                                  SI32_CLKCTRL_A_APBCLKG0_USB0 |
45        45                                                  SI32_CLKCTRL_A_APBCLKG0_TIMER0 |
46        46                                                  SI32_CLKCTRL_A_APBCLKG0_TIMER1 |
47        +                                         SI32_CLKCTRL_A_APBCLKG1_MISC1 |
47        48                                                  SI32_CLKCTRL_A_APBCLKG0_FLASHCTRL0);
49        +  SI32_CLKCTRL_A_enable_ahb_to_dma_controller(SI32_CLKCTRL_0);
48        50         }
3.       Enable SPI DMA configuration in gModes.c.
old        new        
...        ...        @@ -38,8 +38,8 @@ void enter_default_mode_from_reset(void)
38        38        
39        39           // Setup ports
40        40           pb_enter_default_mode_from_reset();
41                -  gSPI0_enter_master_mode_config();
42                -
41        +  //gSPI0_enter_master_mode_config();
42        +  gSPI0_enter_dma_master_mode_config();
43        43           // Initialize clock control
44        44           SystemCoreClock = 20000000;
45        45           cpu_update();
4.       Add DMA operation in mmc.c
19        +#define SPI_DMA_ENABLE
20        +
21        +#ifdef SPI_DMA_ENABLE
22        +static uint32_t rx_ch, tx_ch;
23        +extern SI32_DMADESC_A_Type dma_desc[SI32_DMACTRL_NUM_CHANNELS + SI32_DMADESC_ALT_STRIDE];
24        +#endif
25        +#define SPI_SLOW_SPEED 100000   // 100K HZ
26        +#define SPI_HIGH_SPEED 800000   // 8M Hz
27         /* Port controls  (Platform dependent) */
32        +#define        FCLK_SLOW()        SI32_SPI_A_write_clkrate(SI32_SPI_0, APBCLK / (2 * SPI_SLOW_SPEED) -1) /* Set slow clock 100k Hz*/
33        +#define        FCLK_FAST()        SI32_SPI_A_write_clkrate(SI32_SPI_0, APBCLK / (2 * SPI_HIGH_SPEED) -1) /* Set fast clock 8M Hz */

135         static void xmit_spi_multi(const BYTE *p,UINT cnt)
136         {
137        +#ifdef SPI_DMA_ENABLE
138        +    uint32_t temp;
139        +    SI32_DMADESC_A_configure(&dma_desc[rx_ch],
140        +         SI32_SPI_0_RX_ENDPOINT, &temp, cnt / 4, SI32_DMADESC_A_CONFIG_WORD_PIPE);
141        +    SI32_DMADESC_A_configure(&dma_desc[tx_ch],
142        +        p, SI32_SPI_0_TX_ENDPOINT, cnt / 4, SI32_DMADESC_A_CONFIG_WORD_TX);
143        +
144        +    SI32_DMACTRL_A_enable_channel(SI32_DMACTRL_0, rx_ch);
145        +    SI32_DMACTRL_A_enable_channel(SI32_DMACTRL_0, tx_ch);
146        +
147        +    // 6. Run the complete peripheral DMA cycle
148        +    SI32_SPI_A_enable_dma_requests(SI32_SPI_0);
149        +
150        +    while(SI32_DMACTRL_A_read_chen(SI32_DMACTRL_0));
151        +#else
152        +
...
168         static void rcvr_spi_multi(BYTE *p,UINT cnt)
169         {
170        +#ifdef SPI_DMA_ENABLE
171        +    uint32_t temp;
172        +    SI32_DMADESC_A_configure(&dma_desc[rx_ch],
173        +         SI32_SPI_0_RX_ENDPOINT, p, cnt / 4, SI32_DMADESC_A_CONFIG_WORD_RX);
174        +    SI32_DMADESC_A_configure(&dma_desc[tx_ch],
175        +        &temp, SI32_SPI_0_TX_ENDPOINT, cnt / 4, SI32_DMADESC_A_CONFIG_WORD_PIPE);
176        +
177        +    SI32_DMACTRL_A_enable_channel(SI32_DMACTRL_0, rx_ch);
178        +    SI32_DMACTRL_A_enable_channel(SI32_DMACTRL_0, tx_ch);
179        +
180        +    // 6. Run the complete peripheral DMA cycle
181        +    SI32_SPI_A_enable_dma_requests(SI32_SPI_0);
182        +
183        +    while(SI32_DMACTRL_A_read_chen(SI32_DMACTRL_0));
184        +#else
185                 do {

5.       Source code

No comments: