[STM32GENERIC] SDIO DMA

Discussions about the STM32generic core
danieleff
Posts: 336
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

Re: [STM32GENERIC] SDIO DMA

Post by danieleff » Wed Jun 14, 2017 8:43 am

Yes it is weird. Where did the first 0x680001d2 - 0x68000008 = 458 bytes go.
Anyhow when not aligned we can just do a regular write instead of dma write.

User avatar
Pito
Posts: 1531
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: [STM32GENERIC] SDIO DMA

Post by Pito » Wed Jun 14, 2017 8:50 am

It worked with F103ZET and the Heap in External Sram and with SPI.
http://www.stm32duino.com/viewtopic.php ... 140#p22415
Pukao Hats Cleaning Services Ltd.

danieleff
Posts: 336
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

Re: [STM32GENERIC] SDIO DMA

Post by danieleff » Wed Jun 14, 2017 10:20 am

Then it is probably correct. Try with _useDMA = false;, and remove the alignment check.

User avatar
Pito
Posts: 1531
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: [STM32GENERIC] SDIO DMA

Post by Pito » Wed Jun 14, 2017 10:38 am

With _useDMA=false, and while(1) in the alignment check commented out I get (the 3 numbers at the end there are: block, src, nb)

Code: Select all

 Writing the .bmp to SDcard..
### Not aligned SDIO.cpp writeBlocks line 221  20289 680001D2 63
### Not aligned SDIO.cpp writeBlocks line 221  20352 68007FD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20416 6800FFD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20480 68017FD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20544 6801FFD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20608 68027FD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20672 6802FFD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20736 68037FD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20800 6803FFD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20864 68047FD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20928 6804FFD2 64
### Not aligned SDIO.cpp writeBlocks line 221  20992 68057FD2 64
### Not aligned SDIO.cpp writeBlocks line 221  21056 6805FFD2 64
### Not aligned SDIO.cpp writeBlocks line 221  21120 68067FD2 64
### Not aligned SDIO.cpp writeBlocks line 221  21184 6806FFD2 41
 Done..
and the resulting file is written on the sdcard and looks ok.
PS: There is a regular pattern in the "src" addresses.. From the second address upwards: addr(i) = addr(i-1)+0x8000
So all base_addresses of the 15x 32kB blocks are off.
Pukao Hats Cleaning Services Ltd.

User avatar
Pito
Posts: 1531
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: [STM32GENERIC] SDIO DMA

Post by Pito » Wed Jun 14, 2017 12:50 pm

When stepping through, the first 4 passes go via

Code: Select all

int FatFile::write(const void* buf, size_t nbyte) {
  // convert void* to uint8_t*  -  must be before goto statements
  const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
  cache_t* pc;
  uint8_t cacheOption;
  // number of bytes left to write  -  must be before goto statements
  size_t nToWrite = nbyte;
  size_t n;
while it shows in the first 4 passes (src, nbyte)

Code: Select all

2001ff87 1
2001ff87 1
2001ff94 34
68000008 480000dec
then it starts pass via

Code: Select all

uint8_t SDIOClass::writeBlocks(uint32_t block, const uint8_t* src, size_t nb) {
    if (((uint32_t)src & 0x3) !=0){
while it shows (src, nb)

Code: Select all

680001d2 3f
68007fd2 40
6800ffd2 40
EDIT: Explained to me by BillG offline:
If the file is not positioned on a block boundary the cache will be used for a partial block and then a call will be made for remaining full blocks. Looks like you write 54 byte to the file for a header. (1 + 1 + 0X34) bytes. The first 458 bytes of the 480000 byte transfer will be moved to the cache.
458 + 8 = 0X1D2. That explains the 0x680001d2.
Note this is not 4-byte aligned so you can’t use DMA.
Pukao Hats Cleaning Services Ltd.

User avatar
Pito
Posts: 1531
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: [STM32GENERIC] SDIO DMA

Post by Pito » Wed Jun 14, 2017 4:04 pm

As a proof I commented out the writing of the 54bytes of the bmp header, with __useDMA=true, and added a print out of addresses when aligned:

Code: Select all

 Writing the .bmp to SDcard..
### Aligned SDIO.cpp writeBlocks line 221  20288 68000008 64
### Aligned SDIO.cpp writeBlocks line 221  20352 68008008 64
### Aligned SDIO.cpp writeBlocks line 221  20416 68010008 64
### Aligned SDIO.cpp writeBlocks line 221  20480 68018008 64
### Aligned SDIO.cpp writeBlocks line 221  20544 68020008 64
### Aligned SDIO.cpp writeBlocks line 221  20608 68028008 64
### Aligned SDIO.cpp writeBlocks line 221  20672 68030008 64
### Aligned SDIO.cpp writeBlocks line 221  20736 68038008 64
### Aligned SDIO.cpp writeBlocks line 221  20800 68040008 64
### Aligned SDIO.cpp writeBlocks line 221  20864 68048008 64
### Aligned SDIO.cpp writeBlocks line 221  20928 68050008 64
### Aligned SDIO.cpp writeBlocks line 221  20992 68058008 64
### Aligned SDIO.cpp writeBlocks line 221  21056 68060008 64
### Aligned SDIO.cpp writeBlocks line 221  21120 68068008 64
### Aligned SDIO.cpp writeBlocks line 221  21184 68070008 41
Close file:
### Aligned SDIO.cpp writeBlocks line 221  21225 200000F8 1
### Aligned SDIO.cpp writeBlocks line 221  16384 200000F8 1
### Aligned SDIO.cpp writeBlocks line 221  8790 20000304 1
### Aligned SDIO.cpp writeBlocks line 221  12587 20000304 1
 Done..
The file is there, the size is 480000bytes (instead of 480054bytes with the header).
Now, how to manage SDIO writing with any alignments :)
Pukao Hats Cleaning Services Ltd.

User avatar
Pito
Posts: 1531
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: [STM32GENERIC] SDIO DMA

Post by Pito » Thu Jun 15, 2017 6:03 am

This is a small modification in SDIO.cpp which runs with aligned and misaligned, it does not solve the DMA for misaligned, however:

Code: Select all

uint8_t SDIOClass::readBlocks(uint32_t block, uint8_t* dst, size_t nb) {
    if (((uint32_t)dst & 0x3U) != 0){
       //  while (1); //Hang here, dst was not aligned to word, this is a problem
      _useDMA = false;
    } else {
      _useDMA = true;
    }

Code: Select all

uint8_t SDIOClass::writeBlocks(uint32_t block, const uint8_t* src, size_t nb) {
    if (((uint32_t)src & 0x3U) !=0){
      //  while (1); //Hang here, src was not aligned to word, this is a problem
      _useDMA = false;
    } else {
      _useDMA = true;
    }
Aligned 480kB:

Code: Select all

 Writing the .bmp to SDcard..
 Elapsed 150 msecs
 Done..
Misaligned 480kB:

Code: Select all

 Writing the .bmp to SDcard..
 Elapsed 152 msecs
 Done..
For misaligned data we may use an aligned buffer in between, where we copy the misaligned block before the actual write.
Pukao Hats Cleaning Services Ltd.

danieleff
Posts: 336
Joined: Thu Sep 01, 2016 8:52 pm
Location: Hungary
Contact:

Re: [STM32GENERIC] SDIO DMA

Post by danieleff » Thu Jun 15, 2017 6:29 am

I committed this to master to fix it: https://github.com/danieleff/STM32GENER ... 11f6f9def1

As you can see, just like with SPI, blocking SDIO DMA is not that faster than blocking SDIO non-DMA, so I would not worry about performance.

User avatar
Pito
Posts: 1531
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: [STM32GENERIC] SDIO DMA

Post by Pito » Thu Jun 15, 2017 6:53 am

And the misaligned write result :) at Seahorse Valley

UPDATE: with a Rainbow ColorWheel
Mandel 400x400x1024col SingleP FPU 7secs.JPG
Mandel 400x400x1024col SingleP FPU 7secs.JPG (102.26 KiB) Viewed 89 times
Last edited by Pito on Fri Jun 16, 2017 11:22 pm, edited 1 time in total.
Pukao Hats Cleaning Services Ltd.

victor_pv
Posts: 1654
Joined: Mon Apr 27, 2015 12:12 pm

Re: [STM32GENERIC] SDIO DMA

Post by victor_pv » Thu Jun 15, 2017 9:18 pm

danieleff wrote:Yes it is weird. Where did the first 0x680001d2 - 0x68000008 = 458 bytes go.
Anyhow when not aligned we can just do a regular write instead of dma write.
Sorry I have been busy quite a few days, just trying to catch up.

Bill does that in his library. If it detects non-aligned buffer, it does the transfer in normal mode. I decided to block at the check in purpose just to catch if it was happening at any time. I preferred that at the moment since we were trying to find problems with the transfer.

There should be no problem doing regular transfer when the buffer is not aligned, other than the any speed penalty.

We could do misaligned DMA if we change the buffer size from word to byte, that should work in the F4, since it can read from memory in bytes to the FIFO, and write in Words to the peripheral, but would cause 4x RAM accesses, so a possible slow down.

Post Reply