Subversion Repositories Projects

Rev

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.
}