Other Parts Discussed in Thread: CONTROLSUITE, C2000WARE
Hi,
I am experiencing what appears to be a '17' bit transmission on an SPI bus.
I have 8 uCs connected to together and they communicate using the SPI bus (SPI-b) in a daisy chain. uC1 talks to uC2, uC2 talks to uC3 ......uC8 talks back to uC1.
uC1 is the Master.
Data length is 16 Bits (SpibRegs.SPICCR.bit.SPICHAR = 0x1F;)
SPI clock speed is very slow and the scope traces show excellent set up and hold either side of the SPI clock.
The problem:
When i simply route through the Master dummy word, it ripples through perfectly fine and what is received at each uC (and back at the master) is correct.
However, when i then attempt to 'inject' data in the stream (i.e. i 'overwrite what comes in to the uC), the data that gets back to the Master (uC1) is corrupted.
It took a while, but i eventually realised that the data was being shifted 1 bit to the left - suggesting that the uC was clocking 17 bits!
e.g. i inject 8345 (1000-0011-0100-0101) and i get back 068B (0000-0110-1000-1011) - left shifted 1 bit. I have used a number of different data patterns and the result is the same.
I have read the SPI manual from cover to cover a dozen times, i have attempted different speeds (which i dont think it can be as the 'dummy' data runs perfectly fine at all speeds).
I have checked to ensure that there are no spurious edges (the clock 'resting state' is low)
I have checked the 'errata' data, but nothing relevant to the SPI.
Please can anyone help - i am stumped
i include a few code sections associated with SPI set up
SPI_SET_UP
{
EALLOW;
/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 3; // Asynch input GPIO12 (SPISIMOB)
GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3; // Asynch input GPIO13 (SPISOMIB)
GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 3; // Asynch input GPIO14 (SPICLKB)
GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 3; // Asynch input GPIO14 (!SPISTEB)
/* Configure SPI-B pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be SPI functional pins.
GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 3; // Configure GPIO12 as SPISIMOB
GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 3; // Configure GPIO13 as SPISOMIB
GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 3; // Configure GPIO14 as SPICLKB
GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 3; // Configure GPIO115 as SPISTEB
// Enable internal pull-up for the selected pins
// Pull-ups can be enabled or disabled disabled by the user.
// This will enable the pullups for the specified pins.
GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0; //Enable pull-up on GPIO12 (SPISIMOB)
GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0; //Enable pull-up on GPIO13 (SPISOMIB)
GpioCtrlRegs.GPAPUD.bit.GPIO14 = 0; //Enable pull-up on GPIO14 (SPICLKB)
GpioCtrlRegs.GPAPUD.bit.GPIO15 = 0; //Enable pull-up on GPIO15 (SPISTEB)
EDIS;
SpibRegs.SPICCR.all = 0x0F; //Force SPI reset, 16 bit, Clock polarity, loopback off
SpibRegs.SPIBRR = 0x19; //SPI CLOCK speed - slow
SpibRegs.SPICTL.all = 0x02; //CLK_PHASE = 0, Enables Data Transmission, Disable SPI interrupts (poll),// 0 = SLAVE;
SpibRegs.SPICCR.all = 0x8F; //Clear SPI reset
}
My code to tranmsit (Master)
void Read_SPI_Data (void)
{
Receive_Count = 0;
Dummy = 0x0F0F;
SpibRegs.SPITXBUF = Dummy; //Load the Tx buffer with first bytes - Dummy - initiates the clock
while (SpibRegs.SPISTS.bit.INT_FLAG !=1) //While no received character in the buffer - poll the flag
{
Dummy = SpibRegs.SPIRXBUF; //clear the flags (read the Rx buffer)
SpibRegs.SPITXBUF = Command_Message; //Load the TxBuffer with the next word = which is COMMAND Word
//Command_Message enables / disables O/Ps and sets overrides etc.
while (SpibRegs.SPISTS.bit.INT_FLAG !=1) //While no received character in the buffer - poll the flag
{ }
Dummy = SpibRegs.SPIRXBUF; //clear the flags (read the Rx buffer)
Dummy = 0x6789; //
while (Receive_Count < 35) //Receive_Count is the number of expected words =
{
SpibRegs.SPITXBUF = Dummy; //Load the TxBuffer with the next word
//Following line checks for Rx flag to be set - indicating that a word has been received by the SPI bus
while (SpibRegs.SPISTS.bit.INT_FLAG !=1) //While no received character in the buffer - poll the flag
{ }
test = SpibRegs.SPIRXBUF; //clear the flags (read the Rx buffer)
SPI_RxArray[Receive_Count] = test; //Put the received data in the RxArray
Receive_Count++; //increment to the next received word
}
Receive_Count = 0; //reset the counter when the Read is complete
test = 0;
}
Slave Read
void Transmit_SPI_Data (void)
{
Receive_Count = 0;
//Following comments apply to the 'first' uC.
//Subsequent uC will similarly receive, but with a gap!
//First received Word is a dummy, which was used to start the transmission
//Second received Word is the COMMAND Word - which is being received when this function is called
while (Receive_Count < 37) //Receive_Count is the number of expected words
{
local_buffer = SpibRegs.SPIRXBUF
local_buffer = 0x8345; //<This is where i inject the data IF I COMMENT OUT THIS LINE, THE INPUT IS SIMPLY TRANSMITTED OUT AND THERE IS NO CORRUPTION!
SpibRegs.SPITXBUF = local_buffer; //if the data is not for 'this' device - simply route it through
Receive_Count++;
while (SpibRegs.SPISTS.bit.INT_FLAG !=1) //While no received character in the buffer - poll the flag
{ } //This function simply resets the timer
}
//RESET everything!
Receive_Count = 0; //reset the counter
Transmit_Count = 0; //reset the transmit count
}