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.