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-FR6043: eUSCI_A2 SPI slave mode not working

Part Number: EVM430-FR6043
Other Parts Discussed in Thread: MSP430FR6043, , TIDM-02003

Greetings,

We're trying to communicate our EVM430-FR6043 with an Arduino mega 2560 via SPI (using a 5V-3.3V level shifter). The MSP430FR6043 is intended to work as slave, while the Arduino acts as master. But we're having issues making it work. The eUSCI module simply doesn't seem to work: we're not getting any exceptions on the IDE, the rest of the code is working properly, we don't measure any signals on MISO, the eSUCI_A receive interrupts, although enabled, are not occurring even though we're transmitting data from the Arduino to the MSP.

From what we've seen on the TIDM-02003 schematic, it seems the only eUSCI_A module available is eUSCI_A2, which is multiplexed to pins 0,1,2 & 3 of Port J. These are connected to the BoosterPack pin headers (J7 & J8) as shown on the schematic:

We've also set J30 in order to use pin 1 of J7 as VCC for the level shifter. 

From what we've seen, all connections are correct. We've measured the voltage on the pins of the MSP430FR6043 and we've seen that the signals are correct. For example, in this image the blue signal is the clock outputted by the arduino that is connected to the corresponding pin on the MSP:

This seems to imply that this is an issue on our code. We based our code on the SPI slave example for the eUSCI_A module of the Driver library. Here is our code (some parts were commented for debugging):

#include <msp430.h>
#include <eusci_a_spi.h>
#include <gpio.h>
#include <Communications.h>
#include <stdbool.h>
#include <stdint.h>


CommunicationStatus com_status;

void Communications_setup(void){

    WDT_A_hold(WDT_A_BASE);

    /* 1. Configure pins for eUSCI_A2:
     * Change Peripheral Module Function of pins 0,1,2,3,4,5 of PORT J to use eUSCI_A2 instead
     *  - Set PIN 0 as Input (CLK)
     *  - Set PIN 1 as Input (STE) (Unused)
     *  - Set PIN 2 as Input (MOSI)
     *  - Set PIN 3 as Output (MISO)
     */
    GPIO_setAsOutputPin(GPIO_PORT_PJ, GPIO_PIN3);
    GPIO_setAsInputPin(GPIO_PORT_PJ, GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2);

    GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_PJ,
        GPIO_PIN4 + GPIO_PIN5,
        GPIO_PRIMARY_MODULE_FUNCTION
    );

    GPIO_setAsPeripheralModuleFunctionInputPin(
        GPIO_PORT_PJ,
        GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2,
        GPIO_SECONDARY_MODULE_FUNCTION
        );

    GPIO_setAsPeripheralModuleFunctionOutputPin(
        GPIO_PORT_PJ,
        GPIO_PIN3,
        GPIO_SECONDARY_MODULE_FUNCTION
        );

    //2. Configure GPIO for slave select:
    GPIO_setAsInputPinWithPullDownResistor(
        GPIO_PORT_P2,
        GPIO_PIN2
        );

    GPIO_enableInterrupt(
        GPIO_PORT_P2,
        GPIO_PIN2
        );

    /*
     * 3. Disable the GPIO power-on default high-impedance mode to activate
     * previously configured port settings
     */
    PMM_unlockLPM5();

    // 4. Initialize eUSCI module in SPI slave mode:
    EUSCI_A_SPI_initSlaveParam params = {0};

    // The following parameters are set by default:

    params.msbFirst = EUSCI_A_SPI_MSB_FIRST;
    params.clockPhase = EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT;
    params.clockPolarity = EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW;
    params.spiMode = EUSCI_A_SPI_3PIN;

    EUSCI_A_SPI_initSlave(EUSCI_A2_BASE, &params);

    // 5. Start eUSCI_A2 module:
    EUSCI_A_SPI_enable(EUSCI_A2_BASE);

    // 6. Enable Interrupt & clear flags (just in case)
    EUSCI_A_SPI_clearInterrupt(EUSCI_A2_BASE,EUSCI_A_SPI_TRANSMIT_INTERRUPT);

    EUSCI_A_SPI_enableInterrupt(
                           EUSCI_A2_BASE,
                           EUSCI_A_SPI_TRANSMIT_INTERRUPT + EUSCI_A_SPI_RECEIVE_INTERRUPT
                           );

    //__bis_SR_register(GIE);
}

void Communications_send(uint8_t transmit_data){
    EUSCI_A_SPI_transmitData(EUSCI_A2_BASE, transmit_data);
}


#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = PORT2_VECTOR
__interrupt void Port2_ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT2_VECTOR))) Port2_ISR (void)
#else
#error Compiler not supported!
#endif
{
   switch(GPIO_getInputPinValue(GPIO_PORT_P2, GPIO_PIN2)){
       case GPIO_INPUT_PIN_LOW:
           com_status = COMMUNICATION_STATUS_ACTIVE;
           break;
       /* case GPIO_INPUT_PIN_HIGH:

           com_status = COMMUNICATION_STATUS_INACTIVE;
           EUSCI_A_SPI_disableInterrupt(
                   EUSCI_A2_BASE,
                   EUSCI_A_SPI_RECEIVE_INTERRUPT
                   );
           break;*/
   }
   GPIO_clearInterrupt(GPIO_PORT_P2,GPIO_PIN2);
   //__bis_SR_register(LPM0_bits + GIE);
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A2_VECTOR
__interrupt void USCI_A2_ISR (void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(EUSCI_A2_VECTOR))) USCI_A2_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(__even_in_range(UCA2IV, USCI_SPI_UCTXIFG))
    {
        case USCI_SPI_UCRXIFG:      // UCRXIFG
            //USCI_A0 TX buffer ready?
            while (!EUSCI_A_SPI_getInterruptStatus(EUSCI_A2_BASE,
                       EUSCI_A_SPI_TRANSMIT_INTERRUPT
                        ));

            //Transmit data to master
            EUSCI_A_SPI_transmitData(EUSCI_A2_BASE,
            13
            );

            //Receive data from master
            uint8_t receiveData = EUSCI_A_SPI_receiveData(EUSCI_A2_BASE);
            break;
        default:
            break;
    }
}

bool Communications_isActive(){
    if (com_status == COMMUNICATION_STATUS_ACTIVE) {
        return true;
    }else{
        return false;
    }
}

uint8_t Communications_read(){
    return EUSCI_A_SPI_receiveData(EUSCI_A2_BASE);
}

int main(void)
{
    Communications_setup();
    
    while(1){
        Communications_send(13);
        __delay_cycles(500);
    }
}

Our guess is that, for some reason, the eUSCI_A2 module isn't receiving the clock signal from the Arduino, but we don't know how to confirm this as we can't see UCxCLK.

Checking the EVM schematic once again we found that pin 17 on the MSP430, which is multiplexed to PORTJ.0 and is connected to the BOOSTER_SPI_CLK pin on J7, is labeled as UAC2CLK instead of UCA2CLK:

At first we thought this was simply a typo, as we didn't find any other pin with a similar name and it seems from the datasheet that this pin is indeed connected to the CLK of the eUSCI_A2 module.

We'd like to know if it is possible to verifiy if clock is being read by the eUSCI module, or what could be the issue here that is causing this behavior.

Thanks a lot in advance.

EDIT: We're using the ezFET programming & debugging circuit incorporated on the board

  • Hi Ignacio,

    The blue is SPI_CLK from Master(Arduino)? Looks abnormal。 

    The clock rises very slowly, this maybe cause communication fail.

    I think you can disconnect MSP430 to check if the waveform still bad. It looks like there is too much capacitance on this line。

    Which speed for your SPI?

    From what we've seen, all connections are correct. We've measured the voltage on the pins of the MSP430FR6043 and we've seen that the signals are correct. For example, in this image the blue signal is the clock outputted by the arduino that is connected to the corresponding pin on the MSP:

    Thanks!

    Best Regards

    Johnson

  • The slow rise and fast fall times suggest an open drain driver with a resistor pullup. Perhaps that level shifter was designed for use with (slow) I2C.

  • Hello Johnson, thank you for your help

    The blue signal is indeed the SPI CLK sent by the arduino, but it is the 3.3V output of the level shifter. The signal generated by the Arduino before being fed to the level shifter is much cleaner:

    Although the slow  rise time is undesirable, at first I thought it wouldn't be an issue as i thought the MSP430FR6043 read voltages from 1.8V to 3.3V as HIGH, and according to my oscilloscope, the signal reaches around 1.9V on the beggining of the rise.
    I will try to reduce the master frequency to see if that makes any difference. In any case I'll update this post.

  • Hello David,
    I will try reduce the frequency to see if that makes any difference, thank you.

  • Hi David,

    Any update for reduce SPI speed?

    Thanks!

    Best Regards

    Johnson

  • UPDATE: I tried reducing the CLK frequency for the SPI protocol and I was able to see some output on the MISO pin of the eUSCI_A2, however, that didn't solve the issue completely.

    It turns out i wasn't setting the Port PJ pin functions correctly. As it can be seen on the attached code, i used the `GPIO_setAsPeripheralModuleFunctionOutputPin()` (or input, depending on the case) function from the driver library to set pins 0,1,2 & 3 of port PJ (which correspond to CLK, STE, MOSI & MISO respectively) to `GPIO_SECONDARY_MODULE_FUNCTION`, which I thought corresponded to the eUSCI_A2 module since on the datasheet the eUSCI_A2 is selected by setting PJSEL1.x to 0 and PJSEL0.x to 1:

    Intuitively, I thought that GPIO_SECONDARY_MODULE_FUNCTION corresponded to PJSEL1.X=0, PJSEL0.X=1, while GPIO_PRIMARY_MODULE_FUNCTION corresponded to PJSEL1.X=0, PJSEL0.X=0. However, upon inspecting the code, I found out that GPIO_SECONDARY_MODULE_FUNCTION actually corresponds to  PJSEL1.X=0, PJSEL0.X=1. In order to use Port PJ as GPIO, one must call the GPIO_setAsOutputPin() function. Upon changing the module function I was able to send and receive from the MSP to the Arduino.

    So, for anyone else who is having a similar issue, make sure you're setting your ports correctly, GPIO_setAsOutputPin() sets PJSEL1.X=0, PJSEL0.X=0, calling GPIO_setAsPeripheralModuleFunctionOutputPin() with GPIO_PRIMARY_MODULE_FUNCTION sets PJSEL1.X=0, PJSEL0.X=1 and so on.

    Thanks to @David Schultz and @Johnson He, I couldn't have figured this out without your help.

    Best Regards.

  • Table 12-2 in the family guide lists the correspondence between SEL bits and module function. No intuition required.

**Attention** This is a public forum