Problems with K22 DSPI with EDMA for SD Card Access

cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with K22 DSPI with EDMA for SD Card Access

Jump to solution
890 Views
Senior Contributor II

Hi,

 

I'm working on a K22F product design that accesses SD Cards using the SPI interface.  I'm using the FRDM-K22F for prototyping and will move to the MK22FN128VLH10 when I'm satisfied with the software operation. 

 

I'm using a basic FRDM-K22F with the following modifications:

1.  Added a Molex 1050270001 uSD Card connector to the FRDM board (this, by the way shouldn't be attempted without the proper tools, it really is a bitch to put on if you don't have a hot air rework tool). 

2.  Removed R52 & R55 to ensure any spurious interrupts from U8 don't affect DSPI operation. 

 

Development tools are:

- KDS 3.1

- KSDK 1.3

- PE 3.02

and I have installed the latest release of the MCUonEclipse (http://mcuoneclipse.com/2014/10/21/mcuoneclipse-releases-on-sourceforge/) for the "Wait" function. 

 

I have attached the current version of my software which uses the "fsl_dspi" set up (which automagically brings in "fsl_edma" as a referenced component) and I am attempting to first put the SD Card into an idle state ("CMD0") and then a test to see if the SD Card is high capacity (send a "CMD8" query).  I have enabled the "Slave" Component but I have not clicked on "Install interrupts" (which, reading below, I wonder is if that is my issue). 

 

With the current software, the CMD0 is sent repeatedly until the SD Card (if present) wakes up and responds.  To follow the spec properly, I need to send 74+ clock signals with !CS and SOUT high, but I can't figure out how to do that with the DSPI module setup by PE.  If you look at the attached code, you'll see that I tried to setup the DSPI IO pins as GPIOs before the DSPI operations as well as just send 0xFF's) but in both cases, the operation failed. 

 

The repeated CMD0 (without the initial clocks) seems to wake up the card and place it in idle state seems to be working well, BUT only the first byte is read back during the SPI transfer - the second byte has the status information, but is not being read, as is the subsequent four bytes of the transfer which are not being passed to the receive buffer.  Subsequent SPI transfers do not seem to execute (I don't see them on my 'scope). 

 

I'm comparing my code to the example application "dspi_edma_non_blocking_example_master_frdmk22f" and the only difference I see is that the example application has (system generated?) "fsl_dspi_edma_irq.c" and "fsl_edma_irq.c" files.  I'm also going through 13.9 of the KSDK 1.3 API Reference and while there is a reference to the two "...irq.c".  The next test, I will try to "install interrupts" to see if there is a change in operation by doing that. 

 

So, my questions are:

1.  Has anybody successfully gotten SD Card IO working with the K22F and it's DSPI port?  This seems to have been successful with the K64F, but I can't find any examples with the K22F - Is this why the Molex SD Card connector ISN'T attached to the FRDM-K22F? 

1.  How can I send the 74+ clock signals with !CS and SOUT high before sending the CMD0? 

2.  Why am I only getting one byte back on the EDMA read?  I suspect that lack of interrupt handlers is the issue but the process to correctly setup dspi with edma using PE doesn't seem to be documented. 

 

Thanx for your help!

 

myke

Original Attachment has been moved to: k22f_dspi_05.zip

Labels (1)
1 Solution
23 Views
Senior Contributor II

Hi Folks,

I've got a reasonably full-functioned demo K22F SPI SD Card Application running - attached is the project. 

It was created under:

KDS 3.1

KSDK 1.3

PE 3.0.2

It uses the K22F's OpenSDA port as an interface, running 115,200bps at 8-N-1 (I use Tera Term with it). 

The console commands are:

help                                                  <==  List commands

dir [Path][fileName.ext]                              <==  Long filenames and wildcards are supported

copy con: [Path]fileName.ext                          <== Copy console input into the specified filename.  End input with ^Z (Ctrl-Z). 

                                                      <== For a new line, press "Enter" and then ^J (Ctrl-J) for CR/LF

copy [Path]sourceFileName.ext [Path]destFileName.ext

cd Path                                               <== Set a new active Path.  ".." is supported. 

md Path                                               <== Make a new Directory

rd Path                                               <== Remove an EMPTY Directory

type [Path]fileName.ext                               <== Dump file contents onto console

rw1                                                   <== Run single block read/write tests at sector 30000

rw2                                                   <== Run two block read/write (using the WRITE_MULTIPLE_BLOCK command)


It supports Version 1.x and 2 SD cards and SDHC/SDXC cards.  I didn't implement the code for MMC simply because it isn't available in the Micro SD format (and I don't know how many people still have some in use with full sized SD Cards).  I've tested it on a variety of uSD Cards from 256 MB to 32 GB, so I'm fairly comfortable with saying that it works. 

As I said, it works with the FRDM-K22F with the following modifications:

- Remove R52

- Remove R55

- Add Molex 1050270001 (Digi-Key WM6825CT-ND) connector (this requires quality soldering equipment)

ChaN's FatFs (http://elm-chan.org/fsw/ff/00index_e.html) is used for interfacing with the SD Card.  All non-KSDK and non-PE code was development by me and it's free for use. If it's not as elegant as you would like, well it's development code.  If you find any errors, I would appreciate it if you would point them out to me. 

I should point out that I think there is an issue with the "Generic" example available on ChaN's side for the Multi Block Write with regards to sending the stop transmission token - I'm going to follow up with him on that.  I believe that it is fixed in my code. 

A goal of this code was to only use vanilla KSDK/PE APIs and, while the SD Card's DETECT pin is connected as an interrupt and debounced, I don't mount/unmount the SD Card FAT file system via the interrupts as I found it made the system unstable.  The mounting takes place when the user presses the Enter button and, it the card is installed, it is mounted before the command is executed.  The LED colours that you should watch on the K22F board is Blue indicating that the mount was successful and Red indicating the mount was unsuccessful. 

One issue that was encountered that I do want to mention is that bulk/continuous/DMA SPI reads/writes are not implemented.  I discovered that they do not work on about 40% of the SD Cards that I am working with.  I have no idea why and I can't find any references as to the reason why - interestingly, I can't find any SPI SD Card example code which implements the bulk SPI reads/writes which leads me to believe that other people have had the same issue. 

Unfortunately, due to the need for procuring and soldering on J8, this is not an application you can just try out on a whim.  Despite this, I hope people will find this code useful. 

myke

View solution in original post

8 Replies
23 Views
Senior Contributor II

Hi Joseph,

No, I haven't done any performance measurements of the reads.  I'm not really sure what would be considered "good", "acceptable" and "poor" - I expect to get a better idea as I work through my application (although I suspect that the speed of the reads will not be an issue as the data on the SD Card will be used to drive steppers).  My main concern will be code size and PIT timer interrupt performance.

Sorry, I should have attached a working version of my code to this thread.  To rectify that, you'll see versions of the code that were built in KSDK 1.3 and KSDK 2.0.  These applications require the K22F FRDM board with the micro SD Socket soldered in (which takes a bit of care) and I would recommend removing R52 and R55 from the board as well.

Let me know what you think of the code and what you think of its performance.

myke

0 Kudos
23 Views
Contributor I

Myke,

The attached zip file appears to only contain the SPI initialization code.  Am I missing something?  For example where are the console commands that you described implemented?

Thanks,

Joe

0 Kudos
23 Views
Contributor I

Myke,

Thank you for sharing.  I'm also working with SD SPI on FRDM-K22F.  I got the ksdk sd spi demo working with INT mode but the read performance is way below what I would expect.  Using this code, which bypasses FATfs and used stock PE drivers and configuration with SCK running 16MHz, the max file read throughput I can get is approx 157K bytes per second:

#define SECTOR_GRP 8

    uint8_t *rcv = malloc(512);

    int sector = 0;

    while (1)

    {

        DRESULT rc = disk_read(SD, rcv, sector, SECTOR_GRP);

        if (rc != RES_OK)

            while (1);

        sector += SECTOR_GRP;

        if (sector >= (512*SECTOR_GRP))  // at some even multiple reset sector to beginning

            sector = 0;

        GPIO_DRV_TogglePinOutput(gpio1_OutConfig0[1].pinName);   // toggle PTA5 after every 1MB read

    }

Have you measured read performance using your implementation?  Any suggestions how to improve it?

Joe

0 Kudos
24 Views
Senior Contributor II

Hi Folks,

I've got a reasonably full-functioned demo K22F SPI SD Card Application running - attached is the project. 

It was created under:

KDS 3.1

KSDK 1.3

PE 3.0.2

It uses the K22F's OpenSDA port as an interface, running 115,200bps at 8-N-1 (I use Tera Term with it). 

The console commands are:

help                                                  <==  List commands

dir [Path][fileName.ext]                              <==  Long filenames and wildcards are supported

copy con: [Path]fileName.ext                          <== Copy console input into the specified filename.  End input with ^Z (Ctrl-Z). 

                                                      <== For a new line, press "Enter" and then ^J (Ctrl-J) for CR/LF

copy [Path]sourceFileName.ext [Path]destFileName.ext

cd Path                                               <== Set a new active Path.  ".." is supported. 

md Path                                               <== Make a new Directory

rd Path                                               <== Remove an EMPTY Directory

type [Path]fileName.ext                               <== Dump file contents onto console

rw1                                                   <== Run single block read/write tests at sector 30000

rw2                                                   <== Run two block read/write (using the WRITE_MULTIPLE_BLOCK command)


It supports Version 1.x and 2 SD cards and SDHC/SDXC cards.  I didn't implement the code for MMC simply because it isn't available in the Micro SD format (and I don't know how many people still have some in use with full sized SD Cards).  I've tested it on a variety of uSD Cards from 256 MB to 32 GB, so I'm fairly comfortable with saying that it works. 

As I said, it works with the FRDM-K22F with the following modifications:

- Remove R52

- Remove R55

- Add Molex 1050270001 (Digi-Key WM6825CT-ND) connector (this requires quality soldering equipment)

ChaN's FatFs (http://elm-chan.org/fsw/ff/00index_e.html) is used for interfacing with the SD Card.  All non-KSDK and non-PE code was development by me and it's free for use. If it's not as elegant as you would like, well it's development code.  If you find any errors, I would appreciate it if you would point them out to me. 

I should point out that I think there is an issue with the "Generic" example available on ChaN's side for the Multi Block Write with regards to sending the stop transmission token - I'm going to follow up with him on that.  I believe that it is fixed in my code. 

A goal of this code was to only use vanilla KSDK/PE APIs and, while the SD Card's DETECT pin is connected as an interrupt and debounced, I don't mount/unmount the SD Card FAT file system via the interrupts as I found it made the system unstable.  The mounting takes place when the user presses the Enter button and, it the card is installed, it is mounted before the command is executed.  The LED colours that you should watch on the K22F board is Blue indicating that the mount was successful and Red indicating the mount was unsuccessful. 

One issue that was encountered that I do want to mention is that bulk/continuous/DMA SPI reads/writes are not implemented.  I discovered that they do not work on about 40% of the SD Cards that I am working with.  I have no idea why and I can't find any references as to the reason why - interestingly, I can't find any SPI SD Card example code which implements the bulk SPI reads/writes which leads me to believe that other people have had the same issue. 

Unfortunately, due to the need for procuring and soldering on J8, this is not an application you can just try out on a whim.  Despite this, I hope people will find this code useful. 

myke

View solution in original post

23 Views
NXP Employee
NXP Employee

Hi Myke,

Thank you for sharing to the Community.  That is really awesome.

Regards,

David

0 Kudos
23 Views
Senior Contributor II

After a few hours of work, some successes and I think I'm going forwards. 

In response to my questions above:

1.  Anybody have success/demo code for this application?  It would be nice to see what people have done. 

2.  I think the 74 clocks requirement after power up are a fiction.  I've downloaded a number of SD Card specifications and about half state that the 74+ clock cycles is absolutely required while one reference I have says that you need to delay the time 74 clock cycles at 400kHz would take.  I suspect that this is what I should be looking at. 

3.  I converted to an Int DSPI operation and things are working fine.  Anybody have any ideas why I can't read more than one byte back using the (d)dma dspi? 

Thanx,

myke

0 Kudos
23 Views
Senior Contributor II

Hello Myke,

Have you seen the SPI SDCard Example contained in the Kinetis SDK examples folder? It is located in the path C:\Freescale\KSDK_1.3.0\examples\twrk22f120m\driver_examples\spi_sdcard, it was built for the tower board but the source code is the same for the freedom board so you shouldn't have problems to migrate it.

The project's description can be found in the Kinetis SDK v.1.3.0 Demo Applications User's Guide located in the doc folder in the Kinetis DSK installation.

Please let me know if this information is useful or if I can do anything else for you.

Best regards,

Earl Ramírez.

0 Kudos
23 Views
Senior Contributor II

Hi Earl,

I've made some good progress on implementing an SD Card reader using the DSPI.  All the examples that I have seen from FSL all use the SDHC built into some Kinetis SoCs like the MK64. 

I will be writing more about it in the coming days (with hopefully an example application) but one of the big issues I have found is that, for some reason, an SPI block read operation will not work with about 40% of the SD Cards that I've tested (and I've tested almost 40 of different manufacturers and sizes). 

So, that renders the use of DMA for this operation moot. 

myke

0 Kudos