Subversion Repositories NaviCtrl

Compare Revisions

Ignore whitespace Rev 11 → Rev 12

/branches/V0.1 killagreg/GPSUart.c
297,8 → 297,8
{
static u32 lasttime;
 
LED_GRN_TOGGLE;
// update GPS data only if the taus is INVALID or PROCESSED
LED_RED_TOGGLE;
// update GPS data only if the status is INVALID or PROCESSED
if(GPS_Data.Status != NEWDATA)
{ // wait for new data at all neccesary ubx messages
if ((UbxSol.Status == NEWDATA) && (UbxPosLlh.Status == NEWDATA) && (UbxVelNed.Status == NEWDATA))
442,7 → 442,6
if (c == ckb)
{
*ubxSp = NEWDATA; // new data are valid
LED_RED_TOGGLE;
Update_GPS_Data(); //update GPS info respectively
}
else
/branches/V0.1 killagreg/Navi-Ctrl.Uv2
32,6 → 32,7
File 1,1,<.\usb_prop.c><usb_prop.c>
File 1,1,<.\usb_pwr.c><usb_pwr.c>
File 1,1,<.\led.c><led.c>
File 1,1,<.\crc16.c><crc16.c>
File 2,5,<.\ramfunc.h><ramfunc.h>
File 2,5,<.\main.h><main.h>
File 2,5,<.\uart.h><uart.h>
49,6 → 50,7
File 2,5,<.\GPS.h><GPS.h>
File 2,5,<.\libstr91x\include\91x_lib.h><91x_lib.h>
File 2,5,<.\led.h><led.h>
File 2,5,<.\crc16.h><crc16.h>
File 3,2,<.\startup912.s><startup912.s>
File 4,1,<.\libstr91x\src\91x_scu.c><91x_scu.c>
File 4,1,<.\libstr91x\src\91x_gpio.c><91x_gpio.c>
/branches/V0.1 killagreg/crc16.c
0,0 → 1,47
#include "91x_lib.h"
 
static const u16 crc16tab[256]=
{
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
};
u16 CRC16(const u8 *pBuffer, u32 len)
{
register u32 counter;
register u16 crc = 0;
for( counter = 0; counter < len; counter++)
crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *pBuffer++)&0x00FF];
return crc;
}
 
/branches/V0.1 killagreg/crc16.h
0,0 → 1,6
#ifndef _CRC16_H
#define _CRC16_H
 
extern u16 CRC16(const u8 * pBuffer, u32 len);
 
#endif // _CRC16_H
/branches/V0.1 killagreg/fat16.c
81,8 → 81,9
// s8 * fgets(s8 *, s16, File);
// u8 fexist_(u8*, File *file);
//........................................................................................................................................
// ext. functions: extern u8 SDC_GetSector (u32,u8 *);
// extern u8 SDC_PutSector (u32,u8 *);
// ext. functions: extern SD_Result_t SDC_Init(void;)
// extern SD_Result_t SDC_GetSector (u32,u8 *);
// extern SD_Result_t SDC_PutSector (u32,u8 *);
//........................................................................................................................................
//
// URL: www.Mikro-Control.de
/branches/V0.1 killagreg/sdc.c
62,19 → 62,20
#include "ssc.h"
#include "timer.h"
#include "main.h"
#include "crc16.h"
 
 
//________________________________________________________________________________________________________________________________________
// Module name: mmc.c
// Module name: sdc.c
// Compiler used: avr-gcc 3.4.5
// Last Modifikation: 24.07.2007
// Version: 1.05
// Authors: Stephan Busker
// Last Modifikation: 08.06.2008
// Version: 1.06
// Authors: Stephan Busker, Gregor Stobrawa
// Description: Source files for connecting to an sd-card using the SSC
//
//........................................................................................................................................
// Functions: SD_Result_t SDC_init(void);
// u8 SDC_PutCommand (u8 *CMD);
// u8 SDC_PutCommand (u8 *cmd);
// SD_Result_t SDC_PutSector(u32 addr,u8 *Buffer);
// SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer);
//
118,10 → 119,11
// bit5-> address error
// bit6-> parameter error
// bit7-> allways zero */
 
#define R1_NO_ERROR 0x00
#define R1_IDLE_STATE 0x01
#define R1_ERASE_RESET 0x02
#define R1_ILLEGAL_CMD 0x04
#define R1_ILLEGAL_cmd 0x04
#define R1_COM_CRC_ERROR 0x08
#define R1_ERASE_SEQUENCE_ERROR 0x10
#define R1_ADDRESS_ERROR 0x20
129,21 → 131,15
#define R1_BAD_RESPONSE 0x80
 
#define DATA_START_TOKEN 0xFE
#define DATA_RESPONSE_MASK 0x1F
#define DATA_RESPONSE_OK 0x05
#define DATA_RESPONSE_CRC_ERROR 0x0B
#define DATA_RESPONSE_WRITE_ERROR 0x1D
 
typedef struct
{
u8 MID; // Manufacturer ID
u8 OID[2]; // OEM/Application ID
u8 PNM[5]; // Product name
u8 PRV; // Product revision
u32 PSN; // Product serial number
u16 MDT; // Manufacturing date
u8 CRC7; // CRC7 checksum
} __attribute__((packed)) CID_t;
 
typedef enum
{
VER_UNKNOWN,
VER_1X,
VER_20
} SDVersion_t;
151,61 → 147,25
typedef struct
{
u8 Valid;
SDVersion_t Version;
CID_t CID;
SDVersion_t Version; // HW-Version
u32 Capacity; // Memory capacity in bytes
u8 CID[16]; // CID register
u8 CSD[16]; // CSD register
} __attribute__((packed)) SDCardInfo_t;
 
volatile SDCardInfo_t SDCardInfo;
 
 
//________________________________________________________________________________________________________________________________________
// Function: CRC7(u8* cmd, u32 len);
//
// Description: This function calculated the CRC7 checksum used in the last byte of a spi command frame.
//
//
// Returnvalue: the function returns the crc7
//________________________________________________________________________________________________________________________________________
 
/* CRC16 implementation acording to CCITT standards */
static const u16 crc16tab[256]=
{
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
};
u16 CRC16(const u8 *pBuffer, u32 len)
{
register u32 counter;
register u16 crc = 0;
for( counter = 0; counter < len; counter++)
crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *pBuffer++)&0x00FF];
return crc;
}
 
 
u8 CRC7(u8 * cmd, u32 len)
{
u8 i, a;
227,7 → 187,7
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_PutCommand(* CMD);
// Function: SDC_PutCommand(* cmd);
//
// Description: This function send a command frame the SDCard in spi-mode.
//
235,7 → 195,7
// Returnvalue: the function returns the first response byte
//________________________________________________________________________________________________________________________________________
 
u8 SDC_PutCommand (u8 const *CMD)
u8 SDC_PutCommand (u8 const *cmd)
{
u8 rsp = 0xFF;
u16 Timeout = 0;
246,7 → 206,7
for (a = 0;a < 6; a++) // send the command sequence to the sdcard (6 bytes)
{
SSC_PutChar(*CMD++);
SSC_PutChar(*cmd++);
}
SSC_ClearRxFifo(); // clear the rx fifo to discard the bytes received during the transmission of the 6 command bytes
258,36 → 218,152
return(rsp);
}
 
void PrintCID(CID_t * pCID)
 
 
//________________________________________________________________________________________________________________________________________
// Function: SDC_GetData(u8 * cmd ,u8 *Buffer, u32 len);
//
// Description: This function sneds cmd an reads a datablock of len from the sd-card
//
//
// Returnvalue: SD_Result_t
//________________________________________________________________________________________________________________________________________
 
SD_Result_t SDC_GetData(const u8 * cmd, u8 *Buffer, u32 len)
{
u8 rsp;
u32 Timeout;
u16 a, Crc16;
SD_Result_t result = SD_ERROR_UNKNOWN;
// send the command
rsp = SDC_PutCommand (cmd); // Send command to the sdcard.
if (rsp != R1_NO_ERROR)
{
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
SSC_ClearRxFifo();
Timeout = SetDelay(200); // wait alt least 0.2 seconds for data ready
do
{
rsp = SSC_GetChar();
if((rsp & 0xF0) == 0x00) // data error token
{
result = SD_ERROR_READ_DATA;
goto end;
}
if(CheckDelay(Timeout))
{
result = SD_ERROR_TIMEOUT;
goto end;
}
}while(rsp != DATA_START_TOKEN);
// data start token received
for (a = 0; a < len; a++) // read the block from the SSC
{
Buffer[a] = SSC_GetChar();
}
// Read two bytes CRC16-Data checksum
Crc16 = SSC_GetChar();
Crc16 = (Crc16<<8)|SSC_GetChar();
if(Crc16 != CRC16(Buffer, 512)) result = SD_ERROR_CRC_DATA;
else result = SD_SUCCESS;
 
end:
SSC_Disable(); // disable sdcard.
return(result);
}
 
 
//________________________________________________________________________________________________________________________________________
// Function: SDC_PrintCID(u8 * pCID);
//
// Description: This function prints the CIS register in a human readable format.
//
//
// Returnvalue: the function returns nothing
//________________________________________________________________________________________________________________________________________
 
void SDC_PrintCID(u8 * pCID)
{
u8 text[50];
u8 pn[6];
u16 temp2;
u16 temp3;
sprintf(text, "Manufacturer ID: %i\r\n",pCID->MID);
u16 temp1, temp2;
 
sprintf(text, "\r\nManufacturer ID: %i\r\n", pCID[0]);
SerialPutString(text);
memcpy(pn, pCID->OID, 2);
memcpy(pn, &pCID[1], 2);
pn[2] = '\0'; // terminate string
sprintf(text, "Application ID: %s\r\n",pn);
SerialPutString(text);
memcpy(pn, pCID->PNM, 5);
memcpy(pn, &pCID[3], 5);
pn[5] = '\0'; // terminate string
sprintf(text, "Product Name: %s\r\n",pn);
SerialPutString(text);
sprintf(text, "Product Rev.: %i.%i\r\n",(pCID->PRV)>>4, (pCID->PRV)&0xF);
sprintf(text, "Product Rev.: %i.%i\r\n",pCID[8]>>4, pCID[8]&0xF);
SerialPutString(text);
temp2 = (u16)((pCID->PSN)/65536);
temp3 = (u16)((pCID->PSN)%65536); // ??
sprintf(text, "Serial Num.: %i%i\r\n", temp2, temp3);
SerialPutString("Serial No.: ");
for(temp1 = 0; temp1<4; temp1++)
{
sprintf(text,"%02X", pCID[9+temp1]);
SerialPutString(text);
}
SerialPutString("\r\n");
temp1 = pCID[14] & 0x0F; // month
temp2 = ((pCID[14]>>4)|(pCID[13]<<4)) + 2000; // year
sprintf(text, "Manufac. Date: %i/%i\r\n\r\n",temp1, temp2);
SerialPutString(text);
temp3 = ((pCID->MDT)>>8); // month
temp2 = ((pCID->MDT)&0x000F) + 2000; // year
sprintf(text, "Manufac. Date: %i/%i\r\n",temp3, temp2);
SerialPutString(text);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetCID(u8 * pCID);
//
// Description: This function reads the CIS register form the sd card in spi mode.
//
//
// Returnvalue: the function returns error state
//________________________________________________________________________________________________________________________________________
 
SD_Result_t SDC_GetCID(u8 * pCID)
{
u8 cmd[6];
 
/* Send cmd10 (SEND_CID) */;
cmd[0] = 0x40|10; // set command index 58
cmd[1] = 0x00; // set cmd argument
cmd[2] = 0x00;
cmd[3] = 0x00;
cmd[4] = 0x00;
cmd[5] = CRC7(cmd, 5); // update checksum
return SDC_GetData(cmd, pCID, 16);
}
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_GetCSD(u8 * pCSD);
//
// Description: This function reads the CSD register form the sd card in spi mode.
//
//
// Returnvalue: the function returns error state
//________________________________________________________________________________________________________________________________________
 
SD_Result_t SDC_GetCSD(u8 * pCSD)
{
u8 cmd[6];
 
/* Send cmd09 (SEND_CSD) */;
cmd[0] = 0x40|9; // set command index 58
cmd[1] = 0x00; // set cmd argument
cmd[2] = 0x00;
cmd[3] = 0x00;
cmd[4] = 0x00;
cmd[5] = CRC7(cmd, 5); // update checksum
return SDC_GetData(cmd, pCSD, 16);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_Init(void);
//
// Description: This function initialises the SDCard to spi-mode.
301,14 → 377,15
SerialPutString("SDC init...");
u32 Timeout = 0;
u8 text[50];
u8 CMD[6]; // SD-SPI command buffer
u8 RSP[6]; // SD-SPI response buffer
u8 cmd[6]; // SD-SPI command buffer
u8 rsp[6]; // SD-SPI response buffer
SD_Result_t result = SD_ERROR_UNKNOWN;
 
SSC_Init();
 
SDCardInfo.Valid = 0;
/* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and
start to supply at least 74 SD clocks to the SD card with keeping CMD line to high. In case of SPI
start to supply at least 74 SD clocks to the SD card with keeping cmd line to high. In case of SPI
mode, CS shall be held to high during 74 clock cycles. */
SSC_Disable(); // set SD_CS high
SSC_ClearRxFifo(); // clear the rx fifo
316,60 → 393,63
{
SSC_PutChar(0xFF);
}
/* In case of SPI host, CMD0 shall be the first command to send the card to SPI mode.
Send CMD0 (GO_IDLE_STATE) to the sd-card when CS-SD is activated (lowactive)
/* In case of SPI host, cmd0 shall be the first command to send the card to SPI mode.
Send cmd0 (GO_IDLE_STATE) to the sd-card when CS-SD is activated (lowactive)
until the response byte indicates no error and in idle state (0x01).*/
CMD[0] = 0x40|0; // set command index 0
CMD[1] = 0x00; // set cmd argument (4bytes)
CMD[2] = 0x00;
CMD[3] = 0x00;
CMD[4] = 0x00;
CMD[5] = CRC7(CMD, 5); // update checksum
cmd[0] = 0x40|0; // set command index 0
cmd[1] = 0x00; // set cmd argument (4bytes)
cmd[2] = 0x00;
cmd[3] = 0x00;
cmd[4] = 0x00;
cmd[5] = CRC7(cmd, 5); // update checksum
Timeout = 0;
while(SDC_PutCommand (CMD) != R1_IDLE_STATE)
while(SDC_PutCommand (cmd) != R1_IDLE_STATE)
{
if (Timeout++ > 200)
{
SerialPutString("reset timeout.\r\n");
return(SD_ERROR_RESET);
result = SD_ERROR_RESET;
goto end;
}
}
 
/* In case of SPI mode the checksum feature is disabled by default.
CMD59 can be used to contol the checksum feature.
Send CMD59 (CRC_ON_OFF) to the sd-card to enable CRC feature.*/
CMD[0] = 0x40|59; // set command index 0
CMD[1] = 0x00; // set cmd argument (4bytes)
CMD[2] = 0x00;
CMD[3] = 0x00;
CMD[4] = 0x01; // enable CRC
CMD[5] = CRC7(CMD, 5); // update checksum
RSP[0] = SDC_PutCommand(CMD);
if ( RSP[0] != R1_IDLE_STATE)
cmd59 can be used to contol the checksum feature.
Send cmd59 (CRC_ON_OFF) to the sd-card to enable CRC feature.*/
cmd[0] = 0x40|59; // set command index 0
cmd[1] = 0x00; // set cmd argument (4bytes)
cmd[2] = 0x00;
cmd[3] = 0x00;
cmd[4] = 0x01; // enable CRC
cmd[5] = CRC7(cmd, 5); // update checksum
rsp[0] = SDC_PutCommand(cmd);
if ( rsp[0] != R1_IDLE_STATE)
{
sprintf(text,"Bad CMD59 R1=%02X.\r\n", RSP[0]);
sprintf(text,"Bad cmd59 R1=%02X.\r\n", rsp[0]);
SerialPutString(text);
return(SD_ERROR_BAD_RESPONSE);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
 
/* Send CMD8 (SEND_IF_COND). The CRC for that command is allways enabled */
CMD[0] = 0x40|8; // set command index 8
CMD[1] = 0x00; // set cmd argument
CMD[2] = 0x00;
CMD[3] = 0x01; // 2.7-3.6V Range
CMD[4] = 0xAA; // check pattern
CMD[5] = CRC7(CMD, 5); // update checksum
RSP[0] = SDC_PutCommand(CMD); //send cmd and get first response byte
// answer to CMD8 is an R7 response (R1 + 4 bytes)
if(RSP[0] & R1_BAD_RESPONSE)
/* Send cmd8 (SEND_IF_COND). The CRC for that command is allways enabled */
cmd[0] = 0x40|8; // set command index 8
cmd[1] = 0x00; // set cmd argument
cmd[2] = 0x00;
cmd[3] = 0x01; // 2.7-3.6V Range
cmd[4] = 0xAA; // check pattern
cmd[5] = CRC7(cmd, 5); // update checksum
rsp[0] = SDC_PutCommand(cmd); //send cmd and get first response byte
// answer to cmd8 is an R7 response (R1 + 4 bytes)
if(rsp[0] & R1_BAD_RESPONSE)
{
sprintf(text,"Bad CMD8 R1=%02X.\r\n", RSP[0]);
sprintf(text,"Bad cmd8 R1=%02X.\r\n", rsp[0]);
SerialPutString(text);
return(SD_ERROR_BAD_RESPONSE);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if(RSP[0] & R1_ILLEGAL_CMD)
if(rsp[0] & R1_ILLEGAL_cmd)
{
//Ver1.X SD Memory Card or Not SD Memory Card
//Ver1.X SD Memory Card or not a SD Memory Card
SDCardInfo.Version = VER_1X;
}
else
379,52 → 459,56
SDCardInfo.Version = VER_20;
for(Timeout = 1; Timeout < 5; Timeout++)
{
RSP[Timeout] = SSC_GetChar();
rsp[Timeout] = SSC_GetChar();
}
//check pattern
if(RSP[4]!= 0xAA)
if(rsp[4]!= 0xAA)
{
SerialPutString("Bad CMD8 R7 check pattern.\r\n");
return(SD_ERROR_BAD_RESPONSE);
SerialPutString("Bad cmd8 R7 check pattern.\r\n");
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if ( (RSP[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
if ( (rsp[3] & 0x0F)!= 0x01 ) // voltage range is not 2.7-3.6V
{
SerialPutString("Card is incompatible to 3.3V.\r\n");
return(SD_ERROR_BAD_VOLTAGE_RANGE);
result = SD_ERROR_BAD_VOLTAGE_RANGE;
goto end;
}
}
 
/* Send CMD58 (READ_OCR) */
CMD[0] = 0x40|58; // set command index 58
CMD[1] = 0x00; // set cmd argument
CMD[2] = 0x00;
CMD[3] = 0x00;
CMD[4] = 0x00;
CMD[5] = CRC7(CMD, 5); // update checksum
RSP[0] = SDC_PutCommand(CMD); //send cmd and get first response byte
// answer to CMD58 is an R3 response (R1+ 4Byte OCR)
if(RSP[0] & R1_BAD_RESPONSE)
/* Send cmd58 (READ_OCR) */
cmd[0] = 0x40|58; // set command index 58
cmd[1] = 0x00; // set cmd argument
cmd[2] = 0x00;
cmd[3] = 0x00;
cmd[4] = 0x00;
cmd[5] = CRC7(cmd, 5); // update checksum
rsp[0] = SDC_PutCommand(cmd); //send cmd and get first response byte
// answer to cmd58 is an R3 response (R1+ 4Byte OCR)
if(rsp[0] & R1_BAD_RESPONSE)
{
sprintf(text,"Bad CMD58 R1 %02x.\r\n", RSP[0]);
sprintf(text,"Bad cmd58 R1 %02x.\r\n", rsp[0]);
SerialPutString(text);
return(SD_ERROR_BAD_RESPONSE);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if(RSP[0] & R1_ILLEGAL_CMD)
if(rsp[0] & R1_ILLEGAL_cmd)
{
SerialPutString("Not an SD-CARD.\r\n");
return(SD_ERROR_NO_SDCARD);
result = SD_ERROR_NO_SDCARD;
goto end;
}
// read 4 bytes of OCR register
for(Timeout = 1; Timeout < 5; Timeout++)
{
RSP[Timeout] = SSC_GetChar();
rsp[Timeout] = SSC_GetChar();
}
/*
RSP[1] bits 31-24
RSP[2] bits 23-16
RSP[3] bits 15-08
RSP[4] bits 07-00
rsp[1] bits 31-24
rsp[2] bits 23-16
rsp[3] bits 15-08
rsp[4] bits 07-00
bit 23 -> 3.5 - 3.6 V
bit 22 -> 3.4 - 3.5 V
bit 21 -> 3.3 - 3.4 V
436,83 → 520,124
bit 15 -> 2.7 - 2.8 V
NavicCtrl uses 3.3 V, therefore check for bit 20 & 21
*/
if((RSP[2] & 0x30) != 0x30)
if((rsp[2] & 0x30) != 0x30)
{
// supply voltage is not supported by sd-card
SerialPutString("Card is incompatible to 3.3V.\r\n");
return(SD_ERROR_BAD_VOLTAGE_RANGE);
result = SD_ERROR_BAD_VOLTAGE_RANGE;
goto end;
}
/* Initialize the sd-card sending continously ACMD41 (SD_SEND_OP_COND)
/* Initialize the sd-card sending continously Acmd41 (SD_SEND_OP_COND)
until the R1 response byte is 0x00 indicating no error and not in idle state */
Timeout = SetDelay(2000); // set timeout to 2000 ms (large cards tend to longer)
CMD[1] = 0x00; // set cmd argument
CMD[2] = 0x00;
CMD[3] = 0x00;
CMD[4] = 0x00;
cmd[1] = 0x00; // set cmd argument
cmd[2] = 0x00;
cmd[3] = 0x00;
cmd[4] = 0x00;
do
{
/* First send the CMD55 that defines to the card that the next command
/* First send the cmd55 that defines to the card that the next command
is an application specific command rather than a standard command */
CMD[0] = 0x40|55; // CMD55 (APP_CMD)
CMD[5] = CRC7(CMD, 5); // update checksum
RSP[0] = SDC_PutCommand(CMD); // send the command
if(RSP[0] & R1_BAD_RESPONSE)
cmd[0] = 0x40|55; // cmd55 (APP_cmd)
cmd[5] = CRC7(cmd, 5); // update checksum
rsp[0] = SDC_PutCommand(cmd); // send the command
if(rsp[0] & R1_BAD_RESPONSE)
{
sprintf(text,"Bad CMD55 R1=%02X.\r\n", RSP[0]);
sprintf(text,"Bad cmd55 R1=%02X.\r\n", rsp[0]);
SerialPutString(text);
return(SD_ERROR_BAD_RESPONSE);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if(RSP[0] == R1_NO_ERROR) break; // not in idle state
CMD[0] = 0x40|41; // ACMD41 (SD_SEND_OP_COND)
CMD[5] = CRC7(CMD, 5); // update checksum
RSP[0] = SDC_PutCommand (CMD); // send the command
if(RSP[0] & R1_BAD_RESPONSE)
if(rsp[0] == R1_NO_ERROR) break; // not in idle state
cmd[0] = 0x40|41; // Acmd41 (SD_SEND_OP_COND)
cmd[5] = CRC7(cmd, 5); // update checksum
rsp[0] = SDC_PutCommand (cmd); // send the command
if(rsp[0] & R1_BAD_RESPONSE)
{
sprintf(text,"Bad ACMD41 R1=%02X.\r\n", RSP[0]);
sprintf(text,"Bad Acmd41 R1=%02X.\r\n", rsp[0]);
SerialPutString(text);
return(SD_ERROR_BAD_RESPONSE);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
if(CheckDelay(Timeout))
{
SerialPutString("Init timeout.\r\n");
return(SD_ERROR_INITIALIZE);
result = SD_ERROR_INITIALIZE;
goto end;
}
} while(RSP[0] & R1_IDLE_STATE); // loop until idle state
} while(rsp[0] & R1_IDLE_STATE); // loop until idle state
if(RSP[0] != R1_NO_ERROR)
if(rsp[0] != R1_NO_ERROR)
{
SerialPutString("Init error.\r\n");
return(SD_ERROR_INITIALIZE);
result = SD_ERROR_INITIALIZE;
goto end;
}
// read CID register
/* Send CMD10 (READ_CID) */;
CMD[0] = 0x40|10; // set command index 58
CMD[1] = 0x00; // set cmd argument
CMD[2] = 0x00;
CMD[3] = 0x00;
CMD[4] = 0x00;
CMD[5] = CRC7(CMD, 5); // update checksum
RSP[0] = SDC_PutCommand(CMD); //send cmd and get first response byte
if(RSP[0] != R1_NO_ERROR)
result = SDC_GetCID((u8 *)&SDCardInfo.CID);
if(result != SD_SUCCESS)
{
SerialPutString("Error reading CID.\r\n");
return(SD_ERROR_READ_CID);
goto end;
}
u8 * pCID;
pCID = (u8 *)&SDCardInfo.CID;
for(Timeout = 0; Timeout < 16; Timeout++)
 
// read CSD register
result = SDC_GetCSD((u8 *)&SDCardInfo.CSD);
if(result != SD_SUCCESS)
{
pCID[Timeout] = SSC_GetChar();
SerialPutString("Error reading CSD.\r\n");
goto end;
}
// read CRC16 of data block to waist
SSC_GetChar();
SSC_GetChar();
 
SSC_Disable(); // disable sdcard.
SDCardInfo.Valid = 1;
SerialPutString("ok\r\n");
 
u8 c_size_mult, read_bl_len;
u32 c_size;
 
switch(SDCardInfo.CSD[0]>>6) // check CSD Version
{
case 0x00: // if CSD is V1.0 structure (2GB limit)
 
/*
memory capacity = BLOCKNR * BLOCK_LEN
BLOCKNR = (C_SIZE+1) * MULT
MULT = 2^(C_SIZE_MULT+2)
BLOCK_LEN = 2^READ_BL_LEN
C_SIZE is 12 bits [73:62] in CSD register
C_SIZE_MULT is 3 bits [49:47] in CSD register
READ_BL_LEN is 4 bits [83:80] in CSD register
*/
 
read_bl_len = (SDCardInfo.CSD[5] & 0x0F); //CSD[05] -> [87:80]
c_size = ((u32)(SDCardInfo.CSD[6] & 0x03))<<10; //CSD[06] -> [79:72]
c_size |= ((u32)SDCardInfo.CSD[7])<<2; //CSD[07] -> [71:64]
c_size |= (u32)(SDCardInfo.CSD[8]>>6); //CSD[08] -> [63:56]
c_size_mult = (SDCardInfo.CSD[9] & 0x03)<<1; //CSD[09] -> [55:48]
c_size_mult |=(SDCardInfo.CSD[10] & 0x80)>>7; //CSD[10] -> [47:40]
SDCardInfo.Capacity = (u32)(c_size+1)*(1L<<(c_size_mult+2))*(1L<<read_bl_len);
break;
 
case 0x01: // if CSD is V2.0 structure (HC SD-Card > 2GB)
 
/*
memory capacity = (C_SIZE+1) * 512K byte
C_SIZE is 22 bits [69:48] in CSR register
*/
 
c_size = ((u32)(SDCardInfo.CSD[7] & 0x3F))<<16; //CSD[07] -> [71:64]
c_size |= ((u32)SDCardInfo.CSD[8])<<8; //CSD[08] -> [63:56]
c_size |= (u32)SDCardInfo.CSD[9]; //CSD[09] -> [55:48];
SDCardInfo.Capacity = (c_size + 1)* 512L * 1024L;
break;
 
default: //unknown CSD Version
SDCardInfo.Capacity = 0;
break;
}
 
switch(SDCardInfo.Version)
{
case VER_1X:
523,35 → 648,43
default:
break;
}
PrintCID((CID_t *)&SDCardInfo.CID);
return(SD_SUCCESS);
u16 mb_size = (u16)(SDCardInfo.Capacity/(1024L*1024L));
sprintf(text, "Capacity = %i MB\r\n", mb_size);
SerialPutString(text);
 
SDC_PrintCID((u8 *)&SDCardInfo.CID);
SDCardInfo.Valid = 1;
// jump point for error condition before
end:
SSC_Disable();
return(result);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: EXTIT1_IRQHandler(void);
// Funtion: SDC_Deinit(void);
//
// Description: This function handles the extnernal interrupts from port 5.3 (SD_SWITCH)
// Description: This function deinitialises the SDCard interface.
//
//
// Returnvalue: none
// Returnvalue: the function returns 0 if the initialisation was successfull otherwise the function returns an errorcode.
//________________________________________________________________________________________________________________________________________
void EXTIT1_IRQHandler(void)
 
SD_Result_t SDC_Deinit(void)
{
VIC_ITCmd(EXTIT1_ITLine, DISABLE);
if(WIU_GetITStatus(WIU_Line11) != RESET)
{
if(SD_SWITCH) // if sd-card is mechanically present
{
BeepTime = 100;
SDC_Init(); // initialize sd-card.
}
WIU_ClearFlag(WIU_Line1);
WIU_ClearITPendingBit(WIU_Line11);
}
VIC_ITCmd(EXTIT1_ITLine, ENABLE);
SerialPutString("SDC deinit...");
SSC_Deinit();
 
SDCardInfo.Valid = 0;
SDCardInfo.Capacity = 0;
SDCardInfo.Version = VER_UNKNOWN;
 
SerialPutString("ok\r\n");
return(SD_SUCCESS);
}
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: SDC_PutSector(void);
//
565,40 → 698,79
{
u8 rsp;
u16 a, Crc16;
u8 CMD[6]; // SD-SPI command buffer
u32 Timeout = 0;
SD_Result_t result = SD_ERROR_UNKNOWN;
u8 cmd[6]; // SD-SPI command buffer
 
addr = addr << 9; // convert sectoradress to byteadress
CMD[0] = 0x40|24; // set CMD24 (WRITE_BLOCK)
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 0x0000FF00) >>8 );
CMD[4] = 0x00;
CMD[5] = CRC7(CMD, 5); // update checksum
rsp = SDC_PutCommand (CMD); // send command to sdcard.
cmd[0] = 0x40|24; // set cmd24 (WRITE_BLOCK)
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
cmd[4] = 0x00;
cmd[5] = CRC7(cmd, 5); // update checksum
rsp = SDC_PutCommand (cmd); // send command to sdcard.
if (rsp != R1_NO_ERROR)
{
return(SD_ERROR_BAD_RESPONSE);
result = SD_ERROR_BAD_RESPONSE;
goto end;
}
SSC_ClearRxFifo();
for (a=0;a<100;a++) // wait until sdcard is ready
for (a=0;a<10;a++) // at least one byte
{
SSC_GetChar();
}
Crc16 = CRC16(Buffer, 512); // calc checksum for data block
SSC_PutChar(DATA_START_TOKEN); // send start of header to the SSC
SSC_PutChar(DATA_START_TOKEN); // send data start of header to the SSC
for (a=0;a<512;a++) // transmitt one sector (normaly 512bytes) of data to the sdcard.
for (a=0;a<512;a++) // transmit one sector (normaly 512bytes) of data to the sdcard.
{
SSC_PutChar(Buffer[a]);
}
SSC_PutChar((u8)(Crc16>>8)); // write two bytes of crc to the sdcard
SSC_PutChar((u8)(Crc16>>8)); // write two bytes of crc16 to the sdcard
SSC_PutChar((u8)(0x00FF&Crc16));
SSC_ClearRxFifo();
while ((rsp = SSC_GetChar()) != 0xFF){}; // wait until the sdcard is ready.
Timeout = SetDelay(200);
do // wait for data response token
{
rsp = SSC_GetChar();
if(CheckDelay(Timeout))
{
result = SD_ERROR_TIMEOUT;
goto end;
}
}while((rsp & 0x11) != 0x01 );
// analyse data response token
switch(rsp & DATA_RESPONSE_MASK)
{
case DATA_RESPONSE_OK:
result = SD_SUCCESS;
break;
case DATA_RESPONSE_CRC_ERROR:
result = SD_ERROR_CRC_DATA;
break;
case DATA_RESPONSE_WRITE_ERROR:
result = SD_ERROR_WRITE_DATA;
break;
default:
result = SD_ERROR_UNKNOWN;
break;
 
}
// wait until the sdcard is not busy.
Timeout = SetDelay(200);
while (SSC_GetChar() != 0xFF)
{
if(CheckDelay(Timeout))
{
result = SD_ERROR_TIMEOUT;
goto end;
}
}
end:
SSC_Disable(); // disable sdcard.
if( (0x1F & rsp) != DATA_RESPONSE_OK) return(SD_ERROR_WRITE_DATA);
else return(SD_SUCCESS);
return(result);
}
 
 
613,44 → 785,42
 
SD_Result_t SDC_GetSector(u32 addr,u8 *Buffer)
{
u8 rsp;
u32 Timeout;
u16 Crc16;
u16 a;
u8 CMD[6]; // SD-SPI command buffer
u8 cmd[6]; // SD-SPI command buffer
addr = addr << 9; // convert sectoradress to byteadress.
CMD[0] = 0x40|17; // set CMD17 (READ_SINGLE_BLOCK)
CMD[1] = ((addr & 0xFF000000) >>24 );
CMD[2] = ((addr & 0x00FF0000) >>16 );
CMD[3] = ((addr & 0x0000FF00) >>8 );
CMD[4] = 0x00;
CMD[5] = CRC7(CMD, 5); // update checksum
rsp = SDC_PutCommand (CMD); // Send command to the sdcard.
if (rsp != R1_NO_ERROR)
{
return(SD_ERROR_BAD_RESPONSE);
}
SSC_ClearRxFifo();
Timeout = SetDelay(200); // wait alt least 0.2 seconds for data ready
do
{
rsp = SSC_GetChar();
if((rsp & 0xF0) == 0x00) return(SD_ERROR_READ_DATA);
if(CheckDelay(Timeout)) return(SD_ERROR_TIMEOUT);
}while(rsp != DATA_START_TOKEN);
cmd[0] = 0x40|17; // set cmd17 (READ_SINGLE_BLOCK)
cmd[1] = ((addr & 0xFF000000) >>24 );
cmd[2] = ((addr & 0x00FF0000) >>16 );
cmd[3] = ((addr & 0x0000FF00) >>8 );
cmd[4] = 0x00;
cmd[5] = CRC7(cmd, 5); // update checksum
 
for (a=0;a < 512;a++) // read the block from the SSC (normaly 512Bytes)
return SDC_GetData(cmd, Buffer, 512);
}
 
 
 
//________________________________________________________________________________________________________________________________________
// Funtion: EXTIT1_IRQHandler(void);
//
// Description: This function handles the extnernal interrupts from port 5.3 (SD_SWITCH)
//
//
// Returnvalue: none
//________________________________________________________________________________________________________________________________________
void EXTIT1_IRQHandler(void)
{
VIC_ITCmd(EXTIT1_ITLine, DISABLE);
if(WIU_GetITStatus(WIU_Line11) != RESET)
{
Buffer[a] = SSC_GetChar();
if(SD_SWITCH) // if sd-card is mechanically present
{
BeepTime = 100;
SDC_Init(); // initialize sd-card.
}
WIU_ClearFlag(WIU_Line1);
WIU_ClearITPendingBit(WIU_Line11);
}
// Read two bytes CRC16-Data checksum
Crc16 = SSC_GetChar();
Crc16 = (Crc16<<8)|SSC_GetChar();
SSC_Disable(); // disable sdcard.
if(Crc16 != CRC16(Buffer, 512)) return(SD_ERROR_CRC_DATA);
else return(SD_SUCCESS);
VIC_ITCmd(EXTIT1_ITLine, ENABLE);
}
 
 
 
/branches/V0.1 killagreg/sdc.h
17,7 → 17,6
SD_ERROR_BAD_RESPONSE,
SD_ERROR_BAD_VOLTAGE_RANGE,
SD_ERROR_NO_SDCARD,
SD_ERROR_READ_CID,
SD_ERROR_TIMEOUT,
SD_ERROR_CRC_DATA,
SD_ERROR_WRITE_DATA,
28,6 → 27,7
extern SD_Result_t SDC_Init(void);
extern SD_Result_t SDC_GetSector (u32 ,u8 *);
extern SD_Result_t SDC_PutSector (u32, const u8 *);
extern SD_Result_t SDC_Deinit(void);
 
#endif // _SDC_H
 
/branches/V0.1 killagreg/ssc.c
189,7 → 189,40
 
}
 
void SSC_Deinit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
 
SSP_Cmd(SSP1, DISABLE);
SSP_DeInit(SSP1);
 
// configure P5.4 -> SD-CS as an input pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init (GPIO5, &GPIO_InitStructure);
// configure P3.4 -> SCK1 and P3.6 -> MOSI1 as an input pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull ;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init (GPIO3, &GPIO_InitStructure);
// configure P3.5 <- MISO1 as an input pin
GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;
GPIO_InitStructure.GPIO_IPConnected = GPIO_IPConnected_Disable;
GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
GPIO_Init (GPIO3, &GPIO_InitStructure);
 
// disable APB clock for SPI1
SCU_APBPeriphClockConfig(__SSP1 ,DISABLE);
}
 
 
//________________________________________________________________________________________________________________________________________
// Function: SSC_GetChar(void);
//
/branches/V0.1 killagreg/ssc.h
12,6 → 12,7
#define SD_SWITCH !(GPIO_ReadBit(GPIO5, GPIO_Pin_3))
 
extern void SSC_Init(void);
extern void SSC_Deinit(void);
extern u8 SSC_GetChar (void);
extern void SSC_PutChar (u8);
extern void SSC_Enable(void);