gCore (II) - a dev board for portable GUI gadgets

A high-end ESP32 development board with a 480x320 pixel capacitive touchscreen and sophisticated features.

Similar projects worth following
Starting from
globoy has 111 orders / 1reviews
Ships from United States of America
Designing my own thermal imaging camera led me to design my own development board with a set of features that aren't usually present on other dev board that fit my needs. I've been working with Group Gets to make it available to others in a campaign. This project describes gCore in detail and will be a place where I document various gadgets created with it.

My vision for gCore is as a base for all kinds of portable devices utilizing a display or GUI. gCore provides a rich set of features aimed at allowing developers to focus on the unique functionality of their device while providing a polished solution with high performance graphics and file IO, great battery management and user-friendly features such as soft power control and automatic low-battery shutdown.

gCore uses the ESP32-WROVER-E module which has dual-CPU revision 3 ESP32 silicon, 16 MB Flash memory and 8 MB PSRAM.

High Performance LCD Capacitive Touchscreen Display

TFT 480x320 pixel LCD Display using ILI9488 controller configured to use a 8-bit parallel interface.  The parallel interface is driven by a shift register and other logic connected to the native ESP32 VSPI GPIO pins.  This allows code on the ESP32 to drive the SPI bus at the maximum 80 MHz (faster than the ILI9488 allows in SPI mode).   Bodmer's fantastic TFT_eSPI library has been ported and screams on gCore.  A FT6236 touchscreen controller allows up to two point touch detection.

Full Power Path Li-Ion Charger

gCore is powered by a 3.7V Li-Ion or LiPo battery (typ 500-4400 mA) or USB.  The battery connection uses the standard Adafruit/Sparkfun JST connector.  A Microchip MCP73871 charge controller provides a separate path for battery charging and for board power.  This ensures it can accurately determine charge completion and allow board power to be sourced from USB only when possible or shared between USB and battery power when necessary.  I wanted a full power path charging circuit because I've seen battery life problems with the dev boards that simply hang the board load directly on the battery connection with the both powered by the same charge controller output.  A jumper allows either a 500 mA or 1A maximum charge current selection.

Soft Power Control / RTC

gCore contains a Silicon Labs EFM8SB20F32 8-bit microcontroller that acts as a power manager (PMIC), provides a real-time clock (RTC) with alarm and NVRAM/NVFlash, and board control/monitoring control.  The ESP32 communicates with it over I2C.

  • The board can be powered on by a press on the power button, an alarm from the RTC or when charging is started or completed.  When powered the button has two functions.  It can act as a general purpose button with presses detectable by code running on the ESP32 or it can be held for five seconds to power off the board (like the long press on laptop power buttons).
  • Code running on the ESP32 can initiate a power off.  The EFM8 also switches power off for a critically low battery automatically (a warning status is available to the ESP32 before power is shut off).
  • Dimmable backlight control.  8-bit PWM dimming at 25 kHz.
  • The EFM8 provides 4096 bytes of NVRAM and 1024 bytes of flash accessible by the ESP32 via I2C for storing parameters when the ESP32 is powered off.
  • The EFM8 monitors battery voltage, load current, USB voltage and charge current.  It provides averaged and filtered values via the I2C bus to the ESP32.
  • Charge LED pulses when charging, turns solid when USB power is connected but charge is complete or blinks if there has been a charge error (for example timeout during charging).
  • SD Card insertion detection.  Status bit for ESP32 indicating presence of Micro-SD Card.

4-bit Micro-SD Card

All four bits of the Micro-SD Card connector are connected to the ESP32 allowing high performance 4-bit SD-mode access.  I've seen up to a 5.5X performance increase for large writes over the typical SPI-based SD Card interface.  The GPIO signals are also available on SMT pads if the SD Card is not being used.

USB Interface

A Silicon Labs CP2102N USB UART is connected to the ESP32 serial port and includes the traditional auto-programming (DTR/RTS) circuitry to put the ESP32 into boot mode.

Expansion Port

Unused ESP32 GPIO plus the GPIO used for the I2C interface are brought out to a connector along with both switched and un-switched 3.3V regulated outputs, a switched version of the battery rail, and other signals such as USB power and the power button signals for external circuits.   The I2C interface is also available on a Qwiic compatible connector for easy connection to peripheral devices from Sparkfun, Adafruit and others.

Software Support...

Read more »

  • Fixed a pair of bugs in the EFM8 PMIC/RTC

    Dan Julio09/11/2023 at 19:23 0 comments

    TL;DR: I found a pair of bugs related to gCore's Real Time Clock (implemented on the EFM8 RTC/PMIC co-processor).  There's a new version of the EFM8 firmware (version 1.2) and instructions how anyone with an older board can get updated at the end of this post.  The bug is fixed in all boards shipping in Sept 2023 and beyond.

    The Bugs

    I added support for Caller ID to the weeBell bluetooth code.  Caller ID sends the date and time as part of the message to the phone so I also enabled use of gCore's RTC to set the system time when powered up.  During testing I noticed that the gCore RTC would lose tens of seconds per day.  This lead to an investigation that ultimately found two issues with my version 1.1 EFM8 firmware.

    The first problem is that the RTC timer preset was wrong.  The RTC timer is configured to interrupt once per second and is clocked by a 32768 Hz crystal.   I set the preset to 32768.  I had missed that the Silicon Labs documentation said I should set it to 32767.  But it turns out even their documentation doesn't account for a hardware bug in the chip and it should be set to 32766.  Thankfully someone posted this to a Silicon Labs forum.  The off-by-two error lead to a timekeeping error of about -5 seconds per day.  Unfortunately I didn't see this during testing.

    But that still didn't explain why I was seeing much larger errors.  Because the clock was always slow I immediately suspected the code was missing the RTC interrupt somehow.  Turns out that assumption was correct.  The RTC interrupt is not latched.  It only exists for one clock cycle (1/32768 = 30.5 uSec).  So if the code is servicing another interrupt with equal or higher priority and that service takes longer than 30.5 uSec then the RTC interrupt will be missed.

    The EFM8SB2 has two levels of interrupt priority and the RTC interrupt has high priority.  But the I2C interrupt also has high priority because it occurs at least once for every byte transferred on I2C and I want to minimize clock stretching during reads.  I had done analysis and testing to characterize the I2C interrupt and thought it would always finish quickly enough.  However I committed a cardinal sin.  I added more code after the analysis and didn't re-analyze.  And now the I2C interrupt could take, under certain circumstances, more than 30 uSec to execute.

    The weeBell bluetooth code polls the EFM8 via I2C fairly often, multiple times per second, looking to see if the power button has been pressed so it can turn itself off.  It's also reading the battery voltage and charge status for the GUI.  It turns out that every few hundred or thousand reads one slow I2C access would line up with the RTC interrupt and the RTC interrupt would be lost.  The RTC would lose a second.

    The slow I2C ISR routine had to do with how I guarantee atomicity for multi-byte values.  The fix was to restructure the code so the atomicity was assured by non-ISR code and the ISR simply does nothing but access an array to get data for read responses.

    Lots of testing later and I'm pretty confident that the RTC is now good to go.

    Updating Existing Boards

    I feel badly about letting this set of bugs through and want to make it right with anyone who is impacted.

    Users of boards obtained before Sept 2023 who want to upgrade their EFM8 firmware from version 1.1 to version 1.2 have the following options.

    1. Send the board back to me and I'll re-flash the firmware and return the board to you.  You pay shipping to me and I'll pay to ship the board back to you.
    2. Use a Simplicity Labs USB Debug Adapter and the programming software in their Simplicity Studio to load the hex file from the repository onto the EFM8 by connecting three wires from the Debug Adapter to the board.
    3. Use a 3.3V 32-bit Arduino board (PJRC Teensy 3/4, ESP32 or RP2040) as a programmer with a sketch in the repository...
    Read more »

  • gCore's first shield

    Dan Julio07/01/2023 at 17:54 0 comments

    One idea I have had is to create a set of gCore shields which like various Arduino shields and Pi Hats add hardware functionality for specific applications.  The first board is called the gCore POTS shield and was designed to let me re-imagine the BluePOT project in a more general purpose project called weeBell.

    (gCore POTS shield)

    The gCore POTS shield connects to gCore's IO Expansion header and contains a codec chip and the Silvertel AG1171 Ringing Subscriber Line Interface module.  These two devices allow creation of a full Foreign Exchange Service (FXS) device which simulates a central office.  Old school POTS telephones plug into the RJ11 jack.  Firmware running on gCore implements functionality necessary to ring the phone for incoming calls, detect on- and off-hook conditions, support both rotary and DTMF dialing and provide echo-cancelled audio.

    (Rotary Dialing)

    Currently firmware called weeBell_bluetooth allows phone calls to be answered or initiated via a paired cellphone.  I hope to create other firmwares as well.  All firmware will be included as part of the gCore Serial Programmer library making it easy to load new versions.

    (Loading weeBell firmware)

  • Downloader/Programming app for gCore

    Dan Julio06/04/2023 at 21:04 0 comments

    I wrote a desktop app (Linux x86, Mac OS, Windows) that lets you program almost all of the demos and applications I've written for gCore without needing to build them first using Arduino or the IDF.  It accesses pre-compiled binaries from my website.  You can find it in the Downloads section of the gCore page.

    The idea is to make it easy to see all the things gCore can do.  The only demos I wrote that aren't included are those where you need to include your own Wifi SSID and password in them like the LiFX LED light bulb remote control.

    Unfortunately I couldn't sign the app for Mac OS or Windows because the app calls a compiled version of esptool behind the scenes to do the actual programming and I couldn't sign that so the who application bundle couldn't be signed.  This means both Mac OS and Windows will complain.  On Mac OS you'll have to go to System Preferences->Security & Privacy and tell OS X you want to run the app anyway (you may also have to tell it to allow apps from both the App Store and identified developers).  On Windows you may have tell it that the zip is ok to download.

    Here it is running on Linux.

    And Mac OS X

    And Windows

  • Internet Clock Radio

    Dan Julio02/16/2023 at 23:03 0 comments

    I wanted to learn about I2S audio on the ESP32 and found a great project in github user schreibfau1's ESP32-MiniWebRadio.  He has written some amazing audio libraries and then wrapped them up in a fun project.  His code is understandable and more importantly, reasonably easy to modify so I spent a couple of days getting it running on gCore - using gCore features of course - with a cheap Sparkfun I2S breakout board for the audio out.  The port can be found here.

    It connects via Wifi to a list of internet radio stations held in a file on the Micro-SD card (along with lots of graphical assets for the GUI) and can output via I2S or via SPI to the VS1053 audio decoder chip. 

    It can also act as an alarm clock and playback local files in a variety of formats.  Time is normally automatically obtained from an NTP service but will fall back to gCore's battery backed RTC if necessary.

    There's even a web interface!  You can select from a humungous list of internet radio stations thanks to Community Radio Browser.

    MiniWebRadio really shows what the ESP32 is capable of.  It connects to the internet, provides both a GUI and web server interface, decodes a bunch of audio formats in software and decodes and displays compressed images from both the Micro-SD card and internet streams. 

    Be sure to check out schreibfaul1's ESP32-audioI2S library  too.  Very, very cool.

  • Galaga!

    Dan Julio01/27/2023 at 22:42 0 comments

    I always loved Galaga - although I have never been very good at video games - so I was excited when I found Till Haubaum's Galaga emulator already ported to the ESP32.  It was a pretty straight forward project to port it to gCore with one hiccup that caused me to spend a few hours getting audio to work again.  One cool thing is that  gCore's fast LCD updates allow for higher FPS than the original 40 MHz ILI9341.  The project is an Arduino sketch (Arduino 1.8.19 with the ESP Arduino 2.0.6 package).  Code in a github repo.

  • First production run here

    Dan Julio01/20/2023 at 01:53 0 comments

    Yesterday I received a very heavy box with the first 250 gCore boards.  I feel pretty bad for my Fedex driver because we recently got a snowstorm here in Colorado and he had to lug that box up a long, snowy driveway to deliver it.  But production quality looks great.

  • Another demo

    Dan Julio12/22/2022 at 19:35 0 comments

    I got the LVGL Music Demo running on gCore.  It's running on lvgl v9.0.0 so shows how to include the LCD and touchscreen drivers on that version (which has some differences from previous releases).

    Code can be found in this repository.

    This demo is used to benchmark LVGL running on various platforms when they are submitted for qualification (something I'm not sure I'll do as it is $900USD as you've just read about the economics of this project).  I didn't expect gCore to work as well as some of the boards with GPUs and much higher speed interfaces to the LCD but I was disappointed in my initial results - and a bit confused.

    This demo has run on a couple of other ESP32 based boards that use the ESP32 parallel interface to directly drive the LCD controller.  I expected them to be slightly faster but not over twice as fast, especially since when I put my scope on the CSN signal to the LCD I see that the code is not limited by transfer speed to the LCD.  I verified this by slowing the SPI clock speed from 80 MHz to 40 Mhz with very little difference.  There are large periods of time between transfers which indicates a lot of compute is happening in the single-threaded demo code.  Because the SPI transfers are handled by a DMA engine then I can surmise that the demo is not being slowed by the LCD update.  Since I'm running the same chip as these other boards I would expect they have the same time spent in the compute parts of the code.  I wonder if I'm missing some type of optimization but not sure what.  I'm running the ESP32 at 240 MHz with 80 MHz QIO flash access, internal RAM and  the compiler set for performance optimization.  Bears some more investigation I think.

    In other news I was able to issue a PR for the gCore python ILI9488 driver into the official lv_micropython project so now it's an officially supported display in that project.

  • The brutal financials of a project like this

    Dan Julio12/17/2022 at 21:10 2 comments

    This post covers a subject I haven't seen much discussion about: The [not so great] economics of selling a board like this.  I figure I've open sourced the design, why not be open about the business aspects of it.

    I designed gCore for my own needs but I always thought it - and tCam - might be interesting to other people.  However, I am a one-man shop, interested in technical issues and not in marketing, managing production and shipping logistics.  Since Group Gets specializes in selling thermal imaging modules and boards, including my tCam-Mini board (that is used in tCam), it was an easy decision to have them distribute it and they were interested too.  Plus I like the team there.  They are good people and responsive to people like me (unlike my experience with other electronics crowd funding sites).

    For a development board, gCore has a lot of parts.  These are needed for the added functionality and performance but make it more expensive to build.  Especially in low volumes.  Most boards in the same category have an ESP module, LCD display, USB IF chip, and voltage regulator (5V->3.3V).  Perhaps a Micro-SD socket.  gCore adds a LiPo charger, the EFM8 co-processor, TI current monitor chip, PWM backlight CC driver and the SPI-to-parallel converter (3 chips), plus supporting components.  As opposed to boards with the ESP32 WROOM module with 4 MB flash, it has a WROVER module with 16 MB flash and an 8 MB PSRAM.  These additional parts almost double the raw component cost over simpler boards.

    At qty 500 boards the ideal raw cost for parts is about $37-38/board based on US distributor pricing.  I say ideal because that's the price if there were no parts shortages, which is not the world we live in.  Unfortunately these days we either have to redesign or pay through the nose occasionally because parts brokers [scalpers] bought the parts and charge 3-10x.

    A problem is that a lot of makers and DIY types are used to super inexpensive dev boards, mostly built in China, with a lot less features.  And for a lot of projects the additional capabilities and performance of gCore don't matter.  There was never a way gCore would be cheap like these boards so I also knew it would never sell in high volumes.  I also feared that people would simply look at the price and be turned off before considering the value of the extra features and performance and how those could be useful. 

    Initially Group Gets was going to be responsible for building the boards using their USA contract manufacturer.  I would get a negotiated percentage as a royalty.  Of course they need to make money and they charge a certain percentage to manage production to cover their costs, as well as percentages for managing, marketing and distributing the product, plus a profit.  Unfortunately the end result was a $160/board price.  There was no way this would be interesting to anybody.

    So I decided to bite the bullet and assumed responsibility of building the boards in China using a CM I have used with success in the past, TinySine.  This would theoretically result in a lower cost to build boards and Group Gets wouldn't have to add their manufacturing management overhead to the final price.  In addition I don't have to necessarily mark up the costs as much as traditional companies since a) I'm don't have the same overhead and b) I'm not looking to make a lot of money with this project.  We talked and agreed that $99 was about the highest we could expect to charge - and even then we'd have to explain the value of this board (e.g. why one would buy a high end car when a Yugo will still get you from point A to point B).

    Group Gets also wanted me to have a cute box for the board to come in.  I personally am just fine if boards come to me in anti-static bags but apparently the rest of the world disagrees...  So...

    Read more »

  • Micropython and LVGL

    Dan Julio12/07/2022 at 16:00 0 comments

    LVGL supports a python binding and they provide a pair of repositories supporting it.  One contains the bindings and the other with the bindings as part of micropython.  There are even drivers for the ILI9488 LCD controller and FT6236 touchscreen controller used by gCore and since Micropython runs just fine on the ESP32 getting the lv_micropython build running on gCore is easy.  However there's room for an optimization that speeds drawing on gCore even more than the higher 80 MHz SPI clock.

    The ILI9488 chip supports multiple interfaces: 8- or 9-bit SPI, 8-, 16- or 24-bit parallel or DSI/MIPI parallel.  Most micro-based systems use the 4-wire SPI interface.  gCore uses the 8-bit parallel interface.  The chip also supports either 16-bit (RGB565) or 18-bit (RGB666) pixels, but only on the parallel interfaces.  When using the SPI interface directly the chip is limited to 18-bit pixels which must be loaded with 3 bytes (8-bits each for R, G and B).  This is why you'll see a lot of drivers with an extra step of converting data from 16-bits to 24-bits or from 32-bits down to 24-bits (as is done by the default driver in the lv_micropython repository).  This is a significant performance hit.  The "ili9488" class in the driver only supports LVGL in 32-bit (RGBA8888) mode and generates an error if LVGL is configured for 16-bit pixels.  But since gCore uses the parallel interface we can avoid this.  For this reason I modified the driver to include a new class "ili9488g" that implements the following optimizations (leaving the original ILI9488 class alone).

    1. Changed the default SPI peripheral to VSPI and default pins to match
    2. Set a default 80 MHz SPI bus frequency
    3. Added support for 16-bit pixels

    The new driver will work with LVGL compiled for either 16- or 32-bit pixels.  There is a noticeable speed-up when running with 16-bit pixels and not a lot of image degradation since the ILI9488 is really only capable of 18-bit pixels.

    I also got one of the demos running.

    One of the nice things about LVGL on Micropython is that it's really easy to use.  The REPL makes it great for experimentation too.  Just a few lines of code to get a GUI.  For example the following code initializes LVGL and both the touchscreen and LCD drivers, and then creates and displays a button.

    from ili9XXX import ili9488g
    from ft6x36 import ft6x36
    touch=ft6x36(0, 21, 22, 10000)

    The main github repository has been updated with instructions and the new driver.

  • Manufacturing test and programming fixture

    Dan Julio11/24/2022 at 03:09 0 comments

    The functional test and programming fixture is done and ready to send to the contract manufacturer.  It's a fairly simple piece of hardware with a bunch of software that, as usual, took me longer than I originally planned...  It has the following functionality

    • Functional hardware test
    • Program EFM8 firmware
    • Program the ESP32 with the calculator demo program (also used to verify the LCD and touchscreen functionality)

    The hardware uses a PJRC Teensy 3.2 as a local controller with software running on a PC and connects to the gCore using a set of pogo-pins.  A 3D printed mechanism holds the gCore down.  The Teensy reads various voltages, outputs digital signals that control a simulated battery, power button and USB power supply, interfaces to the gCore I2C bus and implements a programmer for the EFM8.  The ESP32 is programmed by the PC via USB.

    Originally I intended the switched USB connection to gCore to run through a pair of USB-C connectors on the test fixture PCB.  However I got some signals reversed so the connectors didn't work.  I ended up just splitting a USB cable open, cutting the +5 line and running that through the pair of P-channel MOSFETs on the test fixture used to turn Vusb on and off.  And holding the cable down with lots of glue.

    On the other hand the circuit I designed to simulate a LiPo battery worked really well.  The test fixture has to handle both a drain and charge of a simulated battery.  I looked into a dual quadrant power supply design but the complexity and cost put me off.  Then I realized all I really needed to test was that the charger IC put out current.  That could be implemented by simulating a battery at one voltage through a Schottky diode and then observing if the voltage went close to 4.2V when the charger was active when Vusb was energized.  The diode prevents back flow to the 4V regulator.

    In the circuit above, +5V is supplied by teensy and U2 is a 4V regulator enabled by the Teensy using BP_EN. The voltage is routed through D1 to V+ which is connected to the battery input.  When Vusb is supplied the charger IC on gCore will attempt to charge the battery to 4.2V.  A small load is provided via Q1 so the charger sees some current flow.  For a functional board V+ will jump from about 3.7-3.8 V to 4.1-4.2V when the charger is running and is sensed via A_BP_SNS.

    Software running on the Windows PC (and Mac, for me) was written in xojo.  The program encapsulates the pre-compiled esptool binary I found in the ESP32 Arduino package and binary files for both the EFM8 and ESP32.  Although it has a set of manual controls, during normal operation the operator only has to press Run and acknowledge one dialog box for each board.  Excluding the time to insert and remove a gCore the entire test and programming process takes around 20 seconds.

    I still have to write a document that correlates error messages with parts of the gCore for debugging of failed boards.

View all 12 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates