Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - justin@uc

Pages: [1]
1
utFAT / Re: DMA with SPI for SD Cards
« on: July 14, 2012, 04:47:35 AM »
Hi Mark,

Thank you for the information! I never realized that SPI didn't have support to generate DMA timers. The Reference Manual made it seem like it did, but I guess when they say that "the source/destination addresses can include peripheral device registers", then it would only work on a per-byte basis. How dissapointing!

So does this mean the only peripheral device that can use DMA effectively is UART?  :( How crazy...

Hmmm...I'm still trying to find ways to speed up SD writing. Byte-at-a-time seems so...slow!

Thanks again Mark. This info helps!

Justin

2
utFAT / DMA with SPI for SD Cards
« on: July 11, 2012, 03:26:27 AM »
Hi Mark,

Have you attempted or given some thought into using DMA for SPI? I'm *trying* to implement DMA in the SD write routine for my M52259 board, but I'm having no luck.

Specifically, I'm trying to replace the WRITE_SPI_CMD(BYTE) function. Here is what I have so far:

Code: [Select]
void utWriteSPICmdWithDMA(unsigned char *ptrBuf, signed long ulLength)
{
        // Allow access to SPI for DMA
GPACR0 = SUP_USER_FULL_ACCESS;
PACR_QSPI = SUP_USER_FULL_ACCESS;

// DMA
    // Config SPI registers
    QAR = QSPI_TRANSMIT_RAM_0;
    QWR = ((0 << QSPI_START_SHIFT) | (0 << QSPI_END_SHIFT));
   
    // Setup DMA
    DMA_SR_BCR2 = ulLength;
    DMA_SAR2  = (unsigned long)ptrBuf;                          // address of first byte to be transferred  (SARn)
   
    DMA_DAR2  = (unsigned long)(QSPI_ADD + 0x14);                                // address of first destination byte       (DARn) = QDR
    DMA_DCR2  = (DCR_BWC_16K | DCR_SINC | /*DCR_DINC |*/ DCR_SSIZE_BYTE | DCR_DSIZE_BYTE | DCR_START); // set up DMA operation (DCRn) and start DMA transfer
   
    while (!(DMA_SR_BCR2 & DSR_DONE)) { };                 // wait until the transfer has terminated

QDLYR = QSPI_SPE;

// DMA transfer done.
    DMA_SR_BCR2 = DSR_DONE;                                          // clear all status bits ready for future transfer
}

After running this code I probed the clock, DataIn, and ChipSelect lines, all look OK. But no writes ever take place...the QSPI data register is always empty and the DMA status register reports no error either.

There are almost NO examples or anything online relating to using DMA with QSPI on my board (or any other boards for that matter!). Your DMA+UART code helps, but there are differences (I'm guessing) that prevent it from working. Shouldn't DMA automatically take care of handling the SPI though?

Does anyone have any ideas as well? Insights? Anything is appreciated!

Thanks!
Justin

3
utFAT / Re: SD Card Performance
« on: July 04, 2012, 03:00:41 AM »
Thanks for the information Mark and Andrija!

I've "solved" my next problem of keeping up with 3000 messages/second by increasing the SPI baud rate to 20MHz from 8MHz. Seems to work well!

I've also solved the problem of the dangers of holding the FAT information in RAM too long--I write back the FAT cache every time 128 new sectors/clusters are created.

One more question though: If the file is fresh I can get 3000 messages/sec just fine for as long as I want (the files typically get to about 5-10MBs in size before I manually stop the logging). But once I close then reopen the file (and re-start the logging) the performance starts to drop, with each consecutive open/close further slowing the logging performance down (to about 2400 messages/sec). My solution now is to delete the file and start fresh, but obviously this isn't sustainable. Does anyone have any ideas as to why this is happening? Is it the increased seek times because the file gets too large?

Thanks!
Justin

4
utFAT / Re: SD Card Performance
« on: June 29, 2012, 02:29:38 AM »
Thanks aersek! That's a very good idea! I moved the FAT updating to utCloseFile() and it worked! My system can now keep up with 2000 messages/sec!

I'm not too worried about power being cut before the FAT updating at the moment, maybe if I have time later I'll implement it. Thanks for the heads up though!

For the record, I commented out this line in mass_storage.c from the function utWriteFile():

Code: [Select]
//while (utCommitSector(ptr_utDisk, ptr_utFile->private_disk_location.directory_location.ulSector) == CARD_BUSY_WAIT) {} // force writeback to finalise the operation
And my utCloseFile() now looks like:

Code: [Select]
extern void utCloseFile(UTFILE *ptr_utFile)
{
// Update FAT at close of file instead of every write.
UTDISK *ptr_utDisk = &utDisks[ptr_utFile->ucDrive];
DIR_ENTRY_STRUCTURE_FAT32 *ptrFileEntry = (DIR_ENTRY_STRUCTURE_FAT32 *)ptr_utDisk->ptrSectorData; // the directory entry in the sector buffer
while (utCommitSector(ptr_utDisk, ptr_utFile->private_disk_location.directory_location.ulSector) == CARD_BUSY_WAIT) {} // force writeback to finalise the operation
// End of changes.
...
}

Hope that helps someone!

5
utFAT / SD Card Performance
« on: June 28, 2012, 01:51:43 AM »
Hi Mark,

I'm currently using a 16GB SD card hooked up via SPI to my M52259DEMO board to log incoming CAN data (and also send the data to a server program on the PC). The CAN is set to 1 Mb/s, and each message has an 8byte payload. I use a temporary 1KB buffer in RAM to store the data (since I know that SD cards like larger data sets).
The data can come in at either 100, 1000, or 2000 messages/second.

The system can keep up with saving 100 and 1000 messages/sec, but at 2000 it can't. I only get about 1500/second, even after I tried to streamline my application. If I disable SD logging, my system can keep up with 2000 (as I can see from my server program).

I've traced through the SD write routines (through utFAT, mass_storage.c, etc), and I don't see any use of DMA. Is there a way I can easily enable it? Or do I have to manually implement it?

Also, does uTasker support other high-speed "tricks", such as 4-bit mode or setting the card to use "burst mode"?

In short, is there anything I can do to improve performance?

Thank you!
Justin

Pages: [1]