Skip to content

Drawing APIs

Building and Flashing the Program

Create a new Pico SDK project named tftlcd-apis.

Create Pico SDK Project
  1. In VSCode, run >Raspberry Pi Pico: New Pico Project in the command palette.
  2. In the dialog below, select C/C++. new-project-dialog

  3. Create a project with the following settings:

    • Name ... Enter the project name.
    • Board type ... Select your board type.
    • Location ... Select the parent directory where the project directory will be created.
    • Stdio support ... Leave Console over USB unchecked when you use LABOPlatform or other USB features because they conflict with each other. You can enable it by editing the CMakeLists.txt file later.
    • Code generation options ... Check Generate C++ code.

new-project

Open Existing Pico SDK Project

Open the project folder in VSCode using one of the following methods:

  • In a command prompt, change the current directory to the project folder and execute code ..
  • In a Explorer, choose the project folder, push Alt+D to focus the address bar, and execute code ..

    vscode-from-explorer

If the folder is already prepared as a Pico SDK project, just proceed with editing and building the project.

If not, you will see the following message at the bottom right corner of VSCode.

do-you-want-to-import

Click Yes and you will see the following window.

import-project

Click Import and the project will be prepared as a Pico SDK project.

When the Do you want to import this project as Raspberry Pi Pico project? message disappears before you click Yes, you can reveal it by clicking the icon notify-icon at the bottom right corner of VSCode.

Clone the pico-jxglib repository from GitHub so the direcory structure looks like this:

├── pico-jxglib/
└── tftlcd-apis/
    ├── CMakeLists.txt
    ├── tftlcd-apis.cpp
    └── ...
Clone the Repository

Change the current directory to the parent directory where you want to clone the pico-jxglib repository and run the following commands:

$ git clone https://github.com/ypsitau/pico-jxglib.git
$ cd pico-jxglib
$ git submodule update --init --recursive

pico-jxglib is updated almost daily. If you've already cloned it, run the following command in the pico-jxglib directory to get the latest version:

$ git pull

A directory from a Git repository can safely be moved to another location even after cloning.

Add the following lines to the end of CMakeLists.txt:

CMakeLists.txt
1
2
3
4
target_link_libraries(tftlcd-apis
    jxglib_Shell jxglib_Serial jxglib_ShellCmd_Basic
    jxglib_Display_ST7789)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../pico-jxglib pico-jxglib)

Edit the source file as follows:

tftlcd-apis.cpp
#include <stdio.h>
#include "pico/stdlib.h"
#include "jxglib/Shell.h"
#include "jxglib/Serial.h"
#include "jxglib/Display/ST7789.h"
#include "jxglib/sample/cat-240x320.h"
#include "jxglib/Font/shinonome16.h"

using namespace jxglib;

int main()
{
    ::stdio_init_all();
    // Prepare the Shell with Stdio
    Serial::Terminal terminal;
    Shell::AttachTerminal(terminal.Initialize());
    // Initialize the display
    ::spi_init(spi1, 125 * 1000 * 1000);
    GPIO14.set_function_SPI1_SCK();
    GPIO15.set_function_SPI1_TX();
    Display::ST7789 display(spi1, 240, 320, {RST: GPIO10, DC: GPIO11, CS: GPIO12, BL: GPIO13});
    display.Initialize(Display::Dir::Rotate0);
    display.DrawImage(20, 20, image_cat_240x320, {20, 20, 200, 200});
    display.SetFont(Font::shinonome16);
    const char* str = "I am a cat";
    Size sizeStr = display.CalcStringSize(str);
    int x = (display.GetWidth() - sizeStr.width) / 2, y = 230;
    display.DrawString(x, y, str);
    display.DrawRect(x - 8, y - 4, sizeStr.width + 8 * 2, sizeStr.height + 4 * 2, Color::white);
    display.DrawRectFill(0, 260, 55, 60, Color::red);
    display.DrawRectFill(60, 260, 55, 60, Color::green);
    display.DrawRectFill(120, 260, 55, 60, Color::blue);
    display.DrawRectFill(180, 260, 55, 60, Color::aqua);
    for (;;) {
        Tickable::Tick();
    }
}

Running the Program

tftlcd-apis.jpg

Program Explanation

The first half of the source file initializes the device.

::spi_init(spi1, 125 * 1000 * 1000);

This is a Pico SDK function. It initializes SPI1 with a clock of 125MHz.

GPIO14.set_function_SPI1_SCK();
GPIO15.set_function_SPI1_TX();

Sets GPIO14 and GPIO15 to SPI1 SCK and TX (MOSI), respectively.

Display::ST7789 display(spi1, 240, 320, {RST: GPIO10, DC: GPIO11, CS: GPIO12, BL: GPIO13});

Creates an instance to operate the ST7789. Specify the SPI to connect, display size, and GPIOs to connect (RST: Reset, DC: Data/Command, CS: Chip Select, BL: Backlight).

display.Initialize(Display::Dir::Rotate0);

Initializes the LCD and makes it ready for drawing. The argument specifies the LCD drawing direction as follows:

  • Display::Dir::Rotate0 or Display::Dir::Normal ... Draws in the normal direction
  • Display::Dir::Rotate90 ... Rotates 90 degrees
  • Display::Dir::Rotate180 ... Rotates 180 degrees
  • Display::Dir::Rotate270 ... Rotates 270 degrees
  • Display::Dir::MirrorHorz ... Mirrors horizontally
  • Display::Dir::MirrorVert ... Mirrors vertically

After this, you can perform drawing operations on the display instance.

display.DrawImage(20, 20, image_cat_240x320, {20, 20, 200, 200});

Draws an image at the specified coordinates. The fourth argument specifies the clipping region within the image.

display.SetFont(Font::shinonome16);

Specifies the font data Font::shinonome16 defined in the include file jxglib/Font/shinonome16-japanese-level1.h.

Size sizeStr = display.CalcStringSize(str);

Calculates the size when drawing the string with the specified font.

display.DrawString(x, y, str);

Draws the string at the specified coordinates.

display.DrawRect(x - 8, y - 4, sizeStr.width + 8 * 2, sizeStr.height + 4 * 2, Color::white);

Draws a rectangle with specified coordinates, size, and color.

display.DrawRectFill(0, 260, 55, 60, Color::red);
display.DrawRectFill(60, 260, 55, 60, Color::green);
display.DrawRectFill(120, 260, 55, 60, Color::blue);
display.DrawRectFill(180, 260, 55, 60, Color::aqua);

Draws filled rectangles with specified coordinates, size, and color.