9 years, 3 months ago.

PullUp/PullDown on nucleos with InterruptIn

Hi,

PullUp and PullDown modes seem to be not working with InterruptIn. The following code leaves the pin floating:

InterruptIn Pull

#include "mbed.h"

InterruptIn trig(PC_5);

int main() {

    trig.mode(PullUp);

}

The PullUp works fine with DigitalIn. I could reproduce the issue both with a F411RE and a F072RB.

Am I the only one with this issue ? Is there a workaround other than using an external pull up ?

cheers

Question relating to:

Hi, I'm working with NUCLEO-F103RB and I've found similar problems using mbed-src source code. I'll try to explain what is happening:

InterruptInt trig(PC_5); 

This, setup PC_5 pin as an input floating interrupt pin. You can check gpio register CPIOC_CRL you can see that CNF5[1:0] bits are setup with value 01 (Input floating) (see section 9.2.1, page 171 of reference manual CD00171190)

trig.mode(PullUp);

This, sets bit1 of CNF5[1:0], but as input floating previously sets CNF5[1:0]=10 now you have CNF5[1:0]=11. If you check the same section 9.2.1, the manual says that now input is setup as "Reserved". In order to setup correctly, bit0 of CNF5[1:0] must be cleared. And then CNF5[1:0] = 10 (Input with pull up, pull down).

Nevertheless there is something more to do. Pull up or pull down is configured by GPIOC_ODR register bits. So if GPIOC_ODR[5] == 0 (pull down) else if GPIOC_ODR[5]==1 (pull up), so if you don't do that, probably you will have a wrong pull up setup.

I've changed manually file pinmap.c (inside mbed-src source code) in order to solve this problem. Look (see ENSURES .... comments in the lines I've added):

extracted from pinmap.c function: void pin_mode(PinName pin, PinMode mode)

        case PullUp:
        case PullDown:
            // Set pull-up / pull-down for Input mode
            if (pin_index < 8) {
                if ((gpio->CRL & (0x03 << (pin_index * 4))) == 0) { // MODE bits = Input mode
                    gpio->CRL |= (0x08 << (pin_index * 4)); // Set pull-up / pull-down
					gpio->CRL &= ~(0x08 << ((pin_index * 4)-1)); // ENSURES GPIOx_CRL.CNFx[1:0] = x0
                }
            } else {
                if ((gpio->CRH & (0x03 << ((pin_index % 8) * 4))) == 0) { // MODE bits = Input mode
                    gpio->CRH |= (0x08 << ((pin_index % 8) * 4)); // Set pull-up / pull-down
					gpio->CRH &= ~(0x08 << (((pin_index % 8) * 4)-1)); // ENSURES GPIOx_CRH.CNFx[1:0] = x0
                }
            }
                        // ENSURES GPIOx_ODR bits properly setup
			if(mode == PullUp)
				gpio->ODR |= (0x01 << (pin_index)); // Set pull-up 
			else
				gpio->ODR &= ~(0x01 << (pin_index)); // Set pull-down
            break;

I hope this could be useful.

posted by Raul Martin 24 Apr 2015

1 Answer

9 years, 3 months ago.

I've seen the issue after attaching to a function (seems like mode defaults to pulldown), so be sure to (re)set the mode after attaching to a function.

Accepted Answer

Thank you, this was my problem :)

posted by Geofrey Marcel 28 Dec 2014