need an advice on using sd card

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

need an advice on using sd card

7,747 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dragilla on Wed Nov 23 03:38:24 MST 2011
Hey,

I want to use sd card in project to:
a) read some configuration data (best would be from a text file)
b) save data regularly from my 100hz loop (I want to save data say every 5 iterations of my loop)

How long do you think will it take to write 100-200 bytes of data to an sd card directly (no fs)? How much longer will it take using petit fatfs for example?

Should I write the data from inside my loop or should I use interrupt maybe and write my data onto sd in a "free" time?

If you have some examples of reading/writing to an sd card (with or without fs) using cmsis 1.3 they are greatly welcome here :)

regards,
--
Luke
0 项奖励
回复
52 回复数

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jaybee on Wed Dec 28 21:38:42 MST 2011
I cant seem to be able to port the Fatfs example given in AN10916 even thou the board they tested on : MCB1700 had the exact pin connections to the board i am using: RDB1768.

Can i have some advise on where do I change the settings on lpcxpresso to generate the \debug\...axf file?

Of if possible some steps on porting the api?? cant seem to find them anywhere online
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Sun Dec 11 04:00:09 MST 2011
I've just created a new version of my test software (see this page).

Things added:

[LIST]
[*]I discovered that my problem was due to a timeout so I made the timeout time configurable.
[*]Also added writing of some data pattern and checking for this pattern while reading a file
[*]Created some real content for the log file write command
[*]Added a command to type a text file to the terminal.
[/LIST]
I've also checked to see that the use of P0.6 as SSEL works.
Not checked yet: use of SSP0.


Regards,[INDENT]Rob

[/INDENT]
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Sat Dec 10 00:48:33 MST 2011
Tabby,

there must be something wrong with the connections.
I have not yet tested with P0.6 as SSEL so there could be a problem in my software ...
If there is no card available (or if there is any problem with the connections) you get this error.

Could you debug and step through SD_Init() ?
When you step into the Send_Command() function you should see the SSEL line going low (just measure with a volt meter). If the line does not go low, check the peripheral view to see if P0.6 is indeed programmed as output pin and if it indeed is low.
The first instance of Send_Command() will send the GO_IDLE_STATE command.
This sends 40h 00h 00h 00h 00h 95h and after this only clock pulses are generated.
If the card accepted the command it should respond with a status that is not FFh within 8 bytes.
If this does not happen it is likely there is a problem with the SPI lines.

I'll see if I can check the P0.6 use today.

Regards,[INDENT]Rob
[/INDENT]
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tabby on Fri Dec 09 16:33:30 MST 2011
sadly i am using version 0.2 and i receive the same error for every command except speed 1m. Any thoughts?

I am sending the commands in this order:
speed 1m
dir
log txt
speed 1m
speed 1m
write what
dir
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Fri Dec 09 13:26:47 MST 2011
Tabby,

the test program is just something I quickly smashed together. I don't like howw it is written too much but it does do the job I want it to do without having an overcomplicated structure.

If you downloaded the first version of the program I posted (meanwhile there is a .zip file with v0.2 in the filename) then you need to perform a "speed" command first.
The thing is that the file system is not mounted when the program starts.
So either do something like "speed 1m" to set the SPI speed or just grab the newer version - I still need to add some tests to write/read certain patterns.

Dragilla,


Quote:
As for the defines should I just comment all the first occurrences of CCR, enable_irq_user() and disable_irq_user()?


The CCR define is usd by the RTC part of the code - so just leave the one in the RTC register structure. The irq_user() functions are not used at all so you can remove both without running into problems during compilation.

There are still a few things I like to add to the program:

[LIST=1]
[*]Write/read using a test pattern
[*]Add DMA
[*]Integrate into a FreeRTOS app (including the RTOS support in FatFS)
[/LIST]
Rob
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by tabby on Fri Dec 09 10:22:36 MST 2011
Rob and dragilla,

I am having the same trouble with the SD card. In my last ditch attempt I am now using the test program that Rob created...nicely done btw. However, I have having some trouble and when I execute dir i receive
   
Quote:
Cannot open dir: res=3 FR_NOT_READY


Any idea on what could be going on?

I am using the LPC expresso 1769
The CS is high and i do not have a scope to test data going over the MOSI.

/*
 * Configuration options:
 *
 * SSP: 0 / 1 to use SSP0 or SSP1
 * USE_EA_BASEBOARD: 0 - Use normal (P0.6 - SSEL) I/O line for CS on SD Card
 *                   1 - Use P2.2 as CS line on the SD card
 */
#define SSP 1
#define USE_EA_BASEBOARD 0


pins are
0.9 - MOSI <-> DI on the SD reader
0.8 - MISO
0.7 - SCK
0.6 - SSEL
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dragilla on Fri Dec 09 10:19:25 MST 2011
The gpdma is just a part of my code. As for the defines should I just comment all the first occurrences of CCR, enable_irq_user() and disable_irq_user()?
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Fri Dec 09 10:04:35 MST 2011
You will probably have found out that these double definitions are just double defined in the LPC1700.h file:

#define    IO0IntStatF    (*(volatile uint32_t*)0x40028088)
#define    IO0IntClr    (*(volatile uint32_t*)0x4002808C)
#define   [COLOR=Red] [B]IO0IntEnR[/B] [/COLOR]   (*(volatile uint32_t*)0x40028090)
#define    [B][COLOR=Red]IO0IntEnR [/COLOR][/B]   (*(volatile uint32_t*)0x40028094)
#define    IO2IntStatR    (*(volatile uint32_t*)0x400280A4)
#define    IO2IntStatF    (*(volatile uint32_t*)0x400280A8)
#define    IO2IntClr    (*(volatile uint32_t*)0x400280AC)
#define    [B][COLOR=Red]IO2IntEnR[/COLOR][/B]    (*(volatile uint32_t*)0x400280B0)
#define    [B][COLOR=Red]IO2IntEnR    [/COLOR][/B](*(volatile uint32_t*)0x400280B4)


The second instances should be IO0IntEn[B]F[/B] and IO2IntEn[B]F[/B].
The CCR define that is being referred in the error messages defines the same define twice with different content. Same goes for the enable_irq_user() and disable_irq_user().
This made me wonder it this software was properly tested ...

I'm not sure where you got the errors in gpdma.c from - there is no gpdma.c in my version. I assumed you downloaded ffsample.zip?

If there is a version that uses DMA it might be worthwhile testing and benchmarking this version against the NXP implementation.

Regards,
[INDENT]Rob
[/INDENT]
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dragilla on Fri Dec 09 05:42:27 MST 2011
Hello again. I managed to run my sd at 10mhz finally. At 25 it fails though. Anyway it works fast enough. I used the chan's example from his site (http://elm-chan.org/fsw/ff/00index_e.html).
I wonder only why there are double definitions of some terms, like:


**** Build of configuration Debug for project TCL ****

...

In file included from ../src/mmc.c:70:0:
../src/LPC1700.h:277:0: warning: "IO0IntEnR" redefined
Finished building: ../src/lpc17xx_clkpwr.c
 
Building file: ../src/lpc17xx_gpdma.c
../src/LPC1700.h:276:0: note: this is the location of the previous definition
../src/LPC1700.h:282:0: warning: "IO2IntEnR" redefined
Invoking: MCU C Compiler
../src/LPC1700.h:281:0: note: this is the location of the previous definition
../src/LPC1700.h:935:0: warning: "CCR" redefined

...

../src/LPC1700.h:776:0: note: this is the location of the previous definition
../src/LPC1700.h:988:0: warning: "__enable_irq_user" redefined

...

../src/LPC1700.h:986:0: note: this is the location of the previous definition
Finished building: ../src/lpc17xx_gpio.c
 
../src/LPC1700.h:989:0: warning: "__disable_irq_user" redefined

...

../src/LPC1700.h:987:0: note: this is the location of the previous definition


If it is on purpose (I assume it is) then what's the point? And how to avoid those ugly compilation warnings?
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Fri Dec 09 00:57:56 MST 2011

Quote: james

I download all the file from https://lpc17xx-fatfs-sdc.googlecode.com/hg/ , and tried compiling but it returns lpc17xx_ssp.h: No such file or directory.
...
Please point me some directions thank you.


Would it not be so much easier to use one of the readily available examples.
I've already pointed out AN10916 ([U]available here[/U]) and my on test program ([U]available here[/U]).
Both contain complete project archives for LPCXpresso. The NXP Application Note sets the SPI to 25 MHz, with my test progam you can easily change the frequency to check what works on your board.

Rob
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by james on Thu Dec 08 21:13:18 MST 2011
Hi,

I am searching on a method to read/write to the SDcard. I am planning to store all the values collected from the ADC to an array[99] then write into the SDcard once it the array has been filled.

I am quite new to ARM, i read up ChanFAT website but still confuse on the methods.

I download all the file from https://lpc17xx-fatfs-sdc.googlecode.com/hg/ , and tried compiling but it returns lpc17xx_ssp.h: No such file or directory.

What should be written in this file?

#define SDC_SSP_PORT   my_ssp_port_value?
#define SDC_MOSI_PIN?
#define SDC_MISO_PIN?
#define SDC_SCLK_PIN?
#define SDC_SSEL_PIN ?

but in the file diskio.c

it already written:
//SSP pins
#define SDC_SSP_PORT        (0)
#define SDC_MOSI_PIN        (9)
#define SDC_MISO_PIN        (8)
#define SDC_SCLK_PIN        (7)
#define SDC_SSEL_PIN        (6)

I am also missing the lpc17xx_gpio.h and lpc17xx_pinsel.h
What should i write or include in these files?
I have CMSISv2_LPC17xx and CMSISv2p00_LPC17xx and CMSISv1p30_LPC17xx in my workspace

i googled for lpc17xx_ssp.h and pasted into my folder but it still returns the same error

Please point me some directions thank you.


i am using rdb1768 board, which has a lpc1768.
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dragilla on Thu Dec 08 14:50:53 MST 2011
I've just made a strange experiment I did something I know I shouldn't be doing. Namely I put most of my code into an ISR

Now I have more less something like this:
main()
{
   init_interrupt(); // initialize a RIT timer (generates interrupt once every 10 ms)

   while(1) {
      if(sd_buffer_full) {
         write_buffer_to_sd_card();
         sd_buffer_full = 0;
      }
   }
}

void main_loop(void)
{
   read_sensors();
   bytes = read_gps_buffer(); // buffer is filled using interrupt
   if(bytes) {
      fill_sd_buffer(); // with data from gps and other sensors
      sd_buffer_full = 1;
   }
}

10ms_isr()
{
   if(main_loop_working) return;
   main_loop_working = 1;
   main_loop();
   main_loop_working = 0;
   return;
}


What is the danger here, why shouldn't I be doing it this way? It works 100% fine - my main loop is 100% stable (10ms) and data is saved to an SD card perfectly.
Without any additional task scheduler or rtos I've got two tasks working in preemptive mode - exactly what I needed.

regards,
--
Luke
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Wed Dec 07 02:32:22 MST 2011
Indeed, as Angelo already points out you need some means of buffering data.

I've just finished a first crude version of the test program (available here) that writes to a file and shows (per f_write() call) how long it takes.
This shows very funny results.
The first block being written (after f_mount() and f_open()) may take as much as 400 ms. Blocks written afterwards are showing different times: around 6 and 3 ms. when running SPI at a 10 MHz clock and times of 11 and 7 ms when running at 1 MHz. This alternates so the first sector takes 11 ms, the next 7 ms etc.
At a certain point, f_write() takes a long time (200 ms or so) most likely due to the fact that the FAT must be written and a new cluster must be searched.

You'll need some way of buffering your data to cope with these larger delays when writing to a file.

The test program is not complete (will it ever be :eek:) and I just remember that I have not even implemented the timer function that is needed by FatFS to guard block write and reads - meaning that the program will just hang when certain errors occur.
Still, I did not want to keep this work away from you too long. Hopefully I've got some more time tonight or tomorrow.

Regards,[INDENT]Rob
[/INDENT]
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Polux rsv on Tue Dec 06 12:25:58 MST 2011
As I explained, data is written to ram buffers. It is fast. But when buffer is full and filesystem decide to write it to the SD, there is a delay when waiting on SD status. This delay is depending on brands and type of SD. That's why you should add another stage of buffering. This is nothing different than an "uart buffer" where receive interrupt fills the buffer and the main loop read chars from the buffer.

Angelo
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dragilla on Tue Dec 06 09:56:56 MST 2011
I'm doing my own tests as well and I discovered that it will be very hard if not impossible for me to save data 20times per second. Or at least using fatfs. I discovered that even writing little pieces as often 100 times/second or bigger buffered pieces as rare as 2 times/second makes my loop unstable - once every 100-200 cycles I get a cycle that lasts 15 ms (loop at 100hz, so 10ms max).
And this is even without f_syncing. F_sync once a second for example takes almost 200ms!

Maybe there is some sort of a hardware buffer I could use?

I'll try to test freertos this week.
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Tue Dec 06 00:34:58 MST 2011
According to the user manual (section 18.6.5 "SSPn Clock Prescale Register"), the clock divider CPSR must be an even number 2..254 in master mode, resulting in a SPI clock of:[INDENT]PCLK / (CPSR × [SCR+1])
[/INDENT]Where SCR is the prescale divider in the CR0 register with a range of 0..255

So the max. SPI clock frequency is 100 / (2 x [0+1]) = 50 MHz
When PCLK = CCLK...
I think that with the lpc1769 you can go up to 60 MHz - this would not be the first fault in the datasheet ... but the max. frequency is not out problem.

Please note: when using slave mode the SPI clock must have a max. frequency of 1/12 PCLK (also in section 18.6.5).

On my own board I had no problems running the SD card up to 25 MHz which is the max. SPI clock frequency according to the SD Card v1.0 product manual.
On the Embedded Artists board I cannot get the SPI clock higher than 10 MHz before getting errors while reading.

Here is why:
[IMG]http://bikealive.nl/img-for-others/LPCXpresso-forum/SD-result-10MHz.png[/IMG]
This picture shows the response from the SD card on a SEND_CID command. The lpc sends 4A 00 00 00 00 01 (command + argument + CRC) and then clocks the SPI bus until it receives a comfirmation from the SD card (FF 00). After this the SPI bus is clocked to read the CID register (16 bytes) but first the SD card has to confirm that it starts sending data by returning the FE byte (shown here) - after this 16 bytes of data are received.

It's this code in SD_ReadConfiguration() on these lines in the code from AN10916 in sd.c:
    /* Read CID */
    if ((SD_SendCommand(SEND_CID, 0, NULL, 0) != R1_NO_ERROR) ||
        SD_RecvDataBlock (CardConfig.cid, 16)==SD_FALSE) goto end;
This is the first point during initialization where the timing is critical, so this is where the software hangs on the EA Base board.
The raising edge of the 8th clock pulse comes sooner than the falling edge of the MISO signal as the clock frequency is increased.
But even when the initialization goes OK (when the edges are close to each other) it could still be that later on during data transfer errors occur.

I'll post my program with a more elaborate version of the transfers later this week.

Rob

P.s: the software from AN10916 does not calculate the divider values to get the correct frequencies. These are hard coded in the spi driver - changing the CCLK value will change the timing.
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dragilla on Mon Dec 05 08:39:45 MST 2011
I had the number in my head, but it was a limit for the slave mode. Quoting UM10360:
"It is required that the system clock driving the SPI logic be at least
8X faster than the SPI."
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Mon Dec 05 05:52:23 MST 2011
Datasheet:

Quote:

7.17 SPI serial I/O controller
7.17.1 Features
• Maximum SPI data bit rate of 12.5 Mbit/s

7.18 SSP serial I/O controller
7.18.1 Features
• Maximum SSP speed of 50 Mbit/s (master) or 8 Mbit/s (slave)

So what do you think is he talking about :rolleyes:
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dragilla on Mon Dec 05 05:21:19 MST 2011
25MHz? I thought that SPI can only work up to 1/8 of the core clock, which gives me 15MHz (120MHz core).
0 项奖励
回复

4,640 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Mon Dec 05 02:08:07 MST 2011
I'm working on the idea.
I've set up an EA base board with lpc1769 module.
The first step was to port my working FatFS implementation. I discovered that you need to actually [I]read[/I] the user's manual, not just glance it, there are just too many jumpers on the baseboard.
And just now I discovered there is indeed too much on the base board.
The software hangs while reading the response on the SEND_CID command due to the status flag (0xFE) never being received.
The logic analyzer shows that the MISO is delayed such that the high-low transition is seen too late. Most likely due to a weak output stage of my Sd card combined with long traces and paracitic capacitances on the board.

Lowering the frequency makes it work again, the EA base board (that is [I]my[/I] EA base board with [I]my[/I] jumper settings and [I]my[/I] SD card) does not work on a 25 MHz SPI clock.

So this could be a source of the damaged content of your card. Since the software does not perform any CRC checking there is no way to know for sure the data received is correct...

To be continued.

Rob
0 项奖励
回复