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.

Read and Write on SD card with TMS320F28335

Other Parts Discussed in Thread: TMS320F28335, TMS320F28379D

Hi everybody,

I program on TMS320F28335 with a XDS100v1 and I have a problem using Fatfs module (0.09a and 1.0 have the same issue so I am the problem ^^) with it to write and read on a SD card. Here is a pseudo-code (Is something with SPI initialization bad ? ) :

int main(){

	// Disable the watchdog initially
	WDogDisable();


	// SYSTEM CLOCK speed based on Crystal = 20 MHz (R1.1 controlCARD)
	// 0xF =  150   MHz		(15)
	// 0xE =  140   MHz		(14)
	// 0xD =  130   MHz		(13)
	// 0xC =  120   MHz		(12)
	// 0xB =  110   MHz		(11)
	// 0xA =  100	MHz		(10)
	// 0x9 =  90	MHz		(9)
	// 0x8 =  80	MHz		(8)
	// 0x7 =  70	MHz		(7)
	// 0x6 =  60	MHz		(6)
	// 0x5 =  50	MHz		(5)
	// 0x4 =  40	MHz		(4)
	// 0x3 =  30	MHz		(3)
	// 0x2 =  20	MHz		(2)

	// SYSTEM CLOCK speed based on Crystal = 25 MHz (R1 controlCARD)
	// 0xF =  187.5 MHz		(15)
	// 0xE =  175   MHz		(14)
	// 0xD =  162.5 MHz		(13)
	// 0xC =  150   MHz		(12)
	// 0xB =  137.5 MHz		(11)
	// 0xA =  125	MHz		(10)
	// 0x9 =  112.5	MHz		(9)
	// 0x8 =  100	MHz		(8)
	// 0x7 =  87.5	MHz		(7)
	// 0x6 =  75	MHz		(6)
	// 0x5 =  62.5	MHz		(5)
	// 0x4 =  50	MHz		(4)
	// 0x3 =  37.5	MHz		(3)
	// 0x2 =  25	MHz		(2)

	// SYSTEM CLOCK speed based on Crystal = 30 MHz (R1.2 controlCARD)
	// 0xA =  150	MHz		(10)
	// 0x9 =  135	MHz		(9)
	// 0x8 =  120	MHz		(8)
	// 0x7 =  105	MHz		(7)
	// 0x6 =  90	MHz		(6)
	// 0x5 =  75	MHz		(5)
	// 0x4 =  60	MHz		(4)
	// 0x3 =  45	MHz		(3)
	// 0x2 =  30	MHz		(2)




	PLLset(0xA);// choose from options above based on the reference crystal
	DINT;			// Global Disable all Interrupts

	IER = 0x0000;	// Disable CPU interrupts
	IFR = 0x0000;	// Clear all CPU interrupt flags

	PieCntlInit();
	InitPieVectTable();


	InitCpuTimers();
	// Configure CPU-Timer 0 to interrupt every microsecond:
	// 150MHz CPU Freq, 1 Period (in uSeconds)
	// Generates a 100us period
	ConfigCpuTimer(&CpuTimer0, 150, 50);


	EALLOW;

	// HIGH / LOW SPEED CLOCKS prescale register settings
	SysCtrlRegs.HISPCP.all = 0x0001;		// Sysclk / 2 (25 MHz)
	SysCtrlRegs.LOSPCP.all = 0x0002;		// Sysclk / 4 (25 MHz)



	// Initialize Gpio
	InitGpio();

	// Initialize Spi
	InitSpi();
	




	/********************************* LECTURE *********************************************/
	fresult = f_mount(0, &Fatfs); // It returns FR_OK SO IT SEEMS TO BE GOOD

	fresult = f_open(&File, "Testounet.txt", FA_READ);
	// It doesn't go out of f_open. There is an infinite loop in which depends on 
	// SPI transmission of a command.
	

	
	
	
}



void InitSpi(void){


	InitSpiaGpio();




	// Initialize SPI FIFO registers
	SpiaRegs.SPIFFTX.all = 0xE040;
	SpiaRegs.SPIFFRX.all = 0x204f;
	SpiaRegs.SPIFFCT.all = 0x0;



	SpiaRegs.SPICCR.all = 0x0007;	             // Reset on, rising edge, 16-bit char bits
	SpiaRegs.SPICTL.all = 0x000E;    		     // Enable master mode, normal phase, enable talk, and SPI int disabled.



	SpiaRegs.SPIBRR = 0x007F;
	SpiaRegs.SPICCR.all = 0x0087;		         // Reset on
	SpiaRegs.SPIPRI.bit.FREE = 1;                // Set so breakpoints don't disturb xmission


    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; /* Switch to SPI MOSI */
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; /* Switch to SPI MISO */
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; /* Switch to SPI SCLK */
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; /* Switch to SPI SSEL */



}



void InitSpiaGpio(void){

    EALLOW;


    GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0;   // Enable pull-up on GPIO16 (SPISIMOA)
    GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0;   // Enable pull-up on GPIO17 (SPISOMIA)
    GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0;   // Enable pull-up on GPIO18 (SPICLKA)
    GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0;   // Enable pull-up on GPIO19 (SPISTEA)


    GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)


    GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // Configure GPIO16 as SPISIMOA
    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // Configure GPIO17 as SPISOMIA
    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // Configure GPIO18 as SPICLKA
    GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // Configure GPIO19 as SPISTEA


    EDIS;
}

I give you the part of f_open where the program enter in an infinite loop.

FRESULT f_open (
	FIL *fp,			/* Pointer to the blank file object */
	const TCHAR *path,	/* Pointer to the file name */
	BYTE mode			/* Access mode and file open mode flags */
)
{
	FRESULT res;
	DIR dj;
	BYTE *dir;
	DEF_NAMEBUF;


	if (!fp) return FR_INVALID_OBJECT;
	fp->fs = 0;			/* Clear file object */

#if !_FS_READONLY
	mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;


	res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ));

In fact it is blocked in the chk_mounted function and more particularly in the while of this sub_function while :

/*-----------------------------------------------------------------------*/
/* Receive a byte from MMC via SPI  (Platform dependent)                 */
/*-----------------------------------------------------------------------*/
static BYTE rcvr_spi (void){

	BYTE ret;
  	SpiaRegs.SPITXBUF = 0xFF00;        				/* Transmit DUMMY Byte */
	while(SpiaRegs.SPISTS.bit.INT_FLAG == 0){

	}; 	/* Wait until the RXBUF has received last bit, but nothing happens...*/
	ret = (SpiaRegs.SPIRXBUF);						/*Read Byte from RXBUF and return */
	return ret;

}