diff --git a/cores/arduino/kendryte-standalone-sdk b/cores/arduino/kendryte-standalone-sdk index 1743492..7440800 160000 --- a/cores/arduino/kendryte-standalone-sdk +++ b/cores/arduino/kendryte-standalone-sdk @@ -1 +1 @@ -Subproject commit 174349202037a760e1865210b15a0703566e8064 +Subproject commit 7440800a8e6c6ee760e8f3a761fe366fbc3972cd diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index f8c7188..3c2c336 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -15,6 +15,9 @@ int main( void ) pll_init(); plic_init(); uarths_init(); + gpio_init(); + sysctl_set_power_mode(SYSCTL_POWER_BANK6,SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK7,SYSCTL_POWER_V18); setup(); do { diff --git a/libraries/SPI/src/SPI.h b/libraries/SPI/src/SPI.h index 2f0e647..a903640 100644 --- a/libraries/SPI/src/SPI.h +++ b/libraries/SPI/src/SPI.h @@ -67,6 +67,9 @@ public: void transferBytes(uint8_t * data, uint8_t * out, uint32_t size); + // special + spi_id_t busId(){ return _spiNum; } + }; extern SPIClass SPI; diff --git a/libraries/Sipeed_ST7789/examples/basic_display/basic_display.ino b/libraries/Sipeed_ST7789/examples/basic_display/basic_display.ino new file mode 100644 index 0000000..09b8933 --- /dev/null +++ b/libraries/Sipeed_ST7789/examples/basic_display/basic_display.ino @@ -0,0 +1,18 @@ +#include + +SPIClass spi_(SPI0); +Sipeed_ST7789 lcd(320, 240, spi_); + +void setup() +{ + lcd.begin(15000000, COLOR_BLACK); + lcd.drawRect(20, 20, 50, 50, COLOR_WHITE); + lcd.drawCircle(100, 100, 40, COLOR_WHITE); + lcd.fillTriangle(10, 200, 300, 200, 300, 150, COLOR_WHITE); +} + +void loop() +{ + +} + diff --git a/libraries/Sipeed_ST7789/keywords.txt b/libraries/Sipeed_ST7789/keywords.txt new file mode 100644 index 0000000..e6f2c53 --- /dev/null +++ b/libraries/Sipeed_ST7789/keywords.txt @@ -0,0 +1,51 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Sipeed_ST7789 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +drawPixel KEYWORD2 +writePixel KEYWORD2 +writeFillRect KEYWORD2 +writeFastVLine KEYWORD2 +writeFastHLine KEYWORD2 +drawFastVLine KEYWORD2 +drawFastHLine KEYWORD2 +fillRect KEYWORD2 +fillScreen KEYWORD2 +drawRect KEYWORD2 +setRotation KEYWORD2 +invertDisplay KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +COLOR_BLACK LITERAL1 +COLOR_NAVY LITERAL1 +COLOR_DARKGREEN LITERAL1 +COLOR_DARKCYAN LITERAL1 +COLOR_MAROON LITERAL1 +COLOR_PURPLE LITERAL1 +COLOR_OLIVE LITERAL1 +COLOR_LIGHTGREY LITERAL1 +COLOR_DARKGREY LITERAL1 +COLOR_BLUE LITERAL1 +COLOR_GREEN LITERAL1 +COLOR_CYAN LITERAL1 +COLOR_RED LITERAL1 +COLOR_MAGENTA LITERAL1 +COLOR_YELLOW LITERAL1 +COLOR_WHITE LITERAL1 +COLOR_ORANGE LITERAL1 +COLOR_GREENYELLOW LITERAL1 +COLOR_PINK LITERAL1 + diff --git a/libraries/Sipeed_ST7789/library.properties b/libraries/Sipeed_ST7789/library.properties new file mode 100644 index 0000000..31ce178 --- /dev/null +++ b/libraries/Sipeed_ST7789/library.properties @@ -0,0 +1,9 @@ +name=Sipeed_ST7789 +version=1.0 +author=Neucrack +maintainer=Neucrack +sentence=LCD display st7789 driver +paragraph=LCD display st7789 driver +category=Display +url= +architectures=k210 diff --git a/libraries/Sipeed_ST7789/src/Sipeed_ST7789.cpp b/libraries/Sipeed_ST7789/src/Sipeed_ST7789.cpp new file mode 100644 index 0000000..3862e0f --- /dev/null +++ b/libraries/Sipeed_ST7789/src/Sipeed_ST7789.cpp @@ -0,0 +1,97 @@ + +#include "Sipeed_ST7789.h" +#include "lcd.h" +#include "sysctl.h" +#include "utils.h" + +Sipeed_ST7789::Sipeed_ST7789(uint16_t w, uint16_t h, SPIClass& spi, int8_t dc_pin, int8_t rst_pin, uint8_t dma_ch ) +:Adafruit_GFX(w,h), + _spi(spi), _dcxPin(dc_pin), _rstPin(rst_pin), + _dmaCh(dma_ch) +{ + configASSERT(_spi.busId()==SPI0); +} + +Sipeed_ST7789::~Sipeed_ST7789(void) +{ + +} + +boolean Sipeed_ST7789::begin( uint32_t freq, uint16_t color ) +{ + uint8_t spiNum = _spi.busId(); + if( (spi_id_t)spiNum == SPI0) + { + fpioa_set_function(SIPEED_ST7789_SS_PIN , (fpioa_function_t)(FUNC_SPI0_SS0 + SIPEED_ST7789_SS)); + fpioa_set_function(SIPEED_ST7789_SCLK_PIN, (fpioa_function_t)FUNC_SPI0_SCLK); + } + else if((spi_id_t)spiNum == SPI1) + { + fpioa_set_function(SIPEED_ST7789_SS_PIN , (fpioa_function_t)(FUNC_SPI1_SS0 + SIPEED_ST7789_SS)); + fpioa_set_function(SIPEED_ST7789_SCLK_PIN, (fpioa_function_t)FUNC_SPI1_SCLK); + } + sysctl_set_spi0_dvp_data(1); + _freq = freq; + lcd_init(spiNum, SIPEED_ST7789_SS, SIPEED_ST7789_RST_GPIONUM, SIPEED_ST7789_DCX_GPIONUM, _freq, _rstPin, _dcxPin, _dmaCh); + lcd_clear(color); + return true; +} + + +void Sipeed_ST7789::drawPixel(int16_t x, int16_t y, uint16_t color) +{ + lcd_draw_point(x, y, color); +} +void Sipeed_ST7789::writePixel(int16_t x, int16_t y, uint16_t color) +{ + lcd_draw_point(x, y, color); +} + +void Sipeed_ST7789::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) +{ + lcd_fill_rectangle(x, y , x+w-1, y+h-1, color); +} + +void Sipeed_ST7789::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) +{ + lcd_fill_rectangle(x, y, x, y+h-1, color); +} + +void Sipeed_ST7789::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) +{ + lcd_fill_rectangle(x, y, x+w-1, y, color); +} + +void Sipeed_ST7789::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) +{ + lcd_fill_rectangle(x, y, x, y+h-1, color); +} + +void Sipeed_ST7789::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) +{ + lcd_fill_rectangle(x, y, x+w-1, y, color); +} + +void Sipeed_ST7789::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) +{ + lcd_fill_rectangle(x, y , x+w-1, y+h-1, color); +} + +void Sipeed_ST7789::fillScreen(uint16_t color) +{ + lcd_clear(color); +} + +void Sipeed_ST7789::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) +{ + lcd_draw_rectangle(x, y, x+w-1, y+h-1, 1, color); +} + +void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, uint16_t lineWidth) +{ + lcd_draw_rectangle(x, y, x+w-1, y+h-1, lineWidth, color); +} + + + + diff --git a/libraries/Sipeed_ST7789/src/Sipeed_ST7789.h b/libraries/Sipeed_ST7789/src/Sipeed_ST7789.h new file mode 100644 index 0000000..fe0f971 --- /dev/null +++ b/libraries/Sipeed_ST7789/src/Sipeed_ST7789.h @@ -0,0 +1,93 @@ +#ifndef _SIPEED_ST7789_H +#define _SIPEED_ST7789_H + + +#include +#include + + +#if (defined(BOARD_SIPEED_MAIX_GO) || defined(BOARD_SIPEED_MAIX_ONE_DOCK) ) +#define SIPEED_ST7789_RST_PIN 37 +#define SIPEED_ST7789_DCX_PIN 38 +#define SIPEED_ST7789_SS_PIN 36 +#define SIPEED_ST7789_SCLK_PIN 39 +#else +#define SIPEED_ST7789_RST_PIN 37 +#define SIPEED_ST7789_DCX_PIN 38 +#define SIPEED_ST7789_SS_PIN 36 +#define SIPEED_ST7789_SCLK_PIN 39 +#endif + +// default peripheral +#define SIPEED_ST7789_RST_GPIONUM 6 +#define SIPEED_ST7789_DCX_GPIONUM 7 +#define SIPEED_ST7789_SS 3 + + +#define COLOR_BLACK 0x0000 +#define COLOR_NAVY 0x000F +#define COLOR_DARKGREEN 0x03E0 +#define COLOR_DARKCYAN 0x03EF +#define COLOR_MAROON 0x7800 +#define COLOR_PURPLE 0x780F +#define COLOR_OLIVE 0x7BE0 +#define COLOR_LIGHTGREY 0xC618 +#define COLOR_DARKGREY 0x7BEF +#define COLOR_BLUE 0x001F +#define COLOR_GREEN 0x07E0 +#define COLOR_CYAN 0x07FF +#define COLOR_RED 0xF800 +#define COLOR_MAGENTA 0xF81F +#define COLOR_YELLOW 0xFFE0 +#define COLOR_WHITE 0xFFFF +#define COLOR_ORANGE 0xFD20 +#define COLOR_GREENYELLOW 0xAFE5 +#define COLOR_PINK 0xF81F + + +class Sipeed_ST7789 : public Adafruit_GFX{ +public: + /** + * @param rst_pin -1: not use reset pin + */ + Sipeed_ST7789(uint16_t w, uint16_t h, SPIClass& spi, int8_t dc_pin = SIPEED_ST7789_DCX_PIN, int8_t rst_pin = SIPEED_ST7789_RST_PIN , uint8_t dma_ch = 3); + + ~Sipeed_ST7789(void); + + boolean begin( uint32_t freq = 15000000, uint16_t color = 0xffff ); + // void display(void); + // void clearDisplay(uint16_t color); + // void invertDisplay(boolean i); + // void dim(boolean dim); + virtual void drawPixel(int16_t x, int16_t y, uint16_t color); + virtual void writePixel(int16_t x, int16_t y, uint16_t color); + virtual void writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + virtual void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color); + virtual void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color); + + virtual void + drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color), + drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color), + fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color), + fillScreen(uint16_t color), + drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color); + + void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color, uint16_t lineWidth); + + //TODO: direction + // virtual void setRotation(uint8_t r); + // virtual void invertDisplay(boolean i); + +private: + SPIClass& _spi; + int8_t _dcxPin; + int8_t _rstPin; + uint8_t _dmaCh; + uint32_t _freq; + + + +}; + +#endif + diff --git a/libraries/Sipeed_ST7789/src/lcd.c b/libraries/Sipeed_ST7789/src/lcd.c new file mode 100644 index 0000000..f1cdc7f --- /dev/null +++ b/libraries/Sipeed_ST7789/src/lcd.c @@ -0,0 +1,283 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "lcd.h" + +static lcd_ctl_t lcd_ctl; + +uint16_t g_lcd_display_buff[LCD_Y_MAX * LCD_X_MAX]; + +static uint16_t gray2rgb565[64] = { + 0x0000, + 0x2000, + 0x4108, + 0x6108, + 0x8210, + 0xa210, + 0xc318, + 0xe318, + 0x0421, + 0x2421, + 0x4529, + 0x6529, + 0x8631, + 0xa631, + 0xc739, + 0xe739, + 0x0842, + 0x2842, + 0x494a, + 0x694a, + 0x8a52, + 0xaa52, + 0xcb5a, + 0xeb5a, + 0x0c63, + 0x2c63, + 0x4d6b, + 0x6d6b, + 0x8e73, + 0xae73, + 0xcf7b, + 0xef7b, + 0x1084, + 0x3084, + 0x518c, + 0x718c, + 0x9294, + 0xb294, + 0xd39c, + 0xf39c, + 0x14a5, + 0x34a5, + 0x55ad, + 0x75ad, + 0x96b5, + 0xb6b5, + 0xd7bd, + 0xf7bd, + 0x18c6, + 0x38c6, + 0x59ce, + 0x79ce, + 0x9ad6, + 0xbad6, + 0xdbde, + 0xfbde, + 0x1ce7, + 0x3ce7, + 0x5def, + 0x7def, + 0x9ef7, + 0xbef7, + 0xdfff, + 0xffff, +}; + +void lcd_polling_enable(void) +{ + lcd_ctl.mode = 0; +} + +void lcd_interrupt_enable(void) +{ + lcd_ctl.mode = 1; +} + +void lcd_init(uint8_t spi, uint8_t ss, uint8_t rst, uint8_t dcx, uint32_t freq, int8_t rst_pin, int8_t dcx_pin, uint8_t dma_ch) +{ + uint8_t data = 0; + + tft_hard_init(spi, ss, rst, dcx, freq, rst_pin, dcx_pin, dma_ch); + /*soft reset*/ + tft_write_command(SOFTWARE_RESET); + usleep(100000); + /*exit sleep*/ + tft_write_command(SLEEP_OFF); + usleep(100000); + /*pixel format*/ + tft_write_command(PIXEL_FORMAT_SET); + data = 0x55; + tft_write_byte(&data, 1); + lcd_set_direction(DIR_YX_RLDU); + + /*display on*/ + tft_write_command(DISPALY_ON); + lcd_polling_enable(); +} + +void lcd_set_direction(lcd_dir_t dir) +{ + //dir |= 0x08; //excahnge RGB + lcd_ctl.dir = dir; + if (dir & DIR_XY_MASK) + { + lcd_ctl.width = LCD_Y_MAX - 1; + lcd_ctl.height = LCD_X_MAX - 1; + } + else + { + lcd_ctl.width = LCD_X_MAX - 1; + lcd_ctl.height = LCD_Y_MAX - 1; + } + + tft_write_command(MEMORY_ACCESS_CTL); + tft_write_byte((uint8_t *)&dir, 1); +} + +static uint32_t lcd_freq = 20000000; // default to 20MHz +void lcd_set_freq(uint32_t freq) +{ + tft_set_clk_freq(freq); + lcd_freq = freq; +} + +uint32_t lcd_get_freq() +{ + return lcd_freq; +} + +void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) +{ + uint8_t data[4] = {0}; + + data[0] = (uint8_t)(x1 >> 8); + data[1] = (uint8_t)(x1); + data[2] = (uint8_t)(x2 >> 8); + data[3] = (uint8_t)(x2); + tft_write_command(HORIZONTAL_ADDRESS_SET); + tft_write_byte(data, 4); + + data[0] = (uint8_t)(y1 >> 8); + data[1] = (uint8_t)(y1); + data[2] = (uint8_t)(y2 >> 8); + data[3] = (uint8_t)(y2); + tft_write_command(VERTICAL_ADDRESS_SET); + tft_write_byte(data, 4); + + tft_write_command(MEMORY_WRITE); +} + +void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color) +{ + lcd_set_area(x, y, x, y); + tft_write_byte((uint8_t*)&color, 2); +} + +void lcd_clear(uint16_t color) +{ + uint32_t data = ((uint32_t)color << 16) | (uint32_t)color; + + lcd_set_area(0, 0, lcd_ctl.width, lcd_ctl.height); + tft_fill_data(&data, LCD_X_MAX * LCD_Y_MAX / 2); +} + +void lcd_fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) +{ + uint32_t data = ((uint32_t)color << 16) | (uint32_t)color; + lcd_set_area(x1, y1, x2, y2); + tft_fill_data(&data, (y2+1-y1)*(x2+1-x1) ); +} + +void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width, uint16_t color) +{ + uint32_t data_buf[640] = {0}; + uint32_t *p = data_buf; + uint32_t data = color; + uint32_t index = 0; + + data = (data << 16) | data; + for (index = 0; index < 160 * width; index++) + *p++ = data; + + lcd_set_area(x1, y1, x2, y1 + width - 1); + tft_write_byte((uint8_t*)data_buf, ((x2 - x1 + 1) * width + 1) * 2); + lcd_set_area(x1, y2 - width + 1, x2, y2); + tft_write_byte((uint8_t*)data_buf, ((x2 - x1 + 1) * width + 1) * 2); + lcd_set_area(x1, y1, x1 + width - 1, y2); + tft_write_byte((uint8_t*)data_buf, ((y2 - y1 + 1) * width + 1) * 2); + lcd_set_area(x2 - width + 1, y1, x2, y2); + tft_write_byte((uint8_t*)data_buf, ((y2 - y1 + 1) * width + 1) * 2); +} + +#define SWAP_16(x) ((x >> 8 & 0xff) | (x << 8)) + +void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr) +{ + uint32_t i; + uint16_t *p = (uint16_t *)ptr; + lcd_set_area(x1, y1, x1 + width - 1, y1 + height - 1); + for (i = 0; i < LCD_MAX_PIXELS; i += 2) + { + g_lcd_display_buff[i] = SWAP_16(*(p + 1)); + g_lcd_display_buff[i + 1] = SWAP_16(*(p)); + p += 2; + } + tft_write_word((uint32_t*)g_lcd_display_buff, width * height / 2); +} + +//draw pic's roi on (x,y) +//x,y of LCD, w,h is pic; rx,ry,rw,rh is roi +void lcd_draw_pic_roi(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t rx, uint16_t ry, uint16_t rw, uint16_t rh, uint32_t *ptr) +{ + int y_oft; + uint8_t *p; + for (y_oft = 0; y_oft < rh; y_oft++) + { //draw line by line + p = (uint8_t *)(ptr) + w * 2 * (y_oft + ry) + 2 * rx; + lcd_set_area(x, y + y_oft, x + rw - 1, y + y_oft); + tft_write_byte(p, rw * 2); //, lcd_ctl.mode ? 2 : 0); + } + return; +} + +static uint16_t line_buf[320]; //TODO: optimize +void lcd_draw_pic_gray(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint8_t *ptr) +{ + int x, y; + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + line_buf[x] = gray2rgb565[(ptr[y * width + x]) >> 2]; + } + lcd_set_area(x1, y1 + y, x1 + width - 1, y1 + y); + tft_write_byte((uint8_t*)line_buf, width * 2); + } + return; +} + +void lcd_draw_pic_grayroi(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t rx, uint16_t ry, uint16_t rw, uint16_t rh, uint8_t *ptr) +{ + int y_oft; + uint8_t *p; + for (y_oft = 0; y_oft < rh; y_oft++) + { //draw line by line + p = (uint8_t *)(ptr) + w * (y_oft + ry) + rx; + lcd_draw_pic_gray(x, y + y_oft, rw, 1, p); + } + return; +} + +void lcd_ram_cpyimg(char *lcd, int lcdw, char *img, int imgw, int imgh, int x, int y) +{ + int i; + for (i = 0; i < imgh; i++) + { + memcpy(lcd + lcdw * 2 * (y + i) + x * 2, img + imgw * 2 * i, imgw * 2); + } + return; +} diff --git a/libraries/Sipeed_ST7789/src/lcd.h b/libraries/Sipeed_ST7789/src/lcd.h new file mode 100644 index 0000000..e01f391 --- /dev/null +++ b/libraries/Sipeed_ST7789/src/lcd.h @@ -0,0 +1,98 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _LCD_H_ +#define _LCD_H_ + +#include +#include "st7789.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* clang-format off */ +#define LCD_X_MAX (240) +#define LCD_Y_MAX (320) +#define LCD_MAX_PIXELS (76800) //LCD_X_MAX*LCD_Y_MAX + +#define BLACK 0x0000 +#define NAVY 0x000F +#define DARKGREEN 0x03E0 +#define DARKCYAN 0x03EF +#define MAROON 0x7800 +#define PURPLE 0x780F +#define OLIVE 0x7BE0 +#define LIGHTGREY 0xC618 +#define DARKGREY 0x7BEF +#define BLUE 0x001F +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define RED 0xF800 +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF +#define ORANGE 0xFD20 +#define GREENYELLOW 0xAFE5 +#define PINK 0xF81F +#define USER_COLOR 0xAA55 +/* clang-format on */ + +typedef enum _lcd_dir +{ + DIR_XY_RLUD = 0x00, + DIR_YX_RLUD = 0x20, + DIR_XY_LRUD = 0x40, + DIR_YX_LRUD = 0x60, + DIR_XY_RLDU = 0x80, + DIR_YX_RLDU = 0xA0, + DIR_XY_LRDU = 0xC0, + DIR_YX_LRDU = 0xE0, + DIR_XY_MASK = 0x20, + DIR_MASK = 0xE0, +} lcd_dir_t; + +typedef struct _lcd_ctl +{ + uint8_t mode; + uint8_t dir; + uint16_t width; + uint16_t height; +} lcd_ctl_t; + +void lcd_polling_enable(void); +void lcd_interrupt_enable(void); +void lcd_init(uint8_t spi, uint8_t ss, uint8_t rst, uint8_t dcx, uint32_t freq, int8_t rst_pin, int8_t dcx_pin, uint8_t dma_ch); +void lcd_clear(uint16_t color); +void lcd_set_freq(uint32_t freq); +uint32_t lcd_get_freq(); +void lcd_set_direction(lcd_dir_t dir); +void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); +void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color); +void lcd_draw_string(uint16_t x, uint16_t y, char *str, uint16_t color); +void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr); +void lcd_draw_pic_roi(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t rx, uint16_t ry, uint16_t rw, uint16_t rh, uint32_t *ptr); +void lcd_draw_pic_gray(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint8_t *ptr); +void lcd_draw_pic_grayroi(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t rx, uint16_t ry, uint16_t rw, uint16_t rh, uint8_t *ptr); +void lcd_fill_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); +void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width, uint16_t color); +void lcd_ram_cpyimg(char* lcd, int lcdw, char* img, int imgw, int imgh, int x, int y); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/libraries/Sipeed_ST7789/src/st7789.c b/libraries/Sipeed_ST7789/src/st7789.c new file mode 100644 index 0000000..26c6faa --- /dev/null +++ b/libraries/Sipeed_ST7789/src/st7789.c @@ -0,0 +1,107 @@ +#include "st7789.h" + + +static uint8_t g_gpio_dcx; +static int8_t g_gpio_rst; +static spi_device_num_t g_spi_num; +static dmac_channel_number_t g_dma_ch; +static uint8_t g_ss; + +static void init_dcx(uint8_t dcx, int8_t dcx_pin) +{ + fpioa_set_function(dcx_pin , FUNC_GPIO0 + dcx); + g_gpio_dcx = dcx; + gpio_set_drive_mode(g_gpio_dcx, GPIO_DM_OUTPUT); + gpio_set_pin(g_gpio_dcx, GPIO_PV_HIGH); +} + +static void set_dcx_control(void) +{ + gpio_set_pin(g_gpio_dcx, GPIO_PV_LOW); +} + +static void set_dcx_data(void) +{ + gpio_set_pin(g_gpio_dcx, GPIO_PV_HIGH); +} + +static void init_rst(uint8_t rst, int8_t rst_pin) +{ + g_gpio_rst = rst; + if( rst_pin < 0) + return ; + fpioa_set_function(rst_pin , FUNC_GPIO0 + rst); + gpio_set_drive_mode(g_gpio_rst, GPIO_DM_OUTPUT); + gpio_set_pin(g_gpio_rst, GPIO_PV_HIGH); +} + +static void set_rst(uint8_t val) +{ + if(g_gpio_rst < 0) + return ; + gpio_set_pin(g_gpio_rst, val); +} + +void tft_set_clk_freq(uint32_t freq) +{ + spi_set_clk_rate(g_spi_num, freq); +} + +void tft_hard_init(uint8_t spi, uint8_t ss, uint8_t rst, uint8_t dcx, uint32_t freq, int8_t rst_pin, int8_t dcx_pin, uint8_t dma_ch) +{ + g_spi_num = spi; + g_dma_ch = dma_ch; + g_ss = ss; + init_dcx(dcx, dcx_pin); + init_rst(rst, rst_pin); + set_rst(0); + spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); + tft_set_clk_freq(freq); + set_rst(1); +} + +void tft_write_command(uint8_t cmd) +{ + set_dcx_control(); + spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); + spi_init_non_standard(g_spi_num, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, + SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); + spi_send_data_normal_dma(g_dma_ch, g_spi_num, g_ss, (uint8_t *)(&cmd), 1, SPI_TRANS_CHAR); +} + +void tft_write_byte(uint8_t *data_buf, uint32_t length) +{ + set_dcx_data(); + spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); + spi_init_non_standard(g_spi_num, 0 /*instrction length*/, 8 /*address length*/, 0 /*wait cycles*/, + SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); + spi_send_data_normal_dma(g_dma_ch, g_spi_num, g_ss, data_buf, length, SPI_TRANS_CHAR); +} + +void tft_write_half(uint16_t *data_buf, uint32_t length) +{ + set_dcx_data(); + spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0); + spi_init_non_standard(g_spi_num, 0 /*instrction length*/, 16 /*address length*/, 0 /*wait cycles*/, + SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); + spi_send_data_normal_dma(g_dma_ch, g_spi_num, g_ss, data_buf, length, SPI_TRANS_SHORT); +} + +void tft_write_word(uint32_t *data_buf, uint32_t length) +{ + set_dcx_data(); + spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); + + spi_init_non_standard(g_spi_num, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/, + SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); + spi_send_data_normal_dma(g_dma_ch, g_spi_num, g_ss, data_buf, length, SPI_TRANS_INT); +} + +void tft_fill_data(uint32_t *data_buf, uint32_t length) +{ + set_dcx_data(); + spi_init(g_spi_num, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); + spi_init_non_standard(g_spi_num, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/, + SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); + spi_fill_data_dma(g_dma_ch, g_spi_num, g_ss, data_buf, length); +} diff --git a/libraries/Sipeed_ST7789/src/st7789.h b/libraries/Sipeed_ST7789/src/st7789.h new file mode 100644 index 0000000..31f0556 --- /dev/null +++ b/libraries/Sipeed_ST7789/src/st7789.h @@ -0,0 +1,107 @@ +#ifndef _ST7789_H_ +#define _ST7789_H_ + +#include +#include "gpio.h" +#include "fpioa.h" +#include "spi.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* clang-format off */ +#define NO_OPERATION 0x00 +#define SOFTWARE_RESET 0x01 +#define READ_ID 0x04 +#define READ_STATUS 0x09 +#define READ_POWER_MODE 0x0A +#define READ_MADCTL 0x0B +#define READ_PIXEL_FORMAT 0x0C +#define READ_IMAGE_FORMAT 0x0D +#define READ_SIGNAL_MODE 0x0E +#define READ_SELT_DIAG_RESULT 0x0F +#define SLEEP_ON 0x10 +#define SLEEP_OFF 0x11 +#define PARTIAL_DISPALY_ON 0x12 +#define NORMAL_DISPALY_ON 0x13 +#define INVERSION_DISPALY_OFF 0x20 +#define INVERSION_DISPALY_ON 0x21 +#define GAMMA_SET 0x26 +#define DISPALY_OFF 0x28 +#define DISPALY_ON 0x29 +#define HORIZONTAL_ADDRESS_SET 0x2A +#define VERTICAL_ADDRESS_SET 0x2B +#define MEMORY_WRITE 0x2C +#define COLOR_SET 0x2D +#define MEMORY_READ 0x2E +#define PARTIAL_AREA 0x30 +#define VERTICAL_SCROL_DEFINE 0x33 +#define TEAR_EFFECT_LINE_OFF 0x34 +#define TEAR_EFFECT_LINE_ON 0x35 +#define MEMORY_ACCESS_CTL 0x36 +#define VERTICAL_SCROL_S_ADD 0x37 +#define IDLE_MODE_OFF 0x38 +#define IDLE_MODE_ON 0x39 +#define PIXEL_FORMAT_SET 0x3A +#define WRITE_MEMORY_CONTINUE 0x3C +#define READ_MEMORY_CONTINUE 0x3E +#define SET_TEAR_SCANLINE 0x44 +#define GET_SCANLINE 0x45 +#define WRITE_BRIGHTNESS 0x51 +#define READ_BRIGHTNESS 0x52 +#define WRITE_CTRL_DISPALY 0x53 +#define READ_CTRL_DISPALY 0x54 +#define WRITE_BRIGHTNESS_CTL 0x55 +#define READ_BRIGHTNESS_CTL 0x56 +#define WRITE_MIN_BRIGHTNESS 0x5E +#define READ_MIN_BRIGHTNESS 0x5F +#define READ_ID1 0xDA +#define READ_ID2 0xDB +#define READ_ID3 0xDC +#define RGB_IF_SIGNAL_CTL 0xB0 +#define NORMAL_FRAME_CTL 0xB1 +#define IDLE_FRAME_CTL 0xB2 +#define PARTIAL_FRAME_CTL 0xB3 +#define INVERSION_CTL 0xB4 +#define BLANK_PORCH_CTL 0xB5 +#define DISPALY_FUNCTION_CTL 0xB6 +#define ENTRY_MODE_SET 0xB7 +#define BACKLIGHT_CTL1 0xB8 +#define BACKLIGHT_CTL2 0xB9 +#define BACKLIGHT_CTL3 0xBA +#define BACKLIGHT_CTL4 0xBB +#define BACKLIGHT_CTL5 0xBC +#define BACKLIGHT_CTL7 0xBE +#define BACKLIGHT_CTL8 0xBF +#define POWER_CTL1 0xC0 +#define POWER_CTL2 0xC1 +#define VCOM_CTL1 0xC5 +#define VCOM_CTL2 0xC7 +#define NV_MEMORY_WRITE 0xD0 +#define NV_MEMORY_PROTECT_KEY 0xD1 +#define NV_MEMORY_STATUS_READ 0xD2 +#define READ_ID4 0xD3 +#define POSITIVE_GAMMA_CORRECT 0xE0 +#define NEGATIVE_GAMMA_CORRECT 0xE1 +#define DIGITAL_GAMMA_CTL1 0xE2 +#define DIGITAL_GAMMA_CTL2 0xE3 +#define INTERFACE_CTL 0xF6 + +/* clang-format on */ + +void tft_hard_init(uint8_t spi, uint8_t ss, uint8_t rst, uint8_t dcx, uint32_t freq, int8_t rst_pin, int8_t dcx_pin, uint8_t dma_ch); +void tft_set_clk_freq(uint32_t freq); +void tft_write_command(uint8_t cmd); +void tft_write_byte(uint8_t *data_buf, uint32_t length); +void tft_write_half(uint16_t *data_buf, uint32_t length); +void tft_write_word(uint32_t *data_buf, uint32_t length); +void tft_fill_data(uint32_t *data_buf, uint32_t length); + +#ifdef __cplusplus +} +#endif + + +#endif