2019-08-19 12:21:54 +01:00
/***************************************************
STM32 Support added by Jaret Burkett at OSHlab . com
This is our library for the Adafruit ILI9488 Breakout and Shield
- - - - > http : //www.adafruit.com/products/1651
Check out the links above for our tutorials and wiring diagrams
These displays use SPI to communicate , 4 or 5 pins are required to
interface ( RST is optional )
Adafruit invests time and resources providing this open source code ,
please support Adafruit and open - source hardware by purchasing
products from Adafruit !
Written by Limor Fried / Ladyada for Adafruit Industries .
MIT license , all text above must be included in any redistribution
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <SPI.h>
# include "ILI9488.h"
# include <limits.h>
// if using software spi this optimizes the code
2020-05-29 18:29:03 +01:00
2020-10-03 17:31:40 +01:00
# ifdef ESP32
# define ILI9488_DIMMER
# undef ESP32_PWM_CHANNEL
# define ESP32_PWM_CHANNEL 1
# endif
2019-08-19 12:21:54 +01:00
# define ILI9488_START start();
# define ILI9488_STOP stop();
const uint16_t ili9488_colors [ ] = { ILI9488_BLACK , ILI9488_WHITE , ILI9488_RED , ILI9488_GREEN , ILI9488_BLUE , ILI9488_CYAN , ILI9488_MAGENTA , \
ILI9488_YELLOW , ILI9488_NAVY , ILI9488_DARKGREEN , ILI9488_DARKCYAN , ILI9488_MAROON , ILI9488_PURPLE , ILI9488_OLIVE , \
ILI9488_LIGHTGREY , ILI9488_DARKGREY , ILI9488_ORANGE , ILI9488_GREENYELLOW , ILI9488_PINK } ;
// Constructor when using software SPI. All output pins are configurable.
ILI9488 : : ILI9488 ( int8_t cs , int8_t mosi , int8_t sclk , int8_t bp ) : Renderer ( ILI9488_TFTWIDTH , ILI9488_TFTHEIGHT ) {
_cs = cs ;
_mosi = mosi ;
_sclk = sclk ;
_bp = bp ;
_hwspi = 0 ;
}
/*
CPU Clock = 80 Mhz
max clock of display is 15 Mhz ( 66 ns sclk cycle )
so cpu / 8 = > 10 Mhz should be ok
HSPI CLK 5 GPIO14
HSPI / CS 8 GPIO15
HSPI MOSI 7 GPIO13
HSPI MISO 6 GPIO12
GPIO names for your easy reference :
GPIO0 : PERIPHS_IO_MUX_GPIO0_U
GPIO1 : PERIPHS_IO_MUX_U0TXD_U
GPIO2 : PERIPHS_IO_MUX_GPIO2_U
GPIO3 : PERIPHS_IO_MUX_U0RXD_U
GPIO4 : PERIPHS_IO_MUX_GPIO4_U
GPIO5 : PERIPHS_IO_MUX_GPIO5_U
GPIO6 : PERIPHS_IO_MUX_SD_CLK_U
GPIO7 : PERIPHS_IO_MUX_SD_DATA0_U
GPIO8 : PERIPHS_IO_MUX_SD_DATA1_U
GPIO9 : PERIPHS_IO_MUX_SD_DATA2_U
GPIO10 : PERIPHS_IO_MUX_SD_DATA3_U
GPIO11 : PERIPHS_IO_MUX_SD_CMD_U
GPIO12 : PERIPHS_IO_MUX_MTDI_U
GPIO13 : PERIPHS_IO_MUX_MTCK_U
GPIO14 : PERIPHS_IO_MUX_MTMS_U
GPIO15 : PERIPHS_IO_MUX_MTDO_U
*/
uint8_t ili9488_start ;
2020-05-29 18:29:03 +01:00
# ifndef ESP32
// ESP8266
# include "spi_register.h"
# define SWSPI_OPTMODE
2020-05-29 19:54:15 +01:00
// this enables the 27 bit packed mode
# define RGB_PACK_MODE
2019-08-19 12:21:54 +01:00
uint32_t ili9488_clock ;
uint32_t ili9488_usr ;
uint32_t ili9488_usr1 ;
uint32_t ili9488_usr2 ;
uint32_t ili9488_spi1c ;
uint32_t ili9488_spi1c1 ;
uint32_t ili9488_spi1p ;
uint32_t ili9488_gpmux ;
uint32_t ili9488_mtdo ;
uint32_t ili9488_clock_prev ;
uint32_t ili9488_usr_prev ;
uint32_t ili9488_usr1_prev ;
uint32_t ili9488_usr2_prev ;
uint32_t ili9488_spi1c_prev ;
uint32_t ili9488_spi1c1_prev ;
uint32_t ili9488_spi1p_prev ;
uint32_t ili9488_gpmux_prev ;
uint32_t ili9488_mtdo_prev ;
// code from espressif SDK
/******************************************************************************
* FunctionName : spi_lcd_mode_init
* Description : SPI master initial function for driving LCD 3 wire spi
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void ILI9488 : : spi_lcd_mode_init ( void ) {
ili9488_clock_prev = SPI1CLK ;
ili9488_usr_prev = SPI1U ;
ili9488_usr1_prev = SPI1U1 ;
ili9488_usr2_prev = SPI1U2 ;
ili9488_spi1c_prev = SPI1C ;
ili9488_spi1c1_prev = SPI1C1 ;
ili9488_spi1p_prev = SPI1P ;
ili9488_gpmux_prev = GPMUX ;
ili9488_mtdo_prev = READ_PERI_REG ( PERIPHS_IO_MUX_MTDO_U ) ;
SPI1U = SPIUMOSI | SPIUDUPLEX | SPIUSSE ;
SPI1U1 = 0 ;
SPI1C = 0 ;
SPI1C1 = 0 ;
//bit9 of PERIPHS_IO_MUX should be cleared when HSPI clock doesn't equal CPU clock
//bit8 of PERIPHS_IO_MUX should be cleared when SPI clock doesn't equal CPU clock
WRITE_PERI_REG ( PERIPHS_IO_MUX , 0x105 ) ; //clear bit9
//PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure miso to spi mode
PIN_FUNC_SELECT ( PERIPHS_IO_MUX_MTCK_U , 2 ) ; //configure mosi to spi mode
PIN_FUNC_SELECT ( PERIPHS_IO_MUX_MTMS_U , 2 ) ; //configure sclk to spi mode
PIN_FUNC_SELECT ( PERIPHS_IO_MUX_MTDO_U , 2 ) ; //configure cs to spi mode
// the current implementation leaves about 1 us between transfers ????
// due to lack of documentation i could not find the reason
// skipping this would double the speed !!!
//SET_PERI_REG_MASK(SPI_USER(1), SPI_CS_SETUP|SPI_CS_HOLD|SPI_USR_COMMAND);
SET_PERI_REG_MASK ( SPI_USER ( 1 ) , SPI_USR_COMMAND ) ;
CLEAR_PERI_REG_MASK ( SPI_USER ( 1 ) , SPI_FLASH_MODE ) ;
// SPI clock=CPU clock/8 => 10 Mhz
/*
WRITE_PERI_REG ( SPI_CLOCK ( 1 ) ,
( ( 1 & SPI_CLKDIV_PRE ) < < SPI_CLKDIV_PRE_S ) |
( ( 3 & SPI_CLKCNT_N ) < < SPI_CLKCNT_N_S ) |
( ( 1 & SPI_CLKCNT_H ) < < SPI_CLKCNT_H_S ) |
( ( 3 & SPI_CLKCNT_L ) < < SPI_CLKCNT_L_S ) ) ; //clear bit 31,set SPI clock div
*/
// will result in 80/6 = 13,3 Mhz
//SPI.setFrequency(15000000);
// due to capacitiv load problems max freq is not always possible
// keep lines as short as possible, especially if other spi devices connected
SPI . setFrequency ( 10000000 ) ;
ili9488_clock = SPI1CLK ;
ili9488_usr = SPI1U ;
ili9488_usr1 = SPI1U1 ;
ili9488_usr2 = SPI1U2 ;
ili9488_spi1c = SPI1C ;
ili9488_spi1c1 = SPI1C1 ;
ili9488_spi1p = SPI1P ;
ili9488_gpmux = GPMUX ;
ili9488_mtdo = READ_PERI_REG ( PERIPHS_IO_MUX_MTDO_U ) ;
ili9488_start = 0 ;
}
void ILI9488 : : start ( void ) {
if ( ili9488_start ) return ;
//while(SPI1CMD & SPIBUSY) {}
while ( READ_PERI_REG ( SPI_CMD ( 1 ) ) & SPI_USR ) ;
SPI1CLK = ili9488_clock ;
SPI1U = ili9488_usr ;
SPI1U1 = ili9488_usr1 ;
SPI1U2 = ili9488_usr2 ;
SPI1C = ili9488_spi1c ;
SPI1C1 = ili9488_spi1c1 ;
SPI1P = ili9488_spi1p ;
GPMUX = ili9488_gpmux ;
WRITE_PERI_REG ( PERIPHS_IO_MUX_MTDO_U , ili9488_mtdo ) ;
ili9488_start = 1 ;
}
void ILI9488 : : stop ( void ) {
if ( ! ili9488_start ) return ;
//while(SPI1CMD & SPIBUSY) {}
while ( READ_PERI_REG ( SPI_CMD ( 1 ) ) & SPI_USR ) ;
WRITE_PERI_REG ( PERIPHS_IO_MUX_MTDO_U , ili9488_mtdo_prev ) ;
SPI1CLK = ili9488_clock_prev ;
SPI1U = ili9488_usr_prev ;
SPI1U1 = ili9488_usr1_prev ;
SPI1U2 = ili9488_usr2_prev ;
SPI1C = ili9488_spi1c_prev ;
SPI1C1 = ili9488_spi1c1_prev ;
SPI1P = ili9488_spi1p_prev ;
GPMUX = ili9488_gpmux_prev ;
ili9488_start = 0 ;
}
// dc = 0
void ILI9488 : : writecommand ( uint8_t c ) {
if ( _hwspi ) {
uint32_t regvalue ;
uint8_t bytetemp ;
bytetemp = ( c > > 1 ) & 0x7f ;
ILI9488_START
regvalue = ( ( 8 & SPI_USR_COMMAND_BITLEN ) < < SPI_USR_COMMAND_BITLEN_S ) | ( ( uint32 ) bytetemp ) ; //configure transmission variable,9bit transmission length and first 8 command bit
if ( c & 0x01 ) regvalue | = BIT15 ; //write the 9th bit
while ( READ_PERI_REG ( SPI_CMD ( 1 ) ) & SPI_USR ) ; //waiting for spi module available
WRITE_PERI_REG ( SPI_USER2 ( 1 ) , regvalue ) ; //write command and command length into spi reg
SET_PERI_REG_MASK ( SPI_CMD ( 1 ) , SPI_USR ) ; //transmission start
} else fastSPIwrite ( c , 0 ) ;
}
// dc = 1
void ILI9488 : : writedata ( uint8_t d ) {
if ( _hwspi ) {
uint32_t regvalue ;
uint8_t bytetemp ;
bytetemp = ( d > > 1 ) | 0x80 ;
ILI9488_START
regvalue = ( ( 8 & SPI_USR_COMMAND_BITLEN ) < < SPI_USR_COMMAND_BITLEN_S ) | ( ( uint32 ) bytetemp ) ; //configure transmission variable,9bit transmission length and first 8 command bit
if ( d & 0x01 ) regvalue | = BIT15 ; //write the 9th bit
while ( READ_PERI_REG ( SPI_CMD ( 1 ) ) & SPI_USR ) ; //waiting for spi module available
WRITE_PERI_REG ( SPI_USER2 ( 1 ) , regvalue ) ; //write command and command length into spi reg
SET_PERI_REG_MASK ( SPI_CMD ( 1 ) , SPI_USR ) ; //transmission start
} else fastSPIwrite ( d , 1 ) ;
}
2020-05-29 18:29:03 +01:00
void ICACHE_RAM_ATTR ILI9488 : : fastSPIwrite ( uint8_t d , uint8_t dc ) {
2019-08-19 12:21:54 +01:00
2020-05-29 18:29:03 +01:00
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _cs ) ;
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( dc ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
2019-08-19 12:21:54 +01:00
2020-05-29 18:29:03 +01:00
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( d & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
2019-08-19 12:21:54 +01:00
}
2020-05-29 18:29:03 +01:00
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _cs ) ;
2019-08-19 12:21:54 +01:00
}
2020-05-29 18:29:03 +01:00
# else
// ESP32 section
void ILI9488 : : writedata ( uint8_t d ) {
2020-06-08 08:24:49 +01:00
ILI9488_START
2020-05-29 18:29:03 +01:00
fastSPIwrite ( d , 1 ) ;
}
void ILI9488 : : writecommand ( uint8_t c ) {
2020-06-08 08:24:49 +01:00
ILI9488_START
2020-05-29 18:29:03 +01:00
fastSPIwrite ( c , 0 ) ;
}
# include "soc/spi_reg.h"
# include "soc/spi_struct.h"
# include "esp32-hal-spi.h"
# include "esp32-hal.h"
# include "soc/spi_struct.h"
2020-05-29 19:54:15 +01:00
# define RGB_PACK_MODE
2020-05-29 18:29:03 +01:00
// since ardunio transferBits ia completely disfunctional
// we use our own hardware driver for 9 bit spi
void ILI9488 : : fastSPIwrite ( uint8_t d , uint8_t dc ) {
digitalWrite ( _cs , LOW ) ;
uint32_t regvalue = d > > 1 ;
if ( dc ) regvalue | = 0x80 ;
else regvalue & = 0x7f ;
if ( d & 1 ) regvalue | = 0x8000 ;
REG_SET_BIT ( SPI_USER_REG ( 3 ) , SPI_USR_MOSI ) ;
REG_WRITE ( SPI_MOSI_DLEN_REG ( 3 ) , 9 - 1 ) ;
uint32_t * dp = ( uint32_t * ) SPI_W0_REG ( 3 ) ;
* dp = regvalue ;
REG_SET_BIT ( SPI_CMD_REG ( 3 ) , SPI_USR ) ;
while ( REG_GET_FIELD ( SPI_CMD_REG ( 3 ) , SPI_USR ) ) ;
digitalWrite ( _cs , HIGH ) ;
}
SPISettings ili9488_spiSettings ;
void ILI9488 : : start ( void ) {
if ( ili9488_start ) return ;
SPI . beginTransaction ( ili9488_spiSettings ) ;
ili9488_start = 1 ;
}
void ILI9488 : : stop ( void ) {
if ( ! ili9488_start ) return ;
SPI . endTransaction ( ) ;
ili9488_start = 0 ;
}
# endif
2019-08-19 12:21:54 +01:00
uint16_t ILI9488 : : GetColorFromIndex ( uint8_t index ) {
if ( index > = sizeof ( ili9488_colors ) / 2 ) index = 0 ;
return ili9488_colors [ index ] ;
}
void ILI9488 : : DisplayInit ( int8_t p , int8_t size , int8_t rot , int8_t font ) {
setRotation ( rot ) ;
invertDisplay ( false ) ;
setTextWrap ( false ) ; // Allow text to run off edges
cp437 ( true ) ;
setTextFont ( font & 3 ) ;
setTextSize ( size & 7 ) ;
setTextColor ( ILI9488_WHITE , ILI9488_BLACK ) ;
setCursor ( 0 , 0 ) ;
fillScreen ( ILI9488_BLACK ) ;
ILI9488_STOP
}
void ILI9488 : : DisplayOnff ( int8_t on ) {
if ( on ) {
writecommand ( ILI9488_DISPON ) ; //Display on
2020-10-03 17:31:40 +01:00
2019-08-19 12:21:54 +01:00
if ( _bp > = 0 ) {
2020-10-03 17:31:40 +01:00
# ifdef ILI9488_DIMMER
ledcWrite ( ESP32_PWM_CHANNEL , dimmer ) ;
# else
2019-08-19 12:21:54 +01:00
digitalWrite ( _bp , HIGH ) ;
2020-10-03 17:31:40 +01:00
# endif
2019-08-19 12:21:54 +01:00
/*
writecommand ( ILI9488_WRCTRLD ) ;
writedata ( 0x0c ) ;
writecommand ( ILI9488_CAPC9 ) ;
writedata ( 0x3f ) ; */
}
} else {
writecommand ( ILI9488_DISPOFF ) ;
2020-10-03 17:31:40 +01:00
2019-08-19 12:21:54 +01:00
if ( _bp > = 0 ) {
2020-10-03 17:31:40 +01:00
# ifdef ILI9488_DIMMER
ledcWrite ( ESP32_PWM_CHANNEL , 0 ) ;
# else
2019-08-19 12:21:54 +01:00
digitalWrite ( _bp , LOW ) ;
2020-10-03 17:31:40 +01:00
# endif
}
2019-08-19 12:21:54 +01:00
//writecommand(ILI9488_WRCTRLD);
//writedata(0x04);
2020-10-03 17:31:40 +01:00
2019-08-19 12:21:54 +01:00
}
ILI9488_STOP
}
2020-10-03 17:31:40 +01:00
// dimmer 0-100
void ILI9488 : : dim ( uint8_t dim ) {
dimmer = dim ;
if ( dimmer > 15 ) dimmer = 15 ;
dimmer = ( ( float ) dimmer / 15.0 ) * 255.0 ;
# ifdef ESP32
ledcWrite ( ESP32_PWM_CHANNEL , dimmer ) ;
# endif
}
2019-08-19 12:21:54 +01:00
void ILI9488 : : begin ( void ) {
pinMode ( _cs , OUTPUT ) ;
digitalWrite ( _cs , HIGH ) ;
pinMode ( _sclk , OUTPUT ) ;
pinMode ( _mosi , OUTPUT ) ;
if ( _bp > = 0 ) {
2020-10-03 17:31:40 +01:00
# ifdef ILI9488_DIMMER
ledcSetup ( ESP32_PWM_CHANNEL , 4000 , 8 ) ;
ledcAttachPin ( _bp , ESP32_PWM_CHANNEL ) ;
ledcWrite ( ESP32_PWM_CHANNEL , 128 ) ;
# else
pinMode ( _bp , OUTPUT ) ;
digitalWrite ( _bp , HIGH ) ;
# endif
2019-08-19 12:21:54 +01:00
}
2020-05-29 18:29:03 +01:00
# ifndef ESP32
2019-08-19 12:21:54 +01:00
if ( ( _sclk = = 14 ) & & ( _mosi = = 13 ) & & ( _cs = = 15 ) ) {
// we use hardware spi
2020-05-29 18:29:03 +01:00
SPI . begin ( ) ;
2019-08-19 12:21:54 +01:00
_hwspi = 1 ;
spi_lcd_mode_init ( ) ;
} else {
// we must use software spi
_hwspi = 0 ;
}
2020-05-29 18:29:03 +01:00
# else
SPI . begin ( _sclk , - 1 , _mosi , - 1 ) ;
ili9488_spiSettings = SPISettings ( 10000000 , MSBFIRST , SPI_MODE3 ) ;
_hwspi = 1 ;
# endif
2019-08-19 12:21:54 +01:00
ILI9488_START
delay ( 1 ) ;
writecommand ( 0xE0 ) ;
writedata ( 0x00 ) ;
writedata ( 0x03 ) ;
writedata ( 0x09 ) ;
writedata ( 0x08 ) ;
writedata ( 0x16 ) ;
writedata ( 0x0A ) ;
writedata ( 0x3F ) ;
writedata ( 0x78 ) ;
writedata ( 0x4C ) ;
writedata ( 0x09 ) ;
writedata ( 0x0A ) ;
writedata ( 0x08 ) ;
writedata ( 0x16 ) ;
writedata ( 0x1A ) ;
writedata ( 0x0F ) ;
writecommand ( 0XE1 ) ;
writedata ( 0x00 ) ;
writedata ( 0x16 ) ;
writedata ( 0x19 ) ;
writedata ( 0x03 ) ;
writedata ( 0x0F ) ;
writedata ( 0x05 ) ;
writedata ( 0x32 ) ;
writedata ( 0x45 ) ;
writedata ( 0x46 ) ;
writedata ( 0x04 ) ;
writedata ( 0x0E ) ;
writedata ( 0x0D ) ;
writedata ( 0x35 ) ;
writedata ( 0x37 ) ;
writedata ( 0x0F ) ;
writecommand ( 0XC0 ) ; //Power Control 1
writedata ( 0x17 ) ; //Vreg1out
writedata ( 0x15 ) ; //Verg2out
writecommand ( 0xC1 ) ; //Power Control 2
writedata ( 0x41 ) ; //VGH,VGL
writecommand ( 0xC5 ) ; //Power Control 3
writedata ( 0x00 ) ;
writedata ( 0x12 ) ; //Vcom
writedata ( 0x80 ) ;
writecommand ( 0x36 ) ; //Memory Access
writedata ( 0x48 ) ;
writecommand ( 0x3A ) ; // Interface Pixel Format
writedata ( 0x66 ) ; //18 bit
writecommand ( 0XB0 ) ; // Interface Mode Control
writedata ( 0x80 ) ; //SDO NOT USE
writecommand ( 0xB1 ) ; //Frame rate
writedata ( 0xA0 ) ; //60Hz
writecommand ( 0xB4 ) ; //Display Inversion Control
writedata ( 0x02 ) ; //2-dot
writecommand ( 0XB6 ) ; //Display Function Control RGB/MCU Interface Control
writedata ( 0x02 ) ; //MCU
writedata ( 0x02 ) ; //Source,Gate scan dieection
writecommand ( 0XE9 ) ; // Set Image Functio
writedata ( 0x00 ) ; // Disable 24 bit data
writecommand ( 0xF7 ) ; // Adjust Control
writedata ( 0xA9 ) ;
writedata ( 0x51 ) ;
writedata ( 0x2C ) ;
writedata ( 0x82 ) ; // D7 stream, loose
writecommand ( ILI9488_SLPOUT ) ; //Exit Sleep
delay ( 120 ) ;
writecommand ( ILI9488_DISPON ) ; //Display on
ILI9488_STOP
}
/*
void ILI9488 : : setScrollArea ( uint16_t topFixedArea , uint16_t bottomFixedArea ) {
writecommand ( 0x33 ) ; // Vertical scroll definition
writedata ( topFixedArea > > 8 ) ;
writedata ( topFixedArea ) ;
writedata ( ( _height - topFixedArea - bottomFixedArea ) > > 8 ) ;
writedata ( _height - topFixedArea - bottomFixedArea ) ;
writedata ( bottomFixedArea > > 8 ) ;
writedata ( bottomFixedArea ) ;
ILI9488_STOP
}
void ILI9488 : : scroll ( uint16_t pixels ) {
writecommand ( 0x37 ) ; // Vertical scrolling start address
writedata ( pixels > > 8 ) ;
writedata ( pixels ) ;
ILI9488_STOP
} */
void ILI9488 : : setAddrWindow ( uint16_t x0 , uint16_t y0 , uint16_t x1 , uint16_t y1 ) {
2021-01-04 15:29:34 +00:00
if ( ! x0 & & ! y0 & & ! x1 & & ! y1 ) {
x0 = 0 ;
y0 = 0 ;
x1 = _width ;
y1 = _height ;
}
setAddrWindow_int ( x0 , y0 , x1 - 1 , y1 - 1 ) ;
}
void ILI9488 : : setAddrWindow_int ( uint16_t x0 , uint16_t y0 , uint16_t x1 , uint16_t y1 ) {
2019-08-19 12:21:54 +01:00
uint8_t flag = 0 ;
if ( ! x0 & & ! y0 & & ! x1 & & ! y1 ) {
x0 = 0 ;
y0 = 0 ;
x1 = _width ;
y1 = _height ;
flag = 1 ;
}
if ( x1 > _width ) x1 = _width ;
if ( y1 > _height ) y1 = _height ;
writecommand ( ILI9488_CASET ) ; // Column addr set
writedata ( x0 > > 8 ) ;
writedata ( x0 & 0xFF ) ; // XSTART
writedata ( x1 > > 8 ) ;
writedata ( x1 & 0xFF ) ; // XEND
writecommand ( ILI9488_PASET ) ; // Row addr set
writedata ( y0 > > 8 ) ;
writedata ( y0 & 0xff ) ; // YSTART
writedata ( y1 > > 8 ) ;
writedata ( y1 & 0xff ) ; // YEND
writecommand ( ILI9488_RAMWR ) ; // write to RAM
if ( flag ) ILI9488_STOP
}
/*
void ILI9488 : : drawImage ( const uint8_t * img , uint16_t x , uint16_t y , uint16_t w , uint16_t h ) {
return ;
// rudimentary clipping (drawChar w/big text requires this)
if ( ( x > = _width ) | | ( y > = _height ) ) return ;
if ( ( x + w - 1 ) > = _width ) w = _width - x ;
if ( ( y + h - 1 ) > = _height ) h = _height - y ;
setAddrWindow ( x , y , x + w - 1 , y + h - 1 ) ;
// uint8_t hi = color >> 8, lo = color;
# if defined(USE_FAST_PINIO) && !defined (_VARIANT_ARDUINO_STM32_)
* dcport | = dcpinmask ;
* csport & = ~ cspinmask ;
# else
digitalWrite ( _dc , HIGH ) ;
digitalWrite ( _cs , LOW ) ;
# endif
uint8_t linebuff [ w * 3 + 1 ] ;
uint16_t pixels = w * h ;
// uint16_t count = 0;
uint32_t count = 0 ;
for ( uint16_t i = 0 ; i < h ; i + + ) {
uint16_t pixcount = 0 ;
for ( uint16_t o = 0 ; o < w ; o + + ) {
uint8_t b1 = img [ count ] ;
count + + ;
uint8_t b2 = img [ count ] ;
count + + ;
uint16_t color = b1 < < 8 | b2 ;
linebuff [ pixcount ] = ( ( ( color & 0xF800 ) > > 11 ) * 255 ) / 31 ;
pixcount + + ;
linebuff [ pixcount ] = ( ( ( color & 0x07E0 ) > > 5 ) * 255 ) / 63 ;
pixcount + + ;
linebuff [ pixcount ] = ( ( color & 0x001F ) * 255 ) / 31 ;
pixcount + + ;
} // for row
# if defined (__STM32F1__)
SPI . dmaSend ( linebuff , w * 3 ) ;
# else
for ( uint16_t b = 0 ; b < w * 3 ; b + + ) {
spiwrite ( linebuff [ b ] ) ;
}
# endif
} // for col
# if defined(USE_FAST_PINIO) && !defined (_VARIANT_ARDUINO_STM32_)
* csport | = cspinmask ;
# else
digitalWrite ( _cs , HIGH ) ;
# endif
if ( hwSPI ) spi_end ( ) ;
}
*/
void ILI9488 : : pushColor ( uint16_t color ) {
write16BitColor ( color ) ;
ILI9488_STOP
}
2021-01-04 15:29:34 +00:00
# if 1
2021-01-08 10:49:07 +00:00
void ILI9488 : : pushColors ( uint16_t * data , uint16_t len , boolean first ) {
2019-08-19 12:21:54 +01:00
uint16_t color ;
uint8_t buff [ len * 3 + 1 ] ;
uint16_t count = 0 ;
uint8_t lencount = len ;
while ( lencount - - ) {
color = * data + + ;
buff [ count ] = ( ( ( color & 0xF800 ) > > 11 ) * 255 ) / 31 ;
count + + ;
buff [ count ] = ( ( ( color & 0x07E0 ) > > 5 ) * 255 ) / 63 ;
count + + ;
buff [ count ] = ( ( color & 0x001F ) * 255 ) / 31 ;
count + + ;
}
for ( uint16_t b = 0 ; b < len * 3 ; b + + ) {
writedata ( buff [ b ] ) ;
}
ILI9488_STOP
}
2021-01-04 15:29:34 +00:00
# else
void ILI9488 : : pushColors ( uint16_t * data , uint8_t len , boolean first ) {
uint16_t color ;
while ( len - - ) {
write16BitColor ( * data + + ) ;
}
ILI9488_STOP
}
# endif
2019-08-19 12:21:54 +01:00
void ILI9488 : : write16BitColor ( uint16_t color ) {
// #if (__STM32F1__)
// uint8_t buff[4] = {
// (((color & 0xF800) >> 11)* 255) / 31,
// (((color & 0x07E0) >> 5) * 255) / 63,
// ((color & 0x001F)* 255) / 31
// };
// SPI.dmaSend(buff, 3);
// #else
uint8_t r = ( color & 0xF800 ) > > 11 ;
uint8_t g = ( color & 0x07E0 ) > > 5 ;
uint8_t b = color & 0x001F ;
r = ( r * 255 ) / 31 ;
g = ( g * 255 ) / 63 ;
b = ( b * 255 ) / 31 ;
# ifndef SWSPI_OPTMODE
writedata ( r ) ;
writedata ( g ) ;
writedata ( b ) ;
# else
if ( _hwspi ) {
writedata ( r ) ;
writedata ( g ) ;
writedata ( b ) ;
} else {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _cs ) ;
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( r & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( g & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( b & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _cs ) ;
}
# endif
ILI9488_STOP
}
void ILI9488 : : drawPixel ( int16_t x , int16_t y , uint16_t color ) {
if ( ( x < 0 ) | | ( x > = _width ) | | ( y < 0 ) | | ( y > = _height ) ) return ;
2021-01-04 15:29:34 +00:00
setAddrWindow_int ( x , y , x + 1 , y + 1 ) ;
2019-08-19 12:21:54 +01:00
write16BitColor ( color ) ;
ILI9488_STOP
}
void ILI9488 : : drawFastVLine ( int16_t x , int16_t y , int16_t h ,
uint16_t color ) {
// Rudimentary clipping
if ( ( x > = _width ) | | ( y > = _height ) ) return ;
if ( ( y + h - 1 ) > = _height )
h = _height - y ;
2021-01-04 15:29:34 +00:00
setAddrWindow_int ( x , y , x , y + h - 1 ) ;
2019-08-19 12:21:54 +01:00
uint8_t r = ( color & 0xF800 ) > > 11 ;
uint8_t g = ( color & 0x07E0 ) > > 5 ;
uint8_t b = color & 0x001F ;
r = ( r * 255 ) / 31 ;
g = ( g * 255 ) / 63 ;
b = ( b * 255 ) / 31 ;
while ( h - - ) {
# ifndef SWSPI_OPTMODE
writedata ( r ) ;
writedata ( g ) ;
writedata ( b ) ;
# else
if ( _hwspi ) {
writedata ( r ) ;
writedata ( g ) ;
writedata ( b ) ;
} else {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _cs ) ;
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( r & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( g & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( b & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _cs ) ;
}
# endif
}
ILI9488_STOP
}
void ILI9488 : : drawFastHLine ( int16_t x , int16_t y , int16_t w ,
uint16_t color ) {
// Rudimentary clipping
if ( ( x > = _width ) | | ( y > = _height ) ) return ;
if ( ( x + w - 1 ) > = _width ) w = _width - x ;
2021-01-04 15:29:34 +00:00
setAddrWindow_int ( x , y , x + w - 1 , y ) ;
2019-08-19 12:21:54 +01:00
uint8_t r = ( color & 0xF800 ) > > 11 ;
uint8_t g = ( color & 0x07E0 ) > > 5 ;
uint8_t b = color & 0x001F ;
r = ( r * 255 ) / 31 ;
g = ( g * 255 ) / 63 ;
b = ( b * 255 ) / 31 ;
while ( w - - ) {
# ifndef SWSPI_OPTMODE
writedata ( r ) ;
writedata ( g ) ;
writedata ( b ) ;
# else
if ( _hwspi ) {
writedata ( r ) ;
writedata ( g ) ;
writedata ( b ) ;
} else {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _cs ) ;
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( r & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( g & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( b & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _cs ) ;
}
# endif
}
ILI9488_STOP
}
// this moves 460 kbytes
// now at 475 ms with 13,3 Mhz clock
void ILI9488 : : fillScreen ( uint16_t color ) {
//uint32_t time=millis();
fillRect ( 0 , 0 , _width , _height , color ) ;
//time=millis()-time;
//Serial.printf("time %d ms\n",time);
ILI9488_STOP
}
//#define WAIT_9BITS asm_nop_9bits();
# define WAIT_9BITS
//#define WAIT_BEFORE while(*((uint32_t *)0x60000100)&SPI_USR); //waiting for spi module available
# define WAIT_SPI_READY while(READ_PERI_REG(SPI_CMD(1))&SPI_USR);
//#define WAIT_SPI_READY
//#define DIAG_PIN_SET WRITE_PERI_REG( PIN_OUT_SET, 1<<2);
//#define DIAG_PIN_CLR WRITE_PERI_REG( PIN_OUT_CLEAR, 1<<2);
# define DIAG_PIN_SET
# define DIAG_PIN_CLR
//#define WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val)
// CMD 0x60000200-1*0x100
// SPI_USER2 0x60000200-1*0x100 + 0x24
//#define WRITE_SPI_REG WRITE_PERI_REG(0x60000124, regvalue_r);SET_PERI_REG_MASK(0x60000100, SPI_USR);
// THIS TAKES 1 us => 80 cpu clock cycles !!!!!!!!!!!!!!!!!!!!!!!!!!
// probably the memw causes this delay
# define WRITE_SPI_REG(A) WRITE_PERI_REG(SPI_USER2(1), A); SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR);
//#define WRITE_SPI_REG(A) *((uint32_t *)0x60000124)=A; *((uint32_t *)0x60000100)|=SPI_USR;
//#define WRITE_SPI_REG
2020-05-29 19:54:15 +01:00
2019-08-19 12:21:54 +01:00
// extremely strange => if this code is merged into pack_rgb() the software crashes
// swap bytes
uint32_t ulswap ( uint32_t data ) {
union {
uint32_t l ;
uint8_t b [ 4 ] ;
} data_ ;
data_ . l = data ;
// MSBFIRST Byte first
data = ( data_ . b [ 3 ] | ( data_ . b [ 2 ] < < 8 ) | ( data_ . b [ 1 ] < < 16 ) | ( data_ . b [ 0 ] < < 24 ) ) ;
return data ;
}
// pack RGB into uint32
uint32_t pack_rgb ( uint32_t r , uint32_t g , uint32_t b ) {
uint32_t data ;
data = r < < 23 ;
data | = g < < 14 ;
data | = b < < 5 ;
data | = 0b10000000010000000010000000000000 ;
return ulswap ( data ) ;
}
2020-05-29 18:29:03 +01:00
# ifndef ESP32
2019-08-19 12:21:54 +01:00
// fill a rectangle
2020-05-29 18:29:03 +01:00
void ILI9488 : : fillRect ( int16_t x , int16_t y , int16_t w , int16_t h , uint16_t color ) {
2019-08-19 12:21:54 +01:00
ILI9488_START
// rudimentary clipping (drawChar w/big text requires this)
if ( ( x > = _width ) | | ( y > = _height ) ) return ;
if ( ( x + w - 1 ) > = _width ) w = _width - x ;
if ( ( y + h - 1 ) > = _height ) h = _height - y ;
2021-01-04 15:29:34 +00:00
setAddrWindow_int ( x , y , x + w - 1 , y + h - 1 ) ;
2019-08-19 12:21:54 +01:00
//ILI9488_START
uint8_t r = ( color & 0xF800 ) > > 11 ;
uint8_t g = ( color & 0x07E0 ) > > 5 ;
uint8_t b = color & 0x001F ;
r = ( r * 255 ) / 31 ;
g = ( g * 255 ) / 63 ;
b = ( b * 255 ) / 31 ;
uint32_t regvalue_r , regvalue_g , regvalue_b ;
uint32_t data ;
if ( _hwspi ) {
// precalculate the register values for rgb
# ifndef RGB_PACK_MODE
uint8_t bytetemp ;
bytetemp = ( r > > 1 ) | 0x80 ;
regvalue_r = ( ( 8 & SPI_USR_COMMAND_BITLEN ) < < SPI_USR_COMMAND_BITLEN_S ) | ( ( uint32 ) bytetemp ) ; //configure transmission variable,9bit transmission length and first 8 command bit
if ( r & 0x01 ) regvalue_r | = BIT15 ; //write the 9th bit
bytetemp = ( g > > 1 ) | 0x80 ;
regvalue_g = ( ( 8 & SPI_USR_COMMAND_BITLEN ) < < SPI_USR_COMMAND_BITLEN_S ) | ( ( uint32 ) bytetemp ) ; //configure transmission variable,9bit transmission length and first 8 command bit
if ( g & 0x01 ) regvalue_g | = BIT15 ; //write the 9th bit
bytetemp = ( b > > 1 ) | 0x80 ;
regvalue_b = ( ( 8 & SPI_USR_COMMAND_BITLEN ) < < SPI_USR_COMMAND_BITLEN_S ) | ( ( uint32 ) bytetemp ) ; //configure transmission variable,9bit transmission length and first 8 command bit
if ( b & 0x01 ) regvalue_b | = BIT15 ; //write the 9th bit
# else
// init 27 bit mode
uint16_t bits = 27 ;
//const uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
const uint32_t mask = ~ ( ( SPIMMOSI < < SPILMOSI ) ) ;
bits - - ;
SPI1U1 = ( ( SPI1U1 & mask ) | ( ( bits < < SPILMOSI ) ) ) ;
SPI1C = 0 ;
SPI1C & = ~ ( SPICWBO | SPICRBO ) ; // => MSBFIRST
SPI1U = SPIUMOSI ;
SPI1C1 = 0 ;
data = pack_rgb ( r , g , b ) ;
# endif
}
for ( y = h ; y > 0 ; y - - ) {
delay ( 0 ) ;
for ( x = w ; x > 0 ; x - - ) {
# ifndef SWSPI_OPTMODE
writedata ( r ) ;
writedata ( g ) ;
writedata ( b ) ;
# else
if ( _hwspi ) {
//noInterrupts();
# ifdef RGB_PACK_MODE
while ( SPI1CMD & SPIBUSY ) { }
SPI1W0 = data ;
SPI1CMD | = SPIBUSY ;
# else
DIAG_PIN_CLR
WAIT_SPI_READY
DIAG_PIN_SET
WRITE_SPI_REG ( regvalue_r )
WAIT_9BITS
DIAG_PIN_CLR
WAIT_SPI_READY
DIAG_PIN_SET
WRITE_SPI_REG ( regvalue_g )
WAIT_9BITS
DIAG_PIN_CLR
WAIT_SPI_READY
DIAG_PIN_SET
WRITE_SPI_REG ( regvalue_b )
WAIT_9BITS
//interrupts();
# endif
} else {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _cs ) ;
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( r & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( g & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
for ( uint8_t bit = 0x80 ; bit ; bit > > = 1 ) {
WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _sclk ) ;
if ( b & bit ) WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _mosi ) ;
else WRITE_PERI_REG ( PIN_OUT_CLEAR , 1 < < _mosi ) ;
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _sclk ) ;
}
WRITE_PERI_REG ( PIN_OUT_SET , 1 < < _cs ) ;
}
# endif
}
}
# ifdef RGB_PACK_MODE
// reinit old mode
while ( SPI1CMD & SPIBUSY ) { }
ILI9488_STOP
//spi_lcd_mode_init();
# endif
}
2020-05-29 18:29:03 +01:00
# else
// ESP32
void ILI9488 : : fillRect ( int16_t x , int16_t y , int16_t w , int16_t h , uint16_t color ) {
// rudimentary clipping (drawChar w/big text requires this)
if ( ( x > = _width ) | | ( y > = _height ) ) return ;
if ( ( x + w - 1 ) > = _width ) w = _width - x ;
if ( ( y + h - 1 ) > = _height ) h = _height - y ;
2021-01-04 15:29:34 +00:00
setAddrWindow_int ( x , y , x + w - 1 , y + h - 1 ) ;
2020-05-29 18:29:03 +01:00
uint8_t r = ( color & 0xF800 ) > > 11 ;
uint8_t g = ( color & 0x07E0 ) > > 5 ;
uint8_t b = color & 0x001F ;
2019-08-19 12:21:54 +01:00
2020-05-29 18:29:03 +01:00
r = ( r * 255 ) / 31 ;
g = ( g * 255 ) / 63 ;
b = ( b * 255 ) / 31 ;
2020-05-29 19:54:15 +01:00
# ifdef RGB_PACK_MODE
// init 27 bit mode
uint32_t data = pack_rgb ( r , g , b ) ;
REG_SET_BIT ( SPI_USER_REG ( 3 ) , SPI_USR_MOSI ) ;
REG_WRITE ( SPI_MOSI_DLEN_REG ( 3 ) , 27 - 1 ) ;
uint32_t * dp = ( uint32_t * ) SPI_W0_REG ( 3 ) ;
digitalWrite ( _cs , LOW ) ;
# endif
2020-05-29 18:29:03 +01:00
for ( y = h ; y > 0 ; y - - ) {
for ( x = w ; x > 0 ; x - - ) {
2020-05-29 19:54:15 +01:00
# ifndef RGB_PACK_MODE
2020-05-29 18:29:03 +01:00
writedata ( r ) ;
writedata ( g ) ;
writedata ( b ) ;
2020-05-29 19:54:15 +01:00
# else
while ( REG_GET_FIELD ( SPI_CMD_REG ( 3 ) , SPI_USR ) ) ;
* dp = data ;
REG_SET_BIT ( SPI_CMD_REG ( 3 ) , SPI_USR ) ;
# endif
2020-05-29 18:29:03 +01:00
}
}
2020-05-29 19:54:15 +01:00
# ifdef RGB_PACK_MODE
while ( REG_GET_FIELD ( SPI_CMD_REG ( 3 ) , SPI_USR ) ) ;
digitalWrite ( _cs , HIGH ) ;
# endif
2020-05-29 18:29:03 +01:00
ILI9488_STOP
}
# endif
2019-08-19 12:21:54 +01:00
2020-05-29 19:54:15 +01:00
2019-08-19 12:21:54 +01:00
// Pass 8-bit (each) R,G,B, get back 16-bit packed color
uint16_t ILI9488 : : color565 ( uint8_t r , uint8_t g , uint8_t b ) {
return ( ( r & 0xF8 ) < < 8 ) | ( ( g & 0xFC ) < < 3 ) | ( b > > 3 ) ;
}
# define MADCTL_MY 0x80
# define MADCTL_MX 0x40
# define MADCTL_MV 0x20
# define MADCTL_ML 0x10
# define MADCTL_RGB 0x00
# define MADCTL_BGR 0x08
# define MADCTL_MH 0x04
void ILI9488 : : setRotation ( uint8_t m ) {
writecommand ( ILI9488_MADCTL ) ;
rotation = m % 4 ; // can't be higher than 3
switch ( rotation ) {
case 0 :
writedata ( MADCTL_MX | MADCTL_BGR ) ;
_width = ILI9488_TFTWIDTH ;
_height = ILI9488_TFTHEIGHT ;
break ;
case 1 :
writedata ( MADCTL_MV | MADCTL_BGR ) ;
_width = ILI9488_TFTHEIGHT ;
_height = ILI9488_TFTWIDTH ;
break ;
case 2 :
writedata ( MADCTL_MY | MADCTL_BGR ) ;
_width = ILI9488_TFTWIDTH ;
_height = ILI9488_TFTHEIGHT ;
break ;
case 3 :
writedata ( MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR ) ;
_width = ILI9488_TFTHEIGHT ;
_height = ILI9488_TFTWIDTH ;
break ;
}
ILI9488_STOP
}
void ILI9488 : : invertDisplay ( boolean i ) {
writecommand ( i ? ILI9488_INVON : ILI9488_INVOFF ) ;
ILI9488_STOP
}