PineDio Stack BL604 RISC-V Board: Testing The Prototype

📝 29 Aug 2021

UPDATE: There’s a new version of PineDio Stack BL604, the GPIO Numbers have changed

What’s it like to create Open Source Software (and firmware) for brand new Prototype Hardware?

What interesting challenges will we encounter?

Find out how we create new firmware to test (and improve) Pine64’s newest and hottest prototype: PineDio Stack BL604 RISC-V Board!

⚠️ Obligatory Disclaimer: Features included in The Prototype are not complete, and will most certainly undergo changes before becoming available for public consumption. (Burp) They are described here for testing, exploration, education and entertainment purposes only. The Prototype shall NOT be used in production gadgets. (Like toasters, microwave ovens, and most definitely not, pressure cookers)

The kind (and super cool) folks at Pine64 told me that I would be receiving a fun new gadget that’s…

  1. Based on BL604 RISC-V + WiFi + Bluetooth LE SoC, which is the upsized sibling of Bouffalo Lab’s BL602 SoC.

    (BL604 has 23 GPIOs vs BL602’s 16 GPIOs. So it’s like comparing millipedes and centipedes, I guess)

  2. And BL604 is supposed to be 100% compatible with BL602

    (Is it really 100% compatible? We’ll find out in a while!)

  3. Has an ST7789 SPI Display

    (Imagine the possibilities)

  4. Has an onboard LoRa SX1262 Transceiver for low-power, long-range, low-bandwidth networking

    (Wow!)

  5. Plus SPI Flash, Battery Charging Chip, Accelerometer (optional) and Heart Rate Sensor (optional)!

After some shipping delays at Shenzhen (due to flooding or pandemic?) I received something totally unexpected…

Solar Panel?

A Solar Panel!

(Yeah Singapore is super sunny… Is this mockery? 🤔)

But a Solar Panel with a JTAG Cable? That’s highly unusual.

Opening the gadget reveals the hidden treasure inside: PineDio Stack BL604 Board!

Inside the Solar Panel: PineDio Stack BL604 Board

That’s typical of Prototype Hardware fresh from the factory: No docs, no fancy packaging, no branding either.

(Ground Plane is also missing, which we’ll fix before FCC Certification)

We shall explore PineDio Stack ourselves… And document all our findings for the sake of the Open Source Community!

PineDio Stack BL604 Board

1 Connect The Display

What’s on the underside of PineDio Stack?

Unscrewing the board (from the glue sticks?) reveals the LCD Display Connector on the underside of the board…

PineDio Stack Underside

The connector matches this familiar ST7789 SPI Display that was shipped with PineDio Stack…

ST7789 SPI Display

So we snapped the ST7789 Display to the board…

ST7789 Display connected to PineDio Stack

And we get an unusual contraption: A Solar Panel with LCD Display inside!

Solar Panel with an LCD Display inside

We’re ready to test our firmware on PineDio Stack! We’ll follow this schematic…

2 BL604 Blinky

What’s the first thing that we run on a brand new prototype board?

Blinky Firmware of course! (Yep the firmware that blinks the LED)

/// PineDio Stack LCD Backlight is connected on GPIO 21
#define LED_GPIO 21

/// Blink the LED
void blinky(char *buf, int len, int argc, char **argv) {
  //  Show a message on the serial console
  puts("Hello from Blinky!");

  //  Configure the LED GPIO for output (instead of input)
  int rc = bl_gpio_enable_output(
    LED_GPIO,  //  GPIO pin number
    0,         //  No GPIO pullup
    0          //  No GPIO pulldown
  );
  assert(rc == 0);  //  Halt on error

  //  Blink the LED 5 times
  for (int i = 0; i < 10; i++) {

    //  Toggle the LED GPIO between 0 (on) and 1 (off)
    rc = bl_gpio_output_set(  //  Set the GPIO output (from BL602 GPIO HAL)
      LED_GPIO,               //  GPIO pin number
      i % 2                   //  0 for low, 1 for high
    );
    assert(rc == 0);  //  Halt on error

    //  Sleep 1 second
    time_delay(                 //  Sleep by number of ticks (from NimBLE Porting Layer)
      time_ms_to_ticks32(1000)  //  Convert 1,000 milliseconds to ticks (from NimBLE Porting Layer)
    );
  }
  //  Return to the command-line interface
}

(Source)

This BL604 Blinky code is 100% identical to the BL602 version of Blinky. Except for the GPIO Pin Number…

/// PineDio Stack LCD Backlight is connected on GPIO 21
#define LED_GPIO 21

(We’re blinking the Backlight of the ST7789 Display)

We build the BL604 Blinky Firmware the exact same way as BL602…

##  Download the 3wire branch of lupyuen's bl_iot_sdk
git clone --recursive --branch 3wire https://github.com/lupyuen/bl_iot_sdk
cd customer_app/pinedio_blinky

##  Build for BL602 (Should this be BL604?)
export CONFIG_CHIP_NAME=BL602

##  Where BL602 / BL604 IoT SDK is located
export BL60X_SDK_PATH=$PWD/../..

##  Build the firmware: build_out/pinedio_blinky.bin
make

(Source)

Let’s flash the firmware to the board!

3 Flash Firmware To BL604

We flash the BL604 Blinky Firmware the exact same way as BL602…

  1. Remove the battery from the Solar Panel

    (Because we’ll reboot the board during flashing)

  2. Switch to Flashing Mode

    Flip the GPIO 8 Jumper to High

    (See this)

  3. Connect the board to our computer’s USB Port

  4. Run blflash to flash this firmware file…

    build_out/pinedio_blinky.bin
    

    (More about blflash)

To run the BL604 Blinky Firmware

  1. Disconnect the board from the USB Port

  2. Switch to Normal Mode

    Flip the GPIO 8 Jumper to Low

    (See this)

  3. Connect the board to the USB Port

  4. Open a Serial Terminal and connect to the BL604 UART Port at 2 Mbps

    Use screen (Linux), CoolTerm (macOS) or putty (Windows)

    (Or use the Web Serial Terminal)

    (Instructions here)

  5. At the BL604 Command Prompt, enter…

    blinky
    

    And the Backlight blinks!

    Watch the Demo Video on YouTube

(PineDio Stack doesn’t have a Reset Button, but we can make one)

Now that the Backlight GPIO is OK, let’s test something more sophisticated: SPI!

PineDio Stack BL604 with LoRa SX1262 Transceiver

4 BL604 SPI

Why test SPI on PineDio Stack?

Because SPI is the Data Bus that connects the key components of PineDio Stack…

  1. SPI Flash

  2. ST7789 Display

  3. LoRa SX1262 Transceiver

SPI Bus on PineDio Stack

GPIO NumberSPI Pin
17Common SDO (MOSI)
0Common SDI (MISO)
11Common SCK
14CS for SPI Flash
20CS for ST7789
15CS for SX1262

UPDATE: There’s a new version of PineDio Stack BL604, the GPIO Numbers have changed

SPI Flash, ST7789 and SX1262 are connected to the same GPIO Pins for SDO (formerly MOSI), SDI (formerly MISO) and SCK.

(More about SDO and SDI)

But won’t BL604 get confused by the SPI crosstalk?

Nope because SPI Flash, ST7789 and SX1262 are connected to different Chip Select Pins.

When our firmware talks to an SPI Peripheral (like ST7789), we shall set the peripheral’s Chip Select Pin to Low.

(Our firmware shall set the Chip Select Pins to High when idle)

How shall we code the firmware for testing SPI?

The same way as BL602… By calling the BL602 / BL604 IoT SDK!

We start by defining the Shared GPIOs for the SPI Peripherals: pinedio_st7789/display.h

/// GPIO for ST7789 / SX1262 / SPI Flash SDO (MOSI)
#define DISPLAY_MOSI_PIN 17

/// GPIO for ST7789 / SX1262 / SPI Flash SDI (MISO)
#define DISPLAY_MISO_PIN  0

/// GPIO for ST7789 / SX1262 / SPI Flash SCK
#define DISPLAY_SCK_PIN  11

Followed by the Chip Select GPIOs for each SPI Peripheral…

/// GPIO for SPI Flash Chip Select. We must set this to High to deselect SPI Flash.
#define FLASH_CS_PIN 14

/// GPIO for SX1262 SPI Chip Select. We must set this to High to deselect SX1262.
#define SX1262_CS_PIN 15

/// GPIO for ST7789 SPI Chip Select. We control Chip Select ourselves via GPIO, not SPI.
#define DISPLAY_CS_PIN   20

The SPI Functions from the BL604 IoT SDK need us to specify a Chip Select GPIO.

Since we’re controlling Chip Select ourselves, we’ll assign GPIO 8 as the Unused Chip Select…

/// GPIO for unused SPI Chip Select Pin. Unused because we control Chip Select ourselves via GPIO, not SPI.
#define DISPLAY_UNUSED_CS_PIN 8

/// For Debug Only: GPIO for SPI Chip Select Pin that is exposed on GPIO Connector and can be connected to Logic Analyser
#define DISPLAY_DEBUG_CS_PIN 5

/// GPIO for Backlight
#define DISPLAY_BLK_PIN  21

(GPIO 8 selects the Flashing Mode when BL604 is booting, so GPIO 8 is normally unused)

We use GPIO 5 to mirror the GPIO High / Low State of GPIO 20 (ST7789 Chip Select). More about this in a while.

4.1 Initialise SPI Port

Let’s initialise the SPI Port before sending data: pinedio_st7789/demo.c

/// Command to init the display
static void test_display_init(char *buf, int len, int argc, char **argv) {
  //  Configure Chip Select, Backlight pins as GPIO Output Pins (instead of GPIO Input)
  int rc;
  rc = bl_gpio_enable_output(DISPLAY_BLK_PIN, 0, 0);  assert(rc == 0);
  rc = bl_gpio_enable_output(DISPLAY_CS_PIN,  0, 0);  assert(rc == 0);
  rc = bl_gpio_enable_output(FLASH_CS_PIN,    0, 0);  assert(rc == 0);
  rc = bl_gpio_enable_output(SX1262_CS_PIN,   0, 0);  assert(rc == 0);
  rc = bl_gpio_enable_output(DISPLAY_DEBUG_CS_PIN, 0, 0);  assert(rc == 0);

First we configure the Chip Select GPIOs for GPIO Output (instead of GPIO Input).

Next we set the Chip Select GPIOs to High to deselect all SPI Peripherals…

  //  Set Chip Select pins to High, to deactivate SPI Flash, SX1262 and ST7789
  rc = bl_gpio_output_set(FLASH_CS_PIN,   1);  assert(rc == 0);
  rc = bl_gpio_output_set(SX1262_CS_PIN,  1);  assert(rc == 0);
  rc = bl_gpio_output_set(DISPLAY_CS_PIN, 1);  assert(rc == 0);
  rc = bl_gpio_output_set(DISPLAY_DEBUG_CS_PIN, 1);  assert(rc == 0);

  //  Switch on the backlight
  rc = bl_gpio_output_set(DISPLAY_BLK_PIN, 0); assert(rc == 0);

  //  Note: We must swap SDO (MOSI) and 
  //  SDI (MISO) to comply with the 
  //  SPI Pin Definitions in BL602 / BL604 
  //  Reference Manual
  rc = GLB_Swap_SPI_0_MOSI_With_MISO(ENABLE);  assert(rc == 0);

(We’ll cover GLB_Swap_SPI in a while)

Finally we configure the SPI Port

  //  Configure the SPI Port
  rc = spi_init(
    &spi_device, //  SPI Device
    SPI_PORT,    //  SPI Port
    0,           //  SPI Mode: 0 for Controller (formerly Master), 1 for Peripheral (formerly Slave)
    0,           //  SPI Polar Phase. Valid values: 0 (CPOL=0, CPHA=0), 1 (CPOL=0, CPHA=1), 2 (CPOL=1, CPHA=0) or 3 (CPOL=1, CPHA=1)
    1 * 1000 * 1000,  //  SPI Frequency (1 MHz, reduce this in case of problems)
    2,   //  Transmit DMA Channel
    3,   //  Receive DMA Channel
    DISPLAY_SCK_PIN,        //  SPI Clock Pin 
    DISPLAY_UNUSED_CS_PIN,  //  Unused SPI Chip Select Pin (Unused because we control the GPIO ourselves as Chip Select Pin)
    DISPLAY_MOSI_PIN,       //  SPI Serial Data Out Pin (formerly MOSI)
    DISPLAY_MISO_PIN        //  SPI Serial Data In Pin  (formerly MISO) (Unused for ST7789)
  );
  assert(rc == 0);

  //  Note: DISPLAY_UNUSED_CS_PIN must NOT be the same as DISPLAY_CS_PIN. 
  //  Because the SPI Pin Function will override the GPIO Pin Function!

We’re ready to transfer data over SPI!

(More about spi_init)

4.2 Transfer SPI Data

Here’s how we transfer data (transmit + receive) over SPI: pinedio_st7789/display.c

/// Write packed data to the SPI port. `data` is the array of bytes to be written. `len` is the number of bytes.
static int transmit_packed(const uint8_t *data, uint16_t len) {
  //  Clear the receive buffer
  memset(&spi_rx_buf, 0, sizeof(spi_rx_buf));

  //  Prepare SPI Transfer
  static spi_ioc_transfer_t transfer;
  memset(&transfer, 0, sizeof(transfer));    
  transfer.tx_buf = (uint32_t) data;        //  Transmit Buffer
  transfer.rx_buf = (uint32_t) spi_rx_buf;  //  Receive Buffer
  transfer.len    = len;                    //  How many bytes

Here we specify the Transmit Buffer and Receive Buffer for the SPI transfer.

Next we set Chip Select GPIO to Low to select the SPI Peripheral (ST7789 Display)…

  //  Select the SPI Peripheral
  int rc;
  rc = bl_gpio_output_set(DISPLAY_CS_PIN, 0);        assert(rc == 0);
  rc = bl_gpio_output_set(DISPLAY_DEBUG_CS_PIN, 0);  assert(rc == 0);

Then we start the SPI Transfer (transmit + receive) and wait for it to complete…

  //  Execute the SPI Transfer with the DMA Controller
  rc = hal_spi_transfer(
    &spi_device,  //  SPI Device
    &transfer,    //  SPI Transfers
    1             //  How many transfers (Number of requests, not bytes)
  );
  assert(rc == 0);

  //  DMA Controller will transmit and receive the SPI data in the background.
  //  hal_spi_transfer will wait for the SPI Transfer to complete before returning.

Finally we set Chip Select GPIO to Low to deselect the SPI Peripheral (ST7789 Display)…

  //  Now that we're done with the SPI Transfer...
  //  Deselect the SPI Peripheral
  rc = bl_gpio_output_set(DISPLAY_CS_PIN, 1);        assert(rc == 0);
  rc = bl_gpio_output_set(DISPLAY_DEBUG_CS_PIN, 1);  assert(rc == 0);
  return 0;
}

That’s how we transmit and receive data over SPI!

Why did we use BL604’s Direct Memory Access (DMA) Controller for the SPI Transfer?

Because we want the SPI Transfer to be executed in the background, freeing up the CPU for other concurrent tasks.

BL604’s DMA Controller executes the SPI Transfer on behalf of the CPU, shuffling data between the Transmit / Receive Buffers and the SPI Peripheral (ST7789).

(More about DMA)

What is DISPLAY_DEBUG_CS_PIN? Why is it mirroring DISPLAY_CS_PIN?

Yep everything we do to DISPLAY_CS_PIN (GPIO 20), we do the same to DISPLAY_DEBUG_CS_PIN (GPIO 5).

We’ll learn why in the next chapter.

PineDio Stack with Logic Analyser

5 Logic Analyser

When testing Prototype Hardware… Always have a Logic Analyser ready! (Pic above)

Why? Because we’ll hit a baffling signalling problem when we test SPI on PineDio Stack.

How do we capture the data transferred over the SPI Port?

PineDio Stack’s GPIO Connector (at right) exposes the SPI Pins: SDO (formerly MOSI), SDI (formerly MISO) and SCK

PineDio Stack GPIO Connector

We connect our Logic Analyser to the GPIO Connector like so…

GPIO NumberSPI PinConnector Pin
17Common SDO (MOSI)7
0Common SDI (MISO)17
11Common SCK4
5Debug CS2

UPDATE: There’s a new version of PineDio Stack BL604, the GPIO Numbers have changed

Logic Analyser connected to PineDio Stack

What about the ST7789 Chip Select Pin: GPIO 20?

Unfortunately GPIO 20 is not exposed on the GPIO Connector.

But remember: Everything we do to GPIO 20, we do the same to GPIO 5!

GPIO 5 is exposed on the GPIO Connector and it mirrors the GPIO High / Low state of GPIO 20.

Thus we simply connect our Logic Analyser to GPIO 5 as the Chip Select Pin! (Pic above)

Let’s look at the data collected by our Logic Analyser…

GPIO 20 is mirrored to GPIO 5

6 SPI Pins Are Swapped

What appears in the Logic Analyser when BL604 transmits data over SPI?

Watch what happened the very first time that we transmitted SPI data from BL604 to ST7789 Display…

SDO (MOSI) is flat

The top line showed that SDO (MOSI) was flat

No data was flowing out from BL604 to ST7789 Display!

Though SDI (MISO) looked OK…

Maybe SDO and SDI were swapped?

Thankfully JF found the fix!

//  Note: We must swap SDO (MOSI) and 
//  SDI (MISO) to comply with the 
//  SPI Pin Definitions in BL602 / BL604 
//  Reference Manual
int rc = GLB_Swap_SPI_0_MOSI_With_MISO(ENABLE);  assert(rc == 0);

(Source)

After applying the fix, BL604 swaps the SDO and SDI pins… And BL604 transmits SPI data correctly to ST7789!

SDO (MOSI) is OK!

But the BL604 Reference Manual says that GPIO 17 is SDO (MOSI)… Not SDI (MISO) right?

GPIO 17 is SDO (MOSI)

Yeah the BL604 Reference Manual says that GPIO 17 is SDO (MOSI)… So we shouldn’t need to call GLB_Swap_SPI_0_MOSI_With_MISO to swap the pins.

But since PineDio Stack was designed for GPIO 17 as SDO (MOSI), we’ll have to call GLB_Swap_SPI_0_MOSI_With_MISO in our firmware to make SPI work.

This SPI Pin Swap Problem sounds familiar…?

Yep if you’ve been following my BL602 Adventures, we’ve seen this SPI Pin Swap Problem on BL602

Hence I’m happy to confirm: BL604 is 100% compatible with BL602… Right down to the SPI Quirks!

How does this SPI Pin Swap Problem affect PineDio Stack Developers?

To work around the SPI Pin Swap Problem…

All PineDio Stack Developers should ensure that GLB_Swap_SPI_0_MOSI_With_MISO is always called before initialising the SPI Port.

(Here’s an example)

PineDio Stack ST7789 Display

7 ST7789 Display

Now that PineDio Stack SPI is OK, let’s draw something on the ST7789 Display!

According to the PineDio Stack Schematic…

The ST7789 SPI Display is connected on these pins…

UPDATE: There’s a new version of PineDio Stack BL604, the GPIO Numbers have changed

Wait are we missing a pin?

Yep we usually connect the ST7789 Data / Command (DC) Pin. (Like on PineTime)

We flip this pin to Low to indicate that we’re sending Command Bytes, and flip it to High for Data Bytes.

We call this the 4-Wire Interface for ST7789: SDO, SDI, SCK and DC.

Data / Command (DC) Pin is missing on PineDio Stack. So we’re using the 3-Wire Interface?

Yep ST7789 supports a 3-Wire Interface: SDO, SDI and SCK. (Without DC)

ST7789 3-Wire Interface

(Source)

Instead of transmitting the Data / Command Indicator on a separate pin, the 3-Wire Interface inserts a Data / Command (DC) Bit to specify whether the upcoming byte is a Command or Data Byte.

(DC Bit is 1 for Command Byte, 0 for Data Byte)

Whoa that means we transmit 9 bits for every Data and Command Byte?

Yep we need to find some way to transmit 9-bit data over our 8-bit SPI Port.

The 3-Wire (9-bit) Interface might actually be more efficient than the 4-Wire (8-bit) Interface… Because it lets us blast out multiple Command and Data Bytes in a single SPI DMA Transfer.

(Without having to flip the Data / Command Pin)

More about this in the next chapter.

Why can’t we stick with the familiar 4-Wire Interface for ST7789?

I guess the PineDio Stack hardware designers wanted to free up a precious GPIO Pin for use by other components.

(And maybe the designers also thought that the 3-Wire Interface is more efficient than the 4-Wire one!)

8 9-Bit SPI for ST7789

How on earth do we send 9-bit data over 8-bit SPI to ST7789 Display?

OK hear me out… We could pack the 9-bit data into chunks of 9 bytes. Then send the chunks over 8-bit SPI.

(Why 9 bytes? Because 9 bytes = 9 bits x 8)

What if the 9-bit data doesn’t fill up a 9-byte chunk?

We fill up the rest of the chunk with the ST7789 NOP Command Byte (0x00).

Show me how?

Previously we did this for the 4-Wire (8-bit) ST7789 Interface

4-Wire ST7789 Interface

Now we do this for the 3-Wire (9-bit) ST7789 Interface

3-Wire ST7789 Interface

Thus we’re sending 8-bit data over SPI… But it magically appears as 9-bit data to ST7789!

8.1 Packing 9-Bit Data

How exactly do we pack 9-bit data into chunks of 9 bytes?

Here’s the 9-Bit Packing Logic (please pardon my peculiar pseudocode)…

To pack 9-bit data into bytes, we do this for every 8 bytes of unpacked data (Most Significant Bit first)…

If Unpacked Length mod 8 is…

0:
DCP0 bit 7
U bits 1 to 7 → P0 bits 0 to 6
U bits 0 to 0 → P1 bits 7 to 7

1:
DCP0 bit 6
U bits 2 to 7 → P0 bits 0 to 5
U bits 0 to 1 → P1 bits 6 to 7

2:
DCP0 bit 5
U bits 3 to 7 → P0 bits 0 to 4
U bits 0 to 2 → P1 bits 5 to 7

6:
DCP0 bit 1
U bits 7 to 7 → P0 bits 0 to 0
U bits 0 to 6 → P1 bits 1 to 7

7:
DCP0 bit 0
U bits 0 to 7 → P1 bits 0 to 7

Where…

(Source)

The implementation looks like this…

Packing 9-bit data

(Source)

8.2 Test the 9-Bit Packing

Since the 9-Bit Packing is implemented in C, let’s test it on Linux!

Test the 9-Bit Packing on Linux

We verify the packed data with this spreadsheet…

Verify the packed data with a spreadsheet

8.3 Does it work?

Sadly nope.

Sending packed data to ST7789 on PineDio Stack

(Source Code is here)

Our 9-bit data is correctly packed into 9-byte chunks and sent to ST7789 over SPI…

Sending packed data to ST7789 on PineDio Stack

Yet nothing appears on the ST7789 Display.

We also verified the SPI Data with our Logic Analyser and its 9-bit SPI Decoder

Logic Analyser with 9-bit SPI Decoder

9 Arduino GFX Ported To BL604

Are we being too smarty-pants with 9-bit SPI? Like adding feet to a drawing of a snake?

Let’s talk to ST7789 the simpler way… With Bit-Banging! (Instead of SPI)

moononournation has built an awesome Arduino GFX Library that supports 9-Bit-Banging to ST7789 Display…

Let’s port this Arduino Library to BL604!

moononournation / Arduino_GFX

We ported only two source files from Arduino GFX Library to BL604…

Arduino GFX Library ported to BL604

(Source)

…By mapping the Arduino API to BL604 IoT SDK.

(And we flattened the C++ Classes into plain C Functions)

Our Logic Analyser shows that the 9-bit ST7789 data is correctly Bit-Banged to ST7789…

Arduino GFX with Logic Analyser

(We’re using the 9-Bit SPI Decoder with our Logic Analyser)

Guess what? Nothing appears on PineDio Stack’s ST7789 Display! 😭

To be super sure, we tested Arduino GFX on Linux and verified the data…

Testing Arduino GFX on Linux

(Source)

Now we’re super stuck with our ST7789 testing!

10 Problem With ST7789?

Wait a minute… Is there a switch that configures ST7789 Display for 3-Wire or 4-Wire Interface?

Pins IM0 to IM3 on ST7789 will select the 3-Wire or 4-Wire Interface

Configuring ST7789 Display for 3-Wire Interface

(Source)

So for 3-Wire (9-Bit) Interface, we should hardwire the pins as…

IM3IM2IM1IM0
1101

Maybe Pins IM0 to IM3 are not hard-wired as such?

That’s a possibility… Which we’re checking with the Display Makers now.

Also we’re probing the tiny ST7789 Connector (with a sharp Pogo Pin) to understand how the pins are connected.

Probing the tiny ST7789 Connector with a sharp Pogo Pin

Here’s what we discovered from the Pogo Pin Probing

ST7789 PinBL604 GPIO
SDAGPIO 0
DCGPIO 17
SCKGPIO 11

UPDATE: There’s a new version of PineDio Stack BL604, the GPIO Numbers have changed

Probe Results

Not quite what we expected. We tried both SPI and Bit-Banging with the discovered settings…

But both don’t show anything on the ST7789 Display.

We also tried to read the display ID (RDDID) by flipping GPIO 0 between output and input modes…

But the GPIO 0 signal looks glitchy. See the top line, centre part…

Reading display ID looks glitchy

Any ideas? 🤔

UPDATE: JF commented…

About the serial modes of the ST7789, my understanding is that it supports 4 modes :

The mode implemented on the PineTime and on this LCD board is the “4-lines interface I” : data/command pin + single MOSI -> SDA pin as data pin. I think we could use the 4-lines interface II mode if we wanted to read data from the display (MOSI -> SDA, MISO -> SDO), but that is not necessary.

The naming of the pins in the datasheet are really confusing : the controller is advertised (and works) as a SPI device, but the pins are labelled as I²C pins. However, I do confirm that I’m driving the controller using the SPI bus, not the I²C!

See JF’s experiment with PineDio Stack and an external ST7789 display

11 Seeking Volunteers!

I’m really excited that PineDio Stack BL604 will be available soon!

But in the meantime, JF and I have plenty to test on PineDio Stack

  1. ST7789 Display (SPI)
  2. LoRa SX1262 (SPI)
  3. SPI Flash (SPI)
  4. Accelerometer (I2C)
  5. Heart Rate Sensor (I2C)
  6. Touch Panel (I2C)
  7. Vibrator (GPIO)
  8. Push Button (GPIO)
  9. WiFi
  10. Bluetooth LE
  11. JTAG Debugging
  12. Battery Charging
  13. Solar Power

Please let us know if you’re keen to help! 🙏

UPDATE: LoRa SX1262 on PineDio Stack has been tested OK! See this article…

PineDio Stack BL604 In A Box

12 What’s Next

Many Thanks to @moononournation and @AndreasDyhrberg for the valuable tips on testing PineDio Stack BL604!

This has been a super exciting first week of testing the Prototype Hardware for PineDio Stack BL604…

I hope you will join JF and me as we continue our testing of PineDio Stack.

(Maybe real soon we’ll create toasters, microwave ovens and pressure cookers with PineDio Stack!)

Got a question, comment or suggestion? Create an Issue or submit a Pull Request here…

lupyuen.github.io/src/pinedio.md

13 Notes

  1. This article is the expanded version of this Twitter Thread

  2. JF has successfully tested PineDio Stack’s SPI Port with an external eInk Display

  3. We have created new firmware to Bit-Bang ST7789’s 4-Wire (8-Bit) Interface: pinedio_st7789_bitbang2

Improvised Reset Button

14 Appendix: Improvised Reset Button for PineDio Stack

Sometimes we need to restart PineDio Stack to see the Boot Messages, without disconnecting the USB port. Here’s how…

  1. We assume that PineDio Stack is already powered on by our computer (via USB)

  2. Connect a Jumper Cable between Pin 5 (GND) and Pin 6 (RESET) of the JTAG Port (Pic above)

  3. Disconnect the Jumper Cable

  4. PineDio Stack will restart. The Boot Messages will appear in the Serial Terminal.