This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EVM430-FR6047: Can't write/read to SPI slave

Part Number: EVM430-FR6047
Other Parts Discussed in Thread: ENERGYTRACE, MSP-FET

Hi! 

I am using the EVM430-FR6047 and I have connected a slave RF95W RF LoRa module with SPI. I connected the MOSI, MISO, CLK and CSN to the appropriate pins on J5 and J6 (RF_SPI_MOSI, RF_SPI_MISO, RF_SPI_CLK, RF_SPI_CSN) on port 7 (EUSCI_A2) with 47 ohm resistors in series on the bus lines. Now when I check the CPU usage of the EUSCI_A2 module using MSP-FET JTAG EnergyTrace, it is always at 0% and the program often gets stuck at interrupts and SPI read data is wrong.

SPI setup code:

   __disable_interrupt();

    GPIO_setAsPeripheralModuleFunctionInputPin( // MOSI MISO
            GPIO_PORT_P7,
            GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2,
            GPIO_PRIMARY_MODULE_FUNCTION
        );

    GPIO_setAsOutputPin(GPIO_PORT_P7, GPIO_PIN3); // SPI channel select pin
    GPIO_setOutputHighOnPin(GPIO_PORT_P7, GPIO_PIN3); // disable channel

    printf("%zu\n", CS_getSMCLK());
    EUSCI_A_SPI_initMasterParam param = {0};
    param.selectClockSource = EUSCI_A_SPI_CLOCKSOURCE_SMCLK;
    param.clockSourceFrequency = CS_getSMCLK();
    param.desiredSpiClock = 8000000;
    param.msbFirst = EUSCI_A_SPI_MSB_FIRST;
    param.clockPhase = EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT;
    param.clockPolarity = EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH;
    param.spiMode = EUSCI_A_SPI_3PIN;
    EUSCI_A_SPI_initMaster(EUSCI_A2_BASE, &param);

    /* enable eUSCI SPI */
    EUSCI_A_SPI_enable(EUSCI_A2_BASE);

    //Enable Receive interrupt
    EUSCI_A_SPI_clearInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_RECEIVE_INTERRUPT);
    EUSCI_A_SPI_clearInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT);
    EUSCI_A_SPI_enableInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_RECEIVE_INTERRUPT);
    EUSCI_A_SPI_enableInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT);

And this is the SPI send and write functions: 

//******************************************************************************
void RFM95W_SPIByteWriteReg(uint8_t addr, uint8_t value)
{
  uint8_t inst;

  GPIO_setOutputLowOnPin(GPIO_PORT_P7, GPIO_PIN3);

  inst = RH_SPI_WRITE_MASK | addr;                                            // for write make sure the address with the write mask on

  //USCI_A2 TX buffer ready?
  while(!EUSCI_A_SPI_getInterruptStatus(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT));

  EUSCI_A_SPI_transmitData(EUSCI_A2_BASE, inst); // send address

  while(!EUSCI_A_SPI_getInterruptStatus(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT));        // Wait for TXBUF ready
  EUSCI_A_SPI_transmitData(EUSCI_A2_BASE, value); // send data

  while (EUSCI_A_SPI_isBusy(EUSCI_A2_BASE));                                                   // Wait for TX complete


  GPIO_setOutputHighOnPin(GPIO_PORT_P7, GPIO_PIN3);
}
//******************************************************************************

uint8_t RFM95W_SPIByteReadReg(uint8_t addr)
{
  uint8_t x, inst;

  GPIO_setOutputLowOnPin(GPIO_PORT_P7, GPIO_PIN3);
  EUSCI_A_SPI_clearInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_RECEIVE_INTERRUPT);
  EUSCI_A_SPI_clearInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT);

  inst = ~RH_SPI_WRITE_MASK & addr;                                            // for read make sure write bit is 0

  while(!EUSCI_A_SPI_getInterruptStatus(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT));       // Wait for TXBUF ready
  EUSCI_A_SPI_transmitData(EUSCI_A2_BASE, inst);          // send address                                                            // Send LSB of address

  while(!EUSCI_A_SPI_getInterruptStatus(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT));                 // Wait for TXBUF ready
  EUSCI_A_SPI_transmitData(EUSCI_A2_BASE, 0);                                                               // Dummy write so we can read data


  while(EUSCI_A_SPI_isBusy(EUSCI_A2_BASE));                                                     // Wait for TX complete

  while(!EUSCI_A_SPI_getInterruptStatus(EUSCI_A2_BASE, EUSCI_A_SPI_RECEIVE_INTERRUPT));
  x = EUSCI_A_SPI_receiveData(EUSCI_A2_BASE);                                                               // Read data



  GPIO_setOutputHighOnPin(GPIO_PORT_P7, GPIO_PIN3);

  printf(“RX: %x\n”, x); // test
  return x;
}

What could the problem be? 

Thanks in advance! 

Kind reagrds
Thibault

  • > EUSCI_A_SPI_clearInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT);
    ...
    > while(!EUSCI_A_SPI_getInterruptStatus(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT)); // Wait for TXBUF ready
    You've cleared the transmit interrupt (UCTXIFG) so you'll never get out of this loop.
    ---> Don't clear the TRANSMIT_INTERRUPT (the RECEIVE_INTERRUPT is fine).
    ----------------------
    >EUSCI_A_SPI_enableInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_RECEIVE_INTERRUPT);
    >EUSCI_A_SPI_enableInterrupt(EUSCI_A2_BASE, EUSCI_A_SPI_TRANSMIT_INTERRUPT);
    You're enabling these interrupts, but I don't see an ISR anywhere. More to the point, you later try to read them outside any ISR, which won't work if they're enabled.
    ---> Remove these two lines.

**Attention** This is a public forum