AnsweredAssumed Answered

KL25Z as SPI slave not able to send data correctly

Question asked by Franco Fusco on Apr 16, 2016
Latest reply on Apr 19, 2016 by Franco Fusco

Hi everybody!

 

I'm working on a project that involves the FreedomBoard (KL25Z) and an Arduino UNO microcontroller. The two boards should communicate through the SPI bus: Arduino acts as the master, the KL25Z as the slave. The problem is that although the FreedomB. is able to receive correctly the data from Arduino, it is not able to write into the transmit buffer. I report below what I've done so far.

 

The involved pins are:

CLK
MISO
MOSI
CS/SS
Arduino pin13121110
KL25Z pinPTC5PTC7PTC6PTD0

 

The Arduino code is very simple: through the official SPI library I set the clock frequency to 4 MHz, the SPI mode to 0 (CPOL=0, CPHA=0), MSBF (Most Significant Bit First). Then in the main loop, using the Serial Monitor, I can ask Arduino to send a byte to the other board and to print the byte received from the KL25Z.

 

From the Freedom side, the code that I wrote is the following (I use CodeWarrior, without processor expert):

 

void setupSPIslave() {
  SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; // clock to port C
  SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK; // clock to port D

  // setup of multiplexer for selecting CLK, MOSI, MISO and SS
   // PTC5 as CLK (pin 13 on Arduino UNO)
  PORTC_PCR5 = (PORTC_PCR5 & (~(PORT_PCR_MUX_MASK))) | PORT_PCR_MUX(2); 
   // PTC6 as MOSI (pin 11 on Arduino UNO)
  PORTC_PCR6 = (PORTC_PCR6 & (~(PORT_PCR_MUX_MASK))) | PORT_PCR_MUX(2);
  // PTC7 as MISO (pin 12 on Arduino UNO)
  PORTC_PCR7 = (PORTC_PCR7 & (~(PORT_PCR_MUX_MASK))) | PORT_PCR_MUX(2); 
   // PTD0 as CS (pin 10 on Arduino UNO)
  PORTD_PCR0 = (PORTD_PCR0 & (~(PORT_PCR_MUX_MASK))) | PORT_PCR_MUX(2); 

  SIM_SCGC4 |= SIM_SCGC4_SPI0_MASK; // clock to SPI0 module
  // SPI slave; SPRF interrupts; Most-Significant-Bit-First; SPI_MODE0 (CPOL=0, CPHA=0); SS=ChipSelect
  SPI0_C1 = SPI_C1_SPIE_MASK; 
  SPI0_C1 |= SPI_C1_SPE_MASK; // enable SPI module

  NVIC_ISER |= NVIC_ISER_SETENA(1<<10); // enables interrupts handling for the SPI0 module
}

 

unsigned volatile char val = 0;
// interrupt handler for SPI0 module interrupts
// an interrupt should be fired any time the module receives data
void SPI0_IRQHandler() {
  // wait until SPRF is set (should be executed once)
  while((SPI0_S & SPI_S_SPRF_MASK)==0);
  unsigned char data = SPI0_D; // read the data register
  
  if(data==0xFF) // 0xFF means switch on a LED
    LED1_ON;
  else if(data==0x00) // 0x00 means switch off the LED
    LED1_OFF;

  val++; // counter that tells me how many interrupts have been fired

  // wait until the data register is ready to be written
  while((SPI0_S & SPI_S_SPTEF_MASK)==0);
  RED_TOG; // toggle the red on-board LED (it tells me that the interrupt has been served)
  SPI0_D = SPI_D_Bits(0x02); // write a value into the data register
}

 

The setup simply configures the module as a slave and enables the interrupts (they'll be fired whenever new data arrives from Arduino).

The interrupt handler reads the received byte; if the value is 0 (255) it switches off (on) a LED.

Then there is the 'hot' section: the interrupt routine should write into the data register (SPI0_D) a value (0x02, it's just an example). Unfortunately, when I run the Arduino sketch, the received values, instead of being 0x02, is always 0x00 or 0xFF (that is, the bytes that I send from Arduino!). Thanks to the red LED I know that the interrupts are fired and served; the additional LED that I drive through the interrupt blinks properly (I therefore know that the SPI module is working well).

 

Any idea?

Outcomes