Why LED1 and LED3 are always off when i use FIOPIN

I am using a mbed board(which uses microcontroller LPC1768). In mbed, p1.18, p1.20, p1.21, p1.23 are connected to LED1, LED2, LED3 and LED4 on the board respectively.

Follow the code, It set the p1.18, p1.20, p1.21, p1.23 as output first, then LED1, LED2, LED3 and LED4 should be on, after a while, these four LEDs should be off.

However, when I download the program to the mbed, LED2 and LED4 are on and off, but the LED1 and LED3 are always off.

Why LED1 and LED3 are always off?

#include "LPC17xx.h"                    // Device header
void delay()
{
    for(int i = 0; i < 15000000; i++){;}
}

int main()
{
    LPC_GPIO1->FIODIR |= 1 << 18;
    LPC_GPIO1->FIODIR |= 1 << 20;
    LPC_GPIO1->FIODIR |= 1 << 21;
    LPC_GPIO1->FIODIR |= 1 << 23;
    
    while(1)
    {
            //led3 cannot be illuminated. Cannot find reason
            LPC_GPIO1->FIOPIN |= 1 << 18;
            LPC_GPIO1->FIOPIN |= 1 << 20;
            LPC_GPIO1->FIOPIN |= 1 << 21;
            LPC_GPIO1->FIOPIN |= 1 << 23;
            delay();
            LPC_GPIO1->FIOPIN &= ~(1 << 18);
            LPC_GPIO1->FIOPIN &= ~(1 << 20);
            LPC_GPIO1->FIOPIN &= ~(1 << 21);
            LPC_GPIO1->FIOPIN &= ~(1 << 23);
            delay();
    }
}

Hello Wang,

It’s a very weird behaviour. I tried to use bit-banding but the result was same. Then I tried to swap some lines. As a result some other LEDs did not blink :

...
    LPC_GPIO1->FIOPIN &= ~(1 << 20);
    LPC_GPIO1->FIOPIN &= ~(1 << 18);
    LPC_GPIO1->FIOPIN &= ~(1 << 23);
    LPC_GPIO1->FIOPIN &= ~(1 << 21);
...

When I inserted some dummy instructions as below, it suddenly worked:

...
volatile char c;
...
while(1) {
...
    LPC_GPIO1->FIOPIN &= ~(1 << 18);
    c = 0;
    LPC_GPIO1->FIOPIN &= ~(1 << 20);
    c = 0;
    LPC_GPIO1->FIOPIN &= ~(1 << 21);
    c = 0;
    LPC_GPIO1->FIOPIN &= ~(1 << 23);
    c = 0;
    delay();
}

Then I tried to build the initial code with Mbed OS 2 and it worked correctly.

I hope someone from Team Mbed can explain/fix this Mbed OS 6 issue.

Best regards, Zoltan

1 Like

I also try to simulate this program on keil uvision5. I compiled the program using keil Compiler ‘V5.06 update 6 (build 750)’, optimiztion set to -O0. In simulation, it works well, the corresponding value of LED1 and LED3 in FIOPIN register are on and off. But after download the program to mbed, it cannot work correctly, LED1 and LED3 still cannot blink.
But everytime I create a new uvision project and paste the code to the new project, using v5.06 compiler and set the optimization to -O0, it works well, all LEDs blink. However, when i add some new lines to the code, and then compile, LED1 and LED3 cannot blink again… It’s weird.

I searched this problem on Internet. Someone said using FIOPIN to change the status of the GPIO is not recommended, because it will cause undesired or unexpected result. But I don’t know why?

Hello Wang,

In the code below first a variable is modified step by step and then the FIOPIN register is set in a single assignment. It’s amazing that in this case all LEDs blink correctly:

#include "mbed.h"

void delay()
{
    for(volatile int i = 0; i < 10000000; i++){}
}

int main()
{
    LPC_GPIO1->FIODIR |= 1 << 18;
    LPC_GPIO1->FIODIR |= 1 << 20;
    LPC_GPIO1->FIODIR |= 1 << 21;
    LPC_GPIO1->FIODIR |= 1 << 23;

    uint32_t leds = LPC_GPIO1->FIOPIN;

    while(1)
    {
            leds |= 1 << 18;
            leds |= 1 << 20;
            leds |= 1 << 21;
            leds |= 1 << 23;
            LPC_GPIO1->FIOPIN = leds;
            delay();
            leds &= ~(1 << 18);
            leds &= ~(1 << 20);
            leds &= ~(1 << 21);
            leds &= ~(1 << 23);
            LPC_GPIO1->FIOPIN = leds;
            delay();
    }
}

Best regards, Zoltan