Hello everybody!!
I'm developping an application and I need to write/read some data in a microSD Card.... I have Freescale's Flexis JM SD Card Reader, hardware and software... If I'm not wrong, documentation DRM104 refers to it.
This Freescale's hardware comes with 2 demo softwares:
1- SD Card Datalogger
2- SD Card Reader (USB-SD Reader)
Both softwares work fine... The datalogge logs the lumens or lux sensed (I don't remember wich one). Then, with the other soft. I can see the file content...
Now, for my application I want to use a microSD instead of a SD Card [Note: for the communication I use a SPI, not the SD Card Protocol]... So, to test if it's working I log the data wiht my own application and read the content wth Fresscale's Card Reader (I put the microSD in a SD adapter)...
Well nothing happens... I can read the microSD Card, but it's empty...
So then I use the microSD with Freescale's Datalogger (again, the microSD inside a SD adapter)... For my sourprise, nothing happens, one more time....
Once, I remember being in a Freescale Seminaire... And if I recall correctly, someone told me that NOT every microSD can be access by SPI.... So my question is... is that true? Does the microSD Card have other interfacing needs?
Thanks all of you!!!!
已解决! 转到解答。
Hi Sebastian
It is true that not all HCSD cards do (or will continue to) support SPI - I don't think that it is microSD card specific though. The SPI support is an option and may be dropped by some manufacturers. Personally I expect that it will only be on high-end cards since there are many devices that use SPI as simple and reliable solution (possible on just about any small processor) and this dem,and will hardly change in the foreseeable future.
As long as you keep away from the highest speed cards (especially for video, etc. where the SD interface will be a must) you probably won't have problems. I tested a number of HCSD cards recently and didn't actually find any in the 'standard' range up to 8GHz that didn't support the SPI mode.
Note also that if the SPI mode is not supported there will be no possibility to communicate with the card (using the SPI mode) and so the SPI based driver will probably declare that the card is not present.
See also the following for some more details: http://www.utasker.com/docs/uTasker/uTasker_utFAT.PDF This may also be made available for the V1 Coldfires shortly but is presently available for the V2 single-chips ones.
Regards
Mark
Thanks you too, Mark!
I try 2 different mircoSD cards from 2 different manufacturers (N*kia and S*nD*sk).. Non if them works as data logger... The strange thing is that both of them works when I load the Card Reader software to the microcontroller... And I can read/write the microSD card...
The Freescale's SD Card Reader software, communicates with the SD Card via SPI so I guess both microSD support SPI, because otherwise they wouldn't work...
So now the question is... If Freescale's DataLogger soft works fine with a SD card, and Card Reader works with microSD via SPI... why doesn't the DataLogger works with microSD cards?
Now I'll check both SPI.c and .h files to see if I can find any difference
Thanks in advance!!
Well I check both SPI.c files and find something interesting...
First, let me introduce you: The SPI must run at 375Khz in order to initiate communicate with the SD card. Then it could (or must?) switch to a higher rate to for data exchange.
The major differences were:
Initialization
DATALOGGER SPI_BR_REG = 0x24 // 375Khz
CARDREADER SPI_BR_REG = 0x14 // 375Khz
I also check clock initialization and was different, so they run at different bus speeds, but the important thing is that both SPI clocks are set to 375Khz
High Rate
DATALOGGER SPI_BR_REG = 0x11 // 375Khz
CARDREADER SPI_BR_REG = 0x00 // 6Mhz
Here I see two things:
1- First of all, hgiher ates are differents. One is "375Khz" while the other is 6Mhz
2- As you can see in red, both comments says that speed is 375Khz... That's not correct, second value of the regsiter is a lower one, so it's actually a higher rate.
Then, doing some math (for the DATALOGGER) we get that:
Assuming that initialization is correct and it's set to 375Khz as it must be
BaudRateDivisor = (SPPR + 1) * (2^(SPR + 1))
SPPR = 2
SPR = 4 -----------> BR_Div = 3 * (2^5) = 96
So, if BaudRate is 375Khz, then BUSCLK = BaudRate * BR_Div = 375Khz * 96 = 36Mhz
Now I'll calculate the higher rate:
SPPR = 1
SPR = 1 -----------> BR_Div = 2 * (2^2) = 8
BaudRate = BUSCLK / BR_Div = 36Mhz * 8 = 4.5Mhz
So we get that:
DATALOGGER HIGH RATE = 4.5Mhz
CARDREADER HIGH RATE = 6Mhz
Maybe this is the difference.... But the odd thing is that it works at the higher rate, so it should also work at a lower one
I'd like to keep testing but it's kind of late on this side of the Earth, LOL..... I'll continue tomorrow, any suggestions/corrections/directions are totally wellcome
Best Regards.
I am developping an application and I need to write some data in a microSD Card. I have Freescale's Flexis JM
SD Card, hardware and software.
I am using micro SD Card. In MC9S08JM60(8 bit) hardware I log the data WITH demo code and it working fine.
But with MC51JM128(32 bit) hardware i could not log data in micro SD card and it is empty.
I tried bug in SD_Write_Bloc (SD.C)
The changes were from:
=============================================
for(u16Counter=0;u16Counter<BLOCK_SIZE;u16Counter++);
if((ReadSPIByte() & 0x0F) != 0x05)
=============================================
To:
=======================================================================
SD_response=0xFF; // #001 created this variable
while (SD_response==0xFF) SD_response=ReadSPIByte(); // #001 wait for SD response <> 0xFF
if((SD_response & 0x0F) != 0x05) // #001 checks if response = 0101 = data accepted
{
SPI_SS=DISABLE;
return(WRITE_DATA_FAILS);
}
========================================================================
But i could not log data in micro SD card
Anyone can help me to solving this problem.
Nitin Gadgeel
Hi Ngadgeel,
You can try our MCF51JM128 demo. Right now we are using a better FAT file system implementation, which supports FAT32 and directory structures. You can download the code in this links:
Coldfire JM128 Demo:
http://brtos.googlecode.com/files/TWR-LCD-FatFS.rar
Coldfire QE128 Demo:
http://brtos.googlecode.com/files/BRTOS%20CFV1%20SD%20Card%20%2B%20FatFS.rar
You can remove the GLCD code simply by not installing the GLCD task in the main.c file. This will reduce a lot the compiled code.
Thank you
Now data is logging in SD card using MCF51JM128.
One other thing is I have FLEXIXJM60 card reader software.
By using this SD card data is read. This is working fine. After converting this code to 32 bit MCF51JM128 code at the time
of compilation some error comes. How to eliminate these errors OR there FLEXIX MCF51JM128 32 bit card
reader code is available?
Regards,
Nitin
I'm me again with this topic....
I'm having the same troubles as before... one year ago... I also got to say that it's been a year since I last work on this project..... Now I'm back to it...
Well as said before, I've got Freescale Hardware and Software, the SD Card Reader with a MC9S08JM60 MCU. If you look for DRM 104 on freescale web site you'll find the App Note and there you can see the hardware I'm talking about.
I also have both codes:
1- SD Card Reader
2- Datalogger
Well soft #1 works perfectly fine but I can't get soft #2 to work... Same thing as before... I'm working with a 2gb SD card and also with a 128mb microSD card with SD adapter...
Datalogger needs file LOG.TXT to be created previously... So I create it using my laptop. Then run the datalogger application with the card inside. When I extract the card, it seems empty.... I mean, it "seems" because if I want to create a file named LOG.TXT it says it allready exists but I can't see any file in there...
I also look at post by Celso and I found nothing that could help me. Also try to use BRTOS, using the new implementation... But still nothing there. User guide is in Portugues and I'm from Argentina, and sadly I don't speak or read this language. Is there an english or better yet spanish version?
I attach datalogger software from Freescale website... If some one could tell me if there's somethign wrong there It would be great... It's not written by me, again, its from freescale.
Problem solve...
Celso's post help a lot.... link to post
also, don't know why but FAST SPI must be at least 4MHz value lower than that causes FAT_Read_Maste_Block to get stuck..
Best Regards, and Good Luck!
Hi sebastian.
im so interested to use a microsd with an JM128 coldfire microcontroller. based on schematics from one of JM60 demos, built a board where the microsd is connected trough channel 1 of SPI module. also, got the entire project of datalogger written for JM60. im using codewarrior 10.1 (new version).
im getting a lot of errors out from the project. found some problems: compiler doesn't recognize library headers, also, there are a lot of errors from fat.c file.
do you have any demo project written on CW 10.1 that works fine for JM128?
thanks a lot.
Hi Mauricio!
I don't have it for CW10.1... I made it work over CW 6.2. If you serch in the forum there are some threads about how to migrate from an earlier version of CW to v10.1.
Or if you don't want to deal with that you can download v6.2 and work with it.
If you've got more question I'd be please to help you out.
Saludos!
Hi Sebastián.
finally i could get it working on codewarrior 6.3
it creates the .txt file if it doesn't exist previously, also it logs data from serial port nice and clean.
but i have some questions about using fat libraries.
At this moment, im using FAT16 libraries, tested with 128Mb Sandisk uSD, 256Mb Nokia uSD and generic 2Gb uSD.
created log files shows data like this:
001;001;001;001;..... and so. i would like to write into uSD card with indexed information, as excel tables like this
001 002 003
001 002 003
...... .... .....
to export data easily on excel, labview or matlab.
also, i wanna create multiple txt files on execution. using this procedure:
u8Error=FAT_FileOpen(FILE_NAME,CREATE);
#define FILE_NAME "DATALOG.TXT"
and changing FILE_NAME would create a new txt file, i think.
how can i change the definition above while running, to create files like:
DATALOG_001.TXT
DATALOG_002.TXT
DATALOG_003.TXT
DATALOG_004.TXT
Than you for your hep, i will await your reply.
Regards;
I forgot about the indexation of the logged data...
You can write on the SD whatever you want. I don't have right here the freescale example project. But there must be a place where it creates the buffer to write into the SD and add a semi-colon ( between each data value. You'll need to change that separator so it would be a space or a tab...
ASCII values:
; --------> 0x3B<space> --> 0x20<tab> ----> 0x09
I've never test the TAB value.
If anything else arrise, you can find me here.
Regards
Sebastian, thank you for you help.
last post related to changing file name during runtime, i think how i can get it work for me.
this is the code to check if eisting file is already on uSD, and create a new one if the card is empty.
u8Error=SD_Init(); FAT_Read_Master_Block(); if (FAT_FileOpen(FILE_NAME, MODIFY) == FILE_NOT_FOUND) { u8Error=FAT_FileOpen(FILE_NAME,CREATE); } FAT_FileClose(); u16SampleCounter=0;
using the expression inside the if, i can create a new file with array managment you propose above. i will try it later.
talking about data spacing on uSD, this is the code to open, write and close data in uSD. also, created a test routine with RTC to send data every 2.5 seconds.
RTC_Counter=RTCCNT; if(RTC_Flag){ RTC_Flag=0; State_Led=~State_Led; DEC_to_ACC(gu8ADCResult); gau8LogArray[u16SampleCounter++]=gu8Result[0]; gau8LogArray[u16SampleCounter++]=gu8Result[1]; gau8LogArray[u16SampleCounter++]=gu8Result[2]; gau8LogArray[u16SampleCounter++]=0X09; if(u16SampleCounter==SAMPLES_WRITE){ //State_Led=~State_Led; u16SampleCounter=0; u8Error=FAT_FileOpen(FILE_NAME,MODIFY); FAT_FileWrite(gau8LogArray,SAMPLES_WRITE); FAT_FileClose(); } }
made some test's adding a TAB between samples. works amazing!, just i liked to do.
if you said that works sending ascci codes into the data buffer, maybe i could use this efinitions i created for SCI module:
//definiciones para el modulo USART del microcontrolador;#define ENTER 13 //caracter ASCII para tecla ENTER;#define LF 10 //caracter ASCII para el Line Feed;#define CR 13 //caracter ASCII para el Carriage Return;#define SB 32 //caracter ASCII para el Space Bar;#define Char_NULL 0 //caracter ASCII para NULL (vacio);#define DEL 127 //caracter ASCII para Delete (suprimir);
i'll make some further testing.
Regards;
Hola Mauricio!
Veo que los 2 hablamos español, para que complicarnos con el idioma?
Agrandar el buffer es solo necesario, si el mismo no es lo suficientemente grande como para alojar los datos. Y eso dependerá de tu aplicación y cuántos datos quieras grabar.
Respecto a los caracteres ASCII, no se cual/es habras probado. Deberían funcionar todos, aunque hay algunos una tanto especiales, que no se como se verán reflejados en un archivo de texto. Por ejemplo el caracter de SUPRIMIR y el de NULL, esos no son caracteres de TEXTO validos, y los mas probable es que te escriban algun simbolo extraño. En su mayoria deberia funcionar.
Por ejemplo, en uno de mis trabajos anteriores, cuando queria hacer un cambio de renglon, usaba el caracter LF (Line Feed).
En tu otro post vi que definias al caracter del ENTER como 13 (que es correcto y es igual al CARRIAGE RETURN). Es muy comun querer hacer un cambio de renglon con un ENTER, xq es como uno lo hace al escribir, pero en realidad un cambio de renglon es un LINE FEED (new line).
A modo de comentario, el ENTER cumple una doble funcion. Es como lo que se hacia antiguamente con una maquina de escribir. Primero un Carriage Return ("Retorno de Carro" es llevar el "carro" de la maquina de escribir al inicio del renglon) y luego un Line Feed ( que es bajar de renglon, crear una linea nueva).
Espero que esto te haya servido y puedas terminar tu aplicacion!
Solo por curiosidad... en que proyecto estas trabajando exactamente? (si es que puedes o quieres contarlo, comprendo si decides mantenerlo reservado)
Saludos!!!
Sebastian, un cordial saludo.
bueno, tiene toda la razon, para que complicarnos con el idioma. solamente que me parece importante que lo que solucionemos entre los dos le pueda servir al resto de foreros, por eso el tema de hablar en inglés!.
con respecto a la tarjeta, he intentado meter casi todos los comandos ascii posibles. el unico que tiene un efecto apreciable es el tab. carriage return, line feed y otros no tienen efecto. o generan un caracter extraño en la memoria, o le dañan el formato o simplemente no hacen nada. seguiré probando.
jajaja realmente el proyecto no es secreto. consiste en un core para un UAV. este core se basa en una tarjeta de diseño propio (que hice para mi tesis de grado) y está basada en un MCF51JM128 de 80 pines.
estas son algunas fotos del desarrollo:
}
esta tarjeta incluye:
layout basado en arduino mega
12 entradas analogas disponibles
4 salidas analogas
30 pines I/O de uso general disponibles en riostra
comunicacion CAN, SCI (1 puerto por FTDI232, un puerto por MAX485) un puerto I2C y un puerto SPI disponibles
10 salidas de pwm (4 compartidas con salidas analogas, seleccionables por jumper)
fuente de alimentación triple (12V, 5V, 3.3V) automática (selecciona entre jack y usb automaticamente
alimentación de mcu seleccionable por jumper (3.3V y 5V)
cristal de 12Mhz (el core lo tengo trabajando a 24Mhz de bus)
lector de tarjetas uSD compartido con puerto spi
puerto BDM disponible
riostras para LCD compartidas en puerto A
boton de reset y boton de boot
conector usbotg (para corregir un bug en la version 2.0)
la idea, es agregar un shield con un gps venus de sparkfun, una IMU de 6 grados de libertad y otros periféricos para control de vuelo. el proyecto tendrá un avion con motor glow 0.40, la camara a bordo es una kodak easyshare c743 de 7Mpx también modificada con un micro m9s08se8 para recibir señales de servo.
en fin, un proyecto que tengo desde hace unos 2 años y que ahora estoy avanzando. la uSD es para hacer (la caja negra) del avion.
muchos éxitos, y gracias por toda la ayuda!
Hello Mauricio!
You're right, changing that definition, would change the name of the file created. There are several ways of changing the name...
I gues the easiest way is to define some constant like:
const byte fileName[] = {"DATALOG_"};const byte fileExtension[] = {".TXT"};
With fileName you would have the "base" name of your files, and fileExtension is the extension of that file:
NOTE: If I remind correctly the file name and extension MUST be UPPERCASE.
Then you would need a variable where you will hold the index of the file name. And you'll need a way to increment that value. And then do some string operations to get the complete file name. For example:
byte fileIndex[] = {"001"};byte entireFileName[20];/* entireFileName = "DATALOG_" */ strcpy(entireFileName,fileName); /* entireFileName = "DATALOG_001" */ strcat(entireFileName,fileIndex); /* entireFileName = "DATALOG_001.TXT" */ strcat(entireFileName,fileExtension);u8Error=FAT_FileOpen(entireFileName,CREATE);
I can think of 2 ways to increment the value:
1) You can have a byte value, and convert it to string with some function like itoa (integer to array)
2) You can have the same byte value, as index of a table containg the asociated string
Hope it helps!