Larry Bank Posted November 15, 2017 Posted November 15, 2017 (edited) I was chatting with @tido about ways to help the Armbian community and I came up with the idea of a common C library to access the I2C, SPI and GPIOs of all supported boards. There are of course kernel drivers to communicate with these things, but there are differences between boards that this API could help smooth out. For example, different CPUs (and boards) map the GPIO pins very differently. Projects such as WiringOP and WiringNP try to copy the Raspberry Pi library, but this is also flawed because it's based on the BCM283x GPIO numbering. What I propose is to create a set of simple functions for accessing GPIO pins using the physical pin number as a reference. On all boards, the 5V pin will be considered pin 2 and the numbering goes from there. There are also sometimes pushbuttons present on the board which are mapped to GPIO inputs. These are also covered by my API. Much of the code is already written and I will release it shortly. I'm posting this topic to get feedback and to reach out to people who might make use of this. Here is a list of the functions so far: int AIOInit(void); void AIOShutdown(void); const char * AIOGetBoardName(void); int AIOOpenI2C(int iChannel, int iAddress); int AIOOpenSPI(int iChannel, int iSpeed); int AIOCloseI2C(int iHandle); int AIOCloseSPI(int iHandle); int AIOReadI2C(int iHandle, int iRegister, unsigned char *buf, int iCount); int AIOWriteI2C(int iHandle, int iRegister, unsigned char *buf, int iCount); int AIOReadSPI(int iHandle, unsigned char *buf, int iCount); int AIOWriteSPI(int iHandle, unsigned char *buf, int iCount); int AIOReadWriteSPI(int iHandle, unsigned char *inbuf, unsigned char *outbuf, int iCount); int AIOReadButton(void); int AIOAddPin(int iPin, int iDirection); int AIORemovePin(int iPin); int AIOReadPin(int iPin); int AIOWritePin(int iPin, int iValue); Edited November 29, 2017 by Tido added Testers wanted 3 Quote
chwe Posted November 16, 2017 Posted November 16, 2017 I'm currently working on a fork of the pyA20 python library which is used quite often by people here when playing with GPIO, spi or i2c. It's not ready for public at the moment, but it will be soon. It has an automated board detection, pin naming is consistent so that you can use your python scripts on every supported board without renaming everything. And it has a 'board detection' mechanism to use the right pin mapping during the installation. 1 Quote
Larry Bank Posted November 17, 2017 Author Posted November 17, 2017 I just got the first version ready. It should work correctly with Orange Pi Zero, OPZ+2, Orange Pi One/lite and Nano Pi Duo boards. Please let me know if you want to try it and I'll add you as a developer to my gitlab repo. Once it's in good shape, I'll share it to everyone on github. 1 Quote
botfap Posted November 17, 2017 Posted November 17, 2017 I can test it out if you link me. I dont have any orange pi boards but I can try and patch for some others 0 Quote
Larry Bank Posted November 18, 2017 Author Posted November 18, 2017 It's at a good enough point that I have released it to my public github account. Please feel free to praise/criticize/fix/enhance it: https://github.com/bitbank2/ArmbianIO Thanks 0 Quote
Larry Bank Posted November 27, 2017 Author Posted November 27, 2017 I just added support for callback interrupts to the GPIO pins. This is functionality exposed by the kernel GPIO driver. What I can't find is a way to set the pull-up / pull-down resistors of the pins. Does anyone know how to do that on Allwinner boards? 0 Quote
martinayotte Posted November 27, 2017 Posted November 27, 2017 I see that you are using /sys/class/gpio to access GPIOs. But other libraries are using /dev/mem to do a "mmap" directly to SoC registers located at 0x01C20800, which is faster and allows also to access to Pn_PUL0/Pn_PUL1 registers at offset 0x1c and 0x20 respectively. Maybe you can take a look at this library : https://github.com/duxingkei33/orangepi_PC_gpio_pyH3 1 Quote
Larry Bank Posted November 27, 2017 Author Posted November 27, 2017 1 minute ago, martinayotte said: I see that you are using /sys/class/gpio to access GPIOs. But other libraries are using /dev/mem to do a "mmap" directly to SoC registers located at 0x01C20800, which is faster and allows also to access to Pn_PUL0/Pn_PUL1 registers at offset 0x1c and 0x20 respectively. Maybe you can take a look at this library : https://github.com/duxingkei33/orangepi_PC_gpio_pyH3 I know there are direct means to access GPIOs, but then I would need to write code unique to each CPU. If Armbian only supported AllWinner H3 devices, it would be an easy decision. For now, I think it's best to keep the code simpler and support all SoCs. I'm not sure where this project is headed. I don't have the time to turn it into a support-everything/do-everything library. I saw a need and I put together a simple solution. It would be great if this was given the "blessing" of Armbian and turned into a real community effort. 2 Quote
zador.blood.stained Posted November 27, 2017 Posted November 27, 2017 Also the sysfs is deprecated, so for the mainline kernel it's recommended to use libgpiod instead. 0 Quote
Larry Bank Posted November 27, 2017 Author Posted November 27, 2017 7 minutes ago, zador.blood.stained said: Also the sysfs is deprecated, so for the mainline kernel it's recommended to use libgpiod instead. Thanks for letting me know. I'll read the docs and see how easy it is to swap out the sysfs for gpiod calls. 0 Quote
Tido Posted November 28, 2017 Posted November 28, 2017 Hi, Larry patiently showed my how to use the armbianIO library to talk to the GPIO pins. While all other go for Python and compatible to RPi - this is different. This is designed native for SBC (Single Board Computer). No translation to the GPIO numbering necessary it fits 1-to-1. We have built a first show case where 3 LED show you the temperature of your SoC. I guess you can imagine yourself several scenario's where this can be very helpful. If you have some LEDs, 25min time it would be great to hear from you if it worked with your SBC To start, please look here ! Cheers Tido 1 Quote
pbezza Posted December 14, 2017 Posted December 14, 2017 Can't use this with Opi zero plus. Get this error root@orangepizeroplus:~/git/ArmbianIO# make cc -c -Wall -O2 armbianio.c armbianio.c: In function ‘GPIOThread’: armbianio.c:367:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] int iPin = (int)param; // pin number is passed in ^ armbianio.c: In function ‘AIOAddGPIOCallback’: armbianio.c:447:43: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] pthread_create(&tinfo, NULL, GPIOThread, (void *)iPin); ^ ar -rc libarmbianio.a armbianio.o ;\ sudo cp libarmbianio.a /usr/local/lib ;\ sudo cp armbianio.h /usr/local/include root@orangepizeroplus:~/git/ArmbianIO# make -f make_demo cc -c -Wall -O2 main.c cc main.o -larmbianio -lpthread -lm -o demo root@orangepizeroplus:~/git/ArmbianIO# ./demo Unrecognized board type, aborting... Problem initializing ArmbianIO library root@orangepizeroplus:~/git/ArmbianIO# 0 Quote
Larry Bank Posted December 14, 2017 Author Posted December 14, 2017 Yes, I don't own all of the boards supported by Armbian. The library needs the board name and a pin-to-GPIO table for each supported board. Perhaps you can add the necessary info. You need to add the board name (found in /run/machine.id). Then add the corresponding pin to gpio table for that board. 0 Quote
Tido Posted December 14, 2017 Posted December 14, 2017 @pbezza in your Git folder, look for: armbianio.c and open it in your favorite text-editor. The following are lists which translate pin numbers into the GPIO numbers used by the different boards. The first entry (0) is for the on-board button (if present). A -1 indicates that the pin is not available to use as a GPIO (e.g. +5V, GND, etc). The numbering normally starts with the 3.3v pin as 1 and the 5V pin as 2. The TTY header comes after the last GPIO pin and is numbered from the pin closest to the edge of the board. * each line holds exact 10 numbers * for example: // Tinkerboard static int iTinkerPins[] = {-1,-1,-1,252,-1,253,-1,17,161,-1, 160,164,184,166,-1,167,162,-1,163,257, -1,256,171,254,255,-1,251,233,234,165, -1,168,239,238,-1,185,223,224,187,-1, 188}; Please make a git push - once you have added yours - Thank you. If you are not familiar with Git Introduction to GitHub 0 Quote
pbezza Posted December 15, 2017 Posted December 15, 2017 @TidoOh........ Um Yeah, I'm really not understanding those numbers in your Tinkerboard example. I understand -1 means the pin is not available to use as a GPIO but where do I derive the other numbers from? @Larry Bank I'll look into your info this weekend as this might answer my question to Tido. 0 Quote
pbezza Posted December 16, 2017 Posted December 16, 2017 Have looked at the schematics for the zero plus but am not sure how to translate the gpio to numbers for the armbianio.c file. Any hints? 0 Quote
Tido Posted December 16, 2017 Posted December 16, 2017 If you look at my Google Docs (in the signature) 3-color-LED example, from Asus I found a very nice table. Yesterday evening I was searching this for Le Potato = fail. I found the connector in the schematics, but not the numbers as it was for the Asus Tinker Board. I then tried to Google: ARM GPIO (but now what do I looking for - registers - interrups - ??) I simply don't know Can someone give some guidance ? 0 Quote
pbezza Posted December 16, 2017 Posted December 16, 2017 With a little bit of googling, I was able to figure out GPIO assignment for the Orange Pi Zero Plus. It is identical to the Orange Pi Zero. I don't think I have rights to push to git so here is the code. // Orange Pi Zero Plus static int iOPIZPPins[] = {-1,-1,-1,12,-1,11,-1,6,198,-1, 199,1,7,0,-1,3,19,-1,18,15, -1,16,2,14,13,-1,10,-1,5,4}; // last 3 pins are TTY header 0 Quote
Larry Bank Posted December 16, 2017 Author Posted December 16, 2017 4 hours ago, pbezza said: Git novice here. Added pull request Thanks for your contribution. I'm on the road today and will add it to the master branch when I return. 0 Quote
pbezza Posted December 16, 2017 Posted December 16, 2017 4 hours ago, Larry Bank said: Thanks for your contribution. I'm on the road today and will add it to the master branch when I return. No worries. 0 Quote
TonyMac32 Posted December 16, 2017 Posted December 16, 2017 11 hours ago, Tido said: Yesterday evening I was searching this for Le Potato = fail Baylibre has been labeling all of the GPIO in the device tree. https://github.com/BayLibre/libretech-linux/blob/389b9471d865483aebc681fd3a9e20b61934c82e/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts#L216 0 Quote
Tido Posted December 17, 2017 Posted December 17, 2017 9 hours ago, TonyMac32 said: GPIO in the device tree. a well hidden place by libre, nothing in their Wiki thank you for showing me Tony. To get a picture of the list/qty, I extracted them and put it into a 'logic' order, I only count 36. Of which only 28 are on the 7J1 (40-pin header). Just as I think about it, how can they be addressed - tinker as well as OPi have up to 3-digits number if you look above. I am afraid I still got nowhere beside listing some pins and their logical place (2j3, 7j1, 9j1). I guess I am again in a one-way street or am I wrong? Spoiler 01 2J3 Header Pin3 02 2J3 Header Pin4 03 2J3 Header Pin5 04 2J3 Header Pin6 // 40-pin header is 7J1 // 01 7J1 Header Pin3 02 7J1 Header Pin5 03 7J1 Header Pin7 04 7J1 Header Pin8 05 7J1 Header Pin10 06 7J1 Header Pin11 07 7J1 Header Pin12 08 7J1 Header Pin13 09 7J1 Header Pin15 10 7J1 Header Pin16 11 7J1 Header Pin18 12 7J1 Header Pin19 13 7J1 Header Pin21 14 7J1 Header Pin22 15 7J1 Header Pin23 16 7J1 Header Pin24 17 7J1 Header Pin26 18 7J1 Header Pin27 19 7J1 Header Pin28 20 7J1 Header Pin29 21 7J1 Header Pin31 22 7J1 Header Pin32 23 7J1 Header Pin33 24 7J1 Header Pin35 25 7J1 Header Pin36 26 7J1 Header Pin37 27 7J1 Header Pin38 28 7J1 Header Pin40 9J1 Header Pin2 9J3 Switch HDMI CEC/ Total 36 Pins of 40 0 Quote
TonyMac32 Posted December 17, 2017 Posted December 17, 2017 Remember the 5V, 3.3V, and Gnd lines not being software controlled. ;-)Sent from my Pixel using Tapatalk 0 Quote
Tido Posted December 17, 2017 Posted December 17, 2017 12 are used for that, more than I thought but I counted these now :-) Nevertheless, 6 hours ago, Tido said: tinker as well as OPi have up to 3-digits number whereas in the DTS I only found the Pin-Number. I show you a picture of what I am missing here: 0 Quote
TonyMac32 Posted December 17, 2017 Posted December 17, 2017 I'm familiar, I was using GPIO to try to make the Bluetooth work on Tinker mainline. http://www.mediafire.com/file/sj8doy9vcsgg290/Amlogic_S905X_S905L_GPIO_User_Guide_V0.2-Wesion.pdfGoogle is your friend.Sent from my Pixel using Tapatalk 0 Quote
Tido Posted December 17, 2017 Posted December 17, 2017 I have already downloaded it, looked at it and again looked at it. Still no solution to what I am looking for. My conclusion: Either OPi and tinker do it different to Le Potato (Amlogic) or I simply don't know how to read these tables in that PDF. 0 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.