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.
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 voiduint8_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
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.
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.