Blame |
Last modification |
View Log
| RSS feed
#include <avr/io.h>
#include <util/delay.h>
#include "fat16.h"
#include "sdc.h"
#include "ssc.h"
//________________________________________________________________________________________________________________________________________
// Module name: mmc.c
// Compiler used: avr-gcc 3.4.5
// Last Modifikation: 24.07.2007
// Version: 1.05
// Authors: Stephan Busker
// Description: Source files for connecting to an sdcard using the SSC
//
//........................................................................................................................................
// Functions: u8 SDC_init(void);
// u8 SDC_PutCommand (u8*CMD);
// u8 SDC_PutSector(u32 addr,u8*Buffer);
// u8 SDC_GetSector(u32 addr,u8*Buffer);
// void SDC_GetBlock(u8*CMD,u8*Buffer,u16 Bytes);
//
////........................................................................................................................................
// ext. functions: extern void SSC_Init(void);
// extern u8 SSC_GetChar (void);
// extern void SSC_PutChar (u8);
// extern void SSC_Enable(void);
// extern void SSC_Disable(void);
//........................................................................................................................................
//
// URL: www.Mikro-Control.de
// mailto: stephan.busker@mikro-control.de
//________________________________________________________________________________________________________________________________________
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_Init(void);
//
// Description: This function initialises the SDCard to spi-mode.
//
//
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
//________________________________________________________________________________________________________________________________________
u8 SDC_Init(void)
{
u8 Timeout = 0;
u8 CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};
u16 a = 0;
u8 b = 0;
SSC_Init(); // Initialise SSC to transmit data to the sdcard.
_delay_ms(10); // before initialising the sdcard wait for 10ms
for (b=0;b<0x0f;b++) // sending 74Clocks brings the sdcard into spimode.
{
_delay_us(1); // wait at least 1us between the characters.
SSC_PutChar(0xff);
}
while(SDC_PutCommand (CMD) !=1) // Sending CMD0 (Reset) to the sdcard.
{
if (Timeout++ > 200)
{
return(1);
}
}
Timeout = 0;
CMD[0] = 0x41;
CMD[5] = 0xFF;
while( SDC_PutCommand (CMD) !=0) // Sending CMD1 to the sdcard.
{
if (Timeout++ > 100)
{
return(2);
}
}
SSC_Disable(); // disable sdcard.
return(0);
}
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_PutCommand(* CMD);
//
// Description: This function initialises the SDCard to spi-mode.
//
//
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
//________________________________________________________________________________________________________________________________________
u8 SDC_PutCommand (u8*CMD)
{
u8 tmp = 0xff;
u8 Timeout = 0;
u16 a = 0;
#ifdef SSC_RX_FIFO
SSC_ClearRxFifo();
#endif
SSC_Disable(); // disable chipselect
SSC_PutChar(0xFF); // Send 8 Clocks to the sdcard while card is not selected.
SSC_Enable(); // enable chipselect.
if (*CMD == 0x41) _delay_ms(10); // if command is CMD0 generate a short delay.
for (a = 0;a<0x06;a++) // send the command sequence to the sdcard (6 bytes)
{
SSC_PutChar(*CMD++);
}
#ifdef SSC_RX_FIFO
SSC_ClearRxFifo();
#endif
while (tmp == 0xff) // Wait for response from sdcard.
{
tmp = SSC_GetChar();
if (Timeout++ > 100)
{
break; // or timeout.
}
}
return(tmp);
}
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_PutSector(void);
//
// Description: This function writes one sector of data to the SSC
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
u8 SDC_PutSector(u32 addr,u8*Buffer)
{
u8 tmp;
u8 CMD[] = {0x58,0x00,0x00,0x00,0x00,0xFF};
addr = addr << 9; // convert sectoradress to byteadress
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 0x0000FF00) >>8 );
tmp = SDC_PutCommand (CMD); // send command to sdcard.
if (tmp != 0)
{
return(tmp);
}
#ifdef SSC_RX_FIFO
SSC_ClearRxFifo();
#endif
for (u8 a=0;a<100;a++) // wait until sdcard is ready
{
SSC_GetChar();
}
SSC_PutChar(0xFE); // send start of header to the SSC
for (u16 a=0;a<512;a++) // transmitt one sector (normaly 512bytes) of data to the sdcard.
{
SSC_PutChar(*Buffer++);
}
SSC_PutChar(0xFF); // write two bytes of crc to the sdcard (not used in spi-mode)
SSC_PutChar(0xFF);
#ifdef SSC_RX_FIFO
SSC_ClearRxFifo();
#endif
while (SSC_GetChar() != 0xff){}; // wait untile the sdcard is ready.
SSC_Disable(); // disable sdcard.
return(0);
}
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetSector(u32 addr,u8*Buffer);
//
// Description: This function reads one sector of data from the SSC
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
u8 SDC_GetSector(u32 addr,u8*Buffer)
{
u8 CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};
addr = addr << 9; // convert sectoradress to byteadress.
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 0x0000FF00) >>8 );
SDC_GetBlock(CMD,Buffer,512); // read specified sector from sdcard.
return(0);
}
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetBlock(void);
//
// Description: This function reads one block of data of s16 bytes from the SSC.
//
//
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
//________________________________________________________________________________________________________________________________________
void SDC_GetBlock(u8*CMD,u8*Buffer,u16 Bytes)
{
if (SDC_PutCommand (CMD) != 0) // Send command to the sdcard.
{
return;
}
#ifdef SSC_RX_FIFO
SSC_ClearRxFifo();
#endif
while (SSC_GetChar() != 0xfe){}; // wait until the sdcard is ready to transmitt data.
for (u16 a=0;a<Bytes;a++) // read the block from the SSC (normaly 512Bytes)
{
*Buffer++ = SSC_GetChar();
}
SSC_GetChar(); // Read two bytes CRC- checksum (not used in spi-mode)
SSC_GetChar();
SSC_Disable(); // disable sdcard.
}