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.

MSP432-DEBUGGERS: MSP432P401R SPI problem

Part Number: MSP432-DEBUGGERS
Other Parts Discussed in Thread: ADS1292R, ADS1292

Tool/software:

Hello Fellows,

I have a. big problem with a red board MSP432P401R, I am trying configure it to interface it with analog front end , this deveice work with SPI comunication.
The requirements of the slave device is... the microcontroller should act like a master, the clock CPOL = 0 and CPHA = 1. My clock system is configured to 24MHz (MCLK) and SPI clock source 12MHz (SMCLK).

so the SPI clock is 500KHz(SPI Clock=Source Clock/BRW =>BRW= Source Clock/SPI clocK). But unfortunately something wrong is happening.
The mosi line sends correctlly the data, but the miso line only brings me 0xFF, so this gives me a idea that's its a bad implementention on the code, i hope someone can help me to solve this. I share the SPI integration code and screenshoot of the comunication.

void initialize_spi(void) {
    /*INITIALIZE PORT REGISTERS*/
    // 4. Configure SPI pins: P1.5 (SCLK), P1.6 (MOSI), P1.7 (MISO)
    P1->SEL0 |= (BIT5 | BIT6 | BIT7);   // Select primary module function for P1.5, P1.6, and P1.7
    P1->SEL1 &= ~(BIT5 | BIT6 | BIT7);  // Clear P1SEL1 for those bits to use SPI functionality

    /* set CLK and MOSI as outputs */
    P1->DIR |= (BIT5 | BIT6);
    P1->OUT |= (BIT5 | BIT6);

    /* set MISO as input */
    P1->DIR &= ~(BIT7);


    EUSCI_B0->CTLW1 |= EUSCI_B_CTLW0_SWRST;

    // 2. Configure eUSCI_B0 in SPI master mode, 3-pin SPI (no STE pin), synchronous mode
    EUSCI_B0->CTLW0 = EUSCI_B_CTLW0_SWRST      // Keep eUSCI in reset
                    | EUSCI_B_CTLW0_MST      // Master mode
                    | EUSCI_B_CTLW0_MSB        // MSB first
                    | EUSCI_B_CTLW0_SYNC       // Synchronous mode
                    | EUSCI_B_CTLW0_SSEL__SMCLK   // Use SMCLK (12 MHz)
                    | EUSCI_B_CTLW0_CKPL
                    | EUSCI_B_CTLW0_CKPH;      // Clock Phase: Data changed on the first clock edge, captured on the next (CPHA = 0)




    // 3. Set SPI clock divider for 500 KHz baud rate (12 MHz SMCLK / 24 = 1/2 MHz)
    EUSCI_B0->BRW = 24;  // Clock prescaler
    // 5. Take eUSCI_B0 out of reset mode
    EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;
    EUSCI_B0->CTLW1 &= ~EUSCI_B_CTLW0_SWRST;

}


Thanks in advance.

  • Hi,

    The mosi line sends correctlly the data, but the miso line only brings me 0xFF, so this gives me a idea that's its a bad implementention on the code,

    You said the MOSI line is correct. This means the master is sending the right waveform on MOSI. However, looking at your waveform, your CS is inactive. Does your slave need the CS input as a qualifier? If your slave requires CS input then you need to look at your CS generation. If your slave does not need the CS and you believe the MOSI waveform is correct then you need to look into the slave as to why it does not respond to the master command by returning only 0xFF. Please note that MSP432P has been EOL'ed and discontinued for many years. There is no more e2e support for this device.  

    There is a master spi example in the SDK:

    C:\ti\simplelink_msp432p4_sdk_3_40_01_02\examples\nortos\MSP_EXP432P401R\driverlib\spi_3wire_incrementing_data-master

      

  • Hi Charles,

    Thank you for your support. Yes, I know this card has been stopped and doesn't have any more support for this device, but all my work was done on this platform, I just think about finishing this task. In future work, I will apply for a newer and more supportive device, if you have some advice to be welcomed.
    Focusing, on this problem, my application needs an active CS pin, I think the source of my problem is in integration into the SPI code the task that puts the polarity of the clock CPOL = 0 and CPHA = 1" I think after being integrate this records the CS pin and SCLK will adjust and work properly.

  • To get CPOL=0, use CKPL=0. To get CPHA=1, use CKPH=0.

    SWRST is in CTLW0, not CTLW1

  • Hello Bruce, 

    Thanks for your support. Just a question, the slave require this configuration, but if the configuration. clock was clock "CPOL = 0 and CPHA = 0", this is a bit weird.Anyway I changed my configuration to the following:

    void initialize_spi(void) {
         P1->SEL0 |= BIT5 | BIT6 | BIT7;  // set 4-SPI pin as second function
        P1->DIR  |= BIT5 | BIT6 ;
        P1->DIR  &= ~(BIT7);
    
        EUSCI_B0->CTLW0 |=  EUSCI_B_CTLW0_SWRST;
    
        EUSCI_B0->CTLW0 =   EUSCI_B_CTLW0_SWRST
                            | EUSCI_B_CTLW0_CKPH
                            &~(EUSCI_B_CTLW0_CKPL)
                            | EUSCI_B_CTLW0_MSB
                            &~(EUSCI_B_CTLW0_SEVENBIT)
                            | EUSCI_B_CTLW0_MST
                            | EUSCI_B_CTLW0_MODE_0
                            | EUSCI_B_CTLW0_SYNC
                            | EUSCI_B_CTLW0_SSEL__SMCLK;
    
        EUSCI_B0->BRW = 12;                               // /2,fBitClock = fBRCLK/(UCBRx+1).
        /*INITIALIZE PORT REGISTERS*/
        EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_SWRST);   
    }

    And the logic analyser show me a error on the comunication the initial (idle) state of the CLK line does not match the settings.

  • SCK does appear to be idling high after the end of the activity, though now we're in a different part of the code. Do you do anything special at the end of a transaction?

    Also, do you know what those "Error"s are in the middle of the transaction? The trace resolution doesn't really allow seeing individual bits.

  • Hello Bruce, 

    No, I don't have anything special in the end of transaction.Focus the transaction in individual bits we have the follow

  • You've configured the eUSCI for CPOL=0, CPHA=0 (CKPL=0, CKPH=1). Is that how your analyzer is set?

    Also, /CS is changing very fast -- mid-byte. /CS should at minimum frame an entire byte. (Are you still using the ADS1292R? It expects /CS to stay low for the entire transaction, perhaps multiple bytes.)

    These don't necessarily pertain to SCK (apparently) idling high, but maybe conditions will be different if you sort the other things out.

  • Bruce,
    Now, I have changed the code to the eUSCI for CPOL=0, CPHA=0, for both applications ( code register and settings on digital analyser). That is how is set now. Yes I am trying a new aproach to this chip(ADS1292R). Each time the data was transfered the pin CS goes low and keep it until make the transaction. I dont know why this behavior.In order to satisfy the another conditions I am trying to solve onde problem at each time.

    Thanks

  • Does the analyzer know about the /CS signal? Maybe that's what it's complaining about.

    Also, are you using the debugger? I've forgotten which clocks are stopped (on the P-series) during a breakpoint.

  • Hi Bruce,

    Good news, I've been able to send the data and check it on the analizer digital. Now the reading track brings as a response to all the data sent "0xFF".After the last reading read with 0x10 data, all of the following data comes with the error information, this is normal, shouldn't the channels go back to the initial state? ! I share my readings and change under the code below.

    i share the modified code so it can be analyzed if there is any observations please say .

    void initialize_spi(void) {
        /*INITIALIZE PORT REGISTERS*/
        P1->SEL0 |= BIT5 | BIT6 | BIT7;
        P1->DIR  |= BIT5 | BIT6 ;
        P1->DIR  &= ~(BIT7);
    
        EUSCI_B0->CTLW0 |=  EUSCI_B_CTLW0_SWRST;
    
        EUSCI_B0->CTLW0  =  EUSCI_B_CTLW0_SWRST
                            | EUSCI_B_CTLW0_MSB
                            | EUSCI_B_CTLW0_SYNC
                            | EUSCI_B_CTLW0_MST
                            | EUSCI_B_CTLW0_MODE_0
                            | EUSCI_B_CTLW0_SSEL__SMCLK;
    
        EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_SEVENBIT);
        EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_CKPL);
        EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_CKPH);
    
        EUSCI_B0->BRW = 24;
    
        EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_SWRST);
    
        NVIC->ISER[0] = 1 << ((EUSCIB0_IRQn) & 31);     /*ENABLE EUSCI_B0 INTERRUPT IN NVIC MODULE*/
    }

    Thanks in advance

  • It looks like your /CS (still) isn't coordinated with your transaction. How are you managing this pin?

    I see you're enabling the USCIB0 interrupt, but you haven't enabled any interrupt sources. This is (in itself) harmless, but it suggests there's some significant code elsewhere. [For short transactions on a sufficiently fast SPI, I don't recommend using interrupts.]

  • Hello Bruce, 

    when the transmission of the data is made pin goes down. this pin is managed at the time the data is sent through the transmission of the SPI.

    The interruption now is not applied, until now I have the intention to implement it, now I will take your suggestion into consideration and try to do all these transitions without the use of interruption.

    static void ADS1292R_spi_cmd(uint8_t data){
        ADS1292R_disable_CS();
        _delay(4, 'm');
        ADS1292R_enable_CS();
        _delay(4, 'm');
        ADS1292R_disable_CS();
        _delay(4, 'm');
        EUSCI_B0->TXBUF = data;
        while (EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY);
    
    
    
    }
    
    
    void ADS1292R_register_write(uint8_t WRITE_ADDRESS, uint8_t DATA) {
        // Apply bit masks based on register address
        switch (WRITE_ADDRESS) {
            case 1:
                DATA &= 0x87;
                break;
            case 2:
                DATA &= 0xFB;
                DATA |= 0x80;
                break;
            case 3:
                DATA &= 0xFD;
                DATA |= 0x10;
                break;
            case 7:
                DATA &= 0x3F;
                break;
            case 8:
                DATA &= 0x5F;
                break;
            case 9:
                DATA |= 0x02;
                break;
            case 10:
                DATA &= 0x87;
                DATA |= 0x01;
                break;
            case 11:
                DATA &= 0x0F;
                break;
            default:
                break;
        }
    
        SPI_TX_BUFF[0] = WRITE_ADDRESS | WREG;
        SPI_TX_BUFF[1] = 0;
        SPI_TX_BUFF[2] = DATA;
    
        ADS1292R_disable_CS();
        _delay(2, 'm');
    
    
        EUSCI_B0->TXBUF = SPI_TX_BUFF[0];
        while (EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY);
    
        EUSCI_B0->TXBUF = SPI_TX_BUFF[1];
        while (EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY);
    
        EUSCI_B0->TXBUF = SPI_TX_BUFF[2];
        while (EUSCI_B0->STATW & EUSCI_B_STATW_BBUSY);
    }
    

  • 1) Does enable_CS mean set the (/CS) pin low or high? I would guess the first, but if so the usage seems backwards.

    2) I think the UCBBUSY bit is for I2C. It may work by accident, but try the UCBUSY (EUSCI_B_STATW_BUSY) bit instead.

  • Hello Bruce, 

    ADS1292R_enable_CS in my code mean the (/CS) pin are high.

    void ADS1292R_enable_CS(void) {
        P5->OUT |= BIT2;  // Set CS pin HIGH
    }
    

    The UCBBUSY can be used in both I2C and SPI modes within the eUSCI_B module of the MSP432P401R. So, the syntax to check UCBBUSY applies to both I2C and SPI communication, not exclusively to either one.

  • UCBBUSY is only documented for I2C mode [it appears in TRM (SLAU356I) Table 26-7 but not in Table 25-14]. If you have other information that says it will do what you expect (in SPI mode) then I defer.

    I see that you assert /CS (low) before your transaction(s), but I don't see where you de-assert it (high). How does that happen?

  • Hi bruce,
    You are wright, it was a huge mistake, when I write the code, always try to guide me with Technical Reference Manual and the register reference in "msp432p401r.h" file previously i select EUSCI_B_STATW_BBUSY, but thanks to your alert I read and corret the register to EUSCI_B_STATW_SPI_BUSY this one seems to be the wright one, sorry for the incovinience, but we learn with errors, thanks for the correction.
    On the function "set_spi", I call two other functions, one of them introduce the default register defenitions to interact with slave device. The other call the function responsable for the initialization pins "START, RESET, CLK and the CS. This last one, is tied to high, so at start up the CS pin goes high, when make the data transition he goes low, and stay down until de transmition end.

    #include <msp432.h>
    #include "spi.h"
    #include "ads1292r.h"
    
    void set_spi(void) {
        initialize_ports();
        initialize_spi();
    }
    
    void initialize_spi(void) {
    
    
    
        /*DISABLE EUSCI_B0 MODULE*/
        EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SWRST;         /*PUT EUSCI IN RESET*/
    
        EUSCI_B0->CTLW0 =   EUSCI_B_CTLW0_SWRST         /*KEEP MODULE IN RESET MODE*/
                          | EUSCI_B_CTLW0_MST           /*MASTER MODE*/
                          | EUSCI_B_CTLW0_SYNC          /*SYNCHRONOUS MODE*/
                          | EUSCI_B_CTLW0_MSB           /*MSB FIRST*/
                          //| EUSCI_B_CTLW0_CKPH          /*CPHA = 1*/
                          | EUSCI_B_CTLW0_UCSSEL_2      /*SMCLK AS CLOCK SOURCE*/
                          | EUSCI_B_CTLW0_MODE_0;       /*3-PIN SPI MODE*/
    
    
        EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_CKPH);
        EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_CKPL);
    
        /*SET CLOCK DIVIDER (ASSUME SMCLK = 12MHz, SPI CLOCK 0 500KHz)*/
    
        EUSCI_B0->BRW = 24;                             /*CLOCK PRESCALER (12MHz/24 = 500 KHZ)*/
    
    
        /*INITIALIZE PORT REGISTERS, CONFIGURE FOR SPI FUNCTIONALITY*/
        /*P1.5 = SCLK, P1.6 = SOMI, P1.7 = SIMO*/
    
        P1->SEL0 |= BIT5 | BIT6 | BIT7;
        P1->SEL1 &= ~(BIT5 | BIT6 | BIT7);              /*SELECT THE PRIMARY MOCULE FUNCTION*/
    
    
    
        EUSCI_B0->CTLW0 &= ~(EUSCI_B_CTLW0_SWRST);      /*RELEASE EUSCI FROM RESET*/
    
              //  NVIC->ISER[0] = 1 << ((EUSCIB0_IRQn) & 31);     /*ENABLE EUSCI_B0 INTERRUPT IN NVIC MODULE*/
            }
    
    void initialize_ports(void) {
        /* GPIO PINS ADS COMMAND PIN'S I/O */
        P2->DIR |= BIT4 | BIT5 | BIT6;                  /* P2.4-CLK_SEL; P2.5-START; P2.6-RESET */
        P2->OUT &= ~(BIT5 | BIT6);                      /* START AND RESET PINS */
        P2->OUT |=  BIT6 | BIT4;                        /* ENABLE RESET AND CLK_SEL*/
    
        P5->DIR |= BIT2;                                /* SET P5.2 CS */
        P5->OUT &= ~(BIT2);                             /* SET CS PIN TO LOW */
        P5->OUT |= BIT2;                                /* SET CS PIN TO HIGH */
    }
    

  • What does your symptom look like now?

  • hello bruce,

    i have been sick this week, now i am better and came back to project.
    So I have, change the SPI to a MODE_0 to read only 3wire, in the logic analyzer only MOSI, MISO, AND SCLK is contemplated ...
    Now the response came in this wave form:

    cmd 0x08registers

  • This looks OK as far as it goes. Can you read back what you wrote to CONFIG1?

    You may want to try reading the ID register (0x00), since it should have a well-known value (0x73 based on Table 17).

  • Yes , 

    in the CONFIG1  I sent the following register :

    When I try to read the ID register with (0x00), 

    the result is any value excluding the well-known value 0x73:

  • This response looks vaguely similar to what you saw during the write-register operation.

    I wonder if you're in Continuous mode [Ref datasheet Sec 8.5.2.7] and it isn't listening to you. Try sending a 0x11 (SDATAC) command first.

  • Hello, 

    I have reviewed all my entire code and nothing I can get the de device work properly!!

  • Based on what you've posted, your SPI seems to be operating properly.

    Have you taken the device out of Continuous mode?

  • Hello Bruce, 

    The test is made after stop command  was send  STOP  DATA CMD 0x11, and the MISO line not bring the correct ID.

    Correct if Iam wrong, the MSCLK, is the clock i have use to perform waiting states, becouse this is based in the system clock!!! it is this correct?

    If it is, my clock system runs at 24MHz and each cycle is based in tcycle = (1/24MHz) = 41.67ns, each instruction takes aproximadely 4 cycles so each instruction spends 166.68ns, maybe the waiting state to rise pulse after tPOR is not to enough for bringing up the digital core in the correct state.

    In my application (ADS1292R protocentral board), the CLK pin is not tied, so after the reset the DRDY, should run at constant frequency exact toggling frequency, this should be the DRDY pin frequency, but the pulse seams to be assyncronous.
    Yes, the SPI seems to be well implemented, now this others doubt arrive

  • What does reading the ID register give back? Is it about the same as before, or different?

    If you're referring to the Tclk for the /CS (deassert) delay, this would be the ADS1292R clock. Since you haven't changed this it would be ~2us (Fclk=512kHz per DS p. 27 ["CLOCK"]). This is (coincidentally) about the same as your SCLK speed (SMCLK/24) if that helps. I'm supposing you've jumpered CLKSEL high using JP2 [ref DS Table 9].

    While I'm thinking about it: How is solder-jumper SJ1 set? I'm hoping it's set for VCC=3.3V, but the schematic doesn't indicate.

  • When reading the ID record it returns the value that you can see below in the image. The values ​​always change, every time I restart the device I never get the same value on restart
    I've tried everything,
    Using the digital analyzer I tested the other control connections (START; RESET; CLK AND DRDY), I share transmittion where I sent the register to obtain the ID device . If you want, I can share with you privately all the code of the real state of the project, maybe you can see anything that escape me.

  • How are JP2 and SJ1 set?

    I found a FAQ for debugging SPI to the ADS1292R. Item (2) mentions the /RESET pulse, and uses the word "essential". Are you doing this?

    https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/775262/faq-ads129x-i-m-having-trouble-communicating-with-my-ads129x-device-via-spi-what-debug-steps-i-should-try/2868427#2868427

  • Hi Bruce,
    I'm using a protocentral board, so I don't quite understand your question... But if you're referring to the connections, I'll make the following summary:

    MCU ADS1292
    3V3 VDD
    P2.6 PWD/RESET
    P2.5 START
    P2.4 DRDY
    P5.0 CS
    P1.6 MOSI
    P1.7 MISO
    P1.5 SCK
    N/C GPIO1
    N/C GPIO2
    N/C CLK
    GND GND

    In the table the meaning of N/C is pins not connected. Answering your question, if I understand correctly, in SJ1 (LOGIC LEVEL CONVERTER), the input power is 3.3V, I measure the status of JP2 and check if it is filled with 3.3V power as well. 

    Following the sugested FAQ, i review a lot of time this to debug my problem and obtain power-up and communication timing.

    In each communication tested I see that the MISO line is operating at a higher frequency than the SCLK line. I have tried everything, now I turn my attention to SPI communication again, I read the ADS1292R datasheet which suggests using SPI Mode 1: CPOL = 0, CPHA = 1 (clock is low when idle, data changes on rising edge and are caught on the falling edge). Sometimes I get an ID value close to what I need (0x71).