2021-08-29
Author: Pat Beirne patb@pbeirne.com
Date: 2021-07-14
[TOC]
The OrangePi-i96 is one of the least expensive SBC’s capable of running Linux. It is a member of the Linaro i96 family, and has a 40 pin connector that has been standardized by Linaro.
However, the currently shipping version of the OPi-i96 does not power up properly. This application note describes a few changes that can help get the OPi-i96 into a working and usable state.
Note: This document is written to not use the WiringPi utility, because I could not get it working on the OrangePi-i96. I wrote my own, called opio
Note: Almost all of these notes also apply to the OrangePi 2G-IOT board.
The OrangePi website has downloadable images for Ubuntu and Debian versions of the operating system. The installation instructions on the OrangePi webite will instruct you on how to create a microSD card with the operating system, and how to boot the first time.
Both of these builds expect that there is a sound system (microphone and speakers). But the OPi-i96 board is a cut-down version of the OPi-2G-IoT board, with the microphone and speaker removed.
When the OS boots the first time, it goes into installation mode and works fine. But when the system boots a 2nd time, it tries engage the ALSA sound system (which isn’t there!) and locks up.
To solve this problem, make sure that during the 1st boot up, you remove the ALSA sound system:
cd /usr/sbin
sudo mv alsactl alsactl.bak # execute this on the target OrangePi-i96
If, for some reason, you missed that opportunity, try this: remove the microSD card from the OrangePi, mount
it on a Linux computer and:
rm <mount-point>/usr/sbin/alsactl # execute this on a Linux desktop, with the sdcard mounted
After a sync
and umount
, you can replace the microSD card in the OPi-i96 and reboot. It should proceed through the boot process and be available to log into. [Strangely, after the 2nd boot, you can rename the alsactrl program back to its original name and the system boots!]
The currently shipping u-boot+kernel boots up with the microcontroller (RDA8810) in a strange state, with some GPIO pins set to operate in special-function mode, and some set into GPIO mode, and the mix doesn’t seem to match the intended functions described in the i96 spec.
This table describes the state of the 40 pin bus. Column ‘mode’ is the mode setting of the pin after boot; some of these agree with the i96 spec, some do not. The ‘(rda)’ column is the pin name according to the RDA data sheet. The ‘kernel’ column is the GPIO numbering system used by the Linux kernel. And the ‘verified’ column indicates that I verified(measured) the function of the pin in gpio mode. The ‘alt’ column indicates the special function available on this pin, using the Linux naming scheme.
If there are ‘special function’ groups that you don’t need for your project, you may use these pins as GPIO pins. For example, if you’re not using sound on the PCM group, you can recover pins 15, 17, 19 & 21 for use as general purpose pins.
verified | gpio(kernel) | gpio(rda) | alt | mode° | i96 name | pin | pin | i96 name | mode° | alt | gpio (rda) | gpio (kernel) | verified |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
GND | 1 | 2 | GND | ||||||||||
yes | gpio40 | gpio_b8 | ttyS0 | gpio | UART0_CTS | 3 | 4 | PWR_BTN_N | note 2 | ||||
yes | gpio104 | gpio_c8 | ttyS0 | ttyS0 | UART0_TX | 5 | 6 | v_rtc | 1.4V | ||||
yes | gpio103 | gpio_c7 | ttyS0 | ttyS0 | UART0_RX | 7 | 8 | SPI0_CLK | gpio | spi2 | gpio_a2 | gpio2 | yes |
yes | gpio41 | gpio_b9 | ttyS0 | gpio | UART0_RTS | 9 | 10 | SPI0_DI | gpio | spi2 | gpio_a4 | gpio4 | yes |
yes | gpio14 | gpio_a14 | ttyS1 | ttyS1 | UART1_TX | 11 | 12 | SPI0_CS | gpio | spi2 | gpio_a6 | gpio6 | yes |
yes | gpio102 | gpio_c6 | ttyS1 | ttyS1 | UART1_RX | 13 | 14 | SPI0_DO | gpio | spi2 | gpio_a3 | gpio3 | yes |
yes | gpio0 | gpio_a0 | i2c-1 | i2c-1 | I2C0_SCL | 15 | 16 | PCM_FS | pcm | pcm | gpio_a10 | gpio10 | yes |
yes | gpio1 | gpio_a1 | i2c-1 | i2c-1 | I2C0_SDA | 17 | 18 | PCM_CLK | pcm | pcm | gpio_a9 | gpio9 | yes |
yes | gpio38 | gpio_b6 | i2c-2 | i2c-2 | I2C1_SCL | 19 | 20 | PCM_D0 | pcm | pcm | gpio_a13 | gpio13 | yes |
yes | gpio39 | gpio_b7 | i2c-2 | i2c-2 | I2C1_SDA | 21 | 22 | PCM_DI | pcm | pcm | gpio_a11 | gpio11 | yes |
yes | gpio15 | gpio_a15 | ttyS1 | ttyS1 | GPIO_A | 23 | 24 | GPIO_B | lcd | lcd | gpio_a20 | gpio20 | yes |
yes | gpio56 | gpio_b24 | gpio | GPIO_C | 25 | 26 | GPIO_D | ttyS2 | ttyS2 | gpio_d2 | gpio66 | yes | |
yes | gpio67 | gpio_d3 | ttyS2 | ttyS2 | GPIO_E | 27 | 28 | GPIO_F | lcd | lcd | gpio_a22 | gpio22 | yes |
yes | gpio30 | gpio_a30 | lcd | lcd | GPIO_G | 29 | 30 | GPIO_H | lcd | lcd | gpio_a29 | gpio29 | yes |
yes | gpio28 | gpio_a28 | lcd | lcd | GPIO_I | 31 | 32 | GPIO_J | lcd | lcd | gpio_a27 | gpio27 | yes |
yes | gpio26 | gpio_a26 | lcd | lcd | GPIO_K | 33 | 34 | GPIO_L | lcd | lcd | gpio_a25 | gpio25 | yes |
2.9V | v_pad | +1v8 | 35 | 36 | SYS_DCIN | n/c | |||||||
5V(usb) | +5v | 37 | 38 | SYS_DCIN | n/c | ||||||||
GND | 39 | 40 | GND |
° NOTE: these are the default modes with this software:
function | version |
---|---|
u-boot | U-Boot 2012.04.442-rel5.0.2-g5ee06c1-dirty (Mar 18 2020 - 18:51:54) |
kernel | Linux version 3.10.62-rel5.0.2+ (Linaro) |
distribution | Ubuntu 16.04 |
NOTE 2: this pin measures 0v normally, rises to 3.8V when the power button is pushed; this appears to be the opposite of the i96 spec. The schematic indicates that it’s used as an interrupt, so this inversion probably doesn’t matter.
In order to align the bus pins with the intended function of the i96 bus, we need to make some changes. The UART1, I2C and I2S/PCM pins are configured correctly. Pins 3, 9 (uart), 8, 10,12 and 14 (spi) need to be set to ‘special-function’. And all the pins between 23 and 34 need to be set to ‘gpio’ mode. At the bottom of this file you can find a Python3 utility to restore the pins of the microproccesor to the states intended by the i96 bus.
The existing linux kernel does not give access to the pin-function control registers, but there are a couple of ways to access those registers from the linux environment:
devmem2
utility written by Jan-Derk Bakker; use apt install devmem2
This document was written using devmem2
to locate and test the control registers.
Here are the relevant registers:
Register Name | Register Address | Usage | Existing State | Desired State |
---|---|---|---|---|
IOMUX | 0x11a0.9008 | special-function/gpio select for group C | 0x7fe0.003f | 0x7fe0.003f |
IOMUX-A | 0x11a0.900c | ibid, group A | 0x0002.10fc | 0x7e52.90a0 |
IOMUX-B | 0x11a0.9010 | ibid, group B | 0x3f00.033f | 0x3f00.003f |
IOMUX-D | 0x11a0.9014 | ibid, group D | 0x0000.0010 | 0x0000.001c |
GPIO-DIR | 0x11a0.8000 | direction register for group C | ||
GPIO-DATA | 0x11a0.800c | data register for group C | ||
GPIO-A-DIR | 0x2093.0000 | direction register for group A | ||
GPIO-A-DATA | 0x2093.000c | data register for group A | ||
GPIO-B-DIR | 0x2093.1000 | direction register for group B | ||
GPIO-B-DATA | 0x2093.100c | data register for group B | ||
GPIO-D-DIR | 0x2093.2000 | direction register for group D | ||
GPIO-D-DATA | 0x2093.200c | data register for group D |
The patterns shown on the first 4 lines of this table will set the GPIO pins to align with the i96 bus specifications. And give you access to 12 general purpose GPIO pins (23-34). Note: a ‘1’ written into this register will select a pin for GPIO; a ‘0’ selects the special-function mode.
The last 8 entries are for information only. The Linux GPIO device driver /sys/class/gpio
works perfectly; there’s no need to bypass it. (The linux /dev/gpiochip does not exist in this kernel, since it’s 3.10)
For example, after the GPIO correction, to toggle pin 26 (i96-name: GPIO-D, linux-name: gpio66), simply:
cd /sys/class/gpio
echo 66 > export
cd gpio66
echo out > direction
echo 1 > value
echo 0 > value
## alternatively, use gpio or opio
opio mode 66 out
# this will also do the 'export' function and create /sys/class/gpio/gpio66
opio write 66 1
opio write 66 0
The code to restore the GPIO pins to the i96 standard is in the file gpio_fixup.py
. I recommend you install it at /usr/local/bin/gpio_fixup.py
and add it to /etc/rc.local
near the end of the boot sequence.
Be aware that if you connect ‘output’ hardware to the 40pin connector, the GPIO’s may not be set properly in the 5-20 seconds between U-Boot and running the gpio-correction code. This time can stretch even longer if the Wifi module takes time to stabilize.
If you want to be sure about the state of an output, use one of these:
Prior to setting the gpio pin as an output, these pin will be hi-impedance. Design your hardware that it operates properly in the absence of a drive-voltage.
Once the system has booted, you can set the GPIO mode on pins 3 and 9 using the opio
program: opio mode 40 out
and opio mode 41 out
.
Of course, all of the above comments apply to the current uboot. A modified version could set the other i96 pins properly, but modifying uboot is beyond my skill level.
The 2G-IOT board is very similar, except that the GPIO bits are mostly set correctly. Here is the state of the pins at power-on (using the currently shipping uboot/kernel)
opio -2 status
+-----+-----+----------+------+-+ OrgPi 2G-iot +-+------+----------+-----+-----+
| gpio| alt | i96 Name | Mode | V | Physical | V | Mode | i96 Name | alt | gpio|
+-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
| | 2.8v| V_PAD | | | 1 || 2 | | | VDD_IN | 5V | |
| 63 | SDA | I2C1.SDA | alt | ? | 3 || 4 | | | VDD_IN | 5V | |
| 62 | SCL | I2C1.SCL | alt | ? | 5 || 6 | | | GND | | |
| 56 | | GPIO.B24 | out | 0 | 7 || 8 | ? | alt | UART2.TX | | 104 |
| | | GND | | | 9 || 10 | ? | alt | UART2.RX | | 103 |
| 102 | RX | UART1.RX | alt | ? | 11 || 12 | 1 | out* | GPIO.B5 | | 37 |
| 14 | TX | UART1.TX | alt | ? | 13 || 14 | | | GND | | |
| 15 | CTS | UART1.CT | alt | ? | 15 || 16 | 0 | in* | GPIO.C5 | | 101 |
| | 2.8v| V_PAD | | | 17 || 18 | 0 | in* | GPIO.C25 | SIM | 121 |
| 4 | DI | SPI2.DI | in* | 0 | 19 || 20 | | | GND | | |
| 3 | DIO | SPI2.DIO | in* | 0 | 21 || 22 | ? | alt | UART1.RT | RTS | 16 |
| 2 | CLK | SPI2.CLK | in* | 0 | 23 || 24 | 1 | in* | SPI2.CS0 | CS0 | 5 |
| | | GND | | | 25 || 26 | 0 | in* | SPI2.CS1 | CS1 | 6 |
| 1 | | I2C2.SDA | alt | ? | 27 || 28 | ? | alt | I2C2.SCL | SCL | 0 |
| 122 | SIM | GPIO.C26 | in* | 0 | 29 || 30 | | | GND | | |
| 123 | SIM | GPIO.C27 | in* | 1 | 31 || 32 | 0 | out* | UART2.RT | RTS | 41 |
| 124 | LCD | GPIO.C28 | in* | 0 | 33 || 34 | | | GND | | |
| 125 | LCD | GPIO.C29 | in* | 0 | 35 || 36 | 0 | out* | UART2.CT | CTS | 40 |
| 126 | LCD | GPIO.C30 | in* | 0 | 37 || 38 | ? | alt | I2C3.SCL | SCL | 38 |
| | | GND | | | 39 || 40 | ? | alt | I2C3.SDA | SDA | 39 |
+-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
Note: *these pins are set to GPIO mode but do NOT have exports in /sys/class/gpioNote: *these pins are set to GPIO mode but do NOT have exports in /sys/class/gpio
If you wish to use SPI2, you will have to set the mode pins to ‘alt’; if not, you have 5 extra gpio pins already set up as inputs. Gpio pins 40 and 41 are set to outputs. I2C1, UART1, I2C2 and UART2 (tx+rx) are already set up and ready to use.
You can control the state of the pins using the opio
command line tool, documented here in this file, or here if you want to download it.
optional
The data rates on the two I2C busses seems to be a bit off. Using the current shipping build, the i2c-1 bus runs at 266kb/s, and the i2c-2 bus runs at 160k
b/s. Neither of these are frequencies called out in the I2C standard, although they will work properly with ‘400kB/s’ I2C devices.
There may be cases where you want better control over the bus speeds, and the current Linux I2C driver does not implement hooks to allow a speed change. Use the devmem2
progam to write these words.
Bus (linux name) | Pins (40 pin connector) | Register | Write |
---|---|---|---|
i2c-1 | 15 (scl), 17 (sda) | 0x2096.0000 | 0xnnn.0000 then 0xnnn.0001 |
i2c-2 | 19 (scl), 21 (sda) | 0x2097.0000 | 0xnnn.0000 then 0xnnn.0001 |
where ‘nnn’ = one of these:
The i2cdetect
program does not seem to work well on this microprocessor. If you write your own i2c scanner, it will work ok. Try this:
#!/usr/bin/env python3
import smbus
= smbus.SMBus(1) # 1 indicates /dev/i2c-1
bus
for device in range(128):
try:
bus.read_byte(device)print(hex(device))
except: # exception if read_byte fails
pass
The 2G-IOT board operates the same way.
There are 3 green LED’s located near between the camera connector and the USB-A connector. You can control them with GPIO pins, 1=lit.
Method:
cd /sys/class/gpio
echo 125 > export
cd gpio125
echo out > direction
echo 1/0 > value
# or
opio write 125 1
opio write 125 0
NOTE With the current uboot/kernel combination, the LEDS start off in an indentermined state, which is not reflected properly with the opio leds
command. Once you start using the LED’s though, they operate properly.
There is an embedded ADC converter on the SOC chip (RDA8810), but we have no access to it directly.
If you wish, you can solder a wire from the 3-pin battery connector/pads (J302) over to a spare pin on the 40 pin i96 connector, and you can measure a voltage using channel 1 of the ADC (ac1
at 0x11a0.9054). Again, the software for ADC doesn’t seem to be included in the existing Linux kernel.
To measure the voltage without a kernel driver, you can use these registers:
devmem2 0x11a09054 w 0x80000000 # write to bit 31
# triggers an ADC conversion....wait 50us
devmem2 0x11a09054 # read the lower 10 bits; bit 10 = DATA_VALID
It appears that you can connect a 1-cell LiPo battery to J302; this seems to bhe the 3 oval pads beside the micro-USB connector. I did not test this.
It appears there is only one USB bus, shared by the typeA and micro connectors
The microprocessor has 3 uarts. The datasheet numbers these uart1 (ttyS1), uart2 (ttyS2) and uart3 (ttyS0). The first two are available on the i96 connector, and the ttyS0 is the ‘debug’ serial connector, whose pins do not appear on the i96 connector. See below
If you don’t need the CTS and RTS functions of uart1 (ttyS1), then you can leave these pins in GPIO state and access them through gpio40 and gpio41 respectively. See below
The debug serial port powers up at 921600 baud. If you would prefer the standard 115200, edit /media/boot/boot.cmd
where the baud rate is set, then execute this: [verified]
mkimage -C none -A arm -T script -d /media/boot/boot.cmd /media/boot/boot.scr
Even though the ‘modem’ section of the microprocessor is not used, you must allow the modem driver to be installed. The modem chip includes the Wifi & Bluetooth functions. The microprocessor (RDA8810) will not function without the modem co-processor functioning.
Immediately after a standard boot, the Ubuntu and Debian distribution will notify you with a red Welcome to orangepi
banner. Following that, the screen text is usually a feint grey color. You can reset it to hard black with
tput sgr0
Alternatively, you can edit the offending banner file at /etc/update-motd.d/100-fs-warning
and change the last escape code from \033[37m
into \033[0m
. [verified]
There are cases where the connection between the RDA and the Wifi chip gets locked up, and the system will loop with messages like:
[170837.809875] [RDAWLAN_ERR]:<wland_sdio_send_pkt,480>: wland_sdio_flow_ctrl failed!
[170837.810791] [RDAWLAN_ERR]:<wland_proto_cdc_data,232>: set_dcmd failed status: -5
[170837.811706] [RDAWLAN_ERR]:<wland_run_escan,773>: SCAN error (-12)
One possible solution is to remove-&-reinstall the driver module. As root:
rmmod rdawfmac
modprobe rdawfmac
The default install of Ubuntu and Debian will generate a new MAC address for the Wifi device every time the system powers up. If you are running inside a home network, the DHCP server will probably assign a new IPv4 address after ever power-reboot, which can make it tricky to locate the device on your network.
[As the kernel boots, the wireless driver queries the modem for the MAC address. This processor is intended to be used in a smartphone, with a permanent battery on the modem, so it can remember its MAC address between reboots. Since we have no battery, the modem returns “invalid” and the wireless device starts up with a random IP address.]
Various of finding your i96 device on your LAN:
orangepii96
, but you can change that with nmtui
/etc/network/interfaces
….do not use nmtui
scp
a status file onto a web server somewhereAlternatively, I have re-built the Linux kernel module for the wifi so that it uses a fixed MAC address. Download it and store it on your OrangePi-i96 at /lib/modules/3.10.62-rel5.0.2+/kernel/drivers/net/wireless/rdaw80211/rdawlan/
At module-init time, it uses the first 6 bytes of the file at /data/misc/wifi/WLANMAC
as the MAC address. Make sure to put something unique into that file so that you don’t have multiple i96 boards with the same MAC address. I suggest that the first 2 bytes be 00:00, that seems to work best.
If you decide to build this kernel module yourself, the relevent flag is WLAND_MACADDR_DYNAMIC
(defined) and USE_MAC_FROM_RDA_NVRAM
(undefined)
Some people have asked about running hostapd
and changing the i96 board into an Access Point (AP). Even though the device driver seems to be written to allow it, and the driver reports AP
in its capability list, I don’t think anyone has succeeded in creating an Access Point.
If there are sections of the i96 bus special functions that you don’t need, you can recover these pins for use as GPIO pins.
For example, I do not use the i2s feature of the board, so pins 16,18,20 & 22 (i96 connector) can be converted to GPIO
Pins 16,18,20 and 22 correspond to RDA gpio_a10, gpio_a9, gpio_a13 and gpio_a11. To change these pins into GPIO, we need to write a ‘1’ into the IOMUX register for group A. The bit mask is 0b0010.1110.0000.0000 = 0x2e00, and the IOMUX register for group A is 0x11a0.900c.
devmem2 0x11a0900c
Value at address 0x11a0900c: 0x7e5290a0
# read the result and use a bit-wise OR with 0x2e00 to set the bits
devmem2 0x11a0900c w 7e52bea0
After this operation, you can access the four pins using the linux gpio mechanism at /sys/class/gpio
and address gpio10, gpio9, gpio13 and gpio11 respectively
Function Group | RDA Pins | LInux GPIO | Change to GPIO | Change to Special Function |
---|---|---|---|---|
uart2 | c7,c8 | 103,104 | *0x11a0.9008 |= 0x0000.0180 | *0x0x11a0.9008 &= 0xFFFF.FE7F |
– also uart2 | b8, b9 | 40,41 | *0x11a0.9010 |= 0x0000.0300 | *0x0x11a0.9010 &= 0xFFFF.FCFF |
uart1 | c6 | 102 | *0x11a0.9008 |= 0x0000.0040 | *0x0x11a0.9008 &= 0xFFFF.FFBF |
– also uart1 | a14 | 14 | *0x11a0.900c |= 0x0000.4000 | *0x0x11a0.900c &= 0xFFFF.BFFF |
i2c2 | a0, a1 | 0,1 | *0x11a0.900c |= 0x0000.0003 | *0x0x11a0.900c &= 0xFFFF.FFFC |
i2c3 | b6, b7 | 38,39 | *0x11a0.9010 |= 0x0000.00C0 | *0x0x11a0.9010 &= 0xFFFF.FF3F |
spi2 | a2, a3, a4, a6 | 2,3,4,6 | *0x11a0.900c |= 0x0000.005C | *0x0x11a0.900c &= 0xFFFF.FFA3 |
i2s/pcm | a9, a10, a11, a13 | 9,10,11,13 | *0x11a0.900c |= 0x0000.2E00 | *0x0x11a0.900c &= 0xFFFF.D1FF |
This chip RDA8810 does not have PWM on the GPIO pins. The fastest you can change them as outputs is at OS speeds. I wouldn’t count on anything faster than 2sec, since the Linux OS may be doing other things when you require a GPIO pin to change.
c2 = [IN] hi “boot from TF card”, low “boot from nand”
c5 = [OUT] high lights LED5
c29 = hi to light LED3
c30 = hi to light LED2
a7 = [IN] headset detect (n/a)
a17 = [IN] otg_power_enable
a5/b0/c1/c2/c3/c4 = [IN] internal solder pads to select RDA chip version
a8 = 32kHz clock out (internal connection)
a12 = i2s_d1 (not connected)
a18/19/21/23/31 = not connected
b1 = bt_sleep, connect to modem
b2 = wf_intn, connect to modem
b4 = [IN] tf_detect, low when sd card is present
b5 = connected to the plug_in pin, set to 0v in sd_card boot mode (switch U3-7)
b10-23 = connected to the camera interface
b25-29 = n/c
b30-31 = i2c bus to talk to camera & modem
c9-20 = sdcard (internal connection)
c21/22/23/24 = spi1 (not connected)
c25-28 = n/c
d4 = n/c
Special function mode:
RDA device name | i96 Bus Name | Linux device name |
---|---|---|
uart1 | UART0 | /dev/ttyS1 |
uart2 | UART1 | /dev/ttyS2 |
uart3 | n/a | /dev/ttyS0 (debug terminal; not on i96 bus) |
i2c1 | n/a | /sys/class/i2c/i2c-0 (link to modem chip; not on i96 bus) |
i2c2 | I2C0 | /sys/class/i2c/i2c-1 |
i2c3 | I2C1 | /sys/class/i2c/i2c-2 |
spi2 | SPI0 | /sys/class/spi_master TODO: verify |
i2s2 | PCM | /sys/class/pcm/pcm-1 TODO: verify |
GPIO mode:
RDA gpio driver group | IOMUX address | Linux gpio device numbers |
---|---|---|
Group C | 0x11a0.9008 | gpio96-gpio127 |
Group A | 0x11a0.900c | gpio0-gpio31 |
Group B | 0x11a0.9010 | gpio32-gpio63 |
Group D | 0x11a0.9014 | gpio64-gpio68 (there are only 5 pins) |
Write a ‘1’ into the IOMUX register to set a bit to GPIO mode. Write a ‘0’ to set the same bit to ‘special function’ See this
The actual gpio value registers are at 0x2093.0000(group a), 0x2093.1000(group b), 0x2093.2000(group d) and 0x11a08000(group c) address + 0 = “data direction register 0=output”
+ 4 set for “dir = out”
+ 8 set for “dir = in”
+ c for “read/write”
+ 10 set for “write 1”
+ 14 set for “write 0”
+ 18 gpio interrupt control reg
Other sources for OrangePi information
login orangepi/orangepi
sudo -i
edit /etc/update-motd.d/100-fs-warning
(change last escape sequence to \033[0m)
dpkg -r alsa-utils libasound2
run orangepi-config
reboot
set your timezone :
rm /etc/localtime
ln -s /usr/share/zoneinfo/America/Toronto /etc/localtime
optional
adduser <username>
usermod -a -G sudo <username>
update your system: apt update && apt upgrade
NOTE there are some wifi hotspots that refuse to DHCP/DHCLIENT but others are fine…..why?
NOTE if you go to compile the source for uboot & kernel, you’ll need to load the 32bit versions of the libstdc++6 libraries
The 2G-IOT version of this board includes a GSM tranceiver and an audio subsystem. Otherwise it is very similar to the i96 board and most of the above notes apply.
NOTE: The i2c-0 device is connected to pins 3/5 (I2C1_SDA/I2C1_SCL) on the 2Giot pin connector. It is NOT recommended to use this bus, because it is also connected to the modem chip, and is used for chip-to-chip communication. For the same reason, do not use opio to modify the operation of these pins.
The RaspberryPi and OrangePi environment uses an app simply called gpio
to control the GPIO pins. The original verion was written by Gordon Henderson as part of his WiringPi project and has been ported to work on most of the OrangePi series boards. But there is no (commonly available) version for the OrangePi-i96. Rather than port it, I decided to rewrite it in Python3. To be safe, it has a new name: opio
. It operates very similarly to the original gpio
program, with fewer features.
With opio
you can:
opio
is written in Python3, which is available on the stock Linux distribution for both the i96 and 2G-IOT boards. This of course makes it a bit slow, taking about 500ms to do anything.
The term mode is whether a pin is a GPIO or being used as its alternate function, and whether it’s an input or output. The term value means 1/0, an on these pins, that means 2.8V or 0V.
opio [-d] mode <n> [in | out | alt]
opio [-d] read <n>
opio [-d] write <n> <value>
opio [-2] [readall | readallx | exports | leds]
For the first 3 forms of the command, the
The first version sets the mode for a pin. If the mode is ‘in’ or ‘out’, the pin is set to GPIO mode and the ‘export’ is created. If the mode is set to ‘alt’, the pin is set to its alt-function mode (like i2c or uart) and the ‘export’ is deleted. You can use the -d option to prevent the export from being created or deleted.
The second version simply reads value of the pin and returns ‘1’ or ‘0’. If the pin is an ‘out’ pin, the last value written will be returned.
The third version writes a ‘1’ or a ‘0’ to the pin. If the pin is in mode ‘in’ or ‘alt’, this command will have no effect.
As a convenience, the read and write commands will automatically set the mode on the GPIO pin and create an export. So, generally, the mode command is only required if you wish to change a pin back to its `alt’ function.
The ‘readall’ returns a chart very similar to the chart created by gpio readall
original gpio program. This includes the gpio number, the i96 bus name, the pins alternate function, the current mode and value.
The ‘readallx’ returns a chart with extra information, such as the RDA pin assignments. The ‘exports’ command lists which pins have existing exports in the /sys/class/gpio folder. and the ‘leds’ command lists the state of the LED’s on board. [Note: the LEDs start up in an odd state and the ‘leds’ command will not relect the correct state until the LEDs have been manipulated]