initial commit of support for CYD. Displays graphics on LCD.

This commit is contained in:
Gordon Williams 2024-12-13 19:58:24 +00:00
parent af38afd77b
commit e3f61b0e6e
7 changed files with 351 additions and 14 deletions

237
boards/ESP32_CYD.py Executable file
View File

@ -0,0 +1,237 @@
#!/bin/false
# This file is part of Espruino, a JavaScript interpreter for Microcontrollers
#
# Copyright (C) 2013 Gordon Williams <gw@pur3.co.uk>
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# ----------------------------------------------------------------------------------------
# This file contains information for a specific board - the available pins, and where LEDs,
# Buttons, and other in-built peripherals are. It is used to build documentation as well
# as various source and header files for Espruino.
# ----------------------------------------------------------------------------------------
# A Note about the 'variables' parameter on ESP32 Builds
# ------------------------------------------------------
#
# For the ESP32 build, the number of JsVars is governed by two factors:
# * Available memory
# * Maximum number of JsVars for the used JsVar format
#
# This setting will chose the optimum JsVar format for a given number
# of JsVars.
# If you add PSRAM to your ESP32 or compile with modules removed, you
# may wish to select a value using this table:
#
# Value | Max JsVars | Bytes per JsVar | Maximum References |
# ------+--------------+-----------------+--------------------+
# 4095 | 4095 | 13 | 255 |
# 8191 | 8191 | 13 | 15 |
# 16383 | 16383 | 14 | 255 |
# 65535 | 65535 | 16 | 255 |
# ------+--------------+-----------------+--------------------+
# CAUTION: Chosing 8191 only allows 15 references to a variable. This
# may be too restrictive to run some code.
# Using too large a JsVar format may limit how many JsVars can fit into
# available memory. Using too small a JsVar format will under utilise
# available memory.
import pinutils;
info = {
'name' : "ESP32_CYD",
'espruino_page_link' : 'ESP32',
'default_console' : "EV_SERIAL1",
'default_console_baudrate' : "115200",
'variables' : 16383, # See note above
'io_buffer_size' : 1024, # How big is the input buffer (in 4 byte words). Default is 256, but this makes us less likely to drop data
'binary_name' : 'espruino_%v_esp32_cyd.bin',
'build' : {
'optimizeflags' : '-Og',
'libraries' : [
'ESP32',
'NET',
'GRAPHICS',
'CRYPTO','SHA256','SHA512',
'TLS',
'TELNET',
# 'NEOPIXEL',
'FILESYSTEM',
'BLUETOOTH',
'LCD_SPI_UNBUF'
],
'makefile' : [
'DEFINES+=-DESP_PLATFORM -DESP32=1',
'DEFINES+=-DESP_STACK_SIZE=25000',
'DEFINES+=-DJSVAR_MALLOC', # Allocate space for variables at jsvInit time
'DEFINES+=-DESPR_GRAPHICS_INTERNAL -DESPR_GRAPHICS_SELF_INIT', # ensure graphics instantiates itself
'DEFINES+=-DUSE_FONT_6X8 -DSPISENDMANY_BUFFER_SIZE=1600',
'ESP32_FLASH_MAX=1572864'
]
}
};
chip = {
'part' : "ESP32",
'family' : "ESP32",
'package' : "",
'ram' : 512,
'flash' : 0,
'speed' : 240,
'usart' : 3,
'spi' : 2,
'i2c' : 2,
'adc' : 2,
'dac' : 0,
'saved_code' : {
'address' : 0x320000,
'page_size' : 4096,
'pages' : 64,
'flash_available' : 1344, # firmware can be up to this size - see partitions_espruino.csv
},
};
devices = {
#https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/blob/main/PINS.md
'LED1' : { 'pin' : 'D4' }, # FIXME swap polarity of LEDs
'LED2' : { 'pin' : 'D16' },
'LED3' : { 'pin' : 'D17' },
'BTN1' : { 'pin' : 'D0', "inverted":1, 'pinstate' : 'IN_PULLUP' }, # FIXME swap polarity of button
'SD' : { 'pin_cs' : 'D5',
'pin_di' : 'D23',
'pin_do' : 'D19',
'pin_clk' : 'D18' },
'QWIIC0' : { # CN1
'pin_sda' : 'D22',
'pin_scl' : 'D27'
},
'QWIIC1' : { # P1
'pin_sda' : 'D1',
'pin_scl' : 'D3'
},
'QWIIC3' : { # P3
'pin_sda' : 'D35',
'pin_scl' : 'D22',
'pin_vcc' : 'D21',
},
'TOUCHSCREEN' : { # XPT2046
'pin_irq' : 'D36',
'pin_cs' : 'D33',
'pin_sck' : 'D25',
'pin_miso' : 'D39',
'pin_mosi' : 'D32'
},
'LCD' : {
'width' : 320, 'height' : 240, 'bpp' : 16, 'controller' : 'ili9341',
'pin_dc' : 'D2',
'pin_cs' : 'D15',
'pin_sck' : 'D14',
'pin_mosi' : 'D13',
'pin_miso' : 'D12',
'pin_bl' : 'D21', # backlight pwm
'spi_device' : 'EV_SPI1'
},
# LCD on pin 34
};
# left-right, or top-bottom order
board_esp32 = {
};
board_esp32["_css"] = """
#board {
width: 600px;
height: 435px;
left: 50px;
top: 170px;
background-image: url(img/ESP32_CYD.jpg);
}
#boardcontainer {
height: 700px;
}
#board #right {
top: 80px;
left: 600px;
}
#board #top {
bottom: 440px;
left: 155px;
}
#board #bottom {
top: 435px;
left: 155px;
}
#board .rightpin {
height: 28px;
}
#board .toppin, #board .bottompin {
width: 24px;
}
""";
boards = [ board_esp32 ];
def get_pins():
# { "name":"PD20", "sortingname":"D20", "port":"D", "num":"30", "functions":{ "I2C1_SDA":0 }, "csv":{} },
# pins = pinutils.generate_pins(0,5);
##6-11 are used by Flash chip
# pins.extend(pinutils.generate_pins(12,23));
# pins.extend(pinutils.generate_pins(25,27));
##32-33 are routed to rtc for xtal
# pins.extend(pinutils.generate_pins(34,39));
# pins = pinutils.fill_gaps_in_pin_list(pins);
pins = pinutils.generate_pins(0,39) # 40 General Purpose I/O Pins.
pinutils.findpin(pins, "PD36", True)["functions"]["ADC1_IN0"]=0;
pinutils.findpin(pins, "PD37", True)["functions"]["ADC1_IN1"]=0;
pinutils.findpin(pins, "PD38", True)["functions"]["ADC1_IN2"]=0;
pinutils.findpin(pins, "PD39", True)["functions"]["ADC1_IN3"]=0;
pinutils.findpin(pins, "PD32", True)["functions"]["ADC1_IN4"]=0;
pinutils.findpin(pins, "PD33", True)["functions"]["ADC1_IN5"]=0;
pinutils.findpin(pins, "PD34", True)["functions"]["ADC1_IN6"]=0;
pinutils.findpin(pins, "PD35", True)["functions"]["ADC1_IN7"]=0;
#ADC2 not supported yet, waiting for driver from espressif
# pinutils.findpin(pins, "PD4", True)["functions"]["ADC2_IN0"]=0;
# pinutils.findpin(pins, "PD0", True)["functions"]["ADC2_IN1"]=0;
# pinutils.findpin(pins, "PD2", True)["functions"]["ADC2_IN2"]=0;
# pinutils.findpin(pins, "PD15", True)["functions"]["ADC2_IN3"]=0;
# pinutils.findpin(pins, "PD13", True)["functions"]["ADC2_IN4"]=0;
# pinutils.findpin(pins, "PD12", True)["functions"]["ADC2_IN5"]=0;
# pinutils.findpin(pins, "PD14", True)["functions"]["ADC2_IN6"]=0;
# pinutils.findpin(pins, "PD27", True)["functions"]["ADC2_IN7"]=0;
pinutils.findpin(pins, "PD25", True)["functions"]["DAC_OUT1"]=0;
pinutils.findpin(pins, "PD26", True)["functions"]["DAC_OUT2"]=0;
pinutils.findpin(pins, "PD0", True)["functions"]["LED_1"]=0;
pinutils.findpin(pins, "PD10", True)["functions"]["USART0_TX"]=0;
pinutils.findpin(pins, "PD16", True)["functions"]["USART2_RX"]=0;
pinutils.findpin(pins, "PD17", True)["functions"]["USART2_TX"]=0;
pinutils.findpin(pins, "PD32", True)["functions"]["USART0_RX"]=0;
pinutils.findpin(pins, "PD13", True)["functions"]["SPI1_MOSI"]=0;
pinutils.findpin(pins, "PD12", True)["functions"]["SPI1_MISO"]=0;
pinutils.findpin(pins, "PD14", True)["functions"]["SPI1_SCLK"]=0;
pinutils.findpin(pins, "PD23", True)["functions"]["SPI2_MOSI"]=0;
pinutils.findpin(pins, "PD19", True)["functions"]["SPI2_MISO"]=0;
pinutils.findpin(pins, "PD18", True)["functions"]["SPI2_SCLK"]=0;
# everything is non-5v tolerant
#for pin in pins:
# pin["functions"]["3.3"]=0;
return pins

View File

@ -29,6 +29,9 @@
#ifdef USE_LCD_ST7789_8BIT
#include "lcd_st7789_8bit.h"
#endif
#ifdef USE_LCD_SPI_UNBUF
#include "lcd_spi_unbuf.h"
#endif
#include "jswrap_functions.h" // for asURL
#include "jswrap_object.h" // for getFonts
@ -560,6 +563,10 @@ void jswrap_graphics_init() {
gfx->data.type = JSGRAPHICSTYPE_FSMC;
lcdInit_FSMC(gfx);
lcdSetCallbacks_FSMC(gfx);
#elif defined(USE_LCD_SPI_UNBUF)
gfx->data.type = JSGRAPHICSTYPE_LCD_SPI_UNBUF;
lcd_spi_unbuf_init(gfx);
lcd_spi_unbuf_setCallbacks(gfx);
#else
#error Unknown LCD type
#endif

View File

@ -17,6 +17,7 @@
"class" : "lcd_spi_unbuf"
}*/
#include "lcd_spilcd_info.h"
#include "lcd_spi_unbuf.h"
#include "jsutils.h"
#include "jsinteractive.h"
@ -63,6 +64,20 @@ static inline _put_pixel( uint16_t c) {
if (_chunk_index==LCD_SPI_UNBUF_LEN) flush_chunk_buffer();
}
void lcdSendInitCmd_SPILCD() {
// Send initialization commands to ST7735
const unsigned char *cmd = SPILCD_INIT_CODE;
while(cmd[CMDINDEX_DATALEN]!=255) {
jshPinSetValue(_pin_cs, 0);
spi_cmd(cmd[CMDINDEX_CMD]);
if (cmd[CMDINDEX_DATALEN]) spi_data(&cmd[3], cmd[CMDINDEX_DATALEN]);
if (cmd[CMDINDEX_DELAY])
jshDelayMicroseconds(1000*cmd[CMDINDEX_DELAY]);
jshPinSetValue(_pin_cs, 1);
cmd += 3 + cmd[CMDINDEX_DATALEN];
}
}
/// flush chunk buffer to screen
void lcd_flip(JsVar *parent) {
if(_chunk_index == 0) return;
@ -164,6 +179,45 @@ JsVar *jswrap_lcd_spi_unbuf_connect(JsVar *device, JsVar *options) {
return parent;
}
#ifdef LCD_SPI_DEVICE
void lcd_spi_unbuf_init(JsGraphics *gfx) {
gfx->data.width = LCD_WIDTH;
gfx->data.height = LCD_HEIGHT;
gfx->data.bpp = LCD_BPP;
_pin_mosi = LCD_SPI_MOSI;
_pin_clk = LCD_SPI_SCK;
_pin_cs = LCD_SPI_CS;
_pin_dc = LCD_SPI_DC;
_device = LCD_SPI_DEVICE;
_colstart = 0;
_rowstart = 0;
#ifdef LCD_BL
jshPinOutput(LCD_BL, 1);
#endif
#ifdef LCD_EN
jshPinOutput(LCD_EN, 1);
#endif
jshPinOutput(_pin_dc, 1);
jshPinOutput(_pin_cs, 1);
JshSPIInfo inf;
jshSPIInitInfo(&inf);
#ifndef LCD_SPI_BITRATE
#define LCD_SPI_BITRATE 8000000
#endif
inf.baudRate = LCD_SPI_BITRATE;
inf.pinMOSI = LCD_SPI_MOSI;
#ifdef LCD_SPI_MISO
inf.pinMISO = LCD_SPI_MISO;
#endif
inf.pinSCK = LCD_SPI_SCK;
jshSPISetup(_device, &inf);
lcdSendInitCmd_SPILCD();
}
#endif
void disp_spi_transfer_addrwin(int x1, int y1, int x2, int y2) {
unsigned char wd[4];
flush_chunk_buffer();

View File

@ -8,7 +8,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* ----------------------------------------------------------------------------
* Graphics Backend for drawing to SPI displays in unbuffered mode
* Graphics Backend for drawing to SPI displays in unbuffered mode
* ----------------------------------------------------------------------------
*/
@ -27,6 +27,8 @@ typedef struct {
int rowstart; //!< Aditional starting address some pixels dont begin at 0
} JshLCD_SPI_UNBUFInfo;
void lcd_spi_unbuf_init(JsGraphics *gfx);
bool jswrap_lcd_spi_unbuf_idle();
JsVar *jswrap_lcd_spi_unbuf_connect(JsVar *device, JsVar *options);
void lcd_spi_unbuf_setCallbacks(JsGraphics *gfx);

View File

@ -18,6 +18,40 @@
#define CMDINDEX_DELAY 1
#define CMDINDEX_DATALEN 2
#ifdef LCD_CONTROLLER_ILI9341
static const unsigned char SPILCD_INIT_CODE[] = {
// CMD,DELAY,DATA_LEN,D0,D1,D2...
0xCF/*ILI_PCB*/, 0, 3, 0x00, 0xC1, 0X30,
0xED/*ILI_POSC*/, 0, 4, 0x64, 0x03, 0X12, 0X81,
0xE8/*ILI_DTCA_ic*/, 0, 3, 0x85, 0x10, 0x7A,
0xCB/*ILI_PCA*/, 0, 5, 0x39, 0x2C, 0x00, 0x34, 0x02,
0xF7/*ILI_PRC*/,0, 1, 0x20,
0xEA/*ILI_DTCB*/, 0, 2, 0x00, 0x00,
0xC0/*ILI_PWCTRL1*/, 0, 1, 0x1B,
0xC1/*ILI_PWCTRL2*/,0, 1, 0x01,
0xC5/*ILI_VMCTRL1*/, 0, 2, 0x30, 0x30,
0xC7/*ILI_VMCTRL2*/, 0, 1, 0XB7,
0x36/*ILI_MADCTL*/, 0, 1, 0x48,
0x3A/*ILI_PIXSET*/, 0, 1, 0x55,
0xB1/*ILI_FRMCTR1*/, 0, 2, 0x00, 0x1A,
0xB6/*ILI_DISCTRL*/, 0, 2, 0x0A, 0xA2,
0xF2/*ILI_E3G*/, 0, 1, 0x00,
0x26/*ILI_GAMSET*/, 0, 1, 0x01,
0xE0/*ILI_PGAMCTRL*/, 0, 15, 0x0F, 0x2A, 0x28, 0x08, 0x0E, 0x08, 0x54, 0XA9, 0x43, 0x0A, 0x0F, 0x00, 0x00, 0x00, 0x00,
0xE1/*ILI_NGAMCTRL*/, 0, 15, 0x00, 0x15, 0x17, 0x07, 0x11, 0x06, 0x2B, 0x56, 0x3C, 0x05, 0x10, 0x0F, 0x3F, 0x3F, 0x0F,
0x2B/*ILI_PASET*/, 0, 4, 0x00, 0x00, 0x01, 0x3f,
0x2A/*ILI_CASET*/, 0, 4, 0x00, 0x00, 0x00, 0xef,
0x11/*ILI_SLPOUT*/, 120, 0,
0x29/*ILI_DISPON*/, 0, 0,
0x36/*ILI_MADCTL*/, 0, 1, 0x68,
// End
0, 0, 255/*DATA_LEN = 255 => END*/
};
const unsigned char SPILCD_CMD_WINDOW_X = 0x2A;
const unsigned char SPILCD_CMD_WINDOW_Y = 0x2B;
const unsigned char SPILCD_CMD_DATA = 0x2C;
#endif
#ifdef LCD_CONTROLLER_ST7735
static const unsigned char SPILCD_INIT_CODE[] = {
// CMD,DELAY,DATA_LEN,D0,D1,D2...
@ -130,7 +164,7 @@ static const unsigned char SPILCD_INIT_CODE[] = {
0x36,0,1, 0xB8, // Memory Access Control (rotated 270 degrees)
#else
0x36,0,1, 0x88, // Memory Access Control (no rotation)
#endif
#endif
#else
0x36,0,1, 0x88, // Memory Access Control (no rotation)
#endif

View File

@ -430,19 +430,22 @@ if "LCD" in board.devices:
if "pin_reset" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_reset", "LCD_RESET")
if board.devices["LCD"]["controller"]=="ssd1306" or board.devices["LCD"]["controller"]=="st7567" or board.devices["LCD"]["controller"]=="st7789v" or board.devices["LCD"]["controller"]=="st7735" or board.devices["LCD"]["controller"]=="gc9a01":
codeOutDevicePin("LCD", "pin_mosi", "LCD_SPI_MOSI")
codeOutDevicePin("LCD", "pin_sck", "LCD_SPI_SCK")
codeOutDevicePin("LCD", "pin_cs", "LCD_SPI_CS")
codeOutDevicePin("LCD", "pin_dc", "LCD_SPI_DC")
codeOutDevicePin("LCD", "pin_rst", "LCD_SPI_RST")
if board.devices["LCD"]["controller"]=="LPM013M126":
codeOutDevicePin("LCD", "pin_mosi", "LCD_SPI_MOSI")
codeOutDevicePin("LCD", "pin_sck", "LCD_SPI_SCK")
codeOutDevicePin("LCD", "pin_cs", "LCD_SPI_CS")
codeOutDevicePin("LCD", "pin_disp", "LCD_DISP")
codeOutDevicePin("LCD", "pin_extcomin", "LCD_EXTCOMIN")
if "pin_cs" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_cs", "LCD_SPI_CS")
if "pin_mosi" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_mosi", "LCD_SPI_MOSI")
if "pin_miso" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_miso", "LCD_SPI_MISO")
if "pin_sck" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_sck", "LCD_SPI_SCK")
if "pin_dc" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_dc", "LCD_SPI_DC")
if "spi_device" in board.devices["LCD"]:
codeOut("#define LCD_SPI_DEVICE "+board.devices["LCD"]["spi_device"])
if "pin_tearing" in board.devices["LCD"]:
codeOutDevicePin("LCD", "pin_tearing", "LCD_TEARING")
@ -453,8 +456,8 @@ if "SD" in board.devices:
if "pin_cd" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cd", "SD_DETECT_PIN")
if "pin_pwr" in board.devices["SD"]: codeOutDevicePin("SD", "pin_pwr", "SD_POWER_PIN")
if "pin_cs" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cs", "SD_CS_PIN")
if "pin_di" in board.devices["SD"]: codeOutDevicePin("SD", "pin_di", "SD_DI_PIN")
if "pin_do" in board.devices["SD"]: codeOutDevicePin("SD", "pin_do", "SD_DO_PIN")
if "pin_di" in board.devices["SD"]: codeOutDevicePin("SD", "pin_di", "SD_DI_PIN") # MOSI
if "pin_do" in board.devices["SD"]: codeOutDevicePin("SD", "pin_do", "SD_DO_PIN") # MISO
if "pin_clk" in board.devices["SD"]:
codeOutDevicePin("SD", "pin_clk", "SD_CLK_PIN")
if not "pin_d3" in board.devices["SD"]: # NOT SDIO - normal SD
@ -469,7 +472,7 @@ if "SD" in board.devices:
if "pin_d1" in board.devices["SD"]: codeOutDevicePin("SD", "pin_d1", "SD_D1_PIN")
if "pin_d2" in board.devices["SD"]: codeOutDevicePin("SD", "pin_d2", "SD_D2_PIN")
if "pin_d3" in board.devices["SD"]: codeOutDevicePin("SD", "pin_d3", "SD_D3_PIN")
if "pin_cmd" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cmd", "SD_CMD_PIN")
if "pin_cmd" in board.devices["SD"]: codeOutDevicePin("SD", "pin_cmd", "SD_CMD_PIN")
if "IR" in board.devices:
codeOutDevicePin("IR", "pin_anode", "IR_ANODE_PIN")

View File

@ -62,12 +62,12 @@ void jshSetDeviceInitialised(IOEventFlags device, bool isInit);
/*
https://hackadaycom.files.wordpress.com/2016/10/esp32_pinmap.png
HSPI 2 //SPI bus normally mapped to pins 12 - 15, but can be matrixed to any pins
SPI1 -> HSPI 2 //SPI bus normally mapped to pins 12 - 15, but can be matrixed to any pins
15 HSPI SS
14 HSPI SCK
12 HSPI MISO
13 HSPI MOSI
VSPI 3 //SPI bus normally attached to pin:
SPI2 -> VSPI 3 //SPI bus normally attached to pin:
5 VSPI SS
18 VSPI SCK
19 VSPI MISO