AnsweredAssumed Answered

SPI0_D read causes hardfault

Question asked by Graeme Bragg on May 23, 2014
Latest reply on Jun 9, 2014 by Graeme Bragg

Hello,

 

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 */
     
}

Outcomes