I'm going to try to illustrate this with actual code, butwill embed code fragments from 3 source files to pare thesize down to the minimum.
I am trying to get my first SPI driver working on aTMS320F2812 using my own board. The 2812 is master and theslave doesn't matter.
Inside main(), the first thing I do is call initSysCtrl():> > void main(void) {> initSysCtrl();>
which (among other things) calls initPeripheralClocks():> > initPeripheralClocks();>
which (also among other things) configures the low-speedperipheral clock and routes it to the SPI hardware.> > SysCtrlRegs.LOSPCP.all = 0x0002;> > SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;>
Function main() then calls my own function to initialize theI/O ports: > > initIO();>
inside which I configure the pins on port F to be driven bythe SPI hardware:> > EALLOW; /* Enable access to I/O cfg regs */> > /* + + + + + + + + + + + + + + + + + + + + + + + */> /* GPIOF */> /* - - - - - - - - - - - - - - - - - - - - - - - */> /* P Gpio...Regs */> /* e ----------- */> /* r D P M D Q D */> /* i i U U I U A */> /* Port f r S Signal X R L T */> /* ------- - - - ------------------ - - - - */> /* 15 0 0 • 0 */> /* GPIOF14 • I • --- unused --- 0 0 • 0 */> /* GPIOF13 • O L selEEProm-L 0 1 • 0 */> /* GPIOF12 • O L selPX2-L 0 1 • 0 */> /* */> /* GPIOF11 • O L selPX1-L 0 1 • 0 */> /* GPIOF10 • I • mCUId2-H 0 0 • 0 */> /* GPIOF9 • I • mCUId1-H 0 0 • 0 */> /* GPIOF8 • I • mCUId0-H 0 0 • 0 */> /* */> /* GPIOF7 † I • canRx-H 1 0 • 0 */> /* GPIOF6 † O L canTx-H 1 1 • 0 */> /* GPIOF5 † I • diagTxDatBf-H 1 0 • 0 */> /* GPIOF4 † O L diagRxDatBf-H 1 1 • 0 */> /* */> /* GPIOF3 • I • bootMode1-H 0 0 • 0 */> /* GPIOF2 † O • spiClk-H 1 1 • 0 */> /* GPIOF1 † O • spiMiso-H 1 1 • 0 */> /* GPIOF0 † I • spiMosi-H 1 0 • 0 */> /* - - - - */> /* 0 3 • 0 */> /* Hex 0 8 • 0 */> /* values F 5 • 0 */> /* 7 6 • 0 */> /* + + + + + + + + + + + + + + + + + + + + + + + */> GpioMuxRegs.GPFMUX.all = 0x00F7;> GpioMuxRegs.GPFDIR.all = 0x3856; > GpioDataRegs.GPFDAT.all = 0;> > EDIS; /* Disable access to I/O cfg regs */>
I then go out and initialize the PIE vector table, which isnot relevant to this discussion and call initSPIFifo():> > initSPIFifo(); /* Initialize the Spi FIFO */> which I have tried to modify to disable the SPI FIFO:> > void initSPIFifo(void) {> SpiaRegs.SPIFFTX.all = 0x0040;> SpiaRegs.SPIFFRX.all = 0x4040;> SpiaRegs.SPIFFCT.all = 0x0000;> } /* END initSPIFifo() */>
I then call initSPI():> > initSPI();> which finishes off the initialization:> > void initSPI(void) {> SpiaRegs.SPICCR.all = 0x0007;> SpiaRegs.SPICTL.all = 0x000E;> SpiaRegs.SPIBRR = 0x007F;> SpiaRegs.SPICCR.all = 0x0087;> SpiaRegs.SPIPRI.bit.FREE = 1; /* Set so breakpoints */> /* don't disturb xmission */> } /* END void initSPI() */>
The set-up shown should be compatible with my slave, whichrequires the SPI clock to idle low, and be below 10 MHz (Iam using 293 kHz), to send & receive 8-bit bytes, to changethe data lines on the falling edge of the clock and strobeit on the rising edge.
If I understand the documentation, that last statementshould allow any data I put in the SPITXBUF register toshift out immediately, even if I hit a breakpoint in myemulator right after loading the register.
At this point we are about to enter my main control loop,which will constantly poll the SPI slave (but I don't needto show it because we never get that far).
Past experience (with other micros) leads me to believe Ineed a way to tell whether the last byte I put in theSPITXBUF register has cleared the shift register. Only thencan I bring my slave select line false.
The only reliable signal I could find was the SPI interruptflag in SPISTS.6. Whenever this is set I can safely assume Ican send my next character or terminate the transaction.There is a problem at the top of the MCL because I haven'tsent anything, but it powers up 0. So I decide to send adummy byte (without bringing my slave select line low) toset this bit for the first time through the MCL, by callingmy transmit function:> > sPITxChar(0xFF); /* Set the SPI Int flag */>
which loads my data into SPITXBUF:> > void sPITxChar(Uint16 a) {> SpiaRegs.SPITXBUF = a << 8;> } /* END sPITxChar() */>
Using the emulator, I can see the byte gets loaded intoSPITXBUF, and gets transferred immediately to SPIDAT (theshift register).
The problem is that it just sits there....forever. I ammonitoring the MOSI output with a scope and it goes highonce, but shows no other transitions. The emulator tells methat LOSPCP still holds the 0x0002 I put there, andPCLKCR0.8 (a.k.a. SPIAENCLK) is still set. All the other SPIregisters still show the values that I put in them: SPICCR: 0x0087 SPICTL: 0x000E SPISTS: 0x0000 SPIBRR: 0x007F SPIRXEMU: 0x0000 SPIRXBUF: 0x0000 SPITXBUF: 0xFF00 SPIDAT: 0xFF00 SPIFFTX: 0x0000 SPIFFRX: 0x0000 SPIFFCT: 0x0000 SPIPRI: 0x0010
Can anybody see why this thing isn't working?
Thanks.
============================================================Gary Lynch printf("lynchg%cstacoenergy%ccom", 55+9, 55-9)============================================================
Gary,
Detailed post! We'll get you up and running here. A few comments:
1) If you aren't using the FIFO, let's just comment out the call to the FIFO initialization function.
2) It looks like you are trying to send 0xFF as the 8 bits based on the SPITXBUF register. Can you try to send 0xAA just to be certain the line isn't just staying continuously high?
3) Can you check the SPICLK signal with your scope to see if you see it activate?
Sorry if you already have these somewhere in the post. I don't think I saw them :)
Thanks,
Kris
On Wednesday, April 04, 2012 5:55 PM; Kris Parrent wrote:> > Detailed post! > Practice makes perfect!
> > We'll get you up and running here. > That's what I want to hear.
> > 1) If you aren't using the FIFO, let's just comment out the> call to the FIFO initialization function. > Done.
> > 2) It looks like you are trying to send 0xFF as the 8 bits> based on the SPITXBUF register. Can you try to send 0xAA> just to be certain the line isn't just staying continuously> high?> I didn't think of that. Since the shift register doesn'tappear to shift, I wasn't surprised by the lack of output.But I have changed it now.
> > 3) Can you check the SPICLK signal with your scope to see if> you see it activate?> I am attaching the scope trace in response. At 292.968 kHza single bit ought to last 3.41 usec or about 1/3 of a majordiv on my trace. The entire screen is 100 usec wide, andcould display 29 bit times. TP1 is a spare micro outputwhich I bring low at the time I would be lowering the slaveselect line, used as the trigger.
I can't believe this, but you resolved the whole issue! WhenI compare the status of my SPI registers after loading the character in the SPITXBUF register: SPICCR = 0x0087 SPICTL = 0x000E SPISTS = 0x0040 SPIBRR = 0x007F SPIRXEMU = 0x0000 SPIRXBUF = 0x0000 SPITXBUF = 0xAA00 SPIDAT = 0x0000 SPIFFTX = 0xA000 SPIFFRX = 0x201F SPIFFCT = 0x0000 SPIPRI = 0x0010
the only differences I see are: 1. The SPI INT FLAG in SPISTS is set. 2. The SPIDAT register is empty, instead of holding the same character as SPITXBUF. 3. The FIFO registers are not what I was setting them to. I assume these are reset values.
It would appear my understanding of how the FIFO registersis insufficient to allow correct configuration. I will haveto study this.
Thanks for everything!