Longan Nano
Longan Nano Demo
Longan_nano::Display Class Reference

Longan Nano Display Driver. More...

#include <ST7735S_W160_H80_C16.hpp>

Inheritance diagram for Longan_nano::Display:
Collaboration diagram for Longan_nano::Display:

Classes

struct  _Sprite
 Sprite informations. More...
 

Public Member Functions

 Display (void)
 constructor Display | void | More...
 
 ~Display (void)
 destructor ~Display | void | More...
 
bool init (void)
 Public init init | void |. More...
 
int register_sprite (int origin_h, int origin_w, int size_h, int size_w, uint16_t *sprite_ptr)
 public method register_sprite | int | int | int | int | uint16_t * | More...
 
int register_sprite (int origin_h, int origin_w, int size_h, int size_w, uint16_t sprite_color)
 public method register_sprite | int | int | int | int | uint16_t | More...
 
bool update_sprite (void)
 public method update_sprite | void | More...
 
int draw_sprite (int origin_h, int origin_w, int size_h, int size_w, uint16_t *sprite_ptr)
 public method draw_sprite | int | int | int | int | uint16_t * | More...
 
int draw_sprite (int origin_h, int origin_w, int size_h, int size_w, uint16_t sprite_color)
 public method draw_sprite | int | int | int | int | uint16_t | More...
 
int clear (void)
 public method clear | void | More...
 
int clear (uint16_t color)
 public method clear | void | More...
 

Static Public Member Functions

static uint16_t color (uint8_t r, uint8_t g, uint8_t b)
 Public Method color | uint8_t | uint8_t | uint8_t |. More...
 

Protected Types

enum  _Config {
  WIDTH = 160, HEIGHT = 80, PIXEL_COUNT = WIDTH *HEIGHT, COLOR_DEPTH = 16,
  ROW_ADDRESS_OFFSET = 1, COL_ADDRESS_OFFSET = 26, RS_GPIO = GPIOB, RS_PIN = GPIO_PIN_0,
  RST_GPIO = GPIOB, RST_PIN = GPIO_PIN_1, RESET_DELAY = 1, SPI_CH = SPI0,
  SPI_CS_GPIO = GPIOB, SPI_CS_PIN = GPIO_PIN_2, SPI_CLK_GPIO = GPIOA, SPI_CLK_PIN = GPIO_PIN_5,
  SPI_MISO_GPIO = GPIOA, SPI_MISO_PIN = GPIO_PIN_6, SPI_MOSI_GPIO = GPIOA, SPI_MOSI_PIN = GPIO_PIN_7,
  USE_DMA = true, DMA_SPI_TX = DMA0, DMA_SPI_TX_CH = (dma_channel_enum)DMA_CH2
}
 Configuration parameters of the LCD Display class. More...
 
typedef enum Longan_nano::Display::_Config Config
 Configuration parameters of the LCD Display class. More...
 

Private Types

enum  _Command {
  SETUP_NORMAL_MODE = 0xB1, SETUP_IDLE_MODE = 0xB2, SETUP_PARTIAL_MODE = 0xB3, DISPLAY_INVERSION_CONTROL = 0xB4,
  POWER_GVDD = 0xC0, POWER_VGH_VGL = 0xC1, POWER_VCOM1 = 0xC5, POWER_MODE_NORMAL = 0xC2,
  POWER_MODE_IDLE = 0xC3, POWER_MODE_PARTIAL = 0xC4, ADJUST_GAMMA_PLUS = 0xE0, ADJUST_GAMMA_MINUS = 0xE1,
  COLOR_FORMAT = 0x3A, MEMORY_DATA_ACCESS_CONTROL = 0x36, DISPLAY_ON = 0x29, SLEEP_OUT_BOOSTER_ON = 0x11,
  ENABLE_DISPLAY_INVERSION = 0x21, SEND_ROW_ADDRESS = 0x2A, SEND_COL_ADDRESS = 0x2B, WRITE_MEM = 0x2C,
  TERMINATOR = 0xFF
}
 ST7735S Commands. More...
 
typedef enum Longan_nano::Display::_Command Command
 ST7735S Commands. More...
 
typedef struct Longan_nano::Display::_Sprite Sprite
 Sprite informations. More...
 

Private Member Functions

bool init_gpio (void)
 Private init init_gpio | void |. More...
 
bool init_spi (void)
 Private init init_spi | void |. More...
 
bool init_dma (void)
 Private init init_dma | void |. More...
 
bool init_st7735 (void)
 Private init init_st7735 | void |. More...
 
bool is_spi_idle (void)
 Private HAL Method is_spi_idle | void. More...
 
bool is_spi_done_tx (void)
 Private HAL Method is_spi_done_tx | void. More...
 
void spi_wait_idle (void)
 Private HAL Method spi_wait_idle | void. More...
 
void spi_wait_tbe (void)
 Private HAL Method spi_wait_tbe | void |. More...
 
void cs_active (void)
 Private HAL Method cs_active | void |. More...
 
void cs_inactive (void)
 Private HAL Method cs_inactive | void |. More...
 
void rs_mode_cmd (void)
 Private HAL Method rs_mode_cmd | void |. More...
 
void rs_mode_data (void)
 Private HAL Method rs_mode_data | void |. More...
 
void rst_active (void)
 Private HAL Method rst_active | void |. More...
 
void rst_inactive (void)
 Private HAL Method rst_inactive | void |. More...
 
void spi_set_8bit (void)
 Private HAL Method spi_set_8bit | void |. More...
 
void spi_set_16bit (void)
 Private HAL Method spi_set_16bit | void |. More...
 
void dma_send_map16 (uint16_t *data_ptr, uint16_t data_size)
 Private HAL Method dma_send_map16 | uint16_t * | uint16_t |. More...
 
void dma_send_solid16 (uint16_t *data_ptr, uint16_t data_size)
 Private HAL Method dma_send_map16 | uint16_t * | uint16_t |. More...
 

Private Attributes

Sprite g_sprite
 Runtime sprite informations. More...
 
uint16_t g_address_buffer [2]
 Buffer to send address data using DMA. More...
 
uint32_t g_sprite_status
 FSM status. More...
 

Static Private Attributes

static constexpr uint8_t g_st7735s_init_sequence []
 ST7735S initialization sequence. Stored in flash memory. More...
 

Detailed Description

Longan Nano Display Driver.

Author
Orso Eric
Version
2020-08-08


Driver to use the embedded 160x80 0.96' LCD on the longan nano
SPI0 interface with physical screen
DMA0: executes a number of SPI0 transfers in background
Hardware display has a ST7735S controller
The driver is meant to accelerate sprite based drawing
Sprite buffer and draw are going to be handled by an higher level class
2020-07-07
Ported original LCD example to class. Basic operation. DMA doesn't work
2020-07-08
Skeletron for sprites
2020-07-10
Change architecture. S7735S_W160_H80_C16.hpp. Common name drive class: Display
With another display controller, Screen class and Display class interface remains the same
S7735S_W160_H80_C16.hpp is the specific lbrary for the physical display
Clean up, partition in a more intelligent way calls. Test project for driver only without sprites
2020-07-15
Tested draw with HAL builtin
2020-07-21
Found working DMA example from Samuli Laine https://github.com/slmisc/gd32v-lcd
2020-07-22
Transplant working driver function
Refactor function to use configuration and fit class form
set_sprite and update_sprite provide a non blocking draw method that hide the wait time
application can call update_sprite and immediately continue to do work while SPI and DMA are busy
update_sprite will immediately return without doing work if SPI or DMA are busy or if there is nothing to draw
2020-07-23
Clean up example
Prune excess methods from display class. Leave only the draw sprite primitives. Application is to be given control on resource utilization of the display
Refactor all calls to use configuration enum for the hardware peripherals
2020-07-24
Fixed color conversion function
2020-08-06
Massive update of style
Refactor functions, especially initialization
Full support for USE_DMA=false. screen updates much slower at the same CPU use
2020-08-07
Bugfix: Solid color draw was bugged

Member Typedef Documentation

◆ Command

ST7735S Commands.

◆ Config

Configuration parameters of the LCD Display class.

◆ Sprite

Sprite informations.

Member Enumeration Documentation

◆ _Command

ST7735S Commands.

Enumerator
SETUP_NORMAL_MODE 
SETUP_IDLE_MODE 
SETUP_PARTIAL_MODE 
DISPLAY_INVERSION_CONTROL 
POWER_GVDD 
POWER_VGH_VGL 
POWER_VCOM1 
POWER_MODE_NORMAL 
POWER_MODE_IDLE 
POWER_MODE_PARTIAL 
ADJUST_GAMMA_PLUS 
ADJUST_GAMMA_MINUS 
COLOR_FORMAT 
MEMORY_DATA_ACCESS_CONTROL 
DISPLAY_ON 
SLEEP_OUT_BOOSTER_ON 
ENABLE_DISPLAY_INVERSION 
SEND_ROW_ADDRESS 
SEND_COL_ADDRESS 
WRITE_MEM 
TERMINATOR 

◆ _Config

Configuration parameters of the LCD Display class.

Enumerator
WIDTH 
HEIGHT 
PIXEL_COUNT 
COLOR_DEPTH 
ROW_ADDRESS_OFFSET 
COL_ADDRESS_OFFSET 
RS_GPIO 
RS_PIN 
RST_GPIO 
RST_PIN 
RESET_DELAY 
SPI_CH 
SPI_CS_GPIO 
SPI_CS_PIN 
SPI_CLK_GPIO 
SPI_CLK_PIN 
SPI_MISO_GPIO 
SPI_MISO_PIN 
SPI_MOSI_GPIO 
SPI_MOSI_PIN 
USE_DMA 
DMA_SPI_TX 
DMA_SPI_TX_CH 

Constructor & Destructor Documentation

◆ Display()

Longan_nano::Display::Display ( void  )

constructor Display | void |


initialize display class
will NOT initialize the peripherals

◆ ~Display()

Longan_nano::Display::~Display ( void  )

destructor ~Display | void |

Member Function Documentation

◆ clear() [1/2]

int Longan_nano::Display::clear ( uint16_t  color)
inline

public method clear | void |

Parameters
color| uint16_t | clear the display to a solid color
Returns
int | number of pixels drawn


Clear the screen. Blocking method.
Draw a black sprite the size of the screen

Here is the call graph for this function:

◆ clear() [2/2]

int Longan_nano::Display::clear ( void  )
inline

public method clear | void |

Returns
int | number of pixels drawn


Clear the screen. Blocking method.
Draw a black sprite the size of the screen

Here is the call graph for this function:
Here is the caller graph for this function:

◆ color()

uint16_t Longan_nano::Display::color ( uint8_t  r,
uint8_t  g,
uint8_t  b 
)
static

Public Method color | uint8_t | uint8_t | uint8_t |.

Parameters
r| uint8_t | 8bit red color channel
g| uint8_t | 8bit green color channel
b| uint8_t | 8bit blue color channel
Returns
uint16_t | RGB565 color compatible with ST7735 display color space


convert from 24b 8R8G8B space to 16bit 5R6G5B space
RRRRRRRR
GGGGGGGG
BBBBBBBB
RRRRRGGGGGGBBBBB

Here is the caller graph for this function:

◆ cs_active()

void Longan_nano::Display::cs_active ( void  )
inlineprivate

Private HAL Method cs_active | void |.


Select the ST7735 Display

Here is the caller graph for this function:

◆ cs_inactive()

void Longan_nano::Display::cs_inactive ( void  )
inlineprivate

Private HAL Method cs_inactive | void |.


Deselect the ST7735 Display

Here is the caller graph for this function:

◆ dma_send_map16()

void Longan_nano::Display::dma_send_map16 ( uint16_t *  data_ptr,
uint16_t  data_size 
)
inlineprivate

Private HAL Method dma_send_map16 | uint16_t * | uint16_t |.

Parameters
data_ptr| uint16_t * | pointer to RGB565 pixel color map
data_size| uint16_t | size of the pixel color map in pixels
Returns
void


Use the DMA to send a 16b memory through the SPI

Here is the caller graph for this function:

◆ dma_send_solid16()

void Longan_nano::Display::dma_send_solid16 ( uint16_t *  data_ptr,
uint16_t  data_size 
)
inlineprivate

Private HAL Method dma_send_map16 | uint16_t * | uint16_t |.

Parameters
data_ptr| uint16_t * | pointer to RGB565 solid color for the full sprite
data_size| uint16_t | size of the pixel color map in pixels
Returns
void


Use the DMA to send a 16b data through the SPI a number of times

Here is the caller graph for this function:

◆ draw_sprite() [1/2]

int Longan_nano::Display::draw_sprite ( int  origin_h,
int  origin_w,
int  size_h,
int  size_w,
uint16_t *  sprite_ptr 
)

public method draw_sprite | int | int | int | int | uint16_t * |

Parameters
origin_h| int | starting top left corner height of the sprite
origin_w| int | starting top left corner height of the sprite
size_h| int | height size of the sprite
size_w| int | width size of the sprite
sprite_ptr| uint16_t * | pointer to RGB565 pixel color map
Returns
int | number of pixels drawn


Draw a sprite
Blocking method
Draw a color map, requires a user buffer of the proper size

Here is the call graph for this function:
Here is the caller graph for this function:

◆ draw_sprite() [2/2]

int Longan_nano::Display::draw_sprite ( int  origin_h,
int  origin_w,
int  size_h,
int  size_w,
uint16_t  sprite_color 
)

public method draw_sprite | int | int | int | int | uint16_t |

Parameters
origin_h| int | starting top left corner height of the sprite
origin_w| int | starting top left corner height of the sprite
size_h| int | height size of the sprite
size_w| int | width size of the sprite
sprite_color| uint16_t | RGB565 pixel solid color for the full sprite
Returns
int | number of pixels drawn


Draw a sprite
Blocking method
Draw a solid color sprite and doesn't require a color map

Here is the call graph for this function:

◆ init()

bool Longan_nano::Display::init ( void  )

Public init init | void |.

Returns
bool | false = OK | true = ERR


initialize the longan nano display and related peripherals

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_dma()

bool Longan_nano::Display::init_dma ( void  )
inlineprivate

Private init init_dma | void |.

Returns
bool | false = OK | true = ERR


Initialize DMA that accelerates the SPI

Here is the caller graph for this function:

◆ init_gpio()

bool Longan_nano::Display::init_gpio ( void  )
inlineprivate

Private init init_gpio | void |.

Returns
bool | false = OK | true = ERR


HAL method
initialize GPIO configuration

Here is the caller graph for this function:

◆ init_spi()

bool Longan_nano::Display::init_spi ( void  )
inlineprivate

Private init init_spi | void |.

Returns
bool | false = OK | true = ERR


HAL method
Initialize SPI that communicates with the Display

Here is the caller graph for this function:

◆ init_st7735()

bool Longan_nano::Display::init_st7735 ( void  )
private

Private init init_st7735 | void |.

Returns
bool | false = OK | true = ERR


Send initialization sequence to the ST7735 display controller
First byte in the sequence is command
Next bytes in the sequence are terminators
If the command is a terminator, it means the initialization sequence is complete

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_spi_done_tx()

bool Longan_nano::Display::is_spi_done_tx ( void  )
inlineprivate

Private HAL Method is_spi_done_tx | void.

Returns
bool | false = BUSY | true = IDLE


return true when the SPI is done TX

Here is the caller graph for this function:

◆ is_spi_idle()

bool Longan_nano::Display::is_spi_idle ( void  )
inlineprivate

Private HAL Method is_spi_idle | void.

Returns
bool | false = BUSY | true = IDLE


return true when the SPI is IDLE

Here is the caller graph for this function:

◆ register_sprite() [1/2]

int Longan_nano::Display::register_sprite ( int  origin_h,
int  origin_w,
int  size_h,
int  size_w,
uint16_t *  sprite_ptr 
)

public method register_sprite | int | int | int | int | uint16_t * |

Parameters
origin_h| int | starting top left corner height of the sprite
origin_w| int | starting top left corner height of the sprite
size_h| int | height size of the sprite
size_w| int | width size of the sprite
sprite_ptr| uint16_t * | pointer to RGB565 pixel color map
Returns
int | number of pixels queued for draw


Ask the driver to draw a sprite
The draw method handles sprites that fill only part of the screen
If reworked, the buffer stays the same or is smaller than user buffer
1) Sprite fully inside screen area: the sprite is queued for draw
2) Sprite is fully outside screen area: no pixels are queued for draw
3) sprite is partially outside screen area: the method rework the buffer to include only pixel that can be drawn

Todo:
handle partial sprite draw
Here is the caller graph for this function:

◆ register_sprite() [2/2]

int Longan_nano::Display::register_sprite ( int  origin_h,
int  origin_w,
int  size_h,
int  size_w,
uint16_t  sprite_color 
)

public method register_sprite | int | int | int | int | uint16_t |

Parameters
origin_h| int | starting top left corner height of the sprite
origin_w| int | starting top left corner height of the sprite
size_h| int | height size of the sprite
size_w| int | width size of the sprite
sprite_color| uint16_t | RGB565 pixel solid color for the full sprite
Returns
int | number of pixels queued for draw


Ask the driver to draw a sprite with a solid color
The draw method handles sprites that fill only part of the screen
If reworked, the buffer stays the same or is smaller than user buffer
1) Sprite fully inside screen area: the sprite is queued for draw
2) Sprite is fully outside screen area: no pixels are queued for draw
3) sprite is partially outside screen area: the method rework the buffer to include only pixel that can be drawn

Todo:
handle partial sprite draw

◆ rs_mode_cmd()

void Longan_nano::Display::rs_mode_cmd ( void  )
inlineprivate

Private HAL Method rs_mode_cmd | void |.


Send a command to the display

Here is the caller graph for this function:

◆ rs_mode_data()

void Longan_nano::Display::rs_mode_data ( void  )
inlineprivate

Private HAL Method rs_mode_data | void |.


Send data to the display

Here is the caller graph for this function:

◆ rst_active()

void Longan_nano::Display::rst_active ( void  )
inlineprivate

Private HAL Method rst_active | void |.


Assert the reset pin of the physical display
The display will need time to become ready after an assert

Here is the caller graph for this function:

◆ rst_inactive()

void Longan_nano::Display::rst_inactive ( void  )
inlineprivate

Private HAL Method rst_inactive | void |.


Deassert the reset pin of the physical display

Here is the caller graph for this function:

◆ spi_set_16bit()

void Longan_nano::Display::spi_set_16bit ( void  )
inlineprivate

Private HAL Method spi_set_16bit | void |.


Configure the SPI to 16b

Here is the caller graph for this function:

◆ spi_set_8bit()

void Longan_nano::Display::spi_set_8bit ( void  )
inlineprivate

Private HAL Method spi_set_8bit | void |.


Configure the SPI to 8b

Here is the caller graph for this function:

◆ spi_wait_idle()

void Longan_nano::Display::spi_wait_idle ( void  )
inlineprivate

Private HAL Method spi_wait_idle | void.


Block execution until SPI is IDLE

Here is the caller graph for this function:

◆ spi_wait_tbe()

void Longan_nano::Display::spi_wait_tbe ( void  )
inlineprivate

Private HAL Method spi_wait_tbe | void |.


Block execution until SPI is done TX

Here is the caller graph for this function:

◆ update_sprite()

bool Longan_nano::Display::update_sprite ( void  )

public method update_sprite | void |

Returns
bool | false = IDLE | true = BUSY


Execute a step of the FSM that interfaces with the physical display
Handle both solid color and color map
sprite data must already be valid before execution

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ g_address_buffer

uint16_t Longan_nano::Display::g_address_buffer[2]
private

Buffer to send address data using DMA.

◆ g_sprite

Sprite Longan_nano::Display::g_sprite
private

Runtime sprite informations.

◆ g_sprite_status

uint32_t Longan_nano::Display::g_sprite_status
private

FSM status.

◆ g_st7735s_init_sequence

constexpr uint8_t Longan_nano::Display::g_st7735s_init_sequence[]
staticconstexprprivate
Initial value:
=
{
Command::ENABLE_DISPLAY_INVERSION, Command::TERMINATOR,
Command::SETUP_NORMAL_MODE, 0x05, 0x3a, 0x3a, Command::TERMINATOR,
Command::SETUP_IDLE_MODE, 0x05, 0x3a, 0x3a, Command::TERMINATOR,
Command::SETUP_PARTIAL_MODE, 0x05, 0x3a, 0x3a, 0x05, 0x3a, 0x3a, Command::TERMINATOR,
Command::DISPLAY_INVERSION_CONTROL, 0x03, Command::TERMINATOR,
Command::POWER_GVDD, 0x62, 0x02, 0x04, Command::TERMINATOR,
Command::POWER_VGH_VGL, 0xc0, Command::TERMINATOR,
Command::POWER_MODE_NORMAL, 0x0d, 0x00, Command::TERMINATOR,
Command::POWER_MODE_IDLE, 0x8d, 0x6a, Command::TERMINATOR,
Command::POWER_MODE_PARTIAL, 0x8d, 0xee, Command::TERMINATOR,
Command::POWER_VCOM1, 0x0e, Command::TERMINATOR,
Command::ADJUST_GAMMA_PLUS, 0x10, 0x0e, 0x02, 0x03, 0x0e, 0x07, 0x02, 0x07, 0x0a, 0x12, 0x27, 0x37, 0x00, 0x0d, 0x0e, 0x10, Command::TERMINATOR,
Command::ADJUST_GAMMA_MINUS, 0x10, 0x0e, 0x03, 0x03, 0x0f, 0x06, 0x02, 0x08, 0x0a, 0x13, 0x26, 0x36, 0x00, 0x0d, 0x0e, 0x10, Command::TERMINATOR,
Command::COLOR_FORMAT, 0x55, Command::TERMINATOR,
Command::MEMORY_DATA_ACCESS_CONTROL, 0x78, Command::TERMINATOR,
Command::DISPLAY_ON, Command::TERMINATOR,
Command::SLEEP_OUT_BOOSTER_ON, Command::TERMINATOR,
Command::TERMINATOR,
}

ST7735S initialization sequence. Stored in flash memory.


The documentation for this class was generated from the following file: