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.

MSP430FR2533: USCIB spi SIMO ouput issue

Part Number: MSP430FR2533
Other Parts Discussed in Thread: MSP430FR2633

Hi MSP430 team

Customer use eUSCI_A1 and eUSCI_B0 SPI mode SIMO signal to drive RGB LED, related pin are  P2.6, P1.2.

After using the same initial source code for eUSCI_A1 and eUSCI_B0, they found eUSCI_B0 P1.2 SIMO signal abnormal.

P2.6 can drive the RGB LEDs correctly, while P1.2 cannot drive LEDs correctly(first LED not work).

(两个SIMO信号分别驱动两串相同,做过交叉测试,确认原因是因为P1.2输出波形问题)。

From the capture waveform, it can find the P1.2 SIMO initial level is high, which may cause the issue.

Can you suggest why this happen?

Attached file is customer test P1.2 in TI MSPWARE example.

 

Initial code in customer project:

    P2SEL0 |=  (GPIO_PIN6);            // set 3-SPI pin as second function

    UCA1CTLW0 |= 0x0001;                     // **Put state machine in reset**
    UCA1CTLW0 |= (0x01<<11)|(0x01<<8)|(0x01<<14)|(0x01<<13);   // 3-pin, 8-bit SPI master
    // Clock polarity high, MSB
    UCA1CTLW0 |= (0x01<<7);               // SMCLK
    UCA1BR0 = 0x00;                           // /2,fBitClock = fBRCLK/(UCBRx+1).
    UCA1BR1 = 0;                              //
    UCA1MCTLW = 0;                            // No modulation
    UCA1CTLW0 &= (0xfffe);                    // **Initialize USCI state machine**

    P1SEL0 |= (GPIO_PIN2);

    UCB0CTLW0 |= 0x0001;
    UCB0CTLW0 |= (0x01<<11)|(0x01<<8)|(0x01<<14)|(0x01<<13);   // 3-pin, 8-bit SPI master
    // Clock polarity high, MSB
    UCB0CTLW0 |= (0x01<<7);               // SMCLK
    UCB0BR0 = 0x00;                           // /2,fBitClock = fBRCLK/(UCBRx+1).
    UCB0BR1 = 0;                              //
    UCB0CTLW0 &= (0xfffe);                    // **Initialize USCI state machine**

/* --COPYRIGHT--,BSD
 * Copyright (c) 2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
//*****************************************************************************
//! USCI_B0, SPI 3-Wire Master Incremented Data
//! This example shows how SPI master talks to SPI slave using 3-wire mode.
//! Incrementing data is sent by the master starting at 0x01. Received data is
//! expected to be same as the previous transmission.  eUSCI RX ISR is used to
//! handle communication with the CPU, normally in LPM0. If high, P1.0 indicates
//! valid data reception.  Because all execution after LPM0 is in ISRs,
//! initialization waits for DCO to stabilize against SMCLK.
//! MCLK = SMCLK = ACLK = ~32.768kHz
//!
//! Use with SPI Slave Data Echo code example.  If slave is in debug mode, P1.1
//! slave reset signal conflicts with slave's JTAG; to work around, use IAR's
//! "Release JTAG on Go" on slave device.  If breakpoints are set in
//! slave RX ISR, master must stopped also to avoid overrunning slave
//! RXBUF.
//!
//!             Tested on MSP430FR4133
//!                 -----------------
//!            /|\ |                 |
//!             |  |                 |
//!    Master---+->|RST              |
//!                |                 |
//!                |             P5.2|-> Data Out (UCB0SIMO)
//!                |                 |
//!                |             P5.3|<- Data In (UCB0SOMI)
//!                |                 |
//!                |             P5.1|-> Serial Clock Out (UCB0CLK)
//!
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - SPI peripheral
//! - GPIO Port peripheral (for SPI pins)
//! - UCB0SIMO
//! - UCB0SOMI
//! - UCB0CLK
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - USCI_B0_VECTOR
//!
//*****************************************************************************
#include "driverlib.h"

uint8_t RXData = 0;
uint8_t TXData = 0;

#define uint8_t unsigned char
#define uint16_t unsigned short

#define SPI_DATA_BUFF_SIZE  (33 * 12)

typedef struct
{
   uint16_t   spi_data_idx;
   uint8_t    a_spi_data[SPI_DATA_BUFF_SIZE];
}T_LED_SPI_DATA_FRAME;

#define  GRB_LED_2BIT00        0x88
#define  GRB_LED_2BIT01        0x8e
#define  GRB_LED_2BIT10        0xe8
#define  GRB_LED_2BIT11        0xee

const uint8_t spi_data_table[4] = {GRB_LED_2BIT00,GRB_LED_2BIT01,GRB_LED_2BIT10,GRB_LED_2BIT11};

T_LED_SPI_DATA_FRAME  t_rgb_frame_spi_data_buff;

void rgb_value2_spi_data(uint8_t rgb)
{
    uint8_t temp;
    temp = (rgb>>6)&0x03;

    t_rgb_frame_spi_data_buff.a_spi_data[t_rgb_frame_spi_data_buff.spi_data_idx]= spi_data_table[temp];
    t_rgb_frame_spi_data_buff.spi_data_idx++;

    temp = (rgb>>4)&0x03;
    t_rgb_frame_spi_data_buff.a_spi_data[t_rgb_frame_spi_data_buff.spi_data_idx]= spi_data_table[temp];
    t_rgb_frame_spi_data_buff.spi_data_idx++;

    temp = (rgb>>2)&0x03;
    t_rgb_frame_spi_data_buff.a_spi_data[t_rgb_frame_spi_data_buff.spi_data_idx]= spi_data_table[temp];
    t_rgb_frame_spi_data_buff.spi_data_idx++;

    temp = rgb&0x03;
    t_rgb_frame_spi_data_buff.a_spi_data[t_rgb_frame_spi_data_buff.spi_data_idx]= spi_data_table[temp];
    t_rgb_frame_spi_data_buff.spi_data_idx++;
}

void main(void)
{
    volatile uint16_t i;

    //Stop watchdog timer
    WDT_A_hold(WDT_A_BASE);

    __bis_SR_register(SCG0);                // disable FLL
    CSCTL3 |= SELREF__REFOCLK;              // Set REFO as FLL reference source
    CSCTL0 = 0;                             // clear DCO and MOD registers
    CSCTL1 &= ~(DCORSEL_7);                 // Clear DCO frequency select bits first
    CSCTL1 |= DCORSEL_5;                    // Set DCO = 16MHz

    CSCTL2 = FLLD_0 + 426;
    __delay_cycles(3);
    __bic_SR_register(SCG0);                // enable FLL
    while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
    CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // select DCODIV as MCLK and SMCLK source
    CSCTL5 |= DIVS__4;


    P1SEL0 |= (GPIO_PIN2);

    UCB0CTLW0 |= 0x0001;
    UCB0CTLW0 |= (0x01<<11)|(0x01<<8)|(0x01<<13);   // 3-pin, 8-bit SPI master
    // Clock polarity high, MSB
    UCB0CTLW0 |= (0x01<<7);               // SMCLK
    UCB0BR0 = 0x00;                           // /2,fBitClock = fBRCLK/(UCBRx+1).
    UCB0BR1 = 0;                              //
    UCB0CTLW0 &= (0xfffe);                    // **Initialize USCI state machine**


    uint16_t led_idx;
    uint8_t breathe_up = 0;
    uint8_t breathe_down;

    t_rgb_frame_spi_data_buff.spi_data_idx = 0;
    while(1)
    {
        if (breathe_up < 10)
        {
            t_rgb_frame_spi_data_buff.spi_data_idx = 0;
            for (led_idx = 0; led_idx < 99; led_idx++)
                rgb_value2_spi_data(25 * breathe_up);
            for (led_idx = 0; led_idx < 99 * 4; led_idx++)
                EUSCI_B_SPI_transmitData(EUSCI_B0_BASE, t_rgb_frame_spi_data_buff.a_spi_data[led_idx]);
            breathe_up++;
            breathe_down = 10;
        }
        else
        {
            t_rgb_frame_spi_data_buff.spi_data_idx = 0;
            for (led_idx = 0; led_idx < 99; led_idx++)
                rgb_value2_spi_data(25 * breathe_down);
            for (led_idx = 0; led_idx < 99 * 4; led_idx++)
                EUSCI_B_SPI_transmitData(EUSCI_B0_BASE, t_rgb_frame_spi_data_buff.a_spi_data[led_idx]);
            if (breathe_down == 0)
            {
                breathe_up = 0;
            }
            breathe_down--;
        }
    }
}

P1.2 SIMO signal

P2.6 SIMO signal.

Eric

  • Hi Eric!

    Is there a slave IC connected to the MSP that drives the LEDs or how does the application look like? I think you did not connect the RGB LEDs directly to the SPI lines, right? If so, I would wonder about this mechanism for controlling the LEDs. Anyway - the output of the SPI's SIMO stays at the level it stopped with after the previous transmission. It will be changed before the first clock cycle of the new byte appears.

  • Hi Dennis

    MSP SIMO signal run through a 3.3V/5V level switch IC , then drive the RGB LED string. The LED like below.

    The question is why USCI_B0 P1.2 used the same initial source code as USCI_A0 P2.6, but have different initial level as previous waveform. This cause the LED did't work in correct state.

    Eric

  • Hi Eric,

    The code you give us can not be built.

    I tried our code example on the MSP430FR2633 board and didn't see this issue. The USCI_A1 P2.6 and UCXI_B0 P1.2 are the same initial voltage level. Did you reproduce this customer issue?

    My code is in the attachment.

    #include <msp430.h>
    
    unsigned char RXData = 0;
    unsigned char TXData;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;                 // Stop watchdog timer
    
        __bis_SR_register(SCG0);                // disable FLL
        CSCTL3 |= SELREF__REFOCLK;              // Set REFO as FLL reference source
        CSCTL0 = 0;                             // clear DCO and MOD registers
        CSCTL1 &= ~(DCORSEL_7);                 // Clear DCO frequency select bits first
        CSCTL1 |= DCORSEL_5;                    // Set DCO = 16MHz
    
        CSCTL2 = FLLD_0 + 426;
        __delay_cycles(3);
        __bic_SR_register(SCG0);                // enable FLL
        while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
        CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK; // select DCODIV as MCLK and SMCLK source
        CSCTL5 |= DIVS__4;
    
        P1OUT |= BIT6;
        P1DIR |= BIT6;
    
    
        P2SEL0 |= BIT4 | BIT5 | BIT6;             // set 3-SPI pin as second function
    
        UCA1CTLW0 |= UCSWRST;                     // **Put state machine in reset**
        UCA1CTLW0 |= UCMST|UCSYNC|UCCKPL|UCMSB;   // 3-pin, 8-bit SPI master
                                                  // Clock polarity high, MSB
        UCA1CTLW0 |= UCSSEL__SMCLK;                // Select ACLK
        UCA1BR0 = 0x00;                           // BRCLK = ACLK/2
        UCA1BR1 = 0;                              //
        UCA1MCTLW = 0;                            // No modulation
        UCA1CTLW0 &= ~UCSWRST;                    // **Initialize USCI state machine**
    //    UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
        TXData = 0x01;                            // Holds TX data
    
        PM5CTL0 &= ~LOCKLPM5;                     // Disable the GPIO power-on default high-impedance mode
                                                  // to activate previously configured port settings
        while(1)
        {
            UCA1IE |= UCTXIE;                     // Enable TX interrupt
            __bis_SR_register(LPM0_bits | GIE);   // enable global interrupts, enter LPM0
            __no_operation();                     // For debug,Remain in LPM0
            __delay_cycles(2000);                 // Delay before next transmission
            P1OUT &= ~BIT6;
            TXData++;                             // Increment transmit data
        }
    
    //    P1SEL0 |= BIT1 | BIT2 | BIT3;
    //
    //    UCB0CTLW0 |= UCSWRST;                     // **Put state machine in reset**
    //    UCB0CTLW0 |= UCMST|UCSYNC|UCCKPL|UCMSB;   // 3-pin, 8-bit SPI master
    //                                              // Clock polarity high, MSB
    //    UCB0CTLW0 |= UCSSEL__SMCLK;                // Select ACLK
    //    UCB0BR0 = 0x00;                           // BRCLK = ACLK/2
    //    UCB0BR1 = 0;                              //
    //
    //    UCB0CTLW0 &= ~UCSWRST;                    // **Initialize USCI state machine**
    //    UCB0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
    //    TXData = 0x01;                            // Holds TX data
    //
    //    PM5CTL0 &= ~LOCKLPM5;                     // Disable the GPIO power-on default high-impedance mode
    //                                              // to activate previously configured port settings
    //    while(1)
    //    {
    //        UCB0IE |= UCTXIE;                     // Enable TX interrupt
    //        __bis_SR_register(LPM0_bits | GIE);   // enable global interrupts, enter LPM0
    //        __no_operation();                     // For debug,Remain in LPM0
    //        __delay_cycles(2000);                 // Delay before next transmission
    //        TXData++;                             // Increment transmit data
    //    }
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A1_VECTOR
    __interrupt void USCI_A1_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_A1_VECTOR))) USCI_A1_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        switch(__even_in_range(UCA1IV,USCI_SPI_UCTXIFG))
        {
            case USCI_NONE: break;                // Vector 0 - no interrupt
            case USCI_SPI_UCRXIFG:
                  RXData = UCA1RXBUF;
                  UCA1IFG &= ~UCRXIFG;
                  break;
            case USCI_SPI_UCTXIFG:
                  UCA1TXBUF = TXData;             // Transmit characters
                  UCA1IE &= ~UCTXIE;
                  __bic_SR_register_on_exit(LPM0_bits);// Wake up to setup next TX
                  break;
            default: break;
        }
    }
    //#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    //#pragma vector=USCI_B0_VECTOR
    //__interrupt void USCI_B0_ISR(void)
    //#elif defined(__GNUC__)
    //void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
    //#else
    //#error Compiler not supported!
    //#endif
    //{
    //    switch(__even_in_range(UCB0IV,USCI_SPI_UCTXIFG))
    //    {
    //        case USCI_NONE: break;                // Vector 0 - no interrupt
    //        case USCI_SPI_UCRXIFG:
    //              RXData = UCB0RXBUF;
    //              UCB0IFG &= ~UCRXIFG;
    //
    //              break;
    //        case USCI_SPI_UCTXIFG:
    //              UCB0TXBUF = TXData;             // Transmit characters
    //              UCB0IE &= ~UCTXIE;
    //              __bic_SR_register_on_exit(LPM0_bits);// Wake up to setup next TX
    //              break;
    //        default: break;
    //    }
    //}
    

    Best regards,

    Cash Hao

  • I do not get how you are controlling the LEDs...is there a driver after the level translator? If so and if it uses SPI, it should have something like a chip select. But the given oscilloscope signals look a bit strange, too - if it is the SIMO signal, it is always 1010101010... What kind of data is this? Driving LEDs directly from the USCI module does not make any sense to me. Could you please give some explanation?

    Edit: OK, now I just realized your LEDs have a DIN/DOUT connection - I thought those were some sort of the mentioned level shifter. Could you please tell the used LED type?

**Attention** This is a public forum