Other Parts Discussed in Thread: SYSBIOS
Hello everyone
My target is F28335, boards are custom, CCS 6.0.1, Compiler 6.2.7, SYSBIOS used
Flash accessed by SPI is Spansion S25FL512S
I use the McBSP peripheral of F28335 in SPI mode
I made it work to write and read in a flash memory at 2.5 MHz.
But the slightest change in the code or in the speed config, make it fail to read/write.
The oscilloscope shows correct data read from the flash, so it's a software issue.
In loopback mode everything works (it's too basic)
On the ez eval board with TI example code (multiday workshop module 14) it works too.
I have a few questions about the example code for READ, reproduced below
int McBSP_B_EEPROM_Read(int address)
{
int data;
CS_EEPROM = 0; // activate /CS for the EEPROM
McbspbRegs.DXR1.all = READ; // Read op-code
while (McbspbRegs.SPCR2.bit.XRDY == 0);
McbspbRegs.DXR1.all = address>>8; // Higher byte of starting address
while (McbspbRegs.SPCR2.bit.XRDY == 0);
McbspbRegs.DXR1.all = address; // Lower byte of starting address
while (McbspbRegs.SPCR2.bit.XRDY == 0);
McbspbRegs.DXR1.all = 0x00; // send dummy Data
while (McbspbRegs.SPCR2.bit.XRDY == 0);
data = McbspbRegs.DRR1.all; // Clears receive flag
while (McbspbRegs.SPCR1.bit.RRDY == 0);
data = McbspbRegs.DRR1.all; // Reads data from memory
CS_EEPROM = 1; // deactivate /CS for the EEPROM
return(data);
}
1) Why is it needed to read DRR1 twice ?
It doesn't make sense to me and it's NOT explained anywhere in the McBSP guide or any documentation
Now if we take a look at the init code reproduced below
void McBSPB_Init()
{
EALLOW;
McbspbRegs.SPCR1.all=0x0000; // Reset Receiver
McbspbRegs.SPCR1.bit.CLKSTP = 3; // 3: Clockstop mode set to inactive low.
// McBSP transmits data 1/2 cycle ahead of CLKX
McbspbRegs.SPCR1.bit.RRST = 1; // 1: Enables receiver
McbspbRegs.SPCR2.all=0x0000; // Reset FS generator, sample rate generator & transmitter
McbspbRegs.SPCR2.bit.FREE = 1; // Free run in break event
McbspbRegs.SPCR2.bit.GRST = 1; // 1: Enables sample rate generator
McbspbRegs.SPCR2.bit.XRST = 1; // 1: Enables transmitter
McbspbRegs.SPCR2.bit.FRST=1; // 1: release frame logic from reset
McbspbRegs.PCR.bit.CLKXP = 0; // 0: Transmit data sampled on rising edge of CLKX
McbspbRegs.PCR.bit.CLKRP = 1; // 1: Receive data sampled on rising edge of MCLKR
McbspbRegs.PCR.bit.CLKXM = 1; // 1: McBSP is master in SPI-mode;
// CLKX drives pin MCLKX and MCLKR(internally)
McbspbRegs.PCR.bit.SCLKME = 0; // 0: McBSP clock generator derived from LSPCLK
McbspbRegs.PCR.bit.FSXM = 1; // 1: Transmit frame sync generated internally by CLKG
McbspbRegs.PCR.bit.FSXP = 1; // 1: Transmit frame sync pulses are active low
McbspbRegs.SRGR1.bit.CLKGDV = 37; // 37: CLKG = LSPCLK/(37+1) = 1 MHz on McBSP
McbspbRegs.SRGR2.bit.CLKSM = 1; // 1: McBSP clock generator derived from LSPCLK
McbspbRegs.SRGR2.bit.FSGM = 0; // 0: McBSP generates a frame sync when DXR is copied into XSR
McbspbRegs.XCR1.bit.XFRLEN1 = 0; // 0: One word per frame for transmit
McbspbRegs.XCR1.bit.XWDLEN1 = 0; // 0: 8 bit transmit word
McbspbRegs.XCR2.bit.XPHASE = 0; // 0: Single phase transmit
McbspbRegs.XCR2.bit.XDATDLY = 0; // 0: No data delay between sync and first data bit
McbspbRegs.RCR1.bit.RFRLEN1 = 0; // 0: One word per frame for receive
McbspbRegs.RCR1.bit.RWDLEN1 = 0; // 0: 8 bit receive word
McbspbRegs.RCR2.bit.RDATDLY = 0; // 0: No data delay because FSX not needed for chip select
McbspbRegs.RCR2.bit.RPHASE = 0; // 0: Single phase receive
EDIS;
}
2) Why are XDATDLY and RDATDLY set to 0 ?
In the McBSP user guide table 6.3 it is explicitely said XDATDLY and RDATDLY must be set to 1 in SPI mode
3) Why the init code does not follow the 6-step configuration procedure ?
In the user guide there is a procedure (6.5) that includes waiting clock periods and a specific order of initialization.
Now here's my init routine
{
/* Step 1. Place the transmitter and receiver in reset. */
p_mcbsp_regs->SPCR1.bit.RRST = 0;
p_mcbsp_regs->SPCR2.bit.XRST = 0;
/* Step 2. Place the sample rate generator in reset. */
p_mcbsp_regs->SPCR2.bit.GRST = 0;
/* Step 3. Program registers that affect SPI operation. */
/* Stop mode --> SPI + no delay (phase) */
p_mcbsp_regs->SPCR1.bit.CLKSTP = 2;
/* Loopback disabled */
p_mcbsp_regs->SPCR1.bit.DLB = 0;
/* Right justify the data received and zero fills MSBs */
p_mcbsp_regs->SPCR1.bit.RJUST = 0;
/* Additionnal delay disabled */
p_mcbsp_regs->SPCR1.bit.DXENA = 0;
/* Free run during breakpoints */
p_mcbsp_regs->SPCR2.bit.FREE = 1;
p_mcbsp_regs->SPCR2.bit.SOFT = 1;
/* Receive polarity */
/* Transmit polarity */
/*
* no delay
* data captured on RISING edge
* data out on FALLING edge
*/
p_mcbsp_regs->PCR.bit.CLKRP = 1;
p_mcbsp_regs->PCR.bit.CLKXP = 1;
/* Master */
p_mcbsp_regs->PCR.bit.CLKXM = 1;
p_mcbsp_regs->PCR.bit.CLKRM = 1;
/* single phase transmit/receive frame */
p_mcbsp_regs->XCR2.bit.XPHASE = 0;
p_mcbsp_regs->RCR2.bit.RPHASE = 0;
/* frame length of one serial word */
p_mcbsp_regs->XCR1.bit.XFRLEN1 = 0;
p_mcbsp_regs->RCR1.bit.RFRLEN1 = 0;
/* One word is 8 bits */
p_mcbsp_regs->XCR1.bit.XWDLEN1 = 0;
p_mcbsp_regs->RCR1.bit.RWDLEN1 = 0;
p_mcbsp_regs->RCR2.bit.RCOMPAND = 0;
/* Must be Set to 1 for proper SPI master operation */
p_mcbsp_regs->RCR2.bit.RDATDLY = 1;
p_mcbsp_regs->RCR2.bit.RFIG = 1;
p_mcbsp_regs->XCR2.bit.XCOMPAND = 0;
/* Must be Set to 1 for proper SPI master operation */
p_mcbsp_regs->XCR2.bit.XDATDLY = 1;
p_mcbsp_regs->XCR2.bit.XFIG = 1;
/*
* McBSP generates a transmit frame-synchronization pulse when the content of DXR[1,2] is copied to XSR
* (even though we use the CS pin as a classic GPIO and not let McBSP drive it)
*/
p_mcbsp_regs->SRGR2.bit.FSGM = 0;
/* Input Clock For Sample Rate Generator -> Low Speed Clock LSPCLK */
p_mcbsp_regs->PCR.bit.SCLKME = 0;
p_mcbsp_regs->SRGR2.bit.CLKSM = 1;
/*
* CLKG freq with LSCLK = SYSCLKOUT / 8
* CLKG freq = LSPCLK / (CLKGDV + 1)
* CLKG freq = 5 MHz
*/
p_mcbsp_regs->SRGR1.bit.CLKGDV = 1;
/*
* FSX ~= SPI CS need to be generated internally
* Transmit frame synchronization is generated internally by the Sample Rate generator,
* as determined by the FSGM bit of SRGR2
* (even though we use the CS pin as a classic GPIO and not let McBSP drive it)
*/
p_mcbsp_regs->PCR.bit.FSXM = 1;
/* Receive frame synchronization is supplied by the sample rate generator */
p_mcbsp_regs->PCR.bit.FSRM = 1;
/*
* Transmit frame-synchronization pulses = "Chip select" --> active low
* (even though we use the CS pin as a classic GPIO and not let McBSP drive it)
*/
p_mcbsp_regs->PCR.bit.FSXP = 1;
/* Step 4. Enable the sample rate generator. */
p_mcbsp_regs->SPCR2.bit.GRST = 1;
/*
* After the sample rate generator is released from reset,
* wait two sample rate generator clock periods for the McBSP logic to stabilize
*/
wait(MCBSP_TWO_CLOCK_WAIT);
/* Step 5. Enable the transmitter and receiver. */
p_mcbsp_regs->SPCR1.bit.RRST = 1;
p_mcbsp_regs->SPCR2.bit.XRST = 1;
/*
* After the transmitter and receiver are released from reset,
* wait two sample rate generator clock periods for the McBSP logic to stabilize.
*/
wait(MCBSP_TWO_CLOCK_WAIT);
/*
* Step 6. Enable the frame-synchronization logic of the sample rate generator.
* After the required data acquisition setup is done (DXR[1,2] is loaded with data),
* set FRST = 1 if the McBSP is the SPI master)
*/
p_mcbsp_regs->DXR1 = 0;
p_mcbsp_regs->SPCR2.bit.FRST = 1;
}
4) Do you notice anything wrong with my init routine ?
Regards,
Clement