I am using SPI to control a device. There is already a driver in C for this device. So, now, I am using this driver in RLP to “construct” my buffer to transmit.
The process to send data and read data is:
[ol]Call native function with a byte array (the transmit buffer) in parameter
Send this buffer with managed code and read the response
Call native function to check the response[/ol]
And sometime, for just one command, I have to send 2 bytes, check 1 byte in the received buffer, then send others data. For one command, I have 4 calls in native code.
Is this bad for performance ? I have to be as fast as possible.
Can I create my SPI Object in managed code and, when I need it in RLP, send some data over SPI directly from RLP ?
// initialize SSP
SSP0CPSR = 0x02; // SSP max speed
SSP0CR0 = 0x07; // SSP max speed, 8 bits
SSP0CR1 = 0x02; // SSP master mode
PINSEL1 = 0x2A8; // SSP mode for pins P0.17 to P0.20
while(1)
{
// send two bytes
SSP0DR = 0x55; // one nice thing about the SSP is that it has a 8-words deep FIFO
SSP0DR = 0x54; // so here we write the data to be sent without worrying
// now wait until both bytes are sent
while(!(SSP0SR & 0x01));
// now we can read the two bytes received... and do anything with them
int data1 = SSP0DR;
int data2 = SSP0DR;
// ...
}
I read all the datasheet but I’m still unable to send or receive on the SSP1. I checked on the FEZ Panda II schematics, SPI2 is connected to SSP1.
Is it possible that something in the managed code is preventing me from writing in registers ?
Here is my code:
void initSPI()
{
// Formula for the frequency: PCLK/(CPSDVR*[SCR+1])
// Disable SSP1 to write in registers
SSP1CR1 &= 0xF0;
// 0xXXYY, XX: SCR frequency divider, YY: SCLK falling edge / steady state 0 + Format SPI + transfer 8 bits
SSP1CR0 = 0xFF87;
// CPSDVR in the frequency formula from 2 to 254, just even values
SSP1CPSR = 254;
SSP1IMSC &= 0xF0;
SSP1RIS &= 0xF0;
SSP1MIS &= 0xF0;
SSP1ICR &= 0xFF;
// Enable SSP1
SSP1CR1 &= 0xF2;
}
void sendByte(uint8 *byte)
{
//spiDataToSend[arraySpiDataIndex++] = byte;
// If transmit buffer is full, wait
while(!(SSP1SR & 0x02));
SSP1DR = *byte;
// now wait until both bytes are sent
//while(!(SSP0SR & 0x01));
}
void readByte(uint8 *byte)
{
// If receive buffer is empty, wait
while(!(SSP1SR & 0x04));
*byte = SSP1DR;
}
At least when I used UART it was easiest to set up UART in C# and then use it on native side so you dont need to worry about configuration. Maybe you could do the same…
Maybe I’m wrong, but I am using SSP1 and not SPI0. Because my device is plugged on the SPI2 of the Fez Panda II.
But you were right, I forgot to set PINSEL0 and I try to set PCONP too.
So my new code is:
void initSPI()
{
// Formula for the frequency: PCLK/(CPSDVR*[SCR+1])
PINSEL0 |= 0x000AA000;
PCONP |= 0x00000400;
// Disable SSP1 to write in registers
SSP1CR1 &= 0xF0;
// 0xXXYY, XX: SCR frequency divider, YY: SCLK falling edge / steady state 0 + Format SPI + transfer 8 bits
SSP1CR0 = 0xFF87;
// CPSDVR in the frequency formula from 2 to 254, just even values
SSP1CPSR = 254;
SSP1IMSC &= 0xF0;
SSP1RIS &= 0xF0;
SSP1MIS &= 0xF0;
SSP1ICR &= 0xFF;
// Enable SSP1
SSP1CR1 &= 0xF2;
}
void sendByte(uint8 *byte)
{
// If transmit buffer is full, wait
while(!(SSP1SR & 0x02));
SSP1DR = *byte;
}
void readByte(uint8 *byte)
{
// If receive buffer is empty, wait
while(!(SSP1SR & 0x04));
*byte = SSP1DR;
}
And it still doesn’t work… When I leave while loops in sendByte and readByte, the program stucks on the native call. So I think SSP1SR is never set, which is weird because the reset value has to release each while loops. And when I comment while loops, the native call end but I just read 0 from the SPI.
I forgot to say that my device works with C# code. It cannot come from this.