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.

LP-MSPM0L1306: Glitch generation when changing PF field in PINCMx register to 0x0

Part Number: LP-MSPM0L1306
Other Parts Discussed in Thread: MSPM0L1306

Tool/software:

Dear Experts,

In a test application on the LP-MSPM0L1306 evaluation board we have observed the generation of a glitch. The following images show the glitch.

The glitch is generated on pin PA10 on the MSPM0L1306 when the pin is configured as GPIO with the pull-up enabled and the initial value set to high (inversion and HIZ are diabled, drive strength is set to low).

When pin PA10 is disabled by writing the value 0x0 to the PF field in the PINCMx register the glitch is generated.

 

We have used Code Composer Studio to setup the LP-MSPM0L1306 and the following code to reproduce the problem.

 

Curiously a glitch is not generated when doing the same on pin PA25.

#include "ti_msp_dl_config.h"

__STATIC_INLINE void disableGPIO(uint32_t pincmIndex)
{
    IOMUX->SECCFG.PINCM[pincmIndex] &= ~(IOMUX_PINCM_PC_CONNECTED |  IOMUX_PINCM_INENA_ENABLE);
    IOMUX->SECCFG.PINCM[pincmIndex] &= ~(IOMUX_PINCM_PF_MASK);
}

int main(void)
{
    uint32_t i=0;

    SYSCFG_DL_init();

    // burn some time
    while(i<4700u)
    {
        __asm volatile("NOP");
        i++;
    }

    disableGPIO(GPIO_UART_Grp_PIN_PA10_IOMUX);

    disableGPIO(GPIO_UART_Grp_PIN_PA25_IOMUX);

    while (1) {
    }
}

Is there a possiblity to avoid the glitch on pin PA10?

 

Thanks.

 

Best regards,

Stefan

  • Hi Stefan,

    Interesting...let take a look.

  • Hi Stefan,

    My apologies for the delay.

    I set this up and don't see what you are seeing. PA10 behaves the same as PA25.  When they are disabled, they are disconnected from the external pin, so if you are seeing any residual signal/voltage and not a decay to 0v, there must be something connected to that pin that is causing this.

  • Hi Dennis,

    The glitch is quite short. The resolution in your plot is probably not high enough. So you have to use quite a high resolution on your scope to see it. I have used 2us with a trigger level of 2.8V in my tests as you see from the images in my previous post.

     

    Also, chapter 9.2.5 in the Technical Reference Manual MSPM0 L-Series 32MHz Microcontrollers states that the configuration of the pullup/pulldown resistors is independent from the peripheral function configuration. This is also supported by Figure 9-1. Superset IO Slice in the TRM.

    So I would expect the signal to stay high, i.e. at 3.3V. This is what it also does at PA10 in my setup, however with the glitch in between.

    I can provide my ELF-file for download on a LP-MSPM0L1306 evaluation board if that helps to reproduce the glitch.

     

    Best regards,

    Stefan

  • I also see it. My scope measures it at 400mV for maybe 3usec.

    I wonder if this has to do  with PA10 being High Speed (HSIO) and PA25 being Standard (SDIO).

    [Edit: Per data sheet (SLASEX0D) Sec 7.10.1, VDD-0.4 is within spec for Voh (HSIO).]

  • Thank very much Bruce for jumping in on this one.  We always super appreciate the help!!! ;)

    I'm waiting to hear back from our designers on this issue.

    In the mean time, does this glitch cause you issues with you application?

  • Yes, since we are running a communication on that pin, this can cause problems with that communication.

    Best regards,

    Stefan

  • Hi Stefan,

    I apologize for the delay in responding.  There are 2 system designers looking into this issue.  They have verified what you see and are trying to determine the root cause and if there is a workaround.  I'm hoping to hear from them again tomorrow, 2/13.

  • Hi Stefan,

    Sorry again for the delay.  It took a couple of days for our designers to run simulations and come up with a workaround.  Here are their comments as why you see this glitch.

    1. Pull-Up behaviour in Output mode (Gz=0):
      1. When the pin is actively driving, the internal pull up is disconnected, and only weak PMOS pull up (part of the Output driver) is active.
      2. The PMOS pull up is much weaker than the internal pullup resistor, so it cannot strongly maintain the voltage when the pin transitions to high impedance.
    1. Transition to high - impedance:
      1. When you clear the pin connected and PF, the pin goes in high impedance state.



      2. At this point - even the weak PMOS pull-up is no longer active and the internal pullup if enabled (in this case enabled) is reconnected.
      3. But still there is brief period where the pin is floating and the voltage is held only by the parasitic capacitance (the capacitance value may vary on each IO).

    1. Voltage Dip and Recovery
      1. During the transition to high impedance (PF and PC cleared), the weak PMOS pull-up is disabled, and the internal pull up resistor takes time to reconnect and stabilize the voltage.
      2. The parasitic capacitance discharges slightly due to the leakage currents causing voltage dip to 2.24 V
      3. Once the internal pullup is fully active, it recharges the parasitic capacitance, causing the voltage to recover to 3.3V

    The workaround which works here is keeping HiZ enabled (Z1=1) when pull-up is enabled, in that case the glitch is not seen. I have tried this out, with the same configurations but keeping HiZ enabled (Z1=1), the voltage dip is not seen.

  • Hi Dennis,

    thanks for the detailed answer.

    I have tested your workaround and found that it also works in my setup.

    However, when using pin PA10 as TX output for the UART, the glitch is still there. Keeping HiZ enabled is not possible for us, since we are trying to implement a half-duplex communication on that UART. Switching to HiZ (Z1=1) or switching the alternate function from UART to disabled still results in the glitch. Curiouly though, the glitch is only visible when data has been sent on the TX.

    Here is the code I have used. I have set the UART baudrate to 1000000 baud.

    #include "ti_msp_dl_config.h"
    
    
    __STATIC_INLINE void disableGPIO(uint32_t pincmIndex)
    {
    //    IOMUX->SECCFG.PINCM[pincmIndex] |= IOMUX_PINCM_HIZ1_ENABLE;
        IOMUX->SECCFG.PINCM[pincmIndex] &= ~(IOMUX_PINCM_PC_CONNECTED |  IOMUX_PINCM_INENA_ENABLE);
        IOMUX->SECCFG.PINCM[pincmIndex] &= ~(IOMUX_PINCM_PF_MASK);
    }
    
    
    int main(void)
    {
        uint32_t i=0;
    
        SYSCFG_DL_init();
    
        // burn some time
        while(i<4700u)
        {
            __asm volatile("NOP");
            i++;
        }
    
        DL_UART_Main_transmitData(UART_1_INST, 0xA5);
    
        while(true==DL_UART_isBusy(UART_1_INST))
        {
        }
    
        IOMUX->SECCFG.PINCM[GPIO_UART_1_IOMUX_TX] |= IOMUX_PINCM_HIZ1_ENABLE;
    
        disableGPIO(GPIO_UART_1_IOMUX_TX);
    
    
        disableGPIO(GPIO_UART_Grp_PIN_PA25_IOMUX);
    
    
        while (1) {
        }
    }
    
    void SYSCFG_DL_GPIO_init(void)
    {
        const uint8_t unusedPinIndexes[] =
        {
            IOMUX_PINCM3, IOMUX_PINCM4, IOMUX_PINCM5, IOMUX_PINCM10,
            IOMUX_PINCM12, IOMUX_PINCM16, IOMUX_PINCM17, IOMUX_PINCM18,
            IOMUX_PINCM19, IOMUX_PINCM22, IOMUX_PINCM23, IOMUX_PINCM24,
            IOMUX_PINCM25, IOMUX_PINCM27, IOMUX_PINCM1
        };
    
        for(int i = 0; i < sizeof(unusedPinIndexes)/sizeof(unusedPinIndexes[0]); i++)
        {
            DL_GPIO_initDigitalOutput(unusedPinIndexes[i]);
        }
    
        DL_GPIO_clearPins(GPIOA,
            (DL_GPIO_PIN_2 | DL_GPIO_PIN_3 | DL_GPIO_PIN_4 | DL_GPIO_PIN_9 |
            DL_GPIO_PIN_11 | DL_GPIO_PIN_15 | DL_GPIO_PIN_16 | DL_GPIO_PIN_17 |
            DL_GPIO_PIN_18 | DL_GPIO_PIN_21 | DL_GPIO_PIN_22 | DL_GPIO_PIN_23 |
            DL_GPIO_PIN_24 | DL_GPIO_PIN_26 | DL_GPIO_PIN_0));
        DL_GPIO_enableOutput(GPIOA,
            (DL_GPIO_PIN_2 | DL_GPIO_PIN_3 | DL_GPIO_PIN_4 | DL_GPIO_PIN_9 |
            DL_GPIO_PIN_11 | DL_GPIO_PIN_15 | DL_GPIO_PIN_16 | DL_GPIO_PIN_17 |
            DL_GPIO_PIN_18 | DL_GPIO_PIN_21 | DL_GPIO_PIN_22 | DL_GPIO_PIN_23 |
            DL_GPIO_PIN_24 | DL_GPIO_PIN_26 | DL_GPIO_PIN_0));
    
        DL_GPIO_initPeripheralInputFunction(
            GPIO_UART_1_IOMUX_RX, GPIO_UART_1_IOMUX_RX_FUNC);
    
        DL_GPIO_initPeripheralOutputFunctionFeatures(
             GPIO_UART_1_IOMUX_TX, GPIO_UART_1_IOMUX_TX_FUNC,
             DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_PULL_UP,
             DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_DISABLE);
    
        DL_GPIO_initDigitalOutputFeatures(GPIO_UART_Grp_PIN_PA25_IOMUX,
             DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_PULL_UP,
             DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_DISABLE);
    
        DL_GPIO_setPins(GPIO_UART_Grp_PORT, GPIO_UART_Grp_PIN_PA25_PIN);
        DL_GPIO_enableOutput(GPIO_UART_Grp_PORT, GPIO_UART_Grp_PIN_PA25_PIN);
    
    }
    
    
    static const DL_UART_Main_ClockConfig gUART_1ClockConfig_1 = {
        .clockSel    = DL_UART_MAIN_CLOCK_BUSCLK,
        .divideRatio = DL_UART_MAIN_CLOCK_DIVIDE_RATIO_1
    };
    
    static const DL_UART_Main_Config gUART_1Config_1 = {
        .mode        = DL_UART_MAIN_MODE_NORMAL,
        .direction   = DL_UART_MAIN_DIRECTION_TX_RX,
        .flowControl = DL_UART_MAIN_FLOW_CONTROL_NONE,
        .parity      = DL_UART_MAIN_PARITY_NONE,
        .wordLength  = DL_UART_MAIN_WORD_LENGTH_8_BITS,
        .stopBits    = DL_UART_MAIN_STOP_BITS_ONE
    };
    
    void SYSCFG_DL_UART_1_init(void)
    {
        DL_UART_Main_setClockConfig(UART_1_INST, (DL_UART_Main_ClockConfig *) &gUART_1ClockConfig_1);
    
        DL_UART_Main_init(UART_1_INST, (DL_UART_Main_Config *) &gUART_1Config_1);
    
        DL_UART_Main_setOversampling(UART_1_INST, DL_UART_OVERSAMPLING_RATE_16X);
        DL_UART_Main_setBaudRateDivisor(UART_1_INST, UART_1_IBRD_32_MHZ_1000000_BAUD, UART_1_FBRD_32_MHZ_1000000_BAUD);
    
        DL_UART_Main_enable(UART_1_INST);
    }
    

    Best regards,

    Stefan

  • What happens if instead of switching from PF = UART to PF zero, you set the GPIO to output to 1 and then change to PF=1 (GPIO) and follow TRM section 9.2.2 Logic High to Hi-Z Conversion page 735?

  • Hi Stefan,

    Sorry for the delayed response.  I have shared your follow up questions regarding the half-duplex use of the UART with our designers.

    Antony brings up an interesting point, but I believe whether switching from PF = UART(TX) or switching from PF = GPIO(=1), or any other peripheral driving this pin to a Hi-Z state, there is going to be some bleed off of the voltage on the pin as described above.  Keeping the internal Pull-up resistors enabled during the transition into the Hi-Z state makes sense.

    So question to Stefan - maybe I don't have a full sense of your half-duplex topology, so is this pin used for both UART TX and RX, in other words a "one-wire" type of half-duplex?  Or something else?  If so, what harm is it to leave the pull-up resistor enabled regardless of the use of the pin?

  • Hi Dennis, 

    Some things I am suspicious of:

    1.  dV/dt of the glitch down slope looks incredibly fast. About the same slope as when the UART signal transitions from high to low. Is this really achieved only by the PMOS gate being discharged? Are you sure the NMOS isn't getting a glitch energizing it?

    2.In the TI design engineers section 2.a. above, they quoted TRM page 735:When no peripheral function is selected (PF==0) the output latches are put into a reset state, causing the output NMOS and PMOS to be disabled (leaving the IO pin in a Hi-Z state with the exception of any enabled pullup/pulldown resistors). If PF is set to GPIO, I take it these output latches remain on, until the HiZ comes on?

    Just wondering looking at Figure 9-1. Superset IO Slice, the :Output Logic" DOUT path which conveys the data is independent of the Hi-Z path. If you set PF=zero, does that put a zero on the DOUT line? Using GPIO = high and then HiZ may keep the DOUT line high, so no risk of a race condition glitching the NMOS?

  • Hi Anthony, 

    I have presented these questions to our designers.

  • Hi Dennis, After Gary helped me understand the Figure 9-1. Superset IO Slice diagram a bit better, I suspect there may be peripheral registers associated with the UART TXD and RXD pins at the peripheral level which are not in the TRM. If similar to the SPI peripheral, I wonder if there is a register with an offset <20h for the UART TXD pin which may have both HIGHZ1 and HIGHZ0 bits? If so, it could feed the Hi-Z Output MUX while the UART peripheral is still connected - so no need to set PF 0 and get the glitch.

  • Hi Antony and Stefan

    From what I'm being told, there isn't a register in the UART IP that has those HIGHZ1,Z0 bits. 

    Here is a question for Stefan...

    However, when using pin PA10 as TX output for the UART, the glitch is still there. Keeping HiZ enabled is not possible for us, since we are trying to implement a half-duplex communication on that UART.
    So question to Stefan - maybe I don't have a full sense of your half-duplex topology, so is this pin used for both UART TX and RX, in other words a "one-wire" type of half-duplex?  Or something else?  If so, what harm is it to leave the pull-up resistor enabled regardless of the use of the pin?

    Sorry to ask again, but can you explain why having an internal pull-up resistor enabled while HI-Z is also enabled doesn't work for you?

  • Hi Dennis,

    Yes, it is a half-duplex communication over one wire. TX and RX are connected on both uC participating in the communication. When one uC has finished sending, it switches the UART to RX-only and the TX-pin needs to be disabled sothat the other uC and send data.

    In our application the pull-ups on the RX are always enabled. Keeping the HI-Z always enabled results in signal distortion on the UART line and in problems with the communication.

    As you requested I have tested with an external pull-up of 47.5kOhm on the TX with the code sending one byte on the UART1 as sent earlier. This doesn't change the glitch. Using a 3kOhm pull-up though, reduced the glitch a bit, but didn't solve the problem in total.

    Best regards,

    Stefan

  • Hi Stefan,

    Very interesting.  I would think the pull-up would maintain the TX pin high and eliminate the spike by preventing any pin capacitance from discharging.  But to me this almost sounds like there is something in the logic that, for a very short period of time, attempts to pull the pin low before going HI-Z.  I have updated our designers to see if they can explain.

  • Hi Dennis & Stefan, As you know in my other related posts, i would like to do a similar thing except with the SPI:

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1475464/mspm0l1306-spi-single-bidirectional-pico-poci-for-hoperf-module-interface/5695905#5695905

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1486538/mspm0l1306-peripheral-register-access---unexpected-interrupt-for-spi-registers-lower-than-0x0800h-offset

    The options for implementing fast hardware IO changing methods while retaining the selected peripheral have all been extinguished I think. And the earlier approach jumping to GPIO PF select on the fly without using the recommended PC disconnect may still cause a glitch if the change in bit pattern between PF=UART (or SPI for my case) to PF = 1 (GPIO) changes more than one bit at a time in the PF selection 6 bit pattern.

    I look forward to the response from the design team.

    Best Regards,

    Antony 

  • Hi all,

    I wanted to give you an update on this issue.  Our design engineers are quite busy at the moment and have not had an opportunity to look into this latest information.

  • Hi Stefan,

    I wanted to check with you if you are able to move forward with your project, despite of these glitches for now, or is this a "show stopper"?  I want to reconnect with our designers and let them know so they can possibly hop on this issue.

  • Hi Dennis,

    I got a workaround for the issue from the designers, who proposed to disable the power of the UART additionally to disabling the UART when switching the alternate function.

    I have verified, that this workaround works in our application and the glitch is not visible any more.

    So this solved our issue with the glitch.

    Best regards,

    Stefan