I've been working on a datalogger and banging my head against the wall because what I expected to be trivial has instead been quite difficult for me.
I can create a file on the SD card, but have been unable to actually write to it. f_write() returns FR_RW_ERROR. In f_write, it calls create_chain at line 1000 of ff.c and stepping through calls get_cluster() at line 290. The file system is FAT32, so it jumps to line 162 and calls move_window. In move_window, it goes to line 76 and calls disk_write (contained in mmc-F2837x.c at line 641). Count == 1 so it goes to the conditional:
if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
&& xmit_datablock(buff, 0xFE))
count = 0;
I determined that xmit_datablock is what is creating the issue.
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;
}
Specifically, it returns FALSE due to the last if statement. This is because of the return of rcvr_spi:
static
BYTE rcvr_spi (void) //EDITED
{
volatile DWORD rcvdat;
//Disable transmission channel
//SpicRegs.SPICTL.bit.TALK = 0;
/* write dummy data */
while(SpicRegs.SPISTS.bit.BUFFULL_FLAG); //Wait for space to write
SpicRegs.SPITXBUF = 0xFF00; //Write dummy data
/* read data from RX fifo */
while(SpicRegs.SPISTS.bit.INT_FLAG !=1); //May be possible to switch to '!SpicRegs.SPISTS.bit.INT_FLAG'
rcvdat = (SpicRegs.SPIRXBUF & 0xFF); //Read Transferred data
return (BYTE)rcvdat;
}
Evidently the read data is incorrect as rcvdat = (spicRegs.SPIRSBUF & 0xFF) is resulting in a 255 (assigned to resp), which results in resp & 0x1F = 0 and !=5 as the code expects in xmit_datablock (and that then rolls back through all the function calls to result in the FR_RW_ERROR).
So the question is this: is this a buggy driver provided by TI, an issue with the SD card I'm using, or something I'm doing incorrectly? I can post any relevant code needed as either snippets or whole files.