Using GPIOs on the R-Pi
Pages: 1 2
Neil Fazakerley (464) 124 posts |
I’m starting this new thread so that all things R-Pi/GPIO related can be found in one place (hopefully) in future – at the moment there are odd bits and pieces scattered around various threads, but no complete picture. First of all, many thanks again to Tank for all his efforts in continuing to develop the GPIO module to cover both the R-Pi and Beagle XM/ARMini. Talking of which, I think a small bug may have crept into the R-Pi code on the latest version of the module (v0.44). I was playing around with some LED chaser code but couldn’t get any output from the R-Pi’s pins. I followed the text file instructions in the GPIO archive to the letter, but no joy. For a day or too I just assumed I must have zapped the GPIO pins somehow, probably thanks to the cheapo acrylic sweatshirt I was wearing and being too impatient to mess around with an anti-static wrist strap. Before opening my wallet and ordering a replacement card, I thought I’d throw a few alternative values at the SWIs. Sure enough the pins burst into life once I’d found the magic numbers. The problem boils down to SWI GPIO_ExpAsGPIO. The “!SWIsDetail” file states that r0=0 or r0=1 will set all lines as inputs, and r0=2 will set all lines as outputs. In fact, the reverse seems to be true. It looks as though the module code routines have become swapped or tangled for this particular SWI on R-Pi. So if you’re having trouble getting the expected output from your GPIO pins, try using 0 or 1 to set the lines as outputs, and 2 or 3 to set them as inputs. I’m now looking at a nice line of seventeen LEDs all merrily chasing each other back and forth. Motors next. |
Rick Murray (539) 13851 posts |
Off the top of my head – doesn’t the Beagle use one value to specify output and the Pi use … the opposite? |
Neil Fazakerley (464) 124 posts |
Not sure what your point is Rick.
Whereas, the SWI actually works the other way round. 0 and 1 set expansion connector pins as outputs and 2 sets them as inputs. This is the opposite of the way the SWI works on the XM, but I don’t believe Tank intended it to work that way – hence his instructions to R-Pi owners in the help text above. |
Neil Fazakerley (464) 124 posts |
By the way, for anyone looking for Tank’s GPIO control module, it’s available here and now covers both the Beagle XM/ARMini and R-Pi pretty comprehensively. |
Patrick Dunne (1708) 1 post |
I used tanks module and wrote a little basic program to turn off and on of three leds in any order I choose, Those I had to use Tanks interface to make the GPIO pins writable I only been using pi risc os for little while, But think I soon get to grips with tanks module, those I would like more help with accessing GPIO pin through machine code those |
Tank (53) 375 posts |
OOps… Just to say the pull up/down is not part of the SWI is not available on the Pi yet |
Rick Murray (539) 13851 posts |
Yeah, that’s bitten me before. The EQ/NE seem to be the wrong way around, don’t they? |
Rick Murray (539) 13851 posts |
[…]
I’m guessing it works correctly now due to Tank’s MOVNE/MOVEQ message? It is, for Tank at least, further complicated by the hardware itself behaving differently. For instance, the OMAP3 TRM (sprugn4p page 3515) says:
Meanwhile the BCM TRM (BCM2835-ARM-Peripherals page 92) says:
So as you can see, the values “0” and “1” to set input or output is opposite! |
Tank (53) 375 posts |
Yes, it should now work as per documentation. TST has caught me out a few times as well… |
Neil Fazakerley (464) 124 posts |
Many thanks for sorting that out, Tank. If anyone has a bunch of LEDs and fancies having a go at dabbling with the GPIO outputs, here’s some simple code to get you started: REM RPi 17 LED chaser test 3, 7/11/12 REM Requires GPIO module v0.46 or later ON ERROR PRINT' REPORT$" at line ";ERL: END DIM gp%(17) FOR n%=1 TO 17: READ gp%(n%): NEXT n% SYS "GPIO_EnableI2C",0: REM Enables I2C pins as GPIOs, giving 17 in total SYS "GPIO_ExpAsGPIO",2: REM Sets all GPIOs as outputs PRINT '"Chasing LEDs..." PRINT '"Escape to quit" REPEAT FOR n%=1 TO 17 SYS "GPIO_WriteData",gp%(n%),1 t%=TIME: REPEAT UNTIL TIME=t%+5 NEXT n% FOR n%=17 TO 1 STEP -1 SYS "GPIO_WriteData",gp%(n%),0 t%=TIME: REPEAT UNTIL TIME=t%+5 NEXT n% UNTIL FALSE END DATA 1,0,8,7,15,14,11,9,10,25,4,17,18,21,22,23,24 Any number of LEDs from 1 to 17 can be used, just to get something flashing. Put a 330 ohm resistor between the GPIO output line and the long lead of the LED. Connect the short lead of each LED to a common line and connect that back to the 0v terminal (pin 6) on the GPIO interface. You may need to swap the order of the GPIO leads to get a smooth ‘chase’ effect, or just rearrange the order of the GPIO numbers in the DATA statement above. |
Steve Drain (222) 1620 posts |
Mmm! Been there, done that; it’s fun, isn’t it? ;-) I found that with the right LEDs I did not need a limiting resistor. Given a bit more time Basalt will add some keywords to hide away some of the SWIs, probably of the form:
A couple of comments on your code.
could better be:
because TIME might skip the value you a trying to equal.
is more succinctly expressed as
|
Jochen Lueg (1597) 13 posts |
Thanks for the tip, Neil. I had built an interface board and managed to get all LEDs flashing except G0 and G1. Your line enabling I2C has solved this little problem – you may have guessed that I have never played around with GPIOs before. Is there any website that gives detailed instructions and tips for beginners like me? Jochen |
Neil Fazakerley (464) 124 posts |
Thanks for the code comments Steve. |
Neil Fazakerley (464) 124 posts |
I speed tested my Beagle XM toggling a GPIO output last year and got about 4MHz running flat out using Basic+assembler. REM R-Pi speed test, V2 board, Risc OS BBC Basic V, 9/11/12 SYS "GPIO_ExpAsGPIO",0 T%=TIME FORN%=1TO324000:SYS&58F81,24,1:SYS&58F81,24,0:NEXT:S%=TIME-T% PRINT "Completed in ";S%;" centisecs" g=GET END The V2 board’s 31% increase in GPIO speed is quite impressive, compared with the V1 board. |
Tank (53) 375 posts |
Niel, I forgot to mention that the GPIO_Info SWI will return a pointer to a block that contains the list of pins located on the expansion port that is tied to the board its running on. |
Tank (53) 375 posts |
I have created packages for the GPIO module, !GPIOConfig and GPIOManual. |
Jochen Lueg (1597) 13 posts |
Thanks for the manual, Tank. I’ve downloaded it but can’t figure out the file-type of the document. What program do I need to read it? All the best Jochen |
Steve Pampling (1551) 8172 posts |
“!StrongHelp” Jochen. You can also use Rick Murrays StrawHelp on Windows. |
Tank (53) 375 posts |
What he said ;) |
Jochen Lueg (1597) 13 posts |
Thanks everyone. This certainly gives me all the information I needed. GPIO, here I come. |
Neil Fazakerley (464) 124 posts |
I dusted off my old Beagle XM GPIO speed tester and adapted it for the Pi. MODE MODE: OFF ON ERROR ON: REPORT: PRINT" at line "; ERL: END gpio%=9: REM Set gpio% to the GPIO number we wish to test SYS "OS_Memory",13,&20200000,&100 TO ,,,membase%: REM 41 gpio config registers start at &0x2020000 physical PRINTTAB (10,18) "Speed test of R-Pi GPIO ";gpio%;" using Basic assembler read/write loop:"' PROCassemble SYS "GPIO_EnableI2C",0 SYS "GPIO_ExpAsGPIO",2 A%=(1<<gpio%): B%=membase% + &1C C%=(1<<gpio%): D%=membase% + &28 E%=19700000: t%=TIME CALL set_unsetGPIO% s%=TIME - t% PRINTTAB (10,28) E%;" cycles written in ";s%;" centiseconds",(E%/1000000);"MHz" SYS "GPIO_ExpAsGPIO",0 B%=membase% + &34: C%=7700000 t%=TIME CALL readGPIO% s%=TIME - t% PRINTTAB (10,32) C%;" cycles read in ";s%;" centiseconds ",(C%/1000000);"MHz"''''' END DEF PROCassemble DIM set_unsetGPIO% 100 P%=set_unsetGPIO% [OPT 0 SWI "OS_EnterOS" .more STR R0,[R1] STR R2,[R3] SUBS R4,R4,#1 BPL more SWI "OS_LeaveOS" MOV PC,R14 ] DIM readGPIO% 100 P%=readGPIO% [OPT 0 SWI "OS_EnterOS" .more LDR R0,[R1] STR R0,[R5] SUBS R2,R2,#1 BPL more SWI "OS_LeaveOS" MOV PC,R14 ] ENDPROC |
Tank (53) 375 posts |
Neil Re-writing the assembler to call via the GPIO module gives 495Khz. |
Neil Fazakerley (464) 124 posts |
Thanks Tank, it’s good to have physical confirmation. What I can’t understand is how the R-Pi can be 8x as fast as the XM on GPIO write cycles – running almost identical code on a slower processor. Is it possible Basic fits entirely inside the cache on the R-Pi but doesn’t on the XM? 19.7Mhz is very close to the theoretical maximum for pure arm code on R-Pi, apparently, max being around 21MHz. |
Chris Evans (457) 1614 posts |
I did a bit of ARM code assembler many years ago. The code above being so simple I thought I’d try and understand it, but am stumped. |
Jeffrey Lee (213) 6048 posts |
Remember that memory is often clocked many times slower than the processor. And IO devices (like the GPIO controller) may be clocked slower than memory. Processor speed rarely comes into the equation when you’re just sitting in a loop using LDR & STR to bash at noncacheable addresses. Just because your car has a fast engine, it doesn’t mean the electric windows will move any faster than your neighbours ;) |
Pages: 1 2