SPI0_D read causes hardfault

Showing results for 
Search instead for 
Did you mean: 

SPI0_D read causes hardfault

Contributor II


In my quest to port Contiki to the FRDM-KL25z dev board I am trying to set up SPI communications to a CC1120 radio module.

When I try to READ the SPI0_D register with code compiled under arm-none-eabi GCC on linux, I end up with a hardfault.  The same low-level code being run in CodeWarrior 10.3 (without Processor Expert) works as expected and communicates with the radio module.

The SPI0 module is configured with "the same" initialisation code and I can write to the SPI0_D register before the read without any issues.  If I stick an SPI0_D read before the write, the hard_fault follows the SPI0_D register read. The problem code snippet is below with the hardfault triggering on line 21.  The init code is below that.  printf is defined in Contiki and does work.

Has anyone seen this before and have any ideas what could be triggering this hardfault?

uint8_t SPI_single_tx_rx(uint8_t in, uint8_t module) {         uint8_t i = 1;     uint16_t tmp;     while(i){         tmp = SPI0_S;         tmp &= SPI_S_SPTEF_MASK;         if (tmp == SPI_S_SPTEF_MASK) {             SPI0_D = in;             i = 0;         }     }         i = 1;     while(i) {         tmp = SPI0_S;         tmp &= SPI_S_SPRF_MASK;         if (tmp == SPI_S_SPRF_MASK) {             printf("\n\rData");             tmp = SPI0_D;             printf("%d", tmp);             i = 0;         }     }         return (tmp); }

Init code:

void SPI0_init(void)


    port_enable(PORTD_EN_MASK | PORTC_EN_MASK);                 /* Make sure that clocks are enable to Port D and Port C */



      /* Configure CSn pin on Port D, Pin 0 */

      GPIOD_PDDR |= GPIO_PDDR_PDD(0x01);                         /* Set pin as Output. */                                                 

      GPIOD_PDOR |= GPIO_PDOR_PDO(0x01);                        /* Set initialisation value on 1 */                                          

      PORTD_PCR0 &= ~PORT_PCR_MUX_MASK;                            /* Clear PCR Multiplex. */

      PORTD_PCR0 |= PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x01);        /* Clear ISF & set MUX to be basic pin. */



      /* Configure SPI0. */

      SIM_SCGC4 |= SIM_SCGC4_SPI0_MASK;                          /* Enable clock to SPI Module */


      PORTD_PCR3 &= ~PORT_PCR_MUX_MASK;                         /* Clear Port D, Pin 3 Mux. */

      PORTD_PCR3 |= PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x02);     /* Clear ISF & Set Port D, Pin 3 as MISO. */                                          


      PORTD_PCR2 &= ~PORT_PCR_MUX_MASK;                            /* Clear Port D, Pin 2 Mux. */

      PORTD_PCR2 |= PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x02);     /* Clear ISF & Set Port D, Pin 2 as MOSI. */                                            


      PORTC_PCR5 &= ~PORT_PCR_MUX_MASK;                            /* Clear Port C, Pin 5 Mux. */

      PORTC_PCR5 |= PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x02);     /* Clear ISF & Set Port C, Pin 5 as Clock. */


      SPI0_C1 = (SPI_C1_MSTR_MASK | SPI_C1_SSOE_MASK);                             /* Set SPI0_C1: Master Mode */

      SPI0_C2 = SPI_C2_MODFEN_MASK;                                            /* Set SPI0_C2: Default state */


      SPI0_BR = SPI_BR_SPPR(0x20);                                 /* Set baud rate register */


      SPI0_C1 |= SPI_C1_SPE_MASK;                                  /* Enable SPI module */



3 Replies

Contributor II

I haven't actually done any work on this recently as I have been working on other parts of the project but I was thinking compiler issues as it works with Code Warrior 10.3 (arm-none-eabi-gcc 4.6.2)  but not with my build environment on Linux (arm-none-eabi-gcc 4.8.3) -  I was planning to try different compiler versions to narrow this down but it looks like you already have.

The other thing I was wondering (and haven't had a chance to check yet) is whether this manifests with the CMSIS headers instead of the ones that I have been using.

0 Kudos

NXP Employee
NXP Employee


Please check the Bob Paddock's thread "Why SPRF is never being set on SPI0 read for MKL25Z128VFT4?". it seems that he now found what is the reason of this issue.

Best Regards!

0 Kudos

Senior Contributor II

Did you ever find a solution?  I'm running into the same problem, please see my thread:

"Why SPRF is never being set on SPI0 read for MKL25Z128VFT4?".