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.

TMS320F28335 SD FAT32 File System writing problems

Other Parts Discussed in Thread: TMS320F2812, TMS320F28377D

I have implemented the FatFs file system onto a 28335 with partial sucess. I can read a file ok but cannot write sucessfully. I'm using a 2GB SD formatted to FAT32 in Windows 7. When writing to a file, I can open the filename with sucess, but on writing it appears to overwrite any existing file. I then attempt to read back the data but this fails. Reading it back on the PC there are no files. If I do a 'check now' under properties, the file can be recovered as FILE0000.CHK. I feel I'm close to solving the problem but I've spent too much time and need help please?

I maybe writing to a wrong sector or overwriting to an existing location. Can anyone help please? I've followed a previous thread but alas this was not fully concluded and is now dead. Thanks Geoff

fresult = f_mount(0, &fs[0]);

uart_printf("Create file fileXYZ.txt\n\r");

fresult = f_open(&fsrc,"/fileXYZ.txt", FA_CREATE_ALWAYS | FA_WRITE );

uart_printf("f_open code: %s\n",StringFromFresult(fresult         < RETURNS FR_OK>

uart_printf("Write a message (Hello World!)\n\r");

fresult = f_write(&fsrc,"Hello World!\0",14, &bw);

uart_printf("f_write code: %s\n", StringFromFresult(fresult)); RETURNS <FR_OK>

uart_printf("%d bytes written.\n",bw);  prints <14 bytes written>

f_close(&fsrc);   /* Close open files */

uart_printf("f_close: %s\r\n", StringFromFresult(fresult)); RETURNS <FR_OK

fresult = f_open(&fsrc,"/fileXYZ.txt", FA_OPEN_EXISTING | FA_READ);

uart_printf(f_open code: %s\r\n", StringFromFresult(fresult)); RETURNS <FR_OK>

uart_printf("fileXYZ.txt contents\r\n");

for(;;)

{

fresult = f_read(&fsrc,Buff,sizeof Buff,&br); /* read file */

if (fresult || !br) break;

uart_printf(Buff);   NOTHING PRINTED HERE

}

uart_printf(Buff);

fresult = f_close(&fsrc);

uart_printf("f_close: %s\r\n", StringFromFresult(fresult)); RETURNS <FR_OK>

/* Unregister work area prior to discard it */

 f_mount(0,NULL);

  • Hi Geoff,

    I assume you're using FatFS?  I think there is an option in there to make the API read only, but I forget where it is.  Try looking for that and seeing if it is setup for write only.

    Trey

  • Hi Trey,

    Thanks for your quick reply. _FS_READONLY is 0 by default. So read/write access should be allowable. One thing I thought of however, the get_fattime function is set to return the current date. Is this in a format that Windows would recognise? The reason being is that I can recover the written file. Dumb question but how does the code write any new file to the next available location on the SD card? Is it overwriting an existing file?

    DWORD get_fattime (void)

    {   

    return    ((2012UL-1980) << 25)    // Year = 2012

                | (10UL << 21)           // Month = October

                | (11UL << 16)           // Day = 11

                | (11U << 11)           // Hour = 11

                | (0U << 5)           // Min = 0

    | (0U >> 1)// Sec = ;

    }

  • Geoff,

    The date is in fact the correct format.  The date code as well as everything else is defined in the FAT standard.

    To answer your second question: That's the whole point of the file system.  It keeps track of what memory is used and unused on the SD card and keeps a record of where each file is as it gets split up across the available memory.

    Trey

  • Hi Trey,

    Thanks. The fattime may be a red herring I guess. So if the code keeps track of the available memory then I'm losing an existing text file written in Notepad by some means I don't yet undertsand. Both the written and existing files do not appear in Windows. I did have a state where the SD was being formatted but this was resolved. I'm almost there but not quite so any ideas would be welcome. It seems not many people out there have used this on the TI parts.

  • Geoff,

    Actually lots of people use SD cards with these parts, but we currently don't provide a reference example for the 28x core devices.  As long as my hardware come in the mail, I'm actually planning on building an example that reads and writes to SD cards this weekend.  If you can wait a couple days, I'll have some example code which should work for you.

    Trey

  • Hi Trey,

    That would be truly great thanks very much. I will eagerly wait for your post. I'm sure it will help many people. There is a question on the setting of the ENDIANESS. The 28335 is little endian based. Will this affect the code settings in ff.h?

     

    Regards

    Geoff

  • Hi,

    I have that same problem with FatFs on my TMS320F2812. Have you resolved the problem?

    Regards

    Rydel Wojciech

  • Rydel,

    I apologize, I never ended up getting a chance to get this running.  There is no technical reason why this cannot work on a C2000. 

    BR,

  • Trey,

    Thank you for your quick response.Can you tell me whether you plan to fix this problem in the near future?

    Regards,

    Rydel

  • Hi Rydel,

    I have working code writing to an SD card as FAT32 on a TMS28335. I'd be happy to help where I can. It is based on Elm Chan's FATFs code. There was no problem with the ENDIAN type.

    In my case I found I had to edit out the error response below inthe mmc-28x-ff9a.c file for it to work. Let me know.

     

    Regards

     

    Geoff

    /*-----------------------------------------------------------------------*/

    /* Send a data packet to MMC                                             */

    /*-----------------------------------------------------------------------*/

    //#pragma CODE_SECTION(xmit_datablock, "ramfuncs"); /* Run from SARAM */

    #if

    _READONLY == 0

    static

    BOOL xmit_datablock (

    /* was BOOL instead of int GL*/

       

    const BYTE *buff,    /* 512 byte data block to be transmitted */

        BYTE token           

    /* Data/Stop token */

    )

    {

        Uint16 j;

       

        BYTE resp = 0;

       

    if (wait_ready() != 0xFF) return FALSE;

       

       

    if (token != 0xFD)

        {

        spi_xmit_byte_FATS(token);

    /* Xmit data token */

      

    for(j=0;j<512;j++)

    spi_xmit_byte_FATS(*buff++);

       spi_xmit_byte_FATS(0xFF);

    /* transmit 0xFF twice more to send CRC */

    spi_xmit_byte_FATS(0xFF);

    while (resp != 0xE500) /* data accepted ok */

    {

    resp = spi_xmit_byte_FATS(0xFF);

    /*resp &= 0x0F;*/ /* mask response to test for errors */

    if (resp != 0xE500)

    return FALSE;

    /*resp = rcvr_spi();*/

      

    /* if ((resp & 0x0F) != 0x05) */ /* was 0x1F GL */

               

    /*return FALSE;*/

    }

        }

      

    return TRUE;

    }

    #endif

     

  • Hi Geoff,

    Thank you for your response. I formatted my SD as FAT32 and I changed xmit_datablock() function as you described, but nothing changed. f_write still returns FR_DISK_ERR. I will be very grateful if you can tell me what Elm Chan's FatFs library version you  use. Can you tell me did you write functions for device control interface or you found it somwhere? I use this:

    /*-----------------------------------------------------------------------*/
    /* MMC/SDC (in SPI mode) control module  (C)ChaN, 2007                   */
    /*-----------------------------------------------------------------------*/
    /* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros         */
    /* are platform dependent.                                               */
    /*-----------------------------------------------------------------------*/
    #include "spi_sd.h"
    #include "diskio.h"
    #include "DSP281x_Device.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 */
    
    /*--------------------------------------------------------------------------
    
     Module Private Functions
    
     ---------------------------------------------------------------------------*/
    
    typedef enum {
    	TRUE = 1, FALSE = 0
    } bool;
    
    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 */
    
    static
    void SELECT(void) 		// CS w stan niski
    {
    	EALLOW;
    	GpioDataRegs.GPBDAT.bit.GPIOB10 = 0;
    	EDIS;
    }
    
    static
    void DESELECT(void) 	// CS w stan wysoki
    {
    	EALLOW;
    	GpioDataRegs.GPBDAT.bit.GPIOB10 = 1;
    	EDIS;
    }
    
    void SPI_SD_Init(void) {
    	SPI_Init();
    
    	DESELECT();
    }
    
    static
    void xmit_spi(BYTE Data)  // Wyslanie bajtu do SD
    {
    	SpiaRegs.SPITXBUF = Data << 8;
    	while (!SpiaRegs.SPISTS.bit.INT_FLAG)
    		;
    	SpiaRegs.SPIRXBUF = SpiaRegs.SPIRXBUF;
    }
    
    static BYTE rcvr_spi(void) 		// Odebranie bajtu z SD
    {
    	u8 Data = 0;
    
    	SpiaRegs.SPITXBUF = 0xFF << 8;
    	while (!SpiaRegs.SPISTS.bit.INT_FLAG)
    		;
    	Data = SpiaRegs.SPIRXBUF;
    
    	return Data;
    }
    
    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;
    }
    
    /*-----------------------------------------------------------------------*/
    /* 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) {
    	u8 i;
    
    	DESELECT();      // CS = 1
    
    	//Wyslanie 10 razy 0xFF co daje ponad 80 (>74) cykle zegara
    	//wymagane przez specyfikacje SD
    	for (i = 0; i < 10; i++)
    		xmit_spi(0xFF);
    
    	PowerFlag = 1;
    }
    
    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 = 10;
    	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(
    
    /* was BOOL instead of int GL*/
    
    const BYTE *buff, /* 512 byte data block to be transmitted */
    
    BYTE token
    
    /* Data/Stop token */
    
    )
    
    {
    
    	Uint16 j;
    
    	BYTE resp = 0;
    
    	if (wait_ready() != 0xFF)
    		return FALSE;
    
    	if (token != 0xFD)
    
    	{
    
    		xmit_spi(token);
    
    		/* Xmit data token */
    
    		for (j = 0; j < 512; j++)
    
    			xmit_spi(*buff++);
    
    		xmit_spi(0xFF);
    
    		/* transmit 0xFF twice more to send CRC */
    
    		xmit_spi(0xFF);
    
    		while (resp != 0xE500) /* data accepted ok */
    
    		{
    
    			resp = rcvr_spi();
    
    			/*resp &= 0x0F;*//* mask response to test for errors */
    
    			if (resp != 0xE500)
    
    				return FALSE;
    
    			/*resp = rcvr_spi();*/
    
    			/* if ((resp & 0x0F) != 0x05) *//* was 0x1F GL */
    
    			/*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);
    	xmit_spi(0xFF);
    
    	/* 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 */
    }
    
    /*--------------------------------------------------------------------------
    
     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();
    
    	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 */
    	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_cmd(CMD12, 0); /* 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 ((2011UL - 1980) << 25)    // Year = 2011
    	| (1UL << 21)            // Month = January
    			| (1UL << 16)            // Day = 1
    			| (12U << 11)            // Hour = 12
    			| (0U << 5)              // Min = 00
    			| (0U >> 1)              // Sec = 00
    	;
    
    }
    
    
    for device control interface and I don't know if all functions are ok.

    BR,
    Rydel

  • Hi Rydel,

    Check the speed of your SD card, start at a low clock frequency. I'm running at 9.6MHz with a SanDisk SDHC 4GB

    The versions I have used and that work for me on the 28335 device are:

    ff-9a.c Elm Chan 2012

    mmc-28x-ff9a.c Elm chan2007

    SD_SPI_Transmission.c Texas Instruments author Tim Love 2007

    SD_SPI_Initialization.c Tim Love 2007

    SD_SPI_Registers.c Tim Love 2007


    This section of code is in main and writes data, time and date to a .CSV file

    /**********************************************************/

    /* SD here */

    fresult = f_mount(0, &Fatfs);

       fresult = f_open(&File,

    "/ALERTLOG.CSV", FA_WRITE | FA_OPEN_EXISTING); /* Write the time the unit was switched on. *

    if (fresult) die(fresult); 

        read_I2C_time_date(&I2C_time);

        WriteCount = f_printf(&File,"ALERT, v%D,b%D\r\n",version,build);

    if (fresult) die(fresult);  

    WriteCount = f_lseek(&File, f_size(&File));

    /* Move to end of the file to append data */

        WriteCount = f_printf(&File,

    "Date,%D-%D-%D,%D:%D:%D\r\n",I2C_time.tm_day,I2C_time.tm_mon,I2C_time.tm_year,

        I2C_time.tm_hour,I2C_time.tm_min,I2C_time.tm_sec);

    fresult = f_sync(&File);

        fresult = f_close(&File);

    /* Unregister work area prior to discarding it */

        f_mount(0,NULL);

        CS_HIGH; 

    I'd be happy to zip these up and send them to you if that helps.

    Regards

    Geoff

     

  • Hi Geoff,

    It would be fantastic if you coud zip these up and send them to me :) . Frankly, I get tired of this for over a week and to save time to you and me for writting posts here I would like to check differences between your and my code and fix what I have wrong.

    My e-mail: rydel.wojciech@gmail.com


    BR,

    Rydel

  • Hi Geoff,

    I'm having the same issue with the Elm chan, im not able to make it work, it would be very appreciated if you could share your findings, this it's my email address: bostan_89@yahoo.com.

    Best regards,

    Adrian.

  • I am using a TMS320F28377d kit. I am also trying to interface it with an sd card (8 gb). I am able to read  a file in the card and create a new file. But I am not able to write anything in the file. I am getting FR_RW_ERROR while closing a file which is opened in a WRITE mode. I have checked that I am able to overwrite in a existing file but unable to write in an empty file. Any help would be appreciable.

    Thanks.

  • Hi Geoff,
    Can you zip me the mmc.c file. I am able to read a file but I am not able to write in an empty file.
    My email id is priti.chakraborty@iitgn.ac.in. I would be really grateful.

    Thanks.
  • I am using a TMS320F28377d kit. I am also trying to interface it with an sd card (8 gb). I am able to read a file in the card and create a new file. But I am not able to write anything in the file. I am getting FR_RW_ERROR while closing a file which is opened in a WRITE mode. I have checked that I am able to overwrite in a existing file but unable to write in an empty file. Any help would be appreciable.

    Thanks
  • Priti,
    Is this the same issue that you have created your other post on?
    Thanks,
    Mark
  • Hi Geoff
    I am using TMS320F28377d kit. I am also trying to interface it with an sd card.i want to create fat32file system on the sd card as well as to read and write file on sd card.Can you please send a program code for it.
    My email id: harshali.in@gmail.com

    Any help would be appreciable.
  • Hello,

    Please consider creating a new post if the discussion on this thread doesn't answer your question. Old posts are generally closed and no longer tracked. You can provide the necessary information regarding your issue in the new post and include a link to this post if you'd like.

    Elizabeth