This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
hi,
i am making use sd card with my controller(TM4C123).
when i am trying with it, i am getting a f_opendir (&g_sDirObject, g_cCwdBuf) ; return status as FR_NOT _READY.
i checked by checking sd cards even though same thing came.i came to know that due to in correct initialization this problem arrises.
but i am not getting where i went wrong, here is my sd init funtion.
void SDCardInit()
{
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinConfigure(GPIO_PD0_SSI3CLK);
GPIOPinConfigure(GPIO_PD1_SSI3FSS);
GPIOPinConfigure(GPIO_PD2_SSI3RX);
GPIOPinConfigure(GPIO_PD3_SSI3TX);
ROM_GPIOPinTypeSSI(GPIO_PORTD_BASE,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
ROM_GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3,
GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU);
}
can any one tell me where i missed..........
Hi,
You should add the file Tiva/third_party/fatfs/port/mmc-dk-tm4c123g.c to your project. If you already done it, please note two problems:
a) the initialization of SSI is already done in this file;
b) This file initialize SSI0 rather than SSI3, so it is quite obvious you will get some wrong results.
Read that file - and if you still need to use SSI3, you should modify it for your SSI3 pins.
Petrei
hi Petrei,
i already changed pins in Tiva/third_party/fatfs/port/mmc-dk-LM4F120H5QR.c to ssi3 even though i got the same problem.
i am using Tiva/third_party/fatfs/port/mmc-dk-LM4F120H5QR.c becaz i dont have it for dk-tm4c123g.any way i think this wont be the problem.
one more thing is that On D0,D1,D2,D3 both ssi1 and ssi3 are there i tried two with no success.
here the way i changed pins in Tiva/third_party/fatfs/port/mmc-dk-LM4F120H5QR.c
// SSI port
#define SDC_SSI_BASE SSI3_BASE
#define SDC_SSI_SYSCTL_PERIPH SYSCTL_PERIPH_SSI3
// GPIO for SSI pins
#define SDC_GPIO_PORT_BASE GPIO_PORTD_BASE
#define SDC_GPIO_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOD
#define SDC_SSI_CLK GPIO_PIN_0
#define SDC_SSI_TX GPIO_PIN_3
#define SDC_SSI_RX GPIO_PIN_2
#define SDC_SSI_FSS GPIO_PIN_1
#define SDC_SSI_PINS (SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK | \
SDC_SSI_FSS)
in init i called like this
void SDCardInit()
{
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
}
is there any thing to change...
Hi,
Some problems:
a) While in the first post you said you have a tm4c, now you change it to lm4f - take care the pins may not have the same location or configuration. Check again.
b) You should first learn from the sd_card example in boards/ek-lm4f232/sd-card/sd-card.c - there the initialization of sd-card is simply
//
// Mount the file system, using logical disk 0.
//
iFResult = f_mount(0, &g_sFatFs);
if(iFResult != FR_OK)….. so start with f_mount file, read it, see what functions are called inside, see how it works.
Note also the SSIFSS is GPIO pin for sd-card - so take care...
c) Related to SSI3, in Tiva 2.0 there is the file mmc-dk-tm4c129x.c in ports folder and uses SSI3 - look how SSI3 is initialized.
Petrei
shyam reddy said:ROM_GPIOPinTypeSSI(GPIO_PORTD_BASE,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
ROM_GPIOPadConfigSet(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3,
GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU);
For the record (you and/or interested others) that first call to, "ROM_GPIOPinTypeSSI()" should automate/embed a call to, "ROM_GPIOPadConfigSet()." And - review of GPIOPinTypeSSI() - w/in StellarisWare\driverlib: gpio.c - reveals, "GPIO_STRENGTH_2MA, & GPIO_PIN_TYPE_STD" - both differing from your selection.
May not matter - but always best to comply with that which is well-known and extensively tested...
And - while you report success, "my problem got solved!" - that in itself does not provide, "useful guidance" to "follow-on readers" - who may well benefit from the more specific & detailed advice you can now uniquely provide...
hi,
there was some initialization problem.
i just done pin muxing for clk,ss,ssiTx,ssiRx by making use of GPIO_PINCONFIG(); in power_on(). function of k-lm4f232.c file.
here is my code
void SDCardInit()
{
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
}
LM4F232.c
/*-----------------------------------------------------------------------*/
/* MMC/SDC (in SPI mode) control module (C)ChaN, 2007 */
/*-----------------------------------------------------------------------*/
/* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros */
/* are platform dependent. */
/*-----------------------------------------------------------------------*/
/*
* This file was modified from a sample available from the FatFs
* web site. It was modified to work with a Stellaris EK-LM4F232H5QD
* evaluation board.
*/
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "third_party/fatfs/src/diskio.h"
/* Definitions for MMC/SDC command */
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
#define CMD1 (0x40+1) /* SEND_OP_COND */
#define CMD8 (0x40+8) /* SEND_IF_COND */
#define CMD9 (0x40+9) /* SEND_CSD */
#define CMD10 (0x40+10) /* SEND_CID */
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
#define CMD23 (0x40+23) /* SET_BLOCK_COUNT */
#define CMD24 (0x40+24) /* WRITE_BLOCK */
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
#define CMD41 (0x40+41) /* SEND_OP_COND (ACMD) */
#define CMD55 (0x40+55) /* APP_CMD */
#define CMD58 (0x40+58) /* READ_OCR */
/* Peripheral definitions for EK-LM3S3748 board */
// SSI port
#define SDC_SSI_BASE SSI3_BASE
#define SDC_SSI_SYSCTL_PERIPH SYSCTL_PERIPH_SSI3
// GPIO for SSI pins
#define SDC_GPIO_PORT_BASE GPIO_PORTD_BASE
#define SDC_GPIO_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOD
#define SDC_SSI_CLK GPIO_PIN_0
#define SDC_SSI_TX GPIO_PIN_3
#define SDC_SSI_RX GPIO_PIN_2
#define SDC_SSI_FSS GPIO_PIN_1
#define SDC_SSI_PINS (SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK | \
SDC_SSI_FSS)
// asserts the CS pin to the card
static
void SELECT (void)
{
ROM_GPIOPinWrite(SDC_GPIO_PORT_BASE, SDC_SSI_FSS, 0);
}
// de-asserts the CS pin to the card
static
void DESELECT (void)
{
ROM_GPIOPinWrite(SDC_GPIO_PORT_BASE, SDC_SSI_FSS, SDC_SSI_FSS);
}
/*--------------------------------------------------------------------------
Module Private Functions
---------------------------------------------------------------------------*/
static volatile
DSTATUS Stat = STA_NOINIT; /* Disk status */
static volatile
BYTE Timer1, Timer2; /* 100Hz decrement timer */
static
BYTE CardType; /* b0:MMC, b1:SDC, b2:Block addressing */
static
BYTE PowerFlag = 0; /* indicates if "power" is on */
/*-----------------------------------------------------------------------*/
/* Transmit a byte to MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static
void xmit_spi(BYTE dat)
{
DWORD rcvdat;
ROM_SSIDataPut(SDC_SSI_BASE, dat); /* Write the data to the tx fifo */
ROM_SSIDataGet(SDC_SSI_BASE, &rcvdat); /* flush data read during the write */
}
/*-----------------------------------------------------------------------*/
/* Receive a byte from MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static
BYTE rcvr_spi (void)
{
DWORD rcvdat;
ROM_SSIDataPut(SDC_SSI_BASE, 0xFF); /* write dummy data */
ROM_SSIDataGet(SDC_SSI_BASE, &rcvdat); /* read data frm rx fifo */
return (BYTE)rcvdat;
}
static
void rcvr_spi_m (BYTE *dst)
{
*dst = rcvr_spi();
}
/*-----------------------------------------------------------------------*/
/* Wait for card ready */
/*-----------------------------------------------------------------------*/
static
BYTE wait_ready (void)
{
BYTE res;
Timer2 = 50; /* Wait for ready in timeout of 500ms */
rcvr_spi();
do
res = rcvr_spi();
while ((res != 0xFF) && Timer2);
return res;
}
/*-----------------------------------------------------------------------*/
/* Send 80 or so clock transitions with CS and DI held high. This is */
/* required after card power up to get it into SPI mode */
/*-----------------------------------------------------------------------*/
static
void send_initial_clock_train(void)
{
unsigned int i;
DWORD dat;
/* Ensure CS is held high. */
DESELECT();
/* Switch the SSI TX line to a GPIO and drive it high too. */
ROM_GPIOPinTypeGPIOOutput(SDC_GPIO_PORT_BASE, SDC_SSI_TX);
ROM_GPIOPinWrite(SDC_GPIO_PORT_BASE, SDC_SSI_TX, SDC_SSI_TX);
/* Send 10 bytes over the SSI. This causes the clock to wiggle the */
/* required number of times. */
for(i = 0 ; i < 10 ; i++)
{
/* Write DUMMY data. SSIDataPut() waits until there is room in the */
/* FIFO. */
ROM_SSIDataPut(SDC_SSI_BASE, 0xFF);
/* Flush data read during data write. */
ROM_SSIDataGet(SDC_SSI_BASE, &dat);
}
/* Revert to hardware control of the SSI TX line. */
ROM_GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_TX);
}
/*-----------------------------------------------------------------------*/
/* Power Control (Platform dependent) */
/*-----------------------------------------------------------------------*/
/* When the target system does not support socket power control, there */
/* is nothing to do in these functions and chk_power always returns 1. */
static
void power_on (void)
{
/*
* This doesn't really turn the power on, but initializes the
* SSI port and pins needed to talk to the card.
*/
/* Enable the peripherals used to drive the SDC on SSI */
ROM_SysCtlPeripheralEnable(SDC_SSI_SYSCTL_PERIPH);
ROM_SysCtlPeripheralEnable(SDC_GPIO_SYSCTL_PERIPH);
/*
* Configure the appropriate pins to be SSI instead of GPIO. The FSS (CS)
* signal is directly driven to ensure that we can hold it low through a
* complete transaction with the SD card.
*/
ROM_GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK);
ROM_GPIOPinTypeGPIOOutput(SDC_GPIO_PORT_BASE, SDC_SSI_FSS);
ROM_GPIOPinConfigure(GPIO_PD0_SSI3CLK);
ROM_GPIOPinConfigure(GPIO_PD1_SSI3FSS);
ROM_GPIOPinConfigure(GPIO_PD2_SSI3RX);
ROM_GPIOPinConfigure(GPIO_PD3_SSI3TX);
/*
* Set the SSI output pins to 4MA drive strength and engage the
* pull-up on the receive line.
*/
ROM_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_RX, GPIO_STRENGTH_4MA,
GPIO_PIN_TYPE_STD_WPU);
ROM_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_CLK | SDC_SSI_TX | SDC_SSI_FSS,
GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
/* Configure the SSI0 port */
ROM_SSIConfigSetExpClk(SDC_SSI_BASE, ROM_SysCtlClockGet(),
SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8);
ROM_SSIEnable(SDC_SSI_BASE);
/* Set DI and CS high and apply more than 74 pulses to SCLK for the card */
/* to be able to accept a native command. */
send_initial_clock_train();
PowerFlag = 1;
}
// set the SSI speed to the max setting
static
void set_max_speed(void)
{
unsigned long i;
/* Disable the SSI */
ROM_SSIDisable(SDC_SSI_BASE);
/* Set the maximum speed as half the system clock, with a max of 12.5 MHz. */
i = ROM_SysCtlClockGet() / 2;
if(i > 12500000)
{
i = 12500000;
}
/* Configure the SSI0 port to run at 12.5MHz */
ROM_SSIConfigSetExpClk(SDC_SSI_BASE, ROM_SysCtlClockGet(),
SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, i, 8);
/* Enable the SSI */
ROM_SSIEnable(SDC_SSI_BASE);
}
static
void power_off (void)
{
PowerFlag = 0;
}
static
int chk_power(void) /* Socket power state: 0=off, 1=on */
{
return PowerFlag;
}
/*-----------------------------------------------------------------------*/
/* Receive a data packet from MMC */
/*-----------------------------------------------------------------------*/
static
BOOL rcvr_datablock (
BYTE *buff, /* Data buffer to store received data */
UINT btr /* Byte count (must be even number) */
)
{
BYTE token;
Timer1 = 100;
do { /* Wait for data packet in timeout of 100ms */
token = rcvr_spi();
} while ((token == 0xFF) && Timer1);
if(token != 0xFE) return FALSE; /* If not valid data token, retutn with error */
do { /* Receive the data block into buffer */
rcvr_spi_m(buff++);
rcvr_spi_m(buff++);
} while (btr -= 2);
rcvr_spi(); /* Discard CRC */
rcvr_spi();
return TRUE; /* Return with success */
}
/*-----------------------------------------------------------------------*/
/* Send a data packet to MMC */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
static
BOOL xmit_datablock (
const BYTE *buff, /* 512 byte data block to be transmitted */
BYTE token /* Data/Stop token */
)
{
BYTE resp, wc;
if (wait_ready() != 0xFF) return FALSE;
xmit_spi(token); /* Xmit data token */
if (token != 0xFD) { /* Is data token */
wc = 0;
do { /* Xmit the 512 byte data block to MMC */
xmit_spi(*buff++);
xmit_spi(*buff++);
} while (--wc);
xmit_spi(0xFF); /* CRC (Dummy) */
xmit_spi(0xFF);
resp = rcvr_spi(); /* Reveive data response */
if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
return FALSE;
}
return TRUE;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Send a command packet to MMC */
/*-----------------------------------------------------------------------*/
static
BYTE send_cmd (
BYTE cmd, /* Command byte */
DWORD arg /* Argument */
)
{
BYTE n, res;
if (wait_ready() != 0xFF) return 0xFF;
/* Send command packet */
xmit_spi(cmd); /* Command */
xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */
xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */
xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */
xmit_spi((BYTE)arg); /* Argument[7..0] */
n = 0xff;
if (cmd == CMD0) n = 0x95; /* CRC for CMD0(0) */
if (cmd == CMD8) n = 0x87; /* CRC for CMD8(0x1AA) */
xmit_spi(n);
/* Receive command response */
if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
n = 10; /* Wait for a valid response in timeout of 10 attempts */
do
res = rcvr_spi();
while ((res & 0x80) && --n);
return res; /* Return with the response value */
}
/*-----------------------------------------------------------------------*
* Send the special command used to terminate a multi-sector read.
*
* This is the only command which can be sent while the SDCard is sending
* data. The SDCard spec indicates that the data transfer will stop 2 bytes
* after the 6 byte CMD12 command is sent and that the card will then send
* 0xFF for between 2 and 6 more bytes before the R1 response byte. This
* response will be followed by another 0xFF byte. In testing, however, it
* seems that some cards don't send the 2 to 6 0xFF bytes between the end of
* data transmission and the response code. This function, therefore, merely
* reads 10 bytes and, if the last one read is 0xFF, returns the value of the
* latest non-0xFF byte as the response code.
*
*-----------------------------------------------------------------------*/
static
BYTE send_cmd12 (void)
{
BYTE n, res, val;
/* For CMD12, we don't wait for the card to be idle before we send
* the new command.
*/
/* Send command packet - the argument for CMD12 is ignored. */
xmit_spi(CMD12);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
xmit_spi(0);
/* Read up to 10 bytes from the card, remembering the value read if it's
not 0xFF */
for(n = 0; n < 10; n++)
{
val = rcvr_spi();
if(val != 0xFF)
{
res = val;
}
}
return res; /* Return with the response value */
}
/*--------------------------------------------------------------------------
Public Functions
---------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0) */
)
{
BYTE n, ty, ocr[4];
if (drv) return STA_NOINIT; /* Supports only single drive */
if (Stat & STA_NODISK) return Stat; /* No card in the socket */
power_on(); /* Force socket power on */
send_initial_clock_train(); /* Ensure the card is in SPI mode */
SELECT(); /* CS = L */
ty = 0;
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
Timer1 = 100; /* Initialization timeout of 1000 msec */
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDC Ver2+ */
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
do {
if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 1UL << 30) == 0) break; /* ACMD41 with HCS bit */
} while (Timer1);
if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit */
for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
ty = (ocr[0] & 0x40) ? 6 : 2;
}
}
} else { /* SDC Ver1 or MMC */
ty = (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) <= 1) ? 2 : 1; /* SDC : MMC */
do {
if (ty == 2) {
if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) == 0) break; /* ACMD41 */
} else {
if (send_cmd(CMD1, 0) == 0) break; /* CMD1 */
}
} while (Timer1);
if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Select R/W block length */
ty = 0;
}
}
CardType = ty;
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
if (ty) { /* Initialization succeded */
Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
set_max_speed();
} else { /* Initialization failed */
power_off();
}
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Get Disk Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0) */
)
{
if (drv) return STA_NOINIT; /* Supports only single drive */
return Stat;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
SELECT(); /* CS = L */
if (count == 1) { /* Single block read */
if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
&& rcvr_datablock(buff, 512))
count = 0;
}
else { /* Multiple block read */
if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
do {
if (!rcvr_datablock(buff, 512)) break;
buff += 512;
} while (--count);
send_cmd12(); /* STOP_TRANSMISSION */
}
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
return count ? RES_ERROR : RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0) */
const BYTE *buff, /* Pointer to the data to be written */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
if (drv || !count) return RES_PARERR;
if (Stat & STA_NOINIT) return RES_NOTRDY;
if (Stat & STA_PROTECT) return RES_WRPRT;
if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
SELECT(); /* CS = L */
if (count == 1) { /* Single block write */
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
&& xmit_datablock(buff, 0xFE))
count = 0;
}
else { /* Multiple block write */
if (CardType & 2) {
send_cmd(CMD55, 0); send_cmd(CMD23, count); /* ACMD23 */
}
if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
do {
if (!xmit_datablock(buff, 0xFC)) break;
buff += 512;
} while (--count);
if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
count = 1;
}
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
return count ? RES_ERROR : RES_OK;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
BYTE n, csd[16], *ptr = buff;
WORD csize;
if (drv) return RES_PARERR;
res = RES_ERROR;
if (ctrl == CTRL_POWER) {
switch (*ptr) {
case 0: /* Sub control code == 0 (POWER_OFF) */
if (chk_power())
power_off(); /* Power off */
res = RES_OK;
break;
case 1: /* Sub control code == 1 (POWER_ON) */
power_on(); /* Power on */
res = RES_OK;
break;
case 2: /* Sub control code == 2 (POWER_GET) */
*(ptr+1) = (BYTE)chk_power();
res = RES_OK;
break;
default :
res = RES_PARERR;
}
}
else {
if (Stat & STA_NOINIT) return RES_NOTRDY;
SELECT(); /* CS = L */
switch (ctrl) {
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
csize = csd[9] + ((WORD)csd[8] << 8) + 1;
*(DWORD*)buff = (DWORD)csize << 10;
} else { /* MMC or SDC ver 1.XX */
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
*(DWORD*)buff = (DWORD)csize << (n - 9);
}
res = RES_OK;
}
break;
case GET_SECTOR_SIZE : /* Get sectors on the disk (WORD) */
*(WORD*)buff = 512;
res = RES_OK;
break;
case CTRL_SYNC : /* Make sure that data has been written */
if (wait_ready() == 0xFF)
res = RES_OK;
break;
case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
&& rcvr_datablock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
if (send_cmd(CMD10, 0) == 0 /* READ_CID */
&& rcvr_datablock(ptr, 16))
res = RES_OK;
break;
case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
for (n = 0; n < 4; n++)
*ptr++ = rcvr_spi();
res = RES_OK;
}
// case MMC_GET_TYPE : /* Get card type flags (1 byte) */
// *ptr = CardType;
// res = RES_OK;
// break;
default:
res = RES_PARERR;
}
DESELECT(); /* CS = H */
rcvr_spi(); /* Idle (Release DO) */
}
return res;
}
/*-----------------------------------------------------------------------*/
/* Device Timer Interrupt Procedure (Platform dependent) */
/*-----------------------------------------------------------------------*/
/* This function must be called in period of 10ms */
void disk_timerproc (void)
{
// BYTE n, s;
BYTE n;
n = Timer1; /* 100Hz decrement timer */
if (n) Timer1 = --n;
n = Timer2;
if (n) Timer2 = --n;
}
/*---------------------------------------------------------*/
/* User Provided Timer Function for FatFs module */
/*---------------------------------------------------------*/
/* This is a real time clock service to be called from */
/* FatFs module. Any valid time must be returned even if */
/* the system does not support a real time clock. */
DWORD get_fattime (void)
{
return ((2007UL-1980) << 25) // Year = 2007
| (6UL << 21) // Month = June
| (5UL << 16) // Day = 5
| (11U << 11) // Hour = 11
| (38U << 5) // Min = 38
| (0U >> 1) // Sec = 0
;
}
shyam
Hi Shyam
I'm facing the same problem... FR_NOT_READY!!
I'm using DK-TM4C129x, microSD of 2GB. I dint make any changes in the example code.
Appreciate your help.
Regards
Alston
hi alston,
this error comes when the initialisation is not proper or not card when there is an sd card problem.
better check with your initialization is proper r not if OK than check by changing the Sd card.
this error comes when the system is not able to read the SD card.