ESP32-SBC-FabGL How to work with the expander module GPIOs from FabGL library and apps

ESP32-SBC-FabLG has CH32V003 expander which adds to it GPIO, I2C and SPI functionality.

In this post I will show you how you can work with the GPIO from the PC Emulator application and drive the GPIOs with QBASIC and TURBO PASCAL 7.0

You need to install our fork of FabGL library to your arduino and remove other FabGL libraries as they will interference (we have PR to original FabGL but it takes time to be merged), once/if our merge is accepted you will be able to do same with the original FabGL library, but right now this is not possible.

Compile and upload PCEmulator.ino from Examples-FabGL-VGA to ESP32-SBC-FabGL board.

Once the example is programmed and started you have to choose this setup:

you will have to connect to WiFi to may download the disk image for the first time.

Now you have to add the BASIC and TurboPascal code.

Download them then power off the ESP32-SBC-FabGL remove the SD card and add the files to it following this procedure:

  1. Put the SD-card in SD card reader and attach to PC
  2. Open the SD-card foler and in terminal execute: $ gnome-disk-image-mounter –writable hd20_DOSDEV.img
  3. You will see new disc mounted and you can write in it the files you download
  4. Unmount the disc
  5. Eject the SD card
  6. Put it back to ESP32-SBC-FabGL

GPIOs are accessable through these ports:

0xF0 – if reads as zero there is no expander, if reads as non zero there is expander. To check the Major and Minor revision of CH32 firmware read 0xFF and 0xFE

0xF1 – GPIO select, when you write value from 0 to 7 you select the corresponding GPIO, the UEXT connector signals are as follows: UEXT.1 = 3.3V; UEXT.2 = GND; UEXT.3 = GPIO0; UEXT.4 = GPIO1; UEXT.5 = GPIO2; UEXT.6 = GPIO3; UEXT.7 = GPIO4; UEXT.8 = GPIO5; UEXT.9 = GPIO6; UEXT.10 = GPIO7;

Note that GPIO3 and GPIO4 alternative function is I2C and they have 2K pullups to +3.3V, this makes them not quite good for GPIO function as when you set one the other will be also set parasitely throught the pullups and vice versa, so we do not recommend them to be used as normal GPIOs but only as I2C.

0xF2 – GPIO config, if GPIO is selected by writing in 0XF1 you can config it by writing 1 in Bit0 as input or as output if you write 0 in Bit0. If Bit0 is 1 you can additionally config the GPIO with pullup if you write 1 to Bit1 or with pulldown if you write 0 to Bit1. Example: write 0x00 to 0xF2 will configure the selected port as OUTPUT, write 0x03 to 0xF2 will configure the selected port as INPUT with Pullup.

0xF3 – GPIO read / write. If the GPIO is configured as Input and you read 0xF3 it will return 0 if the level is low and 1 if the level is high. If the GPIO is configured as Output writing 1 to 0XF3 will set it high and writing 0 will set it low.

Here is the BASIC code for blinking LED on GPIO 6

REM QBASIC program to control CH32V003 I/O expander inside PC Emulator

DECLARE FUNCTION HexByte$ (I)
DECLARE FUNCTION INT$ (I, L)
DECLARE FUNCTION ch32Available ()
DECLARE FUNCTION ch32VersionMinor ()
DECLARE FUNCTION ch32VersionMajor ()
DECLARE SUB gpioSelect (gpio)
DECLARE SUB gpioConfig (cfg)
DECLARE SUB gpioSet (level)
DECLARE FUNCTION gpioGet ()

CLS

REM check for I/O available
IF ch32Available = 0 THEN
  PRINT "CH32V003 expander not available on this board!"
  END
END IF

PRINT "CH32V003 expander firmware version "; INT$(ch32VersionMajor, 0); "."; INT$(ch32VersionMinor, 0); " found"

PRINT "Configure GPIO 6 as input pull-down"
gpioSelect (6)
gpioConfig (1)

PRINT "Configure GPIO 7 as output"
gpioSelect (7)
gpioConfig (0)

PRINT "Press any key to stop"

LOCATE 10, 1
WHILE LEN(INKEY$) = 0
  gpioSet (1)
  t = TIMER
  WHILE TIMER - t < 1: WEND
 
  gpioSet (0)
  t = TIMER
  WHILE TIMER - t < 1: WEND
WEND

FUNCTION HexByte$ (I)
  HexByte$ = RIGHT$("00" + HEX$(I), 2)
END FUNCTION

FUNCTION INT$ (I, L)
  R$ = LTRIM$(STR$(I))
  IF L <> 0 THEN
    R$ = RIGHT$(STRING$(L, " ") + R$, L)
  END IF
  INT$ = R$
END FUNCTION

FUNCTION ch32Available
  ch32Available = (INP(&HF0) AND 1)
END FUNCTION

FUNCTION ch32VersionMinor
  ch32VersionMinor = INP(&HFE)
END FUNCTION

FUNCTION ch32VersionMajor
  ch32VersionMajor = INP(&HFF)
END FUNCTION

SUB gpioSelect (gpio)
  OUT &HF1, gpio
END SUB

SUB gpioConfig (cfg)
  OUT &HF2, cfg
END SUB

FUNCTION gpioGet
  gpioGet = INP(&HF3)
END FUNCTION

SUB gpioSet (level)
  OUT &HF3, level
END SUB

Running this code in QBASIC will blink the LED

Similar code can be written in Turbo Pascal 7.0 which is available on the ‘disk’:

program CH32GPIO;
const input = true;
      output = false;
      pullup = true;
      pulldown = false;
      high = true;
      low = false;

function ch32Available: integer;
begin
  ch32Available := port[$F0];
end;

function ch32Version: string;
  var sa,si: string;
begin
  str(port[$FF],sa);
  str(port[$FE],si);
  ch32Version := sa+'.'+si;
end;

procedure ch32GPIOselect( gpio: integer);
begin
  if (gpio > 0) and (gpio < 8) then
    port[$F1] := gpio;
end;

procedure ch32GPIOconfig( inout, pullup: boolean);
begin
  port[$F2] := integer(inout) + integer(pullup) * 2;
end;

procedure ch32GPIOset(level: boolean);
begin
  port[$F3] := integer(level);
end;

function ch32GPIOget: boolean;
begin
  ch32GPIOget := boolean(port[$F3]);
end;

BEGIN
  if (ch32Available = 0) then
    begin
      writeln('CH32 Expander not found')
    end
  else
    begin
      writeln ('CH32 expander firmware version '+ ch32Version + ' found');
      writeln('GPIO 6 = Input');
      ch32GPIOselect(6);
      ch32GPIOconfig(input, pullup);
      writeln('GPIO 7 = Output');
      ch32GPIOselect(7);
      ch32GPIOconfig(output, pullup);
      writeln('GPIO 7 = High');
      ch32GPIOset(high);
      writeln('GPIO 7 = Low');
      ch32GPIOset(low);
    end;
END.

The extra benefit of using Turbo Pascal is that you have debugger with Step by Step execution 😉

Tomorrow I will show you how you can access I2C Nunchuk from QBASIC and TURBO PASCAL 7.0

Working with A20 OLinuXino or SOM GPIOs when using new Armbian based A20 universal Linux image

a20

A20 GPIO ports are 32 bit registers listed in alphabetical order PA, PB, PC, PD, PE, PF, PG, PH, PI.

In Armbian GPIO ports are numbered from 0 to 287 corresponding from PA0 to PI31.

The GPIO number is calculating using this formula:

gpioNumber = (Port Letter - 'A') * 32 + pinNumber

 

For instance GREEN STATUS LED on A20-OLinuXino-LIME2 is connected to port PH2. This will correspond to GPIO number:

('H'-'A' = 7) * 32 + 2 = 226

 

All GPIO operations in shell should be made as super user. First we have to register the gpio in the Linux Kernel with this command:

sudo echo 226 > /sys/class/gpio/export

 

to check if we did registered this gpio successfully we use ls command:

sudo ls /sys/class/gpio

 

If you did everything correctly you will see gpio226 listed.

Then you have to specify what will be this GPIO input or output. This is done with writing “in” or “out” in gpioxx direction directory. In this case we want to drive the STATUS LED so we have to make it output:

sudo echo out > /sys/class/gpio/gpio226/direction

 

Once we set the GPIO as output we can write 1 or 0 to it’s value and this will make GPIO port to supply 3.3V when 1 is written or 0V when 0 is written.

To switch the LED on we have to write 1:

sudo echo 1 > /sys/class/gpio/gpio226/value

 

Yay the green LED is now lighting. If we want to switch it off we have to write 0:

sudo echo 0 > /sys/class/gpio/gpio226/value

 

To read the GPIO state it has to be set as input first with the command:

sudo echo in > /sys/class/gpio/gpioXXX/direction

 

where XXX is GPIO port number calculated as described above. Then to read the GPIO state you use this command:

sudo cat /sys/class/gpio/gpioXXX/value

the result will be 0 if the GPIO voltage is between 0.0-1.0V and 1 if the voltage is between 2.3-3.3V. If the voltage on the GPIO is between 1.0 and 2.3V the attempt to read will return randomly value 0 or 1.

Be careful when playing with the GPIO ports, some of them are wired to important peripherials like LCD, Ethernet, USB, SATA etc and writing bad values may break the functionality or even damage the board. Test your knowledge on GPIOs which are not connected to anything is best approach.

We are prepare now new version of PyA20 Python module which will add access to GPIO, SPI, I2C, Serial resources of A20 directly from Python code to work with the new universal A20 Armbian Linux image.

EDIT 2019-01-25 14:24:

We got question how fast is the access to the GPIOs via shell. Sure it’s not fast and made just for slow processes like switching on and off relays, or polling status of buttons or sensors which do not change often their state. Running this code below:

nano toggle_led_lime2.sh

 

Enter inside the file this code:

#!/bin/bash
# the lime2 led is PH2 - 32*(8-1) + 2 = 226

echo 226 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio226/direction
while [ 1 -eq 1 ]
do
echo 1 > /sys/class/gpio/gpio226/value
echo 0 > /sys/class/gpio/gpio226/value
done

 

Save and exit, then make executable and run

chmod +x toggle_led_lime2.sh
./toggle_led_lime2.sh

 

We can see square wave with oscilloscope on PH2 with frequency between 3 and 4 kHz. i.e. pulses with high state 125-150uS and low state 125-150uS.

Shell is slow, if we write same code in C:

#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#define PH2        226    // (32 * 7) + 2
#define GPIO_PATH  "/sys/class/gpio/gpio226/value"

int main() {
    int ret;
    int fd;

    fd = open(GPIO_PATH, O_RDWR);
    if (fd < 0)
        return errno;

    while(1) {
        ret = write(fd, "1", 1);
        ret = write(fd, "0", 1);
    }

    return 0;
}

 

The new code produces square wave with 2.13 us high and low state i.e. approx 235 kHz or about 50 times faster than access via shell.

ESP32-EVB our new board for IoT first prototypes are ready

esp32-evbesp32-evb-2

ESP32-EVB is our new board with ESP32-WROOM32 module. It has:

  • ESP32-WROOM32 module
  • two relays 10A/250VAC
  • Ethernet 100Mb interface
  • LiPo charger and step up converter allowing ESP32-EVB to run from LiPo battery
  • microSD card connector
  • two user buttons
  • UEXT connector to attach different sensors and modules
  • 40 pin GPIO 0.1″ step connector with all resources of ESP32
  • 5V power jack
  • three mount holes

Now time to write some examples and if everything works to launch production.

The sale price will be EUR 22.00

Python modules for access to GPIO, I2C and SPI to all OLinuXino boards and SOMs on GitHub

python-logo

We made modules which work same way on all our OLinuXino and SOM boards. The sources are on GitHub.

You can address the GPIOs in two ways – as connector pins and as processor ports.

connector.gpio1p5  means connector GPIO1 pin number 5, same signal can be addressed with port.PG0

Getting started with A13-OLinuXino blog post on element14

Image

 

We spotted blog post on element14 about Getting started with A13-OLinuXino

pyA10Lime 0.1.0. Python library for GPIO access

Image

We just uploaded pyA10Lime https://pypi.python.org/pypi/pyA10Lime/

>>>import A10Lime as lime

# Initialize module
>>>lime.init()

# Read configuration of GPIO
>>>lime.getcfg(lime.PC3)
# or you can use
>>>lime.getcfg(lime.PIN1_29)

# You can address GPIO either by pin numeration or port name
# For example PG0 pin on GPIO-1 connector can be accessed with lime.PG0 or lime.PIN1_5

# Set configuration
>>>lime.setcfg(lime.PC3, lime.OUTPUT)
>>>lime.setcfg(lime.PC3, lime.INPUT)

# Set output level
>>>lime.output(lime.PC3, lime.HIGH)
>>>lime.output(lime.PC3, lime.LOW)

# Read input state
>>>lime.input(lime.PC3)

# Read detailed info about pin
>>>lime.info(lime.PC3)
>>>lime.info(lime.PIN1_29)

New Product in stock: A10-OLinuXino-LIME-UEXT adapter

Image

A10-OLinuXino-LIME-UEXT is adapter board with Male connector on 0.05″ which can connect to A10-OLinuXino-LIME GPIOs with  0.05″ step ribbon CABLE-40-40-10CM and allow LIME GPIOs to be used with BREADBOARD-1, or with A13-LCD43TS, A13-LCD7TS or A13-LCD10TS.

For the moment A20-LCD15.6 is not supported as LVDS signals got noisy when pass through A10-OLinuXino-LIME-UEXT but we are looking for solution.

UEXT signals can be used only when connected to GPIO1. On the other connectors UEXT signals will be not present.

New A20 Android 4.2.2 image now supports all A20-OLinuXino-MICRO hardware features

Image

We received A20-SDK2.0 from Allwinner few weeks ago and were working to generate image for A20-OLinuXino but our aim was to add support to all hardware features the board offers. The process was pretty slow as the compilation is very heavy and even small change requires hours of waiting the image generation to complete.

Now we are ready, the only two features left unsupported are the SATA and second SD-MMC card on the bottom but we think that we should give it a break for a while or our heads will explode 🙂

Two images are uploaded on Wiki: one for 7″LCD and one for 10″LCD, the good news is that the Android 4.2.2 with SDK2.0 now support higher resolution as previous SDK for ICS 4.0.3 had hardcoded 800×600 max resolution which made 10″LCD and HDMI useless.

The image have:

  • LCD and HDMI support at same time
  • Touchscreen support
  • GPIO support – we prepare Android application demo code which show how you can access and use GPIOs under Android
  • I2C1 and I2C2 support – we prepare Android application demo code which show how you can access and use I2C under Android
  • 100Mbit Ethernet
  • USB-Ethernet AX88772
  • USB WiFi RTL8188
  • microSD
  • Audio Out, Audio In
  • USB-OTG device and host with Low/Full/High speed
  • USB HOST upper and bottom with Low/Full/High speed
  • UART6 and UART7 support on UEXT connectors  – we prepare Android application demo code which show how you can access and use UART6,7 under Android
  • Buttons

Python GPIOs module for A20-OLinuXino-MICRO

Image

pyA20 GPIO module is uploaded yesterday to Pypi https://pypi.python.org/pypi/pyA20/0.1.0

The use is same as the Python modules for imx233, A10S, A13 OLinuXino:

#!/usr/bin/env python
import A20_GPIO as GPIO
#init module
GPIO.init()
#configure module
GPIO.setcfg(GPIO.PIN#, GPIO.OUTPUT)
GPIO.setcfg(GPIO.PIN#, GPIO.INPUT)
#read the current GPIO configuration
config = GPIO.getcfg(GPIO.PIN#)
#set GPIO high
GPIO.output(GPIO.PIN#, GPIO.HIGH)
#set GPIO low
GPIO.output(GPIO.PIN#, GPIO.LOW)
#read input
state = GPIO.input(GPIO.PIN#)
#cleanup
GPIO.cleanup()

this is initial release so if you find some bugs please report back to us 🙂

A10S-OLinuXino ANDROID GPIO control LED toggle app

Image

We got lot of requests on our forum how to control GPIOs from Android.

With the new A10S Android image we decided to play a bit and it appear to be not hard to implement.

We found two ways to do GPIO control running Android.

GPIO using ADB

1. Boot android (from nand or sdcard)

2. Connect USB-to-Serial cable on UART1

3. Open terminal at speed 115200

4. When loading is ready in the terminal type “sh” and enter

5. “ls /sys/class/gpio_sw” will give you a list of all accessable GPIOs.

The GPIOs name is according to the chip ports. For example PE3 is LED1.

6. To set PE3 as output:

#echo 1 > /sys/class/gpio_sw/PE3/mul_sel

or as input

#echo 0 > /sys/class/gpio_sw/PE3/mul_sel

7. To turn on LED:

#echo 1 > /sys/class/gpio_sw/PE3/data

and to turn off:

#echo 0 > /sys/class/gpio_sw/PE3/data

8. If GPIO is as input to read state:

#cat /sys/class/gpio_sw/PE3/data

GPIO using Android SDK

Basicly you should read and write to the filesys. Make sure that your app is running as root, or else nothing will happen.

The demo program toggle LED1 on every button press.  The sources are at GitHub: https://github.com/OLIMEX/OLINUXINO/tree/master/SOFTWARE/A10S/A10S-ANDROID-GPIO

All read/write methods are realized in GPIO.java file.

The application is with single button and each time you press it it toggles the green LED on the board.

TOGGLE

You can see ToggleLED.apk running at this video: http://www.youtube.com/watch?v=8kTUkJx2TgQ

Previous Older Entries