MSPM0L2228: Problem with abnormal power consumption of UART0 receiving data in L2228?

Part Number: MSPM0L2228
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

When L2228 communicates with 1FR5043, when L2228 is in low power mode, there is a situation where the receiving current is too large. Using uart0, IO uses PA0 and PA1. When receiving data, the current is approximately 1.3mA. Could you please tell me how to set the low power mode for the serial port? What is the approximate power consumption when the low-power serial port is operating? Is there a procedure available for conducting the test?

  • Is there a jumper connected on J8? If so, try removing it. 

    This jumper applies a pullup (2.2K) to PA1/UART0_RX. When driven low, this draws 3.3V/2200Ohm=1.5mA.

    A UART Rx line is (always) driven from the other end, so I think the pullup isn't (ever) needed.

  • PA0 has no pull-up resistor. May I ask if there are any test routines?

  • The register parameters are as shown in the following screenshot

  • What platform are you using? Is it the Launchpad, or a custom board?

    PA0 (UART0_TX) needs a pullup resistor, since it can't drive high (Open Drain). Moreover, it needs to be external, since PA0 (ODIO in general) lacks an internal pullup.

    I was referring to PA1 (UART0_RX). As long as something is connected to it, it does not require a pullup, since the other end is driving it. If there are times when it operates with the other end disconnected, a pullup (also external, since PA1 is also ODIO) is probably a good idea, but it should be fairly weak (20k maybe?) to avoid the symptom you described.

    What sort of test routines do you have in mind? It seems like you have a test case. The worst case is probably having the other send all-0x00 bytes.

  • Both Launchpad and custom board have been tested, and the phenomenon is the same. What is desired is a routine for testing the low-power data reception of the serial port. Our program tests have been abnormal all the time.

  • The TI Launchpad examples are here:

    https://dev.ti.com/tirex/explore/node?node=A__ABvATzSBKGw7HunA5.8.FQ__MSPM0-SDK__a3PaaoK__LATEST

    The "DriverLib" examples are generally simpler and so easier to experiment with.

    Can you show a schematic of your custom board? When you use the Launchpad, is the J8 (PA1 pullup) jumper installed? [On my Rev-E1 Launchpad this is actually J13.]

  • After testing, the power consumption was still relatively high. This project was used for the ultrasonic gas meter L2228 to receive data from FR5043, communicating once per second.

    1. Is UART0 a low-power serial port?

    2. When performing interrupt reception, is the interrupt service routine running in RUN mode?

    When entering the data reception, there is approximately a high level of about 7mS. What causes it to be above 2mA?

    FR5043 transmits 33 bytes of data once per second and receives an instantaneous current of 1.2mA. Is this receiving current normal?

    The following figure shows the collected current.

  • May I ask if there are any test results? It's extremely urgent. Thank you 

  • May I ask if there are any test results? It's extremely urgent. Thank you 

  • Due respect: You haven't provided many clues. I'm not sure how to read the trace you posted: Is that 1 byte or 33 bytes? If you're using the FIFO (and it isn't full), the "bump" would be the UART by itself, but if not that's the UART plus the CPU (ISR) running.

    For my part: I dusted off my LPM01A and constructed a simple test program, guessing at what configuration(s)/code you might be using. Doing that, I was unable to replicate the trace you posted. (I did notice that the Rx-pin pullup only seemed to increase the current by about 0.5mA, rather than 1.5mA, which surprised me a little.)

    To answer your questions:

    1) I'm not sure what constitutes a "low-power UART". The TRM doesn't seem to use that term. In some contexts, I've seen it mean (a) low-speed + few-features and (b) the bit-clock is gated until a Start-bit (falling) edge is detected [TRM (SLAU847E) Sec 21.2.3.1 suggests it does this, though "only while receiving" makes this somewhat moot].

    2) The ISR runs in RUNx mode ("x" from your Sysconfig); in all other modes the CPU is stopped.

  • Could you share your test code? I'm using the example program.

  • Here's what I've been working with.

    There's not much here: I started with the uart_echo_interrupts_standby Example, and added a second UART over which I send a single byte in a SysTick interrupt (nom. 50ms).

    I have PA0/PA1 jumpered to PB7/PB6. (I also jumper 3V3 to the MCU side of BAT on J101.) My goal was to have a self-contained unit that I could drive using only VCC/GND from the LPM01A, and which produced predictable temporal behavior.

    I experimented using Sysconfig, primarily UART speed and low-power modes; the .syscfg contents reflect whatever I tried most recently.

    .c:

    #include "ti_msp_dl_config.h"
    
    volatile uint8_t gEchoData0 = 0;
    uint8_t Data1 = 0x5A;
    int main(void)
    {
        SYSCFG_DL_init();
    
        NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
        NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
        DL_SYSCTL_enableSleepOnExit();
    
        while (1) {
            __WFI();
        }
    }
    
    void UART_0_INST_IRQHandler(void)
    {
        switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) {
            case DL_UART_MAIN_IIDX_RX:
                DL_GPIO_togglePins(GPIO_LEDS_PORT,
                    GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN);
                gEchoData0 = DL_UART_Main_receiveData(UART_0_INST);
                DL_UART_Main_transmitData(UART_0_INST, gEchoData0);
                break;
            default:
                break;
        }
    }
    void
    SysTick_Handler(void)
    {
        DL_UART_Main_transmitData(UART_1_INST, Data1++);
        return;
    }

    .syscfg:

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "MSPM0L222X" --part "Default" --package "LQFP-80(PN)" --product "mspm0_sdk@2.06.00.06"
     * @v2CliArgs --device "MSPM0L2228" --package "LQFP-80(PN)" --product "mspm0_sdk@2.06.00.06"
     * @versions {"tool":"1.25.0+4268"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const GPIO    = scripting.addModule("/ti/driverlib/GPIO", {}, false);
    const GPIO1   = GPIO.addInstance();
    const SYSCTL  = scripting.addModule("/ti/driverlib/SYSCTL");
    const SYSTICK = scripting.addModule("/ti/driverlib/SYSTICK");
    const UART    = scripting.addModule("/ti/driverlib/UART", {}, false);
    const UART1   = UART.addInstance();
    const UART2   = UART.addInstance();
    
    /**
     * Write custom configuration values to the imported modules.
     */
    const mux2       = system.clockTree["EXCLKMUX"];
    mux2.inputSelect = "EXCLKMUX_LFCLK";
    
    GPIO1.$name                          = "GPIO_LEDS";
    GPIO1.associatedPins.create(2);
    GPIO1.associatedPins[0].$name        = "USER_LED_1";
    GPIO1.associatedPins[0].initialValue = "SET";
    GPIO1.associatedPins[0].assignedPort = "PORTA";
    GPIO1.associatedPins[0].assignedPin  = "23";
    GPIO1.associatedPins[1].$name        = "USER_TEST";
    GPIO1.associatedPins[1].assignedPort = "PORTA";
    GPIO1.associatedPins[1].assignedPin  = "21";
    GPIO1.associatedPins[1].initialValue = "SET";
    
    const Board = scripting.addModule("/ti/driverlib/Board", {}, false);
    
    SYSCTL.clockTreeEn           = true;
    SYSCTL.forceDefaultClkConfig = true;
    SYSCTL.powerPolicy           = "STOP0";
    
    SYSTICK.periodEnable    = true;
    SYSTICK.period          = 1600000;
    SYSTICK.interruptEnable = true;
    SYSTICK.systickEnable   = true;
    
    UART1.$name                    = "UART_0";
    UART1.enabledInterrupts        = ["RX"];
    UART1.uartClkSrc               = "LFCLK";
    UART1.ovsRate                  = "3";
    UART1.peripheral.rxPin.$assign = "PA1";
    UART1.peripheral.txPin.$assign = "PA0";
    UART1.txPinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric0";
    UART1.rxPinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric1";
    
    UART2.$name                    = "UART_1";
    UART2.uartClkSrc               = "LFCLK";
    UART2.ovsRate                  = "3";
    UART2.peripheral.$assign       = "UART1";
    UART2.peripheral.rxPin.$assign = "PB7";
    UART2.peripheral.txPin.$assign = "PB6";
    UART2.txPinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric2";
    UART2.rxPinConfig.$name        = "ti_driverlib_gpio_GPIOPinGeneric3";
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    GPIO1.associatedPins[0].pin.$suggestSolution = "PA23";
    GPIO1.associatedPins[1].pin.$suggestSolution = "PA21";
    Board.peripheral.$suggestSolution            = "DEBUGSS";
    Board.peripheral.swclkPin.$suggestSolution   = "PA20";
    Board.peripheral.swdioPin.$suggestSolution   = "PA19";
    UART1.peripheral.$suggestSolution            = "UART0";