Pull-ups on Raspberry Pi 3B+
Dave Higton (1515) 3526 posts |
Does the GPIO module allow setting GPIO to input with pull-up on a 3B+? I’ve been reading the section of the BCM2837 peripherals data sheet for GPIO. It looks like a really strange device. You can have pull-ups, or you can have pull-downs, but you can’t have both. And the way to set them is truly bizarre. |
Andrew Conroy (370) 740 posts |
I’m failing to set pull-ups on a 3B+ or Zero (don’t have anything else to hand to test on). |
Chris Hall (132) 3554 posts |
My recollection is that the power on status is pre-set (some are pull up, some are pull down and I2C are physical pull up on the PCB). That a binary blob can set them differently but not from power on. I never managed to set them in software but the main reason I didn’t pursue that was that I needed certain GPIOs to be either pulled up or down from power on and that can’t be changed AIUI. |
Andrew Conroy (370) 740 posts |
I think at start up “the first 8 GPIO are pulled up, the rest are pulled down”, but that’s not clear if it’s first 8 numerically or physically (from which end?). They should then be able to be changed in software. Has anyone successfully set internal pull-up or -down resistors on the Pi? |
Steve Drain (222) 1620 posts |
Back in 2012 (so long ago), before the GPIO module, I wrote my MCPIO module. This was targeted at the MCP23017 IIC chip, but also provided for an 8-bit port on the Pi itself. I had a SWI to set the ‘Polarity’ of ports – the pull-ups – and as far as I can recall this worked. That was with the original Pis, though. |
Chris Hall (132) 3554 posts |
think at start up “the first 8 GPIO are pulled up, the rest are pulled down”, Yes GPIO 0 – GPIO 7 are pulled up, of which GPIO 2 (IIC SDA) and GPIO 3 (IIC SCL) have physical pull up resistors) and GPIO 8 – 27 are pulled down – in each case by about 50k. The internal chip pull up/downs can be changed in software but not until the chip has powered up. Has anyone successfully set internal pull-up or -down resistors on the Pi? Yes (I think), with Sprow’s help. A binary blob is put next to start.elf that requires magic incarnations. |
Andrew Conroy (370) 740 posts |
Thanks for clearing that up.
Let me rephrase that – Has anyone successfully set internal pull-up or -down resistors on the Pi using the current GPIO module SWIs as per their documentation? |
Andrew Conroy (370) 740 posts |
I’ve just confirmed that connecting a switch between GPIO 4 & GND reads HIGH when open and LOW when closed, whereas a switch between GPIO 17 & GND reads LOW when open or closed. Using GPIO_WriteMode with bits 5 & 6 set in R1 makes no difference to this. Is this a bug in the GPIO module? I’m using RISC OS 5.24 and 5.27 with GPIO 1.00 on a Pi 3B+, Zero and original Pi 1 |
Steve Drain (222) 1620 posts |
I remember that working out how to program it was quite tricky, and that there had to be a delay between enable and set of the pull state. I have had a look at one version of the source of the GPIO module – I do not read it easily – and I do not see the delay. That by no means says it is not there, but is a delay required for the IO of boards other than the Pi? At this interval it is all a bit hazy so I may be miles off track. ;-) |
Dave Higton (1515) 3526 posts |
The source code for the GPIO module is available as part of the source for RISC OS as a whole, i.e. via git or as a tarball. I’m decompressing the RasPi tarball at the mo, although I won’t be looking at it tonight. |
Tristan M. (2946) 1039 posts |
I wrote the ROGPIO library a few years back. It doesn’t do things the RISC OS way. It’s just a library that directly talks to the BCMxxxx GPIO hardware. It may be an unusual bit of hardware, but the GPIO hardware is very well laid out and practical. I was honestly impressed. I think the top one on this page has everything. The source is pretty simple. Maybe there’s something in it that could help with the pullup issue. http://members.dodo.com.au/~izabellion1/librogpio.html e: I looked at my source. It jogged a memory. I was confused about a 150 cycle delay being required. IIRC the GPIO hardware does that, so it just takes 150 cycles before it’s responsive again. Please note this is just a recollection. Back earlier, did I see something about not being able to set a pullup and a pulldown? Surely not on the same pin. Nice way to make a small heater. |
Dave Higton (1515) 3526 posts |
Well, I’ve looked at the code. I find it utterly impenetrable. I looked at the BCM2835 peripherals doc, and I think I understand it better now. You set the pin up/down control register, then wait for (at least) 150 cycles (cycles of what?), then enable the clock line to the chosen GPIO line, then wait 150 cycles again, then clear the pull up/down control register, then disable the clock line to the chosen GPIO pin. (Those last two actions look to me like they ought to be in the opposite order, because it looks like there’s a chance that the pull up/down might be disabled, but that’s what the document says.) I notice that the number for the delay in the source code is commented as “guess”. I withdraw my comment about not being able to set a pullup and a pulldown. I misunderstood what the document says. I initially thought it was a global setting. I hadn’t understood this bizarre ritual that you have to go through to set the pulls. |
Steve Drain (222) 1620 posts |
Did you have a look at mine? The BASIC assembler source is with the module linked above.
I assumed processor clock cycles, so I had a sub routine for a countdown loop from 30. This was slightly more than necessary, because of the entry and exit instructions. I have now had a look at the last GPIO module source, 1.00 31 Mar 2018. I still cannot see anything accounting for:
;-) |
Rick Murray (539) 13840 posts |
wait for (at least) 150 cycles (cycles of what?) That’s ridiculous. Wouldn’t it be better to talk in terms of actual required delay time, like X nanoseconds? What happens if the processor dual issues so a countdown loop takes less time than expected? What happens if the user is overclocking? What happens when the next incarnation comes out that runs 33% faster? How long, therefore, is a clock cycle, or is the 150 simply “a bodge that seems to work on this one machine”? Because surely we know the tears that will in time follow…? |
Steve Drain (222) 1620 posts |
What if the cycles are required for an internal processor routine to complete and 150 is a round figure to cover any future changes to that? I have ‘?129’ against my subroutine, but I cannot remember why, now. Perhaps I was testing how few cycles were actually required? |
Dave Higton (1515) 3526 posts |
Thanks, Steve, but no, I didn’t. I’m not trying to find some code that works; I don’t think I need any more help to understand the requirements that the document sets out. I want to understand why the existing code appears not to work. So I have to be able to follow the existing code.
So did I, but cycles of which clock? I don’t know whether the GPIO module’s clock always runs at the same speed as the CPU’s clock. To compound the question, I can see that some (all?) GPIO register contents are lost in some power-down state(s), but the pullup/pulldown states are remembered centrally, so the relevant clock may not be the GPIO clock anyway. But I’m sure it’s not of first order importance anyway, so long as the wait is at least long enough. It must be exceptionally rare to be altering the parameters of pullups and pulldowns dynamically. Normally one just sets them up and that’s the way they stay until the machine is switched off.
Very unlikely. It’s a number of clock cycles, and clocks can be at different frequencies. The figure of 150 is from the chip manufacturer’s data sheet, which is available to us all. Those of you who have ever been involved in IC design (I have) will know that crossing clock domains is considered to be a Very Big Deal, involving very careful resynchronisation, which causes delays of some number of clock cycles. |
Dave Higton (1515) 3526 posts |
I have an app that I used on a BeagleBoard for a while, that used three GPIO lines as inputs. I changed it so it used GPIO 17, 18 and 19, and ran it on my RasPi 3B+. It doesn’t appear to pull up any of the three pins. Since no-one has claimed to have successfully set pull-ups on a Raspberry Pi using the GPIO module, it appears that I need to file a bug. |
Dave Higton (1515) 3526 posts |
Ticket #490. |
Steve Drain (222) 1620 posts |
Nor did I think that. I was rather hoping that you would not say “I find it utterly impenetrable.” and maybe find something you had not thought of. ;-) One thing that I did, but cannot now justify, is execute the “bizarre ritual” with interrupts off. |
Dave Higton (1515) 3526 posts |
I may have found another bug. I just tried to run my app on an old RasPi board (which model is it? Full size SD card, Ethernet on board, 26 way expansion connector) using GPIO lines 17, 18 and 21, which are shown on the schematic as going to P1 pins 11, 12 and 13; only to find that GPIO21 cannot be set as GPIO. The reference in the source code (HAL.HAL_BCM2835.s.GPIO) is given as http://elinux.org/RPi_BCM2835_GPIOs which shows GPIO17 and 18 in bold, GPIO21 not on bold, but a few columns to the right it is shown as connected to P1 pin 21. This paragraph will probably only make sense if you look at the source code and follow the reference.
I would be very worried about executing the last two steps, in the order given in the manufacturer’s data sheet, with interrupts on. Think about it:
Those look to me like correct conditions to disable the pullup. What does anyone else think? |
Dave Higton (1515) 3526 posts |
Steve: your MCPIOMod seems to just error out with “SWI &2B returned a bad error pointer”. I notice it was written in 2012. I haven’t got far yet in working out what might be wrong. |
Dave Higton (1515) 3526 posts |
Steve: missing ALIGN directive, so the error block wasn’t word aligned. I still can’t get it to return anything other than R1 = -1 in the call to XOS_Hardware. New (not surprising) or old hardware. |
Steve Drain (222) 1620 posts |
The first Pis had pin 27 instead of pin 21, which was changed at revision 1. This has to be accounted for.
I obviously did, but probably got a hint from somewhere. ;-)
The module only accepts revsions 0 and 1, and will be attempting to provide an informative error. Something is going wrong there. ;-( |
Steve Drain (222) 1620 posts |
Thanks. I probably never reached that error at that time, which is no excuse. |
Steve Drain (222) 1620 posts |
Something does not look quite right there; the -1 should be accepted as the end of the enumeration, shouldn’t it? Trying to debug a rather specialised module at this distance in time it not so much fun. I only really offered it for the source. Still, if we are to proceed, see what happens if you omit the -1 check. I cannot do this myself as I do not have the hardware set up these days. |