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.

MSP430FR5994: Not getting constant speed in SPI

Part Number: MSP430FR5994
Other Parts Discussed in Thread: LMK04832,

Hi All,

I am using SPI protocol to communicate with LMK04832 device. I have a three questions.

1. How to decide what clock speed I should set for device ( my device is LMK04832 )?

2. How can I get constant clock for communication?

3. While reading from the device is it necessary to send dummy data after address to read the data?

Thanks & regards.

Madhav

  • 1) Per data sheet (SNAS688C) Sec 6.6, the maximum SPI speed is 5MHz. The EUSCI provides only an integer prescaler (BRW) so depending on your SMCLK speed you may or may not hit 5MHz exactly.

    2) The bit-clock within a byte will be constant. There may be gaps between bytes depending on how fast you're filling TXBUF. For very small transactions such as these, this rarely matters.

    3) Per data sheet Sec 6.7 (diagram), you need to send a dummy byte after the address in order to receive the data. Are you using 3-wire or 4-wire mode?

  • I am using 3-wire mode for SPI.

  • Actually My slave is LMK04832 and master is MSP430FR5994.

    So first I am transmitting two bytes for address and one byte for data. So when I am transmitting two bytes of address and than data, I am able to see waveform on oscilloscope but not getting required output.

    So I want to confirm that weather I am giving required clock or not. Is there any other issue I do not know.

    First time I am interfacing SPI through MSP microcontroller to any slave.

    Thanks for your previous replays.    

  • I am using MOSI, MISO, CLK and CS lines from MSP430FR5994

  • The point of that other thread is that when using 3-wire mode (i.e. both MISO and MOSI connected to SDIO) you should expect bus conflicts which will (at minimum) garble your read data. There is a suggested procedure for avoiding this.

    What code do you have so far? What sort of board(s) do you have?

  • Hi Bruce,

    I have one confusion that when I use MISO, MOSI,CLK and CS then do I need to configure eUSCI SPI module as 3-wire mode or 4-wire mode?

    Because from user guide I concluded that 4-wire mode is used when there is multi-master. but here I am using only single master.

    So do I have to use 3-wire or 4-wire mode??

  • #include <msp430.h>
    #include <stdio.h>
    #include "lmk04832.h"
    
    #define MSP430_CPU_CLK_HZ      (20000000 / 2)
    #define FAIL            (-1)
    #define TRUE            (1)
    int timeCount = 0;
    
    void spiInit()
    {
        /* Configure GPIO */
        P4SEL1 &= (~BIT7);
        P4SEL0 &= (~BIT7);
        P4OUT &= ~BIT7;
        P4DIR |= BIT7;
    
        /* USCI_B1 SCLK, MOSI, and MISO pin */
        P5SEL1 &= ~(BIT0 | BIT1 | BIT2);
        P5SEL0 |= (BIT0 | BIT1 | BIT2);
    }
    
    void clockInit()
    {
        // XT1 Setup
        CSCTL0_H = CSKEY_H;                     // Unlock CS registers
        CSCTL1 = DCOFSEL_0;                     // Set DCO to 5.33MHz
        CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
        CSCTL3 = DIVA__1 | DIVS__32 | DIVM__1;   // set all dividers
        CSCTL0_H = 0;                           // Lock CS registers
    
        // Configure USCI_B1 for SPI operation
        UCB1CTLW0 = UCSWRST;                    // **Put state machine in reset**
        UCB1CTLW0 |= UCMST | UCSYNC | UCMSB | UCSSEL__SMCLK | UCCKPH; // 3-pin, 8-bit SPI master
                                                // Clock polarity high, MSB
        UCB1BRW = 0x00;                         // 2
        //UCB1MCTLW = 0;                          // No modulation
        UCB1CTLW0 &= ~UCSWRST;                  // **Initialize USCI state machine**
    }
    
    char spiWrite(void)
    {
        int size = 0;
        unsigned int i;
        char addr1, addr2, txData;
    
        size = sizeof(lmkRegVal)/sizeof(lmkRegVal[0]);
        for(i = 0; i<= size; i++)
        {
            printf("Transferred %d byte \n\r",i);
            /* CS line low */
            P4OUT &= ~BIT7;
    
            addr1 = (lmkRegVal[i] & 0xFF0000)>>16;
    
            timeCount = 500;
            while((!(UCB1IFG & UCTXIFG)) && (0 < timeCount))
            {
                /* Wait for 1 msec */
                __delay_cycles(MSP430_CPU_CLK_HZ / 1000);
                timeCount--;
            }
            /* Check for time out error */
            if(0 == timeCount)
                return FAIL;
            else
            {
                /* Transmit R/W and A14-A8 bits */
                UCB1TXBUF = addr1;                   // Load reg addr
            }
    
            addr2 = (lmkRegVal[i] & 0x00FF00)>>8;
            timeCount = 500;
            while((!(UCB1IFG & UCTXIFG)) && (0 < timeCount))
            {
                /* Wait for 1 msec */
                __delay_cycles(MSP430_CPU_CLK_HZ / 1000);
                timeCount--;
            }
            /* Check for time out error */
            if(0 == timeCount)
                return FAIL;
            else
            {
                /* Transmit A7-A0 bits */
                UCB1TXBUF = addr2;                   // Load reg addr
            }
    
            txData = (lmkRegVal[i] & 0x0000FF);
            timeCount = 500;
            while((!(UCB1IFG & UCTXIFG)) && (0 < timeCount))
            {
                /* Wait for 1 msec */
                __delay_cycles(MSP430_CPU_CLK_HZ / 1000);
                timeCount--;
            }
            /* Check for time out error */
            if(0 == timeCount)
                return FAIL;
            else
            {
                /* Transmit D7-D0 bits */
                UCB1TXBUF = txData;                   // Load reg addr
            }
            /* CS line High */
            P4OUT |= BIT7;
        }
    }
    
    char spiRead(void)
    {
        char addr1, addr2, rxData1, rxData2;
        addr1 = 0x0B // Read register;
        P4OUT &= ~BIT7; // CS low
    
        timeCount = 500;
        while((!(UCB1IFG & UCTXIFG)) && (0 < timeCount))
        {
            /* Wait for 1 msec */
            __delay_cycles(MSP430_CPU_CLK_HZ / 1000);
            timeCount--;
        }
        /* Check for time out error */
        if(0 == timeCount)
            return FAIL;
        else
        {
            /* Transmit R/W and A14-A8 bits */
            UCB1TXBUF = addr1;                   // Load reg addr
        }
    
        addr2 = 0x00;
        timeCount = 500;
        while((!(UCB1IFG & UCTXIFG)) && (0 < timeCount))
        {
            /* Wait for 1 msec */
            __delay_cycles(MSP430_CPU_CLK_HZ / 1000);
            timeCount--;
        }
        /* Check for time out error */
        if(0 == timeCount)
            return FAIL;
        else
        {
            /* Transmit A7-A0 bits */
            UCB1TXBUF = addr2;                   // Load reg addr
        }
    
    //    while(!(UCB1IFG&UCRXIFG));
        rxData1 = UCB1RXBUF;
    
        rxData1 = rxData1 << 6;
    
    //    while(!(UCB1IFG&UCRXIFG));
        rxData2 = UCB1RXBUF;
        P4OUT |= BIT7;
    
        rxData1 = rxData1 | rxData2;
    
        return rxData1;
    }
    int main(void)
    {
        printf("Inside main \n\r");
    
        char rxData, checkdata;
    
        WDTCTL = WDTPW | WDTHOLD;               // Stop watchdog timer
    
        // Disable the GPIO power-on default high-impedance mode to activate
        // previously configured port settings
        PM5CTL0 &= ~LOCKLPM5;
    
        spiInit();
        clockInit();
    
    //    checkdata = spiWrite();
        if(checkdata == FAIL)
        {
            printf("Transmision not successful \n\r");
        }
        else
        {
            printf("Transmission successful \n\r");
        }
    
        rxData = spiRead();
        if(rxData == FAIL)
        {
            printf("Transmision not successful \n\r");
        }
        else
        {
            printf("Data = %x", rxData);
        }
    }
    
    
    

    lmk04832.h

    lmk04832.h header file contains register address ( first 16 bits 0xXXXX) and data (last 8 bits 0xXX).

    Si in main code I have masked these values and I am transmitting to lmk device.

  • MSP430 3-pin mode (SCK, MISO, MOSI) is not the same as the LMK0832 3-wire mode (CS, SCK, MISO+MOSI).  The MSP430 EUSCI doesn't know about the LMK0832's 3-wire mode, though you can use its 3-pin mode (with a separate (GPIO) Chip-Select) for it.

    But as a separate matter the fact that MISO and MOSI are connected together to the LMK0832's SDIO is an electrical conflict, which you need to deal with in your code. For a read, you need to send two bytes over MOSI, then disconnect MOSI (using its PSEL) so you can read from MISO.

    According to the LMK0832 data sheet  [Ref Section 8.6.2.1.1] you can use a 4-wire mode that avoids the electrical conflict but it requires different wiring. Can you post a schematic of your board(s), or at least describe how the MSP430 is wired to the LMK0832? 

  • Actually I have used separate GPIO(P4.7) for CS from MSP430 to LMK04832.

    Below wiring connection I am using between MSP430 and LMK04832.

    MSP430          LMK08432

    -------------       -----------------

    P5.0 (MOSI) >> PIN 20 (SDIO)

    P5.1 (MISO) >> PIN 58 (currently CLKIN_SEL0 configured as a MISO )

    P5.2 (CLK) >> PIN 19 (CLK)

    P4.2 (CS) >> PIN 18 (CS)

    from the LMK04832 side 4-wire mode is using to use MISO and MOSI separately and 3-wire mode from MSP430FR5994.

    One more thing I have observed that I am getting abnormal glitch or very small pulse when on CS line when it is LOW.

    What could be the reason for glitch and how can I deal with it?

  • Hi Bruce,

    Now every thing is working fine read as well as write.

    The was a wiring issue due to which I was getting glitches on CS line as a result slave was reading wrong data.

    Thanks for your support.

**Attention** This is a public forum