|
|
|
@ -26,8 +26,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
#include "spi.h"
|
|
|
|
#include "spi.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Allow enable DMA for read display data
|
|
|
|
// Allow enable DMA for read display data
|
|
|
|
#ifdef TINYSA4
|
|
|
|
#ifdef TINYSA4
|
|
|
|
#define __USE_DISPLAY_DMA_RX__
|
|
|
|
#define __USE_DISPLAY_DMA_RX__
|
|
|
|
@ -58,10 +56,10 @@
|
|
|
|
#define LCD_SPI_RX_SPEED SPI_BR_DIV4
|
|
|
|
#define LCD_SPI_RX_SPEED SPI_BR_DIV4
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t spi_buffer[SPI_BUFFER_SIZE];
|
|
|
|
pixel_t spi_buffer[SPI_BUFFER_SIZE];
|
|
|
|
// Default foreground & background colors
|
|
|
|
// Default foreground & background colors
|
|
|
|
uint16_t foreground_color = 0;
|
|
|
|
pixel_t foreground_color = 0;
|
|
|
|
uint16_t background_color = 0;
|
|
|
|
pixel_t background_color = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// Display width and height definition
|
|
|
|
// Display width and height definition
|
|
|
|
#define ILI9341_WIDTH LCD_WIDTH
|
|
|
|
#define ILI9341_WIDTH LCD_WIDTH
|
|
|
|
@ -357,11 +355,8 @@ void set_SPI_mode(uint16_t mode){
|
|
|
|
static void send_command(uint8_t cmd, uint8_t len, const uint8_t *data)
|
|
|
|
static void send_command(uint8_t cmd, uint8_t len, const uint8_t *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// Uncomment on low speed SPI (possible get here before previous tx complete)
|
|
|
|
// Uncomment on low speed SPI (possible get here before previous tx complete)
|
|
|
|
#ifndef TINYSA4
|
|
|
|
// while (SPI_IN_TX_RX(LCD_SPI));
|
|
|
|
while (SPI_IN_TX_RX(LCD_SPI));
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef TINYSA4
|
|
|
|
#ifdef TINYSA4
|
|
|
|
// while (SPI_IN_TX_RX);
|
|
|
|
|
|
|
|
set_SPI_mode(SPI_MODE_LCD);
|
|
|
|
set_SPI_mode(SPI_MODE_LCD);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
LCD_CS_LOW;
|
|
|
|
LCD_CS_LOW;
|
|
|
|
@ -517,7 +512,9 @@ static void ili9341_setWindow(int x, int y, int w, int h){
|
|
|
|
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t *)&yy);
|
|
|
|
send_command(ILI9341_PAGE_ADDRESS_SET, 4, (uint8_t *)&yy);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ili9341_bulk_8bit(int x, int y, int w, int h, uint16_t *palette)
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
// Test code for palette mode
|
|
|
|
|
|
|
|
void ili9341_bulk_8bit(int x, int y, int w, int h, pixel_t *palette)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
|
|
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
|
|
@ -528,27 +525,62 @@ void ili9341_bulk_8bit(int x, int y, int w, int h, uint16_t *palette)
|
|
|
|
spi_TxWord(palette[*buf++]);
|
|
|
|
spi_TxWord(palette[*buf++]);
|
|
|
|
// LCD_CS_HIGH;
|
|
|
|
// LCD_CS_HIGH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if DISPLAY_CELL_BUFFER_COUNT != 1
|
|
|
|
|
|
|
|
#define LCD_BUFFER_1 0x01
|
|
|
|
|
|
|
|
#define LCD_DMA_RUN 0x02
|
|
|
|
|
|
|
|
static uint8_t LCD_dma_status = 0;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pixel_t *ili9341_get_cell_buffer(void){
|
|
|
|
|
|
|
|
#if DISPLAY_CELL_BUFFER_COUNT == 1
|
|
|
|
|
|
|
|
return spi_buffer;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
return &spi_buffer[(LCD_dma_status&LCD_BUFFER_1) ? SPI_BUFFER_SIZE/2 : 0];
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef __USE_DISPLAY_DMA__
|
|
|
|
#ifndef __USE_DISPLAY_DMA__
|
|
|
|
void ili9341_fill(int x, int y, int w, int h, uint16_t color)
|
|
|
|
void ili9341_fill(int x, int y, int w, int h, pixel_t color)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
|
|
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
|
|
int32_t len = w * h;
|
|
|
|
uint32_t len = w * h;
|
|
|
|
while (len-- > 0)
|
|
|
|
do {
|
|
|
|
spi_TxWord(color);
|
|
|
|
while (SPI_TX_IS_NOT_EMPTY(LCD_SPI))
|
|
|
|
// LCD_CS_HIGH;
|
|
|
|
;
|
|
|
|
|
|
|
|
SPI_WRITE_16BIT(LCD_SPI, color);
|
|
|
|
|
|
|
|
}while(--len);
|
|
|
|
|
|
|
|
#ifdef __REMOTE_DESKTOP__
|
|
|
|
|
|
|
|
if (auto_capture) {
|
|
|
|
|
|
|
|
send_region("fill", x,y,w,h);
|
|
|
|
|
|
|
|
send_buffer((uint8_t *)&background_color, 2);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ili9341_bulk(int x, int y, int w, int h)
|
|
|
|
void ili9341_bulk(int x, int y, int w, int h)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
|
|
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
|
|
int32_t len = w * h;
|
|
|
|
spi_TxBuffer((uint8_t *)spi_buffer, w * h * sizeof(pixel_t));
|
|
|
|
while (len-- > 0)
|
|
|
|
#ifdef __REMOTE_DESKTOP__
|
|
|
|
spi_TxWord(*buf++);
|
|
|
|
if (auto_capture) {
|
|
|
|
// LCD_CS_HIGH;
|
|
|
|
send_region("bulk", x,y,w,h);
|
|
|
|
|
|
|
|
send_buffer((uint8_t *)buffer, w *h * sizeof(pixel_t));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ili9341_bulk_continue(int x, int y, int w, int h){
|
|
|
|
|
|
|
|
ili9341_bulk(x, y, w, h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ili9341_bulk_finish(void){
|
|
|
|
|
|
|
|
while (SPI_IS_BUSY(LCD_SPI)); // Wait tx
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Use DMA for send data
|
|
|
|
// Use DMA for send data
|
|
|
|
@ -563,36 +595,57 @@ void ili9341_fill(int x, int y, int w, int h)
|
|
|
|
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD);
|
|
|
|
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD);
|
|
|
|
#ifdef __REMOTE_DESKTOP__
|
|
|
|
#ifdef __REMOTE_DESKTOP__
|
|
|
|
if (auto_capture) {
|
|
|
|
if (auto_capture) {
|
|
|
|
send_region("fill", x,y,w,h);
|
|
|
|
send_region("fill", x, y, w, h);
|
|
|
|
send_buffer((uint8_t *)&background_color, 2);
|
|
|
|
send_buffer((uint8_t *)&background_color, sizeof(pixel_t));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
dmaStreamFlush(w * h);
|
|
|
|
dmaStreamFlush(w * h);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Copy spi_buffer to region
|
|
|
|
void ili9341_bulk_finish(void){
|
|
|
|
void ili9341_bulk(int x, int y, int w, int h)
|
|
|
|
dmaWaitCompletion(dmatx); // Wait DMA
|
|
|
|
{
|
|
|
|
while (SPI_IN_TX_RX(LCD_SPI)); // Wait tx
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void ili9341_DMA_bulk(int x, int y, int w, int h, pixel_t *buffer){
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
|
|
send_command(ILI9341_MEMORY_WRITE, 0, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
// Init Tx DMA mem->spi, set size, mode (spi and mem data size is 16 bit)
|
|
|
|
dmaStreamSetMemory0(dmatx, buffer);
|
|
|
|
dmaStreamSetMemory0(dmatx, spi_buffer);
|
|
|
|
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_MINC);
|
|
|
|
dmaStreamSetMode(dmatx, txdmamode | STM32_DMA_CR_PSIZE_HWORD |
|
|
|
|
dmaStreamSetTransactionSize(dmatx, w * h);
|
|
|
|
STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_MINC);
|
|
|
|
dmaStreamEnable(dmatx);
|
|
|
|
#ifdef __REMOTE_DESKTOP__
|
|
|
|
#ifdef __REMOTE_DESKTOP__
|
|
|
|
if (auto_capture) {
|
|
|
|
if (auto_capture) {
|
|
|
|
send_region("bulk", x,y,w,h);
|
|
|
|
send_region("bulk", x, y, w, h);
|
|
|
|
send_buffer((uint8_t *)spi_buffer, w*h*2);
|
|
|
|
send_buffer((uint8_t *)buffer, w *h * sizeof(pixel_t));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
dmaStreamFlush(w * h);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy spi_buffer to region
|
|
|
|
|
|
|
|
void ili9341_bulk(int x, int y, int w, int h)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
ili9341_DMA_bulk(x, y ,w, h, spi_buffer); // Send data
|
|
|
|
|
|
|
|
ili9341_bulk_finish(); // Wait
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Copy part of spi_buffer to region, no wait completion after if buffer count !=1
|
|
|
|
|
|
|
|
void ili9341_bulk_continue(int x, int y, int w, int h)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#if DISPLAY_CELL_BUFFER_COUNT == 1
|
|
|
|
|
|
|
|
ili9341_bulk(x, y, w, h);
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
ili9341_bulk_finish(); // Wait DMA
|
|
|
|
|
|
|
|
ili9341_DMA_bulk(x, y , w, h, ili9341_get_cell_buffer()); // Send new cell data
|
|
|
|
|
|
|
|
LCD_dma_status^=LCD_BUFFER_1; // Switch buffer
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef __USE_DISPLAY_DMA_RX__
|
|
|
|
#ifndef __USE_DISPLAY_DMA_RX__
|
|
|
|
|
|
|
|
|
|
|
|
void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out)
|
|
|
|
void ili9341_read_memory(int x, int y, int w, int h, int len, pixel_t *out)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
ili9341_setWindow(x, y ,w, h);
|
|
|
|
send_command(ILI9341_MEMORY_READ, 0, NULL);
|
|
|
|
send_command(ILI9341_MEMORY_READ, 0, NULL);
|
|
|
|
@ -627,7 +680,7 @@ void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out)
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
// Copy screen data to buffer
|
|
|
|
// Copy screen data to buffer
|
|
|
|
// Warning!!! buffer size must be greater then 3*len + 1 bytes
|
|
|
|
// Warning!!! buffer size must be greater then 3*len + 1 bytes
|
|
|
|
void ili9341_read_memory(int x, int y, int w, int h, int len, uint16_t *out)
|
|
|
|
void ili9341_read_memory(int x, int y, int w, int h, int len, pixel_t *out)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16_t dummy_tx = 0;
|
|
|
|
uint16_t dummy_tx = 0;
|
|
|
|
uint8_t *rgbbuf = (uint8_t *)out;
|
|
|
|
uint8_t *rgbbuf = (uint8_t *)out;
|
|
|
|
@ -719,7 +772,7 @@ void ili9341_set_rotation(uint8_t r)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint8_t bit_align = 0;
|
|
|
|
static uint8_t bit_align = 0;
|
|
|
|
void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
|
|
|
|
void ili9341_blitBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
|
|
|
|
const uint8_t *b)
|
|
|
|
const uint8_t *b)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16_t *buf = spi_buffer;
|
|
|
|
uint16_t *buf = spi_buffer;
|
|
|
|
@ -735,25 +788,9 @@ void blit8BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height
|
|
|
|
ili9341_bulk(x, y, width, height);
|
|
|
|
ili9341_bulk(x, y, width, height);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
|
|
void blit16BitWidthBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
|
|
|
|
|
|
|
|
const uint16_t *bitmap)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint16_t *buf = spi_buffer;
|
|
|
|
|
|
|
|
for (uint16_t c = 0; c < height; c++) {
|
|
|
|
|
|
|
|
uint16_t bits = *bitmap++;
|
|
|
|
|
|
|
|
for (uint16_t r = 0; r < width; r++) {
|
|
|
|
|
|
|
|
*buf++ = (0x8000 & bits) ? foreground_color : background_color;
|
|
|
|
|
|
|
|
bits <<= 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ili9341_bulk(x, y, width, height);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ili9341_drawchar(uint8_t ch, int x, int y)
|
|
|
|
void ili9341_drawchar(uint8_t ch, int x, int y)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
blit8BitWidthBitmap(x, y, FONT_GET_WIDTH(ch), FONT_GET_HEIGHT, FONT_GET_DATA(ch));
|
|
|
|
ili9341_blitBitmap(x, y, FONT_GET_WIDTH(ch), FONT_GET_HEIGHT, FONT_GET_DATA(ch));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ili9341_drawstring(const char *str, int x, int y)
|
|
|
|
void ili9341_drawstring(const char *str, int x, int y)
|
|
|
|
@ -764,7 +801,7 @@ void ili9341_drawstring(const char *str, int x, int y)
|
|
|
|
if (ch == '\n') {x = x_pos; y+=FONT_STR_HEIGHT; continue;}
|
|
|
|
if (ch == '\n') {x = x_pos; y+=FONT_STR_HEIGHT; continue;}
|
|
|
|
const uint8_t *char_buf = FONT_GET_DATA(ch);
|
|
|
|
const uint8_t *char_buf = FONT_GET_DATA(ch);
|
|
|
|
uint16_t w = FONT_GET_WIDTH(ch);
|
|
|
|
uint16_t w = FONT_GET_WIDTH(ch);
|
|
|
|
blit8BitWidthBitmap(x, y, w, FONT_GET_HEIGHT, char_buf);
|
|
|
|
ili9341_blitBitmap(x, y, w, FONT_GET_HEIGHT, char_buf);
|
|
|
|
x += w;
|
|
|
|
x += w;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -777,7 +814,7 @@ void ili9341_drawstring_7x13(const char *str, int x, int y)
|
|
|
|
if (ch == '\n') {x = x_pos; y+=bFONT_STR_HEIGHT; continue;}
|
|
|
|
if (ch == '\n') {x = x_pos; y+=bFONT_STR_HEIGHT; continue;}
|
|
|
|
const uint8_t *char_buf = bFONT_GET_DATA(ch);
|
|
|
|
const uint8_t *char_buf = bFONT_GET_DATA(ch);
|
|
|
|
uint16_t w = bFONT_GET_WIDTH(ch);
|
|
|
|
uint16_t w = bFONT_GET_WIDTH(ch);
|
|
|
|
blit8BitWidthBitmap(x, y, w, bFONT_GET_HEIGHT, char_buf);
|
|
|
|
ili9341_blitBitmap(x, y, w, bFONT_GET_HEIGHT, char_buf);
|
|
|
|
x += w;
|
|
|
|
x += w;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -792,7 +829,7 @@ void ili9341_drawstring_10x14(const char *str, int x, int y)
|
|
|
|
const uint8_t *char_buf = wFONT_GET_DATA(ch);
|
|
|
|
const uint8_t *char_buf = wFONT_GET_DATA(ch);
|
|
|
|
uint16_t w = wFONT_GET_WIDTH(ch);
|
|
|
|
uint16_t w = wFONT_GET_WIDTH(ch);
|
|
|
|
bit_align = (w<=8) ? 1 : 0;
|
|
|
|
bit_align = (w<=8) ? 1 : 0;
|
|
|
|
blit8BitWidthBitmap(x, y, w, wFONT_GET_HEIGHT, char_buf);
|
|
|
|
ili9341_blitBitmap(x, y, w, wFONT_GET_HEIGHT, char_buf);
|
|
|
|
x += w;
|
|
|
|
x += w;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bit_align = 0;
|
|
|
|
bit_align = 0;
|
|
|
|
@ -834,7 +871,7 @@ void ili9341_drawstring_size(const char *str, int x, int y, uint8_t size)
|
|
|
|
|
|
|
|
|
|
|
|
void ili9341_drawfont(uint8_t ch, int x, int y)
|
|
|
|
void ili9341_drawfont(uint8_t ch, int x, int y)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
blit8BitWidthBitmap(x, y, NUM_FONT_GET_WIDTH, NUM_FONT_GET_HEIGHT,
|
|
|
|
ili9341_blitBitmap(x, y, NUM_FONT_GET_WIDTH, NUM_FONT_GET_HEIGHT,
|
|
|
|
NUM_FONT_GET_DATA(ch));
|
|
|
|
NUM_FONT_GET_DATA(ch));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|