SPI Interfacing KL25Z with TI CC1101

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI Interfacing KL25Z with TI CC1101

1,806 Views
gustavsl
Contributor III

I'm working on a custom board using a MKL25Z128 and a TI CC1101 radio connected via SPI.

I'm having trouble getting the SPI communication between the KL25Z (master) and the CC1101 (slave) using KSDK 2.0.0.

I wrote the CC1101 driver based on other drivers I found (for the Arduino and mbed), but I can't integrate the SPI_ReadData and SPI_WriteData functions into it. The pins are already muxed as SPI.

I've implemented some software SPI routines for testing, and they work, but I want to use the hardware SPI.


As an example, the following is a snippet from the code that's supposed to read a register from the CC1101 and return it:

#define cc1101_Select() GPIO_ClearPinsOutput(SS_PIN_BASE, 1U << SS_PIN)
#define cc1101_Deselect() GPIO_SetPinsOutput(SS_PIN_BASE, 1U << SS_PIN)
#define wait_Miso() while(GPIO_ReadPinInput(MISO_PIN_BASE, MISO_PIN)) // Wait for MISO to go low

uint8_t cc1101_readReg(uint8_t regAddr, uint8_t regType)
{
   uint8_t addr, val;
   addr = regAddr | regType;
   cc1101_Select();
   wait_Miso();
   SPI_WriteData(SPI0,addr);
   val = SPI_ReadData(SPI0);
   cc1101_Deselect();
return val;
}

When I run it, the function usually returns 0 or the MISO pin never goes low.

 

The same code works using with these software SPI functions instead of KSDK's (with the pins configured as GPIO):

void SPIWrite(uint8_t data)
{
        /*send MSB first */

     static uint8_t i, c;
     c = data;
     for(i=0; i<8; i++)
     {
     if((c & 0x80) == 0x80)
          GPIO_SetPinsOutput(GPIOC, 1U << 6);
     else
          GPIO_ClearPinsOutput(GPIOC, 1U << 6);

     GPIO_SetPinsOutput(GPIOC, 1U << 5);
     c = c << 1;
     GPIO_ClearPinsOutput(GPIOC, 1U << 5);
     }
}
     
uint8_t SPIRead(void)
{
     /* software SPI read, MSB read first */
     static uint8_t i, data;

     for(i=0; i<8; i++)
     {
          data = data << 1;
          GPIO_SetPinsOutput(GPIOC, 1U << 5);
          if(GPIO_ReadPinInput(GPIOC, 7)){
               data = data+1;
          }
          GPIO_ClearPinsOutput(GPIOC, 1U << 5);
     }
     
     return data;
}

 

How should I do this using the KSDK SPI driver?

 

Thanks.

Labels (1)
Tags (2)
0 Kudos
3 Replies

1,344 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Gustavo,

Regarding your question, as you know that the KL25 has spi module, why do you use GPIO to simulate the SPI timing? BTW, even if you use GPIO to simulate the spi timing, i do not think the timing is correct. As you know that the spi is a Synchronous serial bus, in other words, it use the same clock to write and read data, in your

void SPIWrite(uint8_t data) and void uint8_t SPIRead(void), you toggle spi clock in both two function,
of course, it is incorrect. But if you can only one of them, it is correct.
In conclusion, I suggest you use the SPI module of Kl25Z instead of simulating spi timing.
I suppose that you have downloaded SDK based on Kl26, pls refer to the directory for spi example:
C:\DriverE\Freescale\SDK2.0KL43Z256\boards\frdmkl43z\driver_examples\spi\interrupt
because I do not download KL26, so I point out the example basec on KL43.
Hope it can help you
BR
XiangJun Rong
pastedImage_1.png
0 Kudos

1,344 Views
gustavsl
Contributor III

I'm trying manually setting the SPI registers. These are the initialization and the send/read functions:

void Init_SPI(void)
{
     SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;
     SIM->SCGC4 |= SIM_SCGC4_SPI0_MASK;
     SPI0->C1 = SPI_C1_MSTR_MASK | SPI_C1_SSOE_MASK;
     SPI0->C2 = 0x00;
     SPI0->BR = SPI_BR_SPPR(0x02)|SPI_BR_SPR(0x08); // baud rate = 15625
     SPI0->C1 |= SPI_C1_SPE_MASK;
}

void SPIWrite(uint8_t spiMsg)
{
     while(!(SPI_S_SPTEF_MASK & SPI0->S))
     {
          __asm("NOP");
     }
     SPI0->D = spiMsg;
}

uint8_t SPIRead(void) {
     uint8_t temp;
     
     while(!(SPI0->S & SPI_S_SPRF_MASK))
     {
          __asm("NOP");
     }
     temp = SPI0->D;
     return temp;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

For example, when calling the write function:

void cc1101_cmdStrobe(uint8_t cmd)
{     
     cc1101_Select();
     wait_Miso();
     SPIWrite(cmd);
     cc1101_Deselect();
}

//...
cc1101_cmdStrobe(CC1101_SRX); // CC1101_SRX = 0x34
//...

It is supposed to write 0x34 to the SPI0->D register, but when debugging, I see the SPI0->D register is set to 0x01 instead.

Also, when trying to read a register, the SPRF register on SPI0->S is never set to indicate data available in the receive buffer.

0 Kudos

1,344 Views
gustavsl
Contributor III

Hi.

Thanks for the answer.

As stated in my post, even after looking at the driver examples, I couldn't get the KSDK SPI functions to work. I initialized SPI master with the default configuration. Every time I try reading a register (with SPI_ReadData(SPI0)) , it returns 0.

0 Kudos