Part Number: TMS320F28379D
Tool/software: Code Composer Studio
Hi,
I am interfacing an SD Card using the McBSP B port on the F2839D microcontroller using the example project file found on Control suite named "Sd_Card". Initially I have implemented the program as it is using the SPI pinouts as indicated and found no problems..I created a file, wrote to it and read it without any problems.
Now I want to implement the same thing using the McBSP-B port programmed as SPI since on the product I am developing I must make use of these pinouts as the other three SPI ports are used for interfacing of other peripherals.. I have followed the example project found on control suite mcbsp_spi_loopback ...however the program is not working and I cannot determine where I could have done something wrong...
I have modified the code in the file mmc_F2837x.c as follows:
static
void power_on (void) //EDITED
{
/*
* This doesn't really turn the power on, but initializes the
* SPI port and pins needed to talk to the SD card.
*/
EALLOW;
/* Enable the peripherals used to drive the SDC on SPI */
CpuSysRegs.PCLKCR11.bit.McBSP_B = 1;
/*
* Configure the appropriate pins to be SPI instead of GPIO. The CS
* signal is directly driven to ensure that we can hold it low through a
* complete transaction with the SD card.
*/
GpioCtrlRegs.GPALOCK.bit.GPIO24 = 0;
GpioCtrlRegs.GPALOCK.bit.GPIO25 = 0;
GpioCtrlRegs.GPALOCK.bit.GPIO26 = 0;
GpioCtrlRegs.GPALOCK.bit.GPIO27 = 0;
GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 0; //Leave as GPIO for manual CS control
GpioCtrlRegs.GPAGMUX2.bit.GPIO24 = 0;
GpioCtrlRegs.GPAGMUX2.bit.GPIO25 = 0;
GpioCtrlRegs.GPAGMUX2.bit.GPIO26 = 0;
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 3; //ok
GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 3; // ok
GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 3; //ok
GpioCtrlRegs.GPADIR.bit.GPIO27 = 1; // CS as output
GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0; //Needs to be normally pulled high MOSI
GpioCtrlRegs.GPAPUD.bit.GPIO25 = 0; //Needs to be normally pulled high MISO
GpioCtrlRegs.GPAPUD.bit.GPIO26 = 1;
GpioCtrlRegs.GPAPUD.bit.GPIO27 = 1;
GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 3; // Asynch input
GpioCtrlRegs.GPAQSEL2.bit.GPIO25 = 3; //ok
GpioCtrlRegs.GPAQSEL2.bit.GPIO26 = 3; //ok
GpioCtrlRegs.GPAQSEL2.bit.GPIO27 = 3; //ok
GpioCtrlRegs.GPACSEL4.bit.GPIO24 = 0; //CPU select
GpioCtrlRegs.GPACSEL4.bit.GPIO25 = 0;
GpioCtrlRegs.GPACSEL4.bit.GPIO26 = 0;
GpioCtrlRegs.GPACSEL4.bit.GPIO27 = 0;
GpioCtrlRegs.GPALOCK.bit.GPIO24 = 1;
GpioCtrlRegs.GPALOCK.bit.GPIO25 = 1;
GpioCtrlRegs.GPALOCK.bit.GPIO26 = 1;
GpioCtrlRegs.GPALOCK.bit.GPIO27 = 1;
EDIS;
/* Deassert the *** chip selects for both the SD card and serial flash */
DESELECT();
/* Configure the McBSP_B port */
//
// McBSP-B register settings
//
McbspbRegs.SPCR2.all = 0x0000; // Reset FS generator, sample rate
// generator & transmitter
McbspbRegs.SPCR1.all = 0x0000; // Reset Receiver, Right justify word,
// Digital loopback disabled.
McbspbRegs.PCR.all = 0x0F08; //(CLKXM=CLKRM=FSXM=FSRM= 1, FSXP = 1)
McbspbRegs.SPCR1.bit.DLB = 0;
McbspbRegs.SPCR1.bit.CLKSTP = 2; // Together with CLKXP/CLKRP
// determines clocking scheme
McbspbRegs.PCR.bit.CLKXP = 1; // CPOL = 0, CPHA = 0 rising edge
// no delay
McbspbRegs.PCR.bit.CLKRP = 0;
McbspbRegs.RCR2.bit.RDATDLY = 01; // FSX setup time 1 in master mode.
// 0 for slave mode (Receive)
McbspbRegs.XCR2.bit.XDATDLY = 01; // FSX setup time 1 in master mode.
// 0 for slave mode (Transmit)
McbspbRegs.RCR1.bit.RWDLEN1 = 0; // 8-bit word
McbspbRegs.XCR1.bit.XWDLEN1 = 0; // 8-bit word
McbspbRegs.SRGR2.all = 0x2000; // CLKSM=1, FPER = 1 CLKG periods
McbspbRegs.SRGR1.all = 0x003F; // Frame Width = 1 CLKG period,
// CLKGDV=16
McbspbRegs.SPCR2.bit.GRST = 1; // Enable the sample rate generator
//delay_loop(); // Wait at least 2 SRG clock cycles
DELAY_US(50);
McbspbRegs.SPCR2.bit.XRST = 1; // Release TX from Reset
McbspbRegs.SPCR1.bit.RRST = 1; // Release RX from Reset
McbspbRegs.SPCR2.bit.FRST = 1; // Frame Sync Generator reset
/* 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();
//DELAY_US(50);
PowerFlag = 1;
}
/*-----------------------------------------------------------------------*/
/* 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) //EDITED
{
volatile DWORD dat;
/* Ensure CS (STE) is held high. */
DESELECT();
EALLOW;
GpioCtrlRegs.GPALOCK.bit.GPIO24 = 0;
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO24 = 1;
GpioCtrlRegs.GPALOCK.bit.GPIO24 = 1;
EDIS;
GpioDataRegs.GPASET.bit.GPIO24 = 1;
/* Send 10 bytes over the SPI. This causes the clock to wiggle the */
/* required number of times. */
unsigned int i;
for(i = 0 ; i < 10 ; i++)
{
/* Write DUMMY data */
while(McbspbRegs.SPCR2.bit.XRDY == FALSE); /// !!!!!!!!!!!!!!!!!!!!!!
McbspbRegs.DXR1.all = 0xFF00;
/* Flush data read during data write. */
while(McbspbRegs.SPCR1.bit.RRDY == FALSE);
dat = (McbspbRegs.DRR1.all & 0xFF);
}
EALLOW;
GpioCtrlRegs.GPALOCK.bit.GPIO24 = 0;
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 3;
GpioCtrlRegs.GPALOCK.bit.GPIO24 = 1;
EDIS;
}
/*-----------------------------------------------------------------------*/
/* Transmit a byte to MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static
void xmit_spi (BYTE dat) //EDITED
{
volatile DWORD rcvdat; //included file like integer.h for DWORD definition
/* Write the data to the tx fifo */
while(McbspbRegs.SPCR2.bit.XRDY == FALSE);
McbspbRegs.DXR1.all = ((DWORD)dat)<<8; //Write data
/* flush data read during the write */
while(McbspbRegs.SPCR1.bit.RRDY == FALSE);
rcvdat = (McbspbRegs.DRR1.all && 0xFF);
// UARTprintf("\n inside xmit spi function\n");
}
/*-----------------------------------------------------------------------*/
/* Receive a byte from MMC via SPI (Platform dependent) */
/*-----------------------------------------------------------------------*/
static
BYTE rcvr_spi (void) //EDITED
{
volatile DWORD rcvdat;
//Disable transmission channel
//SpicRegs.SPICTL.bit.TALK = 0;
/* write dummy data */
while(McbspbRegs.SPCR2.bit.XRDY == FALSE);
McbspbRegs.DXR1.all = 0xFF00;
/* read data from RX fifo */
while(McbspbRegs.SPCR1.bit.RRDY == FALSE);
rcvdat = (McbspbRegs.DRR1.all & 0xFF);
return (BYTE)rcvdat;
}
I have left the functions names as they were, and only modified the contents for McBSP operation. Can maybe someone please indicate if I have missed anything or maybe done something wrong in the configuation?
I have also seen the waveforms on oscillospe and the master is outputting clock and data to SD card however there is no response from SD_Card being the slave..
Thanks
Johann