Discussion in "8051 Discussion Forum" started by    Help    Dec 8, 2008.
Sat Jan 31 2009, 12:58 AM
#71
I'll try:

Firstly, Chan has written two different versions of his FAT file system: FF.C and TFF.C - I chose to port the TFF.C version.

The only files you need to concern yourself with are the DISKIO.C file and the TFF.H file, which has conditional compiler options in it...

Before you begin the port, I recommend you have working the basic SPI functions you need to communicate with the card. This is very important, so you don't waste time trying to debug something within Chan's stuff, when really it's your routine that doesn't work...

My basic routines are as follows:

   enum SPI_FREQUENCIES { kHz400, MHz1, MHz5, MHz10 };

   extern void SPI_EnableCS      ( );
   extern void SPI_DisableCS     ( );
   extern void SPI_Init          ( enum SPI_FREQUENCIES ThisFrequency );
   extern BYTE SPI_Byte          ( BYTE ThisByte );
   extern void SPI_SetChannel    ( BYTE ThisChannel );

   extern BYTE SD_Init           ( );
   extern BYTE SD_Command        ( BYTE ThisCommand, ULONG ThisArgument );
   extern BYTE SD_CRC_7          ( BYTE *List, BYTE Length );
   extern BYTE SD_GetR1          ( );
   extern WORD SD_GetR2          ( );
   extern BYTE SD_ReadSector     ( ULONG SectorNumber, BYTE *Buffer );
   extern BYTE SD_WriteSector    ( ULONG SectorNumber, BYTE *Buffer );
   extern BYTE SD_WaitForReady   ( );


When you feel each of the above routines works perfectly, begin the port by rewriting the 5 simple functions in DISKIO.C, namely:
DSTATUS disk_initialize( BYTE drv )
DSTATUS disk_status( BYTE drv	)
DRESULT disk_read ( BYTE drv, BYTE *buff, DWORD sector, BYTE count )
DRESULT disk_write( BYTE drv, const BYTE *buff, DWORD sector, BYTE count )
DRESULT disk_ioctl ( BYTE drv, BYTE ctrl, void *buff )


Here is an example of how I wrote the disk_read(...) function above:
/*-----------------------------------------------------------------------*/
/* Read Sector...                                                        */
/*-----------------------------------------------------------------------*/
DRESULT disk_read ( BYTE drv, BYTE *buff, DWORD sector, BYTE count )
   {
   /* Supports only single drive and must have a size of 1 sector */
   if( drv || !count || (count>
1) ) 
      return( RES_PARERR );

   /* if we haven't initialized the card yet... */
   if( Stat & STA_NOINIT ) 
      return RES_NOTRDY;
   
   /* Single block read */
   if( SD_ReadSector( sector, buff ) )
      return( RES_ERROR );
   
   return( RES_OK );
   }


The same must be done for each of the 5 functions listed...
Also, the compiler options within TFF.C must be set correctly. Here is how I have mine set:
#define _MCU_ENDIAN	2
#define _FS_READONLY	0
#define _FS_MINIMIZE	0
#define	_USE_STRFUNC	1
#define	_USE_FORWARD	1
#define _FAT32	        0
#define _USE_FSINFO	1
#define	_USE_SJIS	1
#define	_USE_NTFLAG	1


Once you have written each of the 5 functions listed, and everything compiles, you will need one final function:
DWORD get_fattime()
   {
   RTC_CURRENT rtc;
   
   
   RTC_read( &rtc );
   
   return	  ((DWORD)((WORD)(rtc.Year) + 2000 - 1980) << 25)
                  | ((DWORD)rtc.Month << 21)
                  | ((DWORD)rtc.Date << 16)
                  | ((DWORD)rtc.Hours << 11)
                  | ((DWORD)rtc.Minutes << 5)
                  | ((DWORD)rtc.Seconds >
>
 1);
   }


This particular function reads the time from my on-board real-time clock and formats the data for Chan's routines...

Hope this helps - my system is working perfectly...

Mon Feb 02 2009, 05:10 AM
#72
I have been private-messaged by the Original Poster to start from the beginning... :-s

I'm not sure exactly what specific points you need help with. Perhaps you can explain your question in detail here.

i just re-read the entire thread on this subject, and Ajay has been very specific, including example code for the low-level drivers that interface with the SPI bus. I too have been very specific, with code examples and suggestions.

If you have a specific question, I would be happy to try and answer...

By the way, do you have a name, or is your real name "Help"

-dave
Mon Feb 02 2009, 08:15 AM
#73
Dear Dave,

I'm using AT89C52 uC. This uC don't have build in SPI function but Ajay have taught me how to write the SPI routine for MMC.
1) If for my case the uC have not SPI function. Do i still need SPI frequencies initial?
2) SPI_SetChannel() function, may i know how it work? Please can you guide me how to write the function routine.
3) SD_CRC_7(), SD_GetR1(), SD_GetR2(), and SD_WaitForReady() function, please can you share with us how you to write coding?

Dear Dave,..Sure i have a name. You can call me Tang Nice to meet you.

Thank you,.


[ Edited Mon Feb 02 2009, 08:20 AM ]
Mon Feb 02 2009, 11:03 AM
#74
Hello Tang,

To answer your questions:

1. Do i still need SPI frequencies initial? Yes. When communicating with the SD card over the SPI interface, the initial SPI clock frequency cannot exceed 400Khz, and must be faster than 100Khz. This can be found in the SanDisk Secure Digital Card Product Manual Version 1.9, section 4.5. under "Clock Control"

2. SPI_SetChannel() function SPI_SetChannel() is a function I wrote to select between several SPI devices that are all connected to the MOSI and MISO lines from my microcontroller. Recall that each SPI device has 4 basic connections: SPICLK, MISO, MOSI, and CS. These connections are the SPI clock signal, the input line to the microcontroller, the output line from the microcontroller, and a chip select (respectively). A very good description of this bus can be found at:

http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus

If you only have the SD card, you can connect the CS signal to any available output pin on your microcontroller (provided the voltage is 3.3v) and not use this function. If you have more than one device connected to this bus, then you must provide a way of selecting only one device at a time. For instance, say P3.0 is connected to the SD memory card CS pin, and P3.1 is connected to some other device (like a temperature sensor). Your routine might look like this:
enum DeviceChannel = { SD_CARD, TEMP_CHIP };

void SPI_SetChannel( enum DeviceChannel ThisChannel )
   {
   switch( ThisChannel )
      {
      case SD_CARD :
         P3 = (P3 & 0xFC) | 0x01;
         break;
      case TEMP_CHIP :
         P3 = (P3 & 0xFC) | 0x02;
         break;
      default :
         P3 = (P3 & 0xFC);
         break;
      }
   }


Please understand that your routine will be specifically designed for YOUR hardware configuration...
3. SD_CRC_7(), SD_GetR1(), SD_GetR2(), and SD_WaitForReady() function The SD_CRC_7() function is optional, actually. I wrote it so that I could calculate a 7-bit CRC value for a string of bytes. If you do not understand CRC, you can read about it here:

http://en.wikipedia.org/wiki/Cyclic_redundancy_check

Since you don't really need the CRC values for commands when communicating with the SD card, you can just ignore this function.

The SD_GetR1() function is for retrieving the response byte from the card when it is in the R1 format, as described in the SanDisk Secure Digital Card Product Manual Version 1.9, section 5.2.3.1. "Format R1"

My function is as follows:
BYTE SD_GetR1()
   {
   BYTE i, j;

   for( i=0; i<8; i++ )
      {              /* response will be after 1-8 0xffs.. */
      j = SPI_Byte( 0xff );
      if(j != 0xff)  /* if it isn't 0xff, it is a response */
         return(j);
     }
   return(j);
   }


I believe you can get the idea from this example, and write your own code for the R2 response. If you read section 5.2.3.3. from the product manual, it fully describes the format...

And finally, the SD_WaitForReady() function was just something to maintain compatibility with Chan's stuff. It is a simple routine that sends nothing but clock pulses to the SD card, and insures the card isn't in the middle of something.

My rendition of it looks like this:
BYTE SD_WaitForReady()
   {
   BYTE i;
   WORD j;

   SPI_Byte( 0xFF );
   
	j = 500;
   do
      {
		i = SPI_Byte( 0xFF );
      Delay( 1 );
      } while ((i != 0xFF) && j);
   
   return( i );
   }


Undoubtedly, you are wondering what the SPI_Byte() function does, as well as the Delay() function...
The SPI_Byte function sends a byte to the currently selected SPI device, and returns any response from that device. The Delay function waits for the number of milliseconds. In this example, the delay is 1 millisecond.

I hope this helps you...

By the way, if you don't already have a copy of the product manual, you can find it here:

http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf

-dave
Tue Feb 03 2009, 07:46 AM
#75
Dave, me and Help working on a controller with no SPI, i mean its just gonna be slow nothing else that that. everything else is going to remain same.

Well i cannot believe i made this mistake in downloading files

i just downloaded the new files.
so as i checked we only have to bother about diskio.c right? and define our own functions with name
MMC_disk_initialize();
MMC_disk_status();
MMC_disk_read(buff, sector, count);
MMC_disk_write(buff, sector, count);
MMC_disk_ioctl(ctrl, buff);

how much amount of minimum RAM needed for this?
Tue Feb 03 2009, 08:08 AM
#76
Dear Daves,



1. Please can you guide me how to write the SPI clock in 100kHz-400kHz? Is it correct the Clock Timing diagram? If correct, how can we write an efficiency code on this part? I'm worry if i put a while-loop/for-loop for delay 400kHz/100kHz then it will take the processor load usage, somemore SD have 512 byte's to send/receive, am i rite?

2. SPI_SetChannel() function i think i know how to do already. Thank for your advice.

3. I have ready CRC7 function. Please can you compare your result with mine? I would like to confirm the CRC7 function do correct not. Let say,
Ex1:
List[0]=0x40
List[1]=0x00
List[2]=0x00
List[3]=0x00
List[4]=0x00
Length = 5
CRC = 0x4A

Ex2:
List[0]=0x40
List[1]=0x00
List[2]=0x00
List[3]=0x00
List[4]=0x31
Length = 5
CRC = 0x68

The SD_GetR2(), and SD_WaitForReady() function i think should not be the problem, i can understand it. I think this two function have to complete all the basic routines then only can test. Hopefully after the basic routines finished tested is ok.

Thank you,.
Tue Feb 03 2009, 07:10 PM
#77
Tang,

Actually, when they say 100-400kHz, they're talking about frequency, which is defined here:

http://en.wikipedia.org/wiki/Frequency

so actually, your picture should look like this:




That means that from rising edge to rising edge, the time should be 2.5 - 10 usecs, which means you will need an interrupt for the rising edge, and then an interrupt for the falling edge. In other words, your interrupt must happen every 1.25 usecs, but not slower than every 5 usecs. Also, when the interrupt occurs, you must shift 1 bit of information out over your designated MOSI pin, and shift 1 bit of information in from your designated MISO pin, every OTHER interrupt...
Tue Feb 03 2009, 07:43 PM
#78
Ajay,

You are correct. :-) These, along with the compiler options located in either FF.H or TFF.H are the only things that need to be modified...

Regarding the memory, you need a buffer of 512 bytes for the read/write buffer and probably another 512 bytes for static variables, stack variables, and local buffers...

I am using XDATA for my variables, since I have NOVRAM attached to my microcontroller. My memory chip is an ST M48T37Y-70MH1E, which is an expensive part, but works nicely in my system. It also has an embedded real-time clock in it, which satisfies the need for date/time stamping on files I create on my SD card.

-dave
Tue Feb 03 2009, 08:46 PM
#79
Tang,

Regarding the CRC calculations, I get a different answer than you do:

Ex1:
List[0]=0x40
List[1]=0x00
List[2]=0x00
List[3]=0x00
List[4]=0x00
Length = 5
CRC = 0x95

Ex2:
List[0]=0x40
List[1]=0x00
List[2]=0x00
List[3]=0x00
List[4]=0x31
Length = 5
CRC = 0xD1

Here's a link to everything you ever wanted to know about CRC calculations:
http://www.geocities.com/SiliconValley/Pines/8659/crc.htm

I got help from here:

http://www.edaboard.com/ftopic102279.html

Here is how I calculate the proper 7-bit CRC:
// _____________________________________________________________________________________________
//                                                                                              
// Function: SD_CRC_7()                                                                         
//                                                                                              
// Description:                                                                                 
// ------------                                                                                 
// calulates the 7-bit CRC for a list of bytes...                                               
//                                                                                              
// Design Notes:                                                                                
// -------------                                                                                
// In the case of CRC-7, the remainder can be calculated using a 7-bit shift register in        
// software. This shift register is initialized to all zeros at the start of the calculation. As
// each bit (MSB first) of the protected data is shifted into the LSB of the shift register,    
// the MSB of the shift register is shifted out and examined. If the bit just shifted out is    
// one, the contents of the shift register are modified by XORing with the CRC-7 polynomial     
// value 0x09. If the bit shifted out of the shift register is zero, no XOR is performed. Once  
// the last bit of protected data is shifted in and the conditional XOR completed, six more     
// zeros must be shifted through in a similar manner. This process is referred to as            
// augmentation, and completes the polynomial division. At this point, the CRC-7 value can be   
// read directly from the shift register.                                                       
// _____________________________________________________________________________________________
//                                                                                              
BYTE SD_CRC_7( BYTE *List, BYTE Length )
   {
   idata BYTE crc = 0x00;
   idata BYTE i, j, mask;

   for( i=0; i<Length; i++ )
      {
      mask = List[ i ];
      for( j=0; j<8; j++)
         {
         crc <<= 1;
         if(( mask & 0x80 ) ^ ( crc & 0x80 ) )
            crc ^= 0x09;
         mask <<= 1; 
         }
      }
   crc = (crc << 1) | 1;
   return( crc );
   }
Wed Feb 04 2009, 11:32 AM
#80
Dear Daves,

Thank for your usefull information and thank for your CRC7 coding. Previously my code is
crc = crc << 1 | 1;
now i change it to
crc = (crc << 1) | 1;
then work fine already..Thank again.

Please guide me how to write the 1.25uSec interrupt? The frequency is too high. I'm using this fomula
F = 11059200
t = 2us
S = 65535 - (F*t)/12
S = 65533.1568
S = 0xFFFD
So, i define TL0=0xFD and TH0=0xFF.
Is it correct?

I have write a simple Timer0 interrupt code, not sure correct not? Please can you check for me?
void init_timer0(void)
{
	TMOD &= 0xF0;
	TMOD |= 1;

	TL0 = TL;
	TH0 = TH;

	ET0 = 1;
	EA  = 1;
	TR0 = 1;
}

void ticks(void)
{
	char i;
	i++;
                     // SPI coding start
                     // ....
                     // ..   
}

void clk_tick() interrupt 1
{
	TR0 = 0;
	ET0 = 0;

	ticks(); 

	TL0 = TL;
	TH0 = TH;

	ET0 = 1;
	TR0 = 1;
}


Please advice...

Thank you,.


[ Edited Wed Feb 04 2009, 02:33 PM ]

Get Social

Information

Powered by e107 Forum System

Conversation

ExperimenterUK
Thu Nov 20 2014, 06:00 PM
@Mehboob.. I don't think you can do that.
Sat Nov 15 2014, 06:41 AM
Mehboob
Pls can you send me code in c of PWM generation using UART/serial port in 8051.
Fri Nov 14 2014, 02:51 PM
mohammad aqil
NEED A BOOK ON MICROPROCESSOR AND INTERFACING BY D.V.HALL. RIGHT NOW, I SHALL BE VERY THANK FULL TO U....
Thu Nov 13 2014, 02:15 PM
m
please code hex project avr blood pressure monitor
Thu Nov 13 2014, 05:56 AM
Lambo
hi mate, whats the ajay-bhargav? tell us more pls
ExperimenterUK
Wed Nov 12 2014, 12:56 AM
@tmtm000.. have you been able to join ?
ExperimenterUK
Wed Nov 12 2014, 12:54 AM
@Alice..become a member,then send a PM to ajay_bhargav the site owner.
Tue Nov 11 2014, 03:58 AM
Abhishek Bansal
Thanks a lot for your informative tutorials!
Mon Nov 10 2014, 09:03 AM
Alice
Hello, This is Alice from a PCB rototype manufacturer. Our company is interested in your website contents, and wonder if we can advertise our company with payment on your website. There are two ways to advertise: first, if we an get a instant quote section on your main site columns; second, whether we can get a advertising section if you have any avaliable one. If any of above ways avaliable, please contact me with your detailed scheme and advertising charge. Thanks. Alice
Sat Nov 08 2014, 11:58 AM
Mohamed_123sd
Signals and Systems, 2nd Edition by Alan V. Oppenheim Alan S.willsky with S.Hamid Nawab?

Downloads

Comments

VikiPeter
Tue Nov 18 2014, 09:13 AM
gentlboy
Sun Nov 16 2014, 11:13 PM
philipeastbourne
Wed Nov 12 2014, 05:32 AM
astra91
Mon Nov 10 2014, 08:11 AM
francise
Thu Nov 06 2014, 02:55 AM
ashbir
Tue Nov 04 2014, 11:13 PM
shruthig
Tue Nov 04 2014, 10:50 AM
sk8boardboy
Mon Nov 03 2014, 11:20 AM

Online

Guests: 69, Members: 0 ...

most ever online: 182184
(Members: , Guests: 182184) on 06 Aug 2010: 05:37 AM

Members: 37547
Newest member: VikiPeter
Forum Activity
ExperimenterUK Avatar
Posted By ExperimenterUK
Sat Nov 22 2014, 06:15 AM
@ExperimenterUKI make small table to observe Outpu...
Max.otto Avatar
Posted By Max.otto
Fri Nov 21 2014, 02:31 PM
@ExperimeterUKForgot my last question.As i told be...
Max.otto Avatar
Posted By Max.otto
Fri Nov 21 2014, 02:05 PM
@ExperimenterUKI make small table to observe Outpu...
Max.otto Avatar
Posted By Max.otto
Fri Nov 21 2014, 01:12 PM
@ExperimenterUKThank u. I do it. Ohne Period it's ...
ExperimenterUK Avatar
Posted By ExperimenterUK
Thu Nov 20 2014, 05:56 PM
You set the on/off times here as 47%float PWMcom...
vijay.parmar1992 Avatar
Posted By vijay.parmar1992
Thu Nov 20 2014, 04:06 AM
Right now i am studying Bootloader.I want to writ...
Max.otto Avatar
Posted By Max.otto
Wed Nov 19 2014, 03:11 PM
How can i get PWM on-off time..?pls check the atta...
Max.otto Avatar
Posted By Max.otto
Wed Nov 19 2014, 03:05 PM
I am using PSoC 5LP.pls check the attached design ...
ankitbajaj01 Avatar
Posted By ankitbajaj01
Wed Nov 19 2014, 01:49 PM
Thanks for the prompt response, I will try it out ...
engr1931 Avatar
Posted By engr1931
Wed Nov 19 2014, 11:45 AM
this one sir! i attached the whole project! ...