1 2 Previous Next 27 Replies Latest reply on Jun 26, 2020 7:09 AM by EvPa_264126

    SD card write to file using DMA



      I want to interface a sdcard with the psoc5lp to store data coming in at 1Msps.


      I want to do it without using the core (DMA transfers). I would also like to write to a file so that it would be easier to view the data on the laptop and process it further. PSoC creator does have the emFile component. I am unclear as to how to write to a file using DMA while using the emFile component. The emFile example given by PSoC uses the core to write values into a text file. I would like to do that using the DMA. Can someone please point me to some example code and give me some helpful pointers on how to implement this.

        • 1. Re: SD card write to file using DMA



          The emFile middleware SW doesn't use the DMA for data transfer.  However, it is possible to install a file write driver code that you can develop to minimize CPU access.


          Here are some links to similar discussions:

          Emfile read from sd card is slow. any way to increase speed?

          Re: emFile writing is inefficient, any ways to speed it up?

          Regarding emfile component SD SPI Mode with DMA






          A lot of links regarding emFile and DMA.


          I do recommend the following in your stated use case:

          • Store your 1Msps in as Big as RAM as practical.
          • When at least 3/4 of the RAM buffer is full, dump to the File using DMA.
          • Can you implement a FIFO with head and tail pointers?



          1 of 1 people found this helpful
          • 2. Re: SD card write to file using DMA



            Thanks for the quick reply. I will go through these links and figure out a way to do it


            I was thinking something along those lines as well. Since I didn't want to miss any samples while I'm dumping to a file, I was thinking maybe a ping pong buffer implementation would be more suitable? What do you think?

            • 3. Re: SD card write to file using DMA



              Are you acquiring data using DMA?


              If you can, the ping-pong DMA makes a lot of sense for the data acquisition-side.  Since you're probably using the AD4020 with SPI, you can move the 20bit results using DMA.


              • Create two large RAM buffers for your data acquisition.
              • Use two DMA TDs to move the data acquired in a ping-pong configuration.
              • Configure this DMA to provide a interrupt when a TD has completed (this buffer is full).  The next TD will start moving new acquired data into the other buffer.
              • In the ISR, perform a FS_Write() to move this buffered data into a file.  You can use another DMA TD if you want to eliminate CPU overhead for this operation.



              • 4. Re: SD card write to file using DMA

                This is exactly what I had in mind Yes I am using a DMA to acquire data. Thank you, I will implement this and see how it goes

                • 5. Re: SD card write to file using DMA

                  You mentioned that the CPU overhead can be eliminated by using a DMA TD to write to the file. I am still unclear on that, can you please elaborate?

                  • 6. Re: SD card write to file using DMA



                    Look at the emFile V3.22 documentation Section 6.8 "Writing your own driver"


                    The emFile API calls make use of a function table with the Data structure below:

                    Data structure

                    typedef struct {
                         const char * (*pfGetName) (U8 Unit);
                         int (*pfAddDevice) (void);
                         int (*pfRead) (U8 Unit,  U32 SectorNo,  void * pBuffer,  U32 NumSectors);
                         int (*pfWrite) (U8 Unit, U32 SectorNo, const void * pBuffer, U32 NumSectors, U8 RepeatSame);
                         int (*pfIoCtl) (U8 Unit, I32 Cmd, I32 Aux, void * pBuffer);
                         int (*pfInitMedium) (U8 Unit);
                         int (*pfGetStatus) (U8 Unit);
                         int (*pfGetNumUnits) (void);
                    } FS_DEVICE_TYPE;


                    You can create your own DMA driver implementation code for the pfWrite() and insert the pointer for this call in the FS_DEVICE_TYPE for the instance of the SD device.



                    1 of 1 people found this helpful
                    • 7. Re: SD card write to file using DMA

                      Thanks a lot will look into this as well

                      • 8. Re: SD card write to file using DMA



                        I tried to create the ping-pong configuration buffers and used DMA to transfer the data from the ADC to these buffers. Created an ISR which uses FS_Write to transfer the data from the buffers alternatively to the SD Card. However, I noticed that there was inconsistency in writing the data from either of these buffers. It missed out a lot of samples. Any idea on how I could do to avoid this issue?

                        I presume that the FS_Write is taking more time to write data to the SD Card and in turn writing from the same buffer.



                        Sampling Rate of ADC is 10KSPS. The buffer length was around 1000 bytes each.


                        Thanks in advance!


                        • 9. Re: SD card write to file using DMA

                          I had an old project   in Russian (PSoC Creator 2.1), where the real-time ADC data (12 bits) is written to a file on an SD card at a speed of up to 25,000 samples per second. 

                          The main problem was that the recording process on SD is very noisy and this is noticeable in the recording.

                          The project has some bugs / deficiencies ...



                          • 10. Re: SD card write to file using DMA



                            Without having your project, I'm making some guesses.


                            When you are missing data, are they clumps (between the 1000 byte buffers transfers) or is the inconsistency occurring within samples (possible DMA-transfer > 8bit coherency issue)?


                            As a debugging experiment lower the ADC data rate as low as you can tolerate.


                            It appears you might be having a ADC data coherency issue when you DMA grab the data or your FS_Write with the ISR is not keeping up with the second 1000 byte buffer needing to be serviced.



                            • 11. Re: SD card write to file using DMA



                              If you MUST transfer at full speed there is another debugging solution.


                              You need to set up two GPIO outputs as framing signals.


                              Using one of the GPIO outputs toggle it every time the FS_Write ISR starts the next buffer to dump to the SD card.

                              Connect the second GPIO output to the "nrq" output of the DMA component.  On each TD of the ADC ping-pong definition include DMA__TD_TERMOUT_EN.  This will generate a pulse every time the TD to fill the ADC data buffer is completed.


                              Now look at these two framing pulses on an oscilloscope to see if there is any timing/logic issues.



                              • 12. Re: SD card write to file using DMA



                                Evgeniy is very correct.  High speed digital crosstalk on other analog signals such as ADC conversions is a perpetual problem in all mixed-signal MPU designs.  There are some techniques to minimize this but they can be cumbersome.


                                Some of the techniques used:

                                • Good PCB layout techniques for the analog front-end of your ADC signals.
                                • Oversampled averaging of your analog signal.
                                • ADC capture without the SD SPI writes, then stop ADC capture and write to the SD card as quickly as possible.
                                • Make sure there are series resistors in the SPI lines to the SD card interface.  Make the series resistance as high as can be tolerated for the transfer speed desired.  The increased resistance will reduce the slew rates of the output signals for SPI_CLK,  SPI_MOSI.  Adding a little capacitance of these lines to GND might also help reduce the slew rates and minimize current surging from these signals.  This is always a good design practice to increase the RC factor of digital output circuits to the maximum you can tolerate within reliable parameters.
                                • Make sure you are using the internal Vref with the Bypass cap setting.  If you use VDDA as your reference, ANY bouncing of the VDDA supply will change your ADC result.  The internal Vref is 99% immune to VDDA bounce.  By adding the Bypass cap on ports P0.2 or P0.4 will stabilize the ADC reference further.



                                • 13. Re: SD card write to file using DMA

                                  Hey Evgeniy!


                                  Sorry for the late update!.. Thanks for sharing your thoughts and the project files. I am following a similar approach to your design.

                                  I noticed that in my design, I had considered the REQUESTS_PER_BURST for the DMA transfers was set to ZERO, which was causing the problem in transferring the data. Changing that resolved my current issue.


                                  Also, can you please explain to me what exactly you mean by noisy data while using the SD Card write?


                                  Thanks a lot!

                                  Karthik Bhat

                                  • 14. Re: SD card write to file using DMA

                                    Hey Len!


                                    Sorry for the late reply.. I went through your suggestions and your inputs to debug the code.

                                    The problem was with the ADC data coherency. I started off with the lowest possible ADC Sampling rate required for my project and primarily the issue was because the REQUEST_PER_BURST with the DMA Configuration was set to 0 instead of 1. I debugged this issue using two GPIO Signals as framing signals, these were triggered based on the DMA nrq and the active TD.


                                    Thanks again for the suggestions. It was really helpful.




                                    Karthik Bhat

                                    1 2 Previous Next