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.

MSP432P401R : Problem with SPI

Other Parts Discussed in Thread: MSP432P401R

Hi,

I am using the MSP432P401R for programming a DDS (AD9833). When I program it with the UCB0CLK and UCB0SDA, there is no problem, I can do it.

But these pins are used for something else and I tried to program the DDS with the UCB1CLK and UCB1SDA instead, and nothing works. However, the code is exactly the same : i just changed the pins and all the "ucb0" to "ucb1".

Moreover, when I look at the signals with a scope, they seem to be exactly the same. I can't understand where the problem comes from.

Here is the code :

SPI INITIALIZATION :

       P6->OUT &= ~BIT3;
       P6->DIR |= BIT3;                        // Set P1.0 LED
       P6OUT = BIT3;
       P6->OUT &= ~BIT4;
       P6->DIR |= BIT4;                        // Set P1.0 LED
       P6OUT = BIT4;

     /*  P2->OUT &= ~BIT1;
       P2->DIR |= BIT1;                        // Set P1.0 LED
       P2OUT = BIT1;
       P2->OUT &= ~BIT0;
       P2->DIR |= BIT0;                        // Set P1.0 LED
       P2OUT = BIT0;*/

       P6->SEL0 |= BIT3 | BIT4;         // Set P1.5, P1.6, and P1.7 as
                                               // SPI pins functionality

       UCB1CTLW0 |= UCSWRST; // Put eUSCI state machine in reset
       UCB1CTLW0 = UCSWRST | // Remain eUSCI state machine in reset
               UCMST |             // Set as SPI master
               UCSYNC |            // Set as synchronous mode
               UCCKPL |            // Set clock polarity high
               UCMSB;              // MSB first

       UCB1CTLW0 |= UCSSEL__SMCLK; // ACLK
       UCB1BRW = 0x01;                   // /2,fBitClock = fBRCLK/(UCBRx+1).
       UCB1CTLW0 &= ~UCSWRST;// Initialize USCI state machine

And here is the code for the programming of the DDS :

int main(void)
 {
      WDTCTL = WDTPW | WDTHOLD;               // Stop watchdog timer

        // Terminate all remaining pins on the device
        P2DIR |= 0xFF; P2OUT = 0;
        P3DIR |= 0xFF; P3OUT = 0;
        P4DIR |= 0xFF; P4OUT = 0;
        P5DIR |= 0xFF; P5OUT = 0;
        P6DIR |= 0xFF; P6OUT = 0;
        P7DIR |= 0xFF; P7OUT = 0;
        P8DIR |= 0xFF; P8OUT = 0;
        P9DIR |= 0xFF; P9OUT = 0;
        P10DIR |= 0xFF; P10OUT = 0;
        /*** Fonctions d'initialisation ***/
        initialisation_SPI();
        /*** Fin des fonctions d'initalisation ***/


        /*** Autorisation des interruptions ***/
        __enable_interrupt();
        NVIC->ISER[0] = 1 << ((EUSCIB1_IRQn) & 31);
        /*** Fin de l'autorisation des interruptions ***/

       while(1)
        {
        EUSCI_B1->IFG |= EUSCI_B_IFG_TXIFG;// Clear TXIFG flag
        EUSCI_B1->IE |= EUSCI_B_IE_TXIE;    // Enable TX interrupt
        }
}


    int _system_pre_init( void )
    {
      WDTCTL = WDTPW | WDTHOLD;

      return 1;
    }

    // SPI interrupt service routine
    void eUSCIB1IsrHandler(void)
    {
         if (UCB1IFG & UCTXIFG)
        {
            while(!(UCB1IFG & UCTXIFG));
            P9OUT &= ~BIT3;
            EUSCI_B1->TXBUF = 0x20;           // Transmit characters

            while(!(UCB1IFG & UCTXIFG));
            EUSCI_B1->TXBUF = 0x00;           // Transmit characters

            while(!(UCB1IFG & UCTXIFG));
            EUSCI_B1->TXBUF = 0x5D;           // Transmit characters

            while(!(UCB1IFG & UCTXIFG));
            EUSCI_B1->TXBUF = 0x2B;           // Transmit characters

            while(!(UCB1IFG & UCTXIFG));
            EUSCI_B1->TXBUF = 0x40;           // Transmit characters

            while(!(UCB1IFG & UCTXIFG));
            EUSCI_B1->TXBUF = 0x6F;           // Transmit characters

            P9OUT |= BIT3;

            UCB1IFG &=~ UCTXIFG;
            G_uint8Fin_comm_adcFlag = 1 ;
        }

    }

Do you have any idea?

Thank you in advance,

  • void eUSCIB1IsrHandler(void)

    This is an unusual name for the ISR; I would expect to see "EUSCIB1_IRQHandler". Did you change this in startup_msp432p401r_ccs.c?

  • Hi,

    Thank you for your answer.

    I tried to change with EUSCIB1_IRQHandler, and declare it in the startup_msp432p401r_ccs.c.

    Doesn't change anything, still not working...

    NVIC->ISER[0] = 1 << ((EUSCIB1_IRQn) & 31)

    Is this correct?

    Thank you

  • In general, is there a difference between UCB0 and UCB1?

  • As far as I know UCB0 and UCB1 are functionally identical.

    As long as your ISR name matches that in the Interrupt Vector Table, it can be any name. The hazard there is that if they don't match the build won't tell you about it (your program will just crash).

    The ISER assignment looks fine. [I personally would use "NVIC_EnableIRQ(EUSCIB1_IRQn)" so I don't have to check the value, but I checked it before responding.]

    What is the purpose of wiggling SCK and MOSI at startup? Since (at that moment) FSYNC (P9.3) is asserted, I suspect the first transaction would be off-by-1-bit.

    More generally: What is your symptom exactly? You mentioned that the waveforms look correct.

  • What is the purpose of wiggling SCK and MOSI at startup?

    What do you mean by that? What line exactly?

    More generally: What is your symptom exactly? You mentioned that the waveforms look correct.

    The symptom is that the DDS can not be programmed with UCB1, but it can with UCB0

  • The first block (6 lines) in SPI initialization, starting with

           P6->OUT &= ~BIT3;

    as near as I can tell sets SCK low, then high, then low again. Setting the PSEL will bring SCK high again (so I guess that's 2 SCK cycles, not just 1). At that moment FSYNC (P9.3) is low from the initial sequence in main(), so the DDS is listening. P9.3 stays low until the end of the first transaction (in the ISR). 

  • Thank you for your answer. It is still not working...

  • What did you change? The simplest fix might be to just set P9.3 high (deassert FSYNC) early on, in which case you can wiggle SCK all you want.

  • I put P9.3 High before wiggling the others pins

  • I have the same problem with the UCB2 SPI module. I think that there is something that I forgot in the code.

    What I do for switching between different modules is changing all the "zeros" of the differents EUSCI_B0 etc. to "two". And I change the pins.

    I tried your syntax :

            __enable_interrupt();
            NVIC_EnableIRQ(EUSCIB2_IRQn);

    Still not changing.

    thank you

  • I checked again : in fact I manage to make the UCB2 SPI works. But still not the UCB1... The signals are the same. I can't find any functional difference between UCB1 and UCB0&2

  • Could the UCB1 module of the msp432P401R rev D have a problem in sourcing current? I can not see any other solution. From one module to another, FSYNC, CLK and DATA are exactly the same at the scope!!

  • So sorry for the number of messages. But I think we are facing the biggest mystery in the universe..! I took screenshots of the scope to show you the problem.

    The two following pictures are the clock and data signals on the DDS for the UCB0 (the functionning module) in first, and second the non functioning module (the UCB1) :

    Same order for the FSYNC and data :

    CLK and FSYNC :

    And to finish zoom on data :

    Can you see any difference?

    Thank you

  • How do you tell that the DDS initialization doesn't work? The first byte (0x20 rather than 0x21) seems to have RESET=0. Without going through a Reset sequence, your test procedure may observe some history.

    AD9833 data sheet (rev G) p. 20 recommends using CPHA=0, which usually means setting UCCKPH=1.

  • Thank you for your answer,

    I know the DDS doesn't work because in what I call the "functioning state", the DDS outputs the 100 kHz that I want.

    I'm not sure to understand the following ; I thought it was 0x20 not 0X21 for the first byte?

  •   Bruce,

    I added like you said the UCCKPH. It works!

      UCB1CTLW0 = UCSWRST | // Remain eUSCI state machine in reset
                   UCMST |             // Set as SPI master
                   UCSYNC |            // Set as synchronous mode
                   UCCKPL |            // Set clock polarity high
                   UCMSB |
                   UCCKPH;            

    But I'm not sure to understand why it was working with the two others modules... An explanation?

    Big, big, big thanks !

  • Many works-by-accident cases are difficult to explain, but I have seen cases like this in the Forum before. Tolerances? Wire length? 

**Attention** This is a public forum