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