Write some bytes on SPI in RLP

Hi everyone,

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 ?

Thanks :wink:

Depends on how fast you need things to run, what you do is okay.

But you should create an RLP that has similar interface to netmf spi class and also it will handle your special sensor.

Can I call managed function from RLP ?

Or can I just use something like this ? :

// 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 am not able to write or read something with:


SSP0DR = 0x55; // to write
int data1 = SSP0DR; // to read

Even with:


SSP1DR = 0x55; // to write
int data1 = SSP1DR; // to read

My device is plugged on the SPI2, do you know the corresponding register values for SPI ?

Thank you

I am using SPI2 on the Fez Panda II, after some research I found that it is the SSP1 of the LCP2387, am I wrong ?

I include LPC23xx.h to change registers. But is this possible with RLP ? After many tests, I cannot get this to work.

I am not sure, the datasheet + board schematics should get you all info you need.

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;
}

Silly question: Did you power up the SPI module? I don’t know if it is powered up by default…

ssp1cr1 doesn’t do that ? is the power controlled by registers ?

From the manual:

According to the manual it should be enabled after reset, but I don’t know if the MicroFramework disables it.

Also, you don’t set up the clock for the SPI0 which is on pin P0.15(PINSEL0), not P0.17-P0.20(PINSEL1) …

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.

SSP1CR1:
You write 0xF0 to disable and 0xF2 to enable. You are not allowed to write to the upper 4 bits, according to my manual anyway:

[quote]7:4 - Reserved, user software should not write ones to reserved
bits. The value read from a reserved bit is not defined[/quote]

Can’t see anything else wrong… :frowning:

I found what was wrong.

You’re right, I didn’t enable ssp1. Because with a logic AND the bit is always 0. So I replace the line:

SSP1CR1 &= 0xF2

with:

SSP1CR1 |= 0x02

and It works ! Thank you for your help :wink:

Not sure that I helped… :slight_smile:

BTW, I have found that the free version of Keil uVision has a nice emulator to test things on first. And the LPC has sample code for Keil.

Getting Keil to work as it should though is a pain… :slight_smile: