Restoring Digital I/O capability after using pins with register level flexPWM

DrM

Well-known member
Hi,

After programming the flexPWM at the register level, what is needed to return the pins to being available for digital read and write?

I tried pinMode() and digitalWrite() or digitalRead(), but to no avail.

Thank you
 
Hi,

After programming the flexPWM at the register level, what is needed to return the pins to being available for digital read and write?

I tried pinMode() and digitalWrite() or digitalRead(), but to no avail.

Thank you
So im guessing you would need to set the MUX on the pin back to standard io.

You will need to know what bank you are using and the pin.

IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_00 =

The different configurations for the pins are in the datasheet

Screenshot_20250529_092231_Dropbox.jpg
 
It
So im guessing you would need to set the MUX on the pin back to standard io.

It looks like that happens in pinMode() and digitalWrite() in digital.c.

Code:
    p = digital_pin_to_info_PGM + pin;
    if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) {
        *(p->reg + 1) |= p->mask; // TODO: atomic
        if (mode == OUTPUT) {
            *(p->pad) = IOMUXC_PAD_DSE(7);
        } else { // OUTPUT_OPENDRAIN
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_ODE;
        }
    } else {
        *(p->reg + 1) &= ~(p->mask); // TODO: atomic
        if (mode == INPUT) {
            *(p->pad) = IOMUXC_PAD_DSE(7);
        } else if (mode == INPUT_PULLUP) {
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;
        } else if (mode == INPUT_PULLDOWN) {
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(0) | IOMUXC_PAD_HYS;
        } else { // INPUT_DISABLE
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_HYS;
        }
    }
    *(p->mux) = 5 | 0x10;

And, I recall from another thread, that after using analogwriteFrequency() and analogWrite(), that normal gpio functionality is restored by calling pinMode() and digitalWrite()

So, I tried calling those, and the pins are still not functioning as digital i/o pins.

Is there a place in the teensy4 package code where the digital i/o pins are setup from scratch?
 
It


It looks like that happens in pinMode() and digitalWrite() in digital.c.

Code:
    p = digital_pin_to_info_PGM + pin;
    if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) {
        *(p->reg + 1) |= p->mask; // TODO: atomic
        if (mode == OUTPUT) {
            *(p->pad) = IOMUXC_PAD_DSE(7);
        } else { // OUTPUT_OPENDRAIN
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_ODE;
        }
    } else {
        *(p->reg + 1) &= ~(p->mask); // TODO: atomic
        if (mode == INPUT) {
            *(p->pad) = IOMUXC_PAD_DSE(7);
        } else if (mode == INPUT_PULLUP) {
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;
        } else if (mode == INPUT_PULLDOWN) {
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(0) | IOMUXC_PAD_HYS;
        } else { // INPUT_DISABLE
            *(p->pad) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_HYS;
        }
    }
    *(p->mux) = 5 | 0x10;

And, I recall from another thread, that after using analogwriteFrequency() and analogWrite(), that normal gpio functionality is restored by calling pinMode() and digitalWrite()

So, I tried calling those, and the pins are still not functioning as digital i/o pins.

Is there a place in the teensy4 package code where the digital i/o pins are setup from scratch?

Sorry I didn't realise that. Will need someone more knowledgeable to answer that then.
 
Usually pinMode() should be enough if the pins were configured as FlexIO.

There are some unusual cases. Libraries like OctoWS2811 which use DMA to the GPIO registers switch pins from fast-but-no-DMA GPIO5-9 to slow-DMA-friendly GPIO1-4. Calling pinMode() doesn't change fast vs slow GPIO, which is configured in startup.c.

Hard to imagine you're hitting one of the really unusual cases, since FlexIO pretty much only needs a different mux setting.
 
Hard to imagine you're hitting one of the really unusual cases, since FlexIO pretty much only needs a different mux setting.

Hi Paul,

I'll attach the code here. It is continued from our earlier question, except it seems to be working.

A minimum demonstration might go something like this.

Code:
define NBUFFER 2048
uint16_t buffer[NBUFFER]

unsigned int donothing_counter = 0;
void donothing()
{
    donothing_counter++;
    Serial.println("doing nothing")
}

// do this stuff in setup

pinMode(4,OUTPUT);
digitalWrite(4,LOW);

pinMode(5,OUTPUT);
digitalWrite(5,LOW);

pinMode(6,OUTPUT);
digitalWrite(6,LOW);

pinMode(10,OUTPUT);
digitalWrite(10,LOW);

SPISettings spi_settings( 30000000, MSBFIRST, SPI_MODE0);   // 30 MHz, reads 1.5usecs/word including CNVST

SPI.begin();
SPI.beginTransaction(spi_settings);

// do this stuff in loop or main or whatever

if (pwm_lccd_setup( 0.01, 1E-6, 0.01, buffer, 0.01, 3, buffer, NBUFFER, donothing))
{
    pwm_lccd_start();
    
    while (donothing_counter<3)
    {
        sleep(1);
    }
    
    pwm_lcc_stop();   // maybe not necessary

    pwm_lcc_done();

}

pinMode(4,OUTPUT)
pinMode(3,INPUT)   // tie these together with a jumper

while(1) {

    digitalWrite( 4, HIGH);
    delay(1000)
    Serial.println(digitalRead(3));

    digitalWrite( 4, LOW);
    delay(1000)
    Serial.println(digitalRead(3));
}
 
Here are the codes
 

Attachments

  • tcd1304_flexpwm.cpp
    27.4 KB · Views: 132
  • tcd1304_flexpwm.h
    1.3 KB · Views: 125
Here are the codes

This is quite a lot of code, but it doesn't look like a complete program. I don't see a setup() or loop() function. Sorry, I really don't have time to review large code that I can't run on actual hardware.

If the issue is as simple as configuring the pin to FlexIO and then calling pinMode() and digitalWrite(), that ought to be achievable in a fairly small single page of code that I (or anyone else) can just copy into Arduino IDE and upload to a Teensy to reproduce the problem.
 
This is quite a lot of code, but it doesn't look like a complete program. I don't see a setup() or loop() function. Sorry, I really don't have time to review large code that I can't run on actual hardware.

If the issue is as simple as configuring the pin to FlexIO and then calling pinMode() and digitalWrite(), that ought to be achievable in a fairly small single page of code that I (or anyone else) can just copy into Arduino IDE and upload to a Teensy to reproduce the problem.
Well that is pretty much the code snippet that I suggested.

But i will try to put together something like that with setup and loop, and post it
 
Back
Top