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.

MSP430F5418A: LP5036 - LEDs - still having trouble programming them

Part Number: MSP430F5418A
Other Parts Discussed in Thread: LP5036, MSP430F247, TMS320F28035, LP5569

At the end, I program the I2c without the library functions - and everything seems to work fine - though it sometimes gets "stuck".

This is for a 24/7 device - really quite simple - and one of the major functions is the blinking LEDs.

I put in a check that if the I2C times out, the I2C should be reset. This helps most of the time - and is almost imperceptible.

BUT after a few hours of running, the LEDs stop blinking and remain on constantly, even though the rest of the device's functions work well - communication over RS485, etc.

What could be the reason? How can I diagnose that the LEDs are constantly ON - is there a register I could read to make sure that the LEDs and OFF when they should be and ON when they should be?

bool LP5036_bankColor(BYTE red, BYTE green, BYTE blue)
{
    bool ret = 1;

    ret =  LP5036_write2_Byte( LP5036_BANK_A_COLOR, red, green);

    if (ret != STATUS_SUCCESS)
    {
       Reset_I2C();
    }
    return ret;
}

bool LP5036_write2_Byte(BYTE reg, BYTE data1, BYTE data2) //, BYTE data3)
{
    WORD timeout = 1000;

        //Transmit Data to slave
    // UCB1I2CSA = LED_I2C_SLAVE_ADDR;  // don't need - this is default

    UCB1IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts

    UCB1CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

    while(!(UCB1IFG & UCTXIFG) && --timeout);       //Poll for transmit interrupt flag.

    if(timeout == 0)                   //Check if transfer timed out
    {
        return (STATUS_FAIL);
    }

    UCB1TXBUF = reg;

    while(!(UCB1IFG & UCTXIFG) && --timeout);       //Poll for transmit interrupt flag.

    if(timeout == 0)                   //Check if transfer timed out
    {
        return (STATUS_FAIL);
    }

    UCB1TXBUF = data1;

    while(!(UCB1IFG & UCTXIFG) && --timeout);       //Poll for transmit interrupt flag.

    if(timeout == 0)                   //Check if transfer timed out
    {
        return (STATUS_FAIL);
    }

    UCB1TXBUF = data2;

    while(!(UCB1IFG & UCTXIFG) && --timeout);       //Poll for transmit interrupt flag.

    if(timeout == 0)                   //Check if transfer timed out
    {
        return (STATUS_FAIL);
    }

    UCB1CTL1 |= UCTXSTP;     // Send stop condition

    return STATUS_SUCCESS;
}



void Reset_I2C(void)
{
    UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, Enable SW reset
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
    UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
}

  • Hi Mechi

    on I2C application on MSP430F5418A, Please refer to msp430x54xA_usci_i2c_standard_master.c and msp430x54xA_usci_i2c_standard_slave.c code example on MSP430F543xA, MSP430F541xA Code Examples (Rev. K). Thanks!

  • I definitely did - that's where I got the code from.

    The problem is that after hours of working fine, the LEDs stay either lit or off.

    I checked the I2C traffic with a scope - from the MSP430 to the LED board - the commands are still being sent at the same 2Hz rate - but the LEDs freeze.

    What could cause this?

    Since LP5036 is a TI peripheral, I'm asking is there some way to "read" the state of the LEDs and if the LEDs are stuck, to somehow reset them so that they will work again?

  • Monet, could you help Fendel in this case

  • I'd appreciate any help.

    Thanks,

    Mechi

  • Hi Mechi,

    I think there will be some way you can try:

    1.please capture the waveform of SCL and SDA when the LED  stop blinking, check that whether the device communicate successfully. If it is convenient for you, you can provide the waveform for me and i will help to check.

    2.read the LEDx Brightness and OUTx Color registers data to check there status.

    In addition, when LEDs stop blinking and remain constantly, are their brightness and color same?

    Best Regard

    Monet Xu

  • If there is no further feedback I will close this thread.

  • I'm sorry not to have replied. We were on vacation for Memorial and Independence Days.

    The situation described in the previous posts happens after many hours of the device running. In order to debug, I will have to add in the checks you recommended and constantly monitor the device until this situation occurs.

    I will get back to you when I've done this.

    Thanks,

    Mechi

  • Hi Mechi,

    I will keep supporting this issue, if there is any progress, please contact me~

    Monet Xu

  • I think I found where it's getting stuck - still wondering WHY...

    bool LP5036_write2_Byte(BYTE reg, BYTE data1, BYTE data2) //, BYTE data3)
    {
        WORD timeout = 1000;
    
            //Transmit Data to slave
        UCB1I2CSA = LED_I2C_SLAVE_ADDR;  // don't really need - this is default
    
        UCB1IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
    
        UCB1CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition
    
        while(!(UCB1IFG & UCTXIFG) && --timeout);       //Poll for transmit interrupt flag.
    
        if(timeout == 0)                   //Check if transfer timed out
        {
            return (STATUS_FAIL);
        }
    
        timeout = 1000;
        UCB1TXBUF = reg;
    
        while(!(UCB1IFG & UCTXIFG) && --timeout);       //Poll for transmit interrupt flag.
    
        if(timeout == 0)                   //Check if transfer timed out
        {
            return (STATUS_FAIL);
        }
    
        timeout = 1000;
        UCB1TXBUF = data1;
    
        while(!(UCB1IFG & UCTXIFG) && --timeout);       //Poll for transmit interrupt flag.
    
        if(timeout == 0)                   //Check if transfer timed out
        {
            return (STATUS_FAIL);
        }
    
        timeout = 1000;
        UCB1TXBUF = data2;
    
        while(!(UCB1IFG & UCTXIFG) && --timeout);       //Poll for transmit interrupt flag.
    
        if(timeout == 0)                   //Check if transfer timed out
        {
            return (STATUS_FAIL);
        }
    
        UCB1CTL1 |= UCTXSTP;     // Send stop condition
    
        return STATUS_SUCCESS;
    }

    When the LEDs don't blink, it's because the following times out:

    timeout = 1000;
    UCB1TXBUF = reg;
    
    while(!(UCB1IFG & UCTXIFG) && --timeout); //Poll for transmit interrupt flag.
    
    if(timeout == 0) //Check if transfer timed out
    {
       return (STATUS_FAIL);
    }

    Since the function returns a failure, the I2C is reset.

    I don't know why this all of a sudden occurs, and I can't figure out how to restore correct I2C and LED function.

    Maybe the Reset_I2C is not written correctly?

    void Reset_I2C(void)
    {
        UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, Enable SW reset
        UCB1CTL1 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
        UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
    }

    Also, once the I2C gets stuck, the device must be powered ON again for it to continue working (resetting with the debugger is not enough).

  • Hi Monet, please help to keep following this case.

  • I need help in resetting the I2C - this seems to be where the major problem is.

    When it "gets stuck" I can't manage to reset it and continue sending messages to the LED driver.

    Any ideas about this?

    Even restarting a new debugger session in the CCS doesn't help. Only actually powering down the device seems to reset the I2C. I must have a way to do this programmatically.

    Thanks,

    Mechi

  • Hi Mechi,

    Refer to you describe and simulation, It seems that when getting stuck, the MSP430 can't send any I2C signal to the LED device. I will suggest you to recreate this problem to MPS430 team on E2E. They will be more professional about the MCU.

    If there is any question about the LED driver, I will provide support~

    Monet Xu

  • I agree with you...

    At the moment this is an MSP430 problem

  • If you have located the issue. i will close this thread and please ask 430 team for help.

  • But this IS the MSP430 forum...

    It's not a question about the LEDs board - rather an I2C question - why do I have to open a new post?

    Please - ask the 430 team to continue support - until we get that issue fixed.

    Thanks,

    Mechi

  • Hi Xiaodong,

    Could you please help in this issue? Thanks!

    Monet Xu

  • Something else interesting that I noticed - and then the question is: How can this happen?

    Using the same code that I supplied above, I compare a good I2C message that shuts down the LEDs with the one in which the I2C gets stuck (see attached screenshot)

    Can this be caused by HW? It usually happens after a few hours of working.

    And again, once this happens, how can I reset the I2C?

  • Hi Mechi,

    Let me join and help you resolve this issue together.

    I did a summary for this issue, plese correct me if there are some error.

    1. You use MSP430F247 to drive LP5036 via I2C ia normal, and the I2C hang-up issue occur when change MCU to F5418A, right?
    2. I had a look for your I2C wave, you write 3 bytes data to LP5036(0x05 0x00 0x00), I think 0x05 should the register address, and 0x00 is the data you want to load into this register(or register 0x05 and 0x06), right?

    3. As your description, the I2C hang-up issue is occur after running for a while. And you means that only power cycle can resolve this issue?Does the power cycle for both F5418A and LP5036? Because from your waveform, it is possible that the slave pulled the SDA to reset, causing the hang-up issue even if the Mater I2C is re-configuration.

    I think if you can reproduce this issue, maybe you can try to only power cycle the LP5036 to check if this issue can resolved.

    Thanks!

    Best Regards

    Johnson

  • 1. We never used a different MSP430 - just the F5418A. I was successful in integrating the LP5036 in another project using the TMS320F28035.

    2. Correct - I only want to write to registers 5 and 6 (RED and GREEN).

    3. Until now I've tried just resetting the I2C. I will definitely try resetting the LP5036 - that's a good idea.

    The issue seems to happen because there's a very strong EMI field that somehow interferes with the I2C or LP5036. When we shut off the peripheral that produces the strong EMI, the LEDs continued to flash successfully overnight. Since this may occur in the field and powering off is not an option, I will reproduce the issue and try resetting the LP5036.

    Thanks for your help.

  • Hi Mechi,

    Got it, wait your test result.

    Thanks!

    Best Regards

    Johnson

  • /////////////////////////////////////////////////////////////////////
    // If I2C gets stuck (happens because of EMI) - reset I2C and LP5036
    /////////////////////////////////////////////////////////////////////
    void Reset_I2C(void)
    {
        UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, Enable SW reset
        UCB1CTL1 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
        UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
    
        LP5036_powerDown();
        LP5036_init();
    
        TotalErrors += 10;
    }
    
    // functions from LP5036 library
    
    void LP5036_powerDown()
    {
    	LP5036_writeByte( LP5036_DEVICE_CONFIG0, 0x00); //clear bit 6 to shut down
    }
    
    
    void LP5036_powerUp()
    {
    	LP5036_writeByte( LP5036_DEVICE_CONFIG0, 0x40); //set bit 6 to enable
    }
    
    
    void LP5036_init()
    {
        LP5036_powerUp();
        LP5036_powerUp();
    	LP5036_writeByte( LP5036_DEVICE_CONFIG1, 0x20 | 0x10 | 0x08 | 0x04);
    
        LP5036_setRunMode();
    
        LP5036_bankControlOn();   //control banks
    
        LP5036_bankBrightness(0xC0); // mid bright
    
        LEDS_initialized = TRUE;
    
        LP5036_write2_Byte( LP5036_BANK_A_COLOR, 0, 0);   // red & green
    
        SttCtrl.LED_R_state = OFF;
        SttCtrl.LED_G_state = OFF;
    }
    

    I just realized that the LP5036 relies on I2C communication, too. So if the I2C lines are not ready for messaging, then resetting the LP5036 won't work.

    Maybe I should try jiggling the GPIO pins that are used for the I2C.

    The above reset function is called again and again - but to no avail - see screenshot below. 

  • BTW - we tried to disconnect the LP5036 board and reconnect while the device continued running - but this didn't reset the I2C comm

  • Hi Mechi,

    You means that disconnect and power cycle LP5036, then connect again, the MSP430 I2C till keep hang-up? and the timeout funciton can't reset I2C? Right?

    Thanks!

    Best Regards

    Johnson

  • Yes. Correct.

    Unplugging the LP5036 board and plugging it back - while device continued to work didn't reset the I2C.

    Also, the reset function that I wrote also doesn't reset the I2C.

    Any other ideas?

  • Hi Mechi,

    I find there are some error for your code:
    UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, Enable SW reset
    UCB1CTL1 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation

    This should UCB1CTL0.

    Can you share I2C configuration code?

    I think if thimeout had be trigger, the I2C should be able to reset.

    Thanks!

    Best Regards

    Johsnon

  • Thanks for pointing that out. It had been written correctly in the code - and for some reason I changed it...

    Still doesn't work.

    The I2C Config code:

    // Initializes the I/O devices (I/O ports' direction and output values, 4-20mA output and A2D conversion)
    void InitDev()
    {
    
    //  USCI_B_I2C_initMasterParam i2c_param;
    
      /// Initialize to ports' status
    
      P1DIR = 0xFF; // Port P1 - set all bits for output.
      P1SEL = HEATER_BIT; // Port P1 - Set all bits for I/O - except P1.4 heater PWM
      P1OUT = 0x00; // Port P1- All outputs are low.
    
      P2SEL = 0x00; // Port P2 - Set all bits for I/O.
      P2DIR = 0xF3; // Port P2 - Set  bits for output - except for MEMS - P2.2, P2.3
      P2OUT = 0x01; // Port P1- All outputs are low - except for CS for Temp P2.0 -not connected
      
    
      P3SEL = 0xBE; // Port P3 - Set  bits 1-5, 7 for USCI.
      P3DIR = 0x9A; // Port P3 - Set bit 1 and 3 for output (tmp_enbl and sclk)
    
      P4SEL = 0x00; // Port P4 - Set all bits for I/O.
      P4DIR = 0x01; // Port P4 - Set all bit for input, except bit 0, TXD_EN.
      P4OUT = 0x00; // Port P4- All outputs are low.
      
    
      P5SEL = 0x10; // Port P5 - Set all bits for I/O - P5.4 SCL I2C
      P5DIR = 0x10; // Port P5 - Set all bits for input - P5.4 output
      
    
      P6SEL = 0xFF; // Port P6 - Set all bits for A2D (rather than I/O).
     
      P7DIR = 0xFF; // Port P1 - set all bits for output.
      P7SEL = 0x03; // Port P1 - Set all bits for I/O - except for timer external CLK
    
      P7OUT = 0x00; // Port P1- All outputs are low.
      P8DIR = 0xFF; // Port P1 - set all bits for output.
      P8SEL = 0x00; // Port P1 - Set all bits for I/O.
      P8OUT = 0x00; // Port P1- All outputs are low.
      P9DIR = 0xFF; // Port P1 - set all bits for output.
      P9SEL = 0x00; // Port P1 - Set all bits for I/O.
      P9OUT = 0x00; // Port P1- All outputs are low.
      P10DIR = 0xFF; // Port P1 - set all bits for output.
      P10SEL = 0x00; // Port P1 - Set all bits for I/O.
      P10OUT = 0x00; // Port P1- All outputs are low.
      PFDIR = 0xFF; // Port P1 - set all bits for output.
      PFSEL = 0x00; // Port P1 - Set all bits for I/O.
      PFOUT = 0x00; // Port P1- All outputs are low.
    
      /// Initialize the A/D converter
      ClearAveragedA2D();
      
        /* The A/D Control Register */
      /* Initialize the shared reference module */
      REFCTL0 |= REFMSTR + REFVSEL_0 + REFON;    // Enable internal 1.5V reference
    
       
      ADC12CTL0 = ADC12ON + ADC12MSC + ADC12SHT03 + ADC12REFON;   // Sample 32 ADC12CLK cycles - turn REF on for Temperature.
                                                                   // Multiple sample and conversion.
      ADC12CTL1 = ADC12SHP + ADC12DIV_7 + ADC12SSEL_1 + ADC12CONSEQ_1 ; // Sequence conversion, ADC12CLK: ACLK/8.
    
      /* Set the Conversion Memory Registers (a sequence that starts with A0 and ends with A1. */
      
      ADC12MCTL0 = ADC12INCH_2 + ADC12REF2_5V; // ADC12MEM0 will read A2 (VCC -3v ) in the range VE_REF- (GND_420) to VE_REF+ (VCC).
      ADC12MCTL1 = ADC12INCH_3 + ADC12REF2_5V; // ADC12MEM1 will read A3 (VDD- 5v divided by 2) in the range VE_REF- (GND_420) to VE_REF+ (VCC).
      ADC12MCTL2 = ADC12INCH_1 + ADC12REF2_5V; // ADC12MEM2 will read A1 (sns_Vin -divided by 11) in the range VE_REF- (GND_420) to VE_REF+ (VCC).
      ADC12MCTL3 = ADC12INCH_0 + ADC12REF2_5V; // ADC12MEM3 - will read A0 (sns_HEATER) in the range VE_REF- (GND_420) to VE_REF+ (VCC).
      ADC12MCTL4 = ADC12INCH_4 + ADC12REF2_5V; // ADC12MEM4 - will read A4 (sns_12v - factor is 0.203187) in the range VE_REF- (GND_420) to VE_REF+ (VCC).
      ADC12MCTL5 = ADC12INCH_5 + ADC12REF2_5V; // ADC12MEM5 - will read A5 (sns_HV - between 1 and 2.6v) in the range VE_REF- (GND_420) to VE_REF+ (VCC).
      ADC12MCTL6 = ADC12INCH_6 + ADC12REF2_5V; // ADC12MEM6 - will read A6 (sns_HV - between 1 and 2.6v) in the range VE_REF- (GND_420) to VE_REF+ (VCC).
      ADC12MCTL7 = ADC12INCH_10 + ADC12SREF_1 + ADC12EOS; // ADC12MEM7 - will read A10 -temperature sensor
                                          // End of Sequence for the last channel
      
      ADC12IE = 0x0F; //ADC12IE7;  //0x01; // A/D Interrupt Enable
      isA2D_Accumulate = TRUE; // Enable A2D accumulation
      
      SetVCoreUp(2);
    
      UCS_setExternalClockSource(16128000, 0);
    
      // UCB1 for I2C
      UCB1CTL1 |= UCSWRST;                      // Enable SW reset
      UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode
      UCB1CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK
      UCB1BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
      UCB1BR1 = 0;
      UCB1I2CSA = LED_I2C_SLAVE_ADDR;           // Slave default Address is 030h
      UCB1IE &= ~UCTXIE;                        // disable TX interrupt
      UCB1CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation
    
      // UCB0 for SPI
      UCB0CTL1 = UCSSEL_2 | UCSWRST; // Use SMCLK + **Put state machine in reset**
      UCB0CTL0 =  UCSYNC +  UCMSB + UCMODE_0 + UCMST + UCCKPL;   // Master, synchronous mode
      // Clock polarity high, MSB first
      UCB0BR0 = 12; // fSCL = SMCLK/12 = ~ 200khz
      UCB0CTL1 &= ~UCSWRST;   // enable - take out of reset
    }
    

  • What's interesting...and may give us a clue how to fix the situation...

    If the I2C stops - but both the SDA and SCL lines are high, then if I send another I2C command (using a PC host to another peripheral), the I2C goes back to working OK.

    I have to figure out how to do this in the firmware...I can't figure out what sets the SDA to HIGHafter 11, 14 or 15 seconds (as I've observed each time this occurs)...

    If the SDA is LOW - then sending I2C command to another peripheral doesn't help at all.

    Please see attached screenshots

  • Hi Mechi,

    Sorry that reply you too late duo to holiday.

    Does your issue have been resolved? do you still need our support?

    Thanks!

    Best Regards

    Johnson

  • No. The issue isn't resolved.

    How can the I2C be reset programmatically without having to power down the device?

  • use this code to disable I2C module:

    UCB1CTL1 |= UCSWRST;

    And then reinit this I2C module. 

  • I tried this reset of the I2C - but it doesn't work.

    I've been trying so many different ideas.

    The I2C messages are affected by the strong EMI of a flash. I tried synchronizing the I2C messages so that they're sent 80ms after the EMI flash is turned off. Still, the I2C stops after 10-20 hours or running, and I haven't been able to reset it.

  • Is there a setting in the LP5036 driver for it to be in a constant blinking state - without having to send specific I2C messages?

  • Hi Mechi,

    @Monet, could you help to check if LP5036 have this function?

    Thanks!

    Best Regards

    Johnson

  • Hi Mechi,

    I2C interface is the necessary way to configurate the blinking function for LP5036 and it need to work continuously. LP5569 is a channels I2C RGB LED driver with engine control and charge pump. It can release the I2C interface after configurate the related registers and SRAM and the blinking function will operate after enable the engines.

    Best Regard

    Monet Xu

**Attention** This is a public forum