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:
- Put the SD-card in SD card reader and attach to PC
- Open the SD-card foler and in terminal execute: $ gnome-disk-image-mounter –writable hd20_DOSDEV.img
- You will see new disc mounted and you can write in it the files you download
- Unmount the disc
- Eject the SD card
- 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
Recent Comments