1300 lines
31 KiB
C++
1300 lines
31 KiB
C++
#include "lcd.h"
|
|
#include "lcd_dma.h"
|
|
#include "exmc_driver.h"
|
|
#include "systick.h"
|
|
#include <cstdio>
|
|
#include "font.h"
|
|
|
|
extern "C" uint32_t SystemCoreClock;
|
|
|
|
Lcd &Lcd::instance()
|
|
{
|
|
static Lcd inst;
|
|
return inst;
|
|
}
|
|
|
|
Lcd::Lcd()
|
|
: lcddev_{0, 0, 0, 0, 0, 0, 0},
|
|
point_color_(Color::WHITE),
|
|
back_color_(Color::BLACK),
|
|
id_string_{0}
|
|
{
|
|
}
|
|
|
|
Lcd::LcdRegs *Lcd::regs()
|
|
{
|
|
return reinterpret_cast<LcdRegs *>(0x6C000000 | 0x000007FE);
|
|
}
|
|
|
|
void Lcd::rstOn() { gpio_bit_set(GPIOD, GPIO_PIN_12); }
|
|
void Lcd::rstOff() { gpio_bit_reset(GPIOD, GPIO_PIN_12); }
|
|
void Lcd::blkOn() { gpio_bit_set(GPIOD, GPIO_PIN_13); }
|
|
void Lcd::blkOff() { gpio_bit_reset(GPIOD, GPIO_PIN_13); }
|
|
|
|
uint16_t Lcd::width() const { return lcddev_.width_; }
|
|
uint16_t Lcd::height() const { return lcddev_.height_; }
|
|
uint16_t Lcd::id() const { return lcddev_.id_; }
|
|
const char *Lcd::idString() const { return id_string_; }
|
|
uint16_t Lcd::foreground() const { return point_color_; }
|
|
uint16_t Lcd::background() const { return back_color_; }
|
|
void Lcd::setForeground(uint16_t color) { point_color_ = color; }
|
|
void Lcd::setBackground(uint16_t color) { back_color_ = color; }
|
|
|
|
void Lcd::wrReg(uint16_t regval)
|
|
{
|
|
regs()->LCD_REG = regval;
|
|
__DSB();
|
|
}
|
|
|
|
void Lcd::wrData(uint16_t data)
|
|
{
|
|
regs()->LCD_RAM = data;
|
|
__DSB();
|
|
}
|
|
|
|
void Lcd::writeRam(uint16_t color)
|
|
{
|
|
regs()->LCD_RAM = color;
|
|
__DSB();
|
|
}
|
|
|
|
void Lcd::writeReg(uint16_t reg, uint16_t value)
|
|
{
|
|
regs()->LCD_REG = reg;
|
|
__DSB();
|
|
regs()->LCD_RAM = value;
|
|
__DSB();
|
|
}
|
|
|
|
void Lcd::writeRamPrepare()
|
|
{
|
|
regs()->LCD_REG = lcddev_.wramcmd_;
|
|
__DSB();
|
|
}
|
|
|
|
uint16_t Lcd::rdData()
|
|
{
|
|
return regs()->LCD_RAM;
|
|
}
|
|
|
|
void Lcd::flush()
|
|
{
|
|
__DSB();
|
|
volatile uint16_t dummy = regs()->LCD_RAM;
|
|
(void)dummy;
|
|
}
|
|
|
|
uint16_t Lcd::readReg(uint16_t reg)
|
|
{
|
|
wrReg(reg);
|
|
__NOP(); __NOP(); __NOP(); __NOP();
|
|
__NOP(); __NOP(); __NOP(); __NOP();
|
|
uint16_t data = rdData();
|
|
printf("[Lcd::readReg] 0x%04X -> 0x%04X\r\n", reg, data);
|
|
return data;
|
|
}
|
|
|
|
void Lcd::readID()
|
|
{
|
|
uint16_t id1, id2, id3;
|
|
|
|
printf("[LCD ID] Start reading...\r\n");
|
|
delay_1ms(50);
|
|
writeReg(0x0000, 0x0001);
|
|
delay_1ms(50);
|
|
lcddev_.id_ = readReg(0x0000);
|
|
printf("[LCD ID] reg0x0000: 0x%04X\r\n", lcddev_.id_);
|
|
|
|
printf("[LCD ID] Reset LCD...\r\n");
|
|
rstOn();
|
|
delay_1ms(10);
|
|
rstOff();
|
|
delay_1ms(50);
|
|
rstOn();
|
|
delay_1ms(120);
|
|
|
|
wrReg(0XDA00);
|
|
id1 = rdData();
|
|
printf("[LCD ID] ID1: 0x%04X\r\n", id1);
|
|
|
|
wrReg(0XDB00);
|
|
id2 = rdData();
|
|
printf("[LCD ID] ID2: 0x%04X\r\n", id2);
|
|
|
|
if (id2 == 0x8000)
|
|
id2 = 0x80;
|
|
else if ((id2 >> 8) == 0x80)
|
|
id2 >>= 8;
|
|
|
|
wrReg(0XDC00);
|
|
id3 = rdData();
|
|
printf("[LCD ID] ID3: 0x%04X\r\n", id3);
|
|
|
|
lcddev_.id_ = (id2 << 8) | (id3 & 0xFF);
|
|
printf("NT35510 LCD ID:%04X\r\n", lcddev_.id_);
|
|
sprintf(id_string_, "LCD ID:%04X", lcddev_.id_);
|
|
}
|
|
|
|
void Lcd::ctrlLinesConfig()
|
|
{
|
|
rcu_periph_clock_enable(RCU_GPIOD);
|
|
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_13);
|
|
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
|
|
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_12);
|
|
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
|
|
}
|
|
|
|
void Lcd::fsmcConfig()
|
|
{
|
|
exmc_norsram_parameter_struct nor_init_struct;
|
|
exmc_norsram_timing_parameter_struct readWriteTiming;
|
|
exmc_norsram_timing_parameter_struct writeTiming;
|
|
|
|
ExmcBus &exmc_bus = ExmcBus::instance();
|
|
exmc_bus.init();
|
|
ExmcBus::norsram_lcd_pin_init();
|
|
|
|
readWriteTiming.asyn_access_mode = EXMC_ACCESS_MODE_A;
|
|
readWriteTiming.syn_data_latency = EXMC_DATALAT_2_CLK;
|
|
readWriteTiming.syn_clk_division = EXMC_SYN_CLOCK_RATIO_2_CLK;
|
|
readWriteTiming.bus_latency = 0;
|
|
readWriteTiming.asyn_address_holdtime = 0;
|
|
writeTiming = readWriteTiming;
|
|
|
|
if (SystemCoreClock > 100000000)
|
|
{
|
|
printf("[FSMC] 168MHz timing\r\n");
|
|
readWriteTiming.asyn_data_setuptime = 61;
|
|
readWriteTiming.asyn_address_setuptime = 15;
|
|
writeTiming.asyn_data_setuptime = 5;
|
|
writeTiming.asyn_address_setuptime = 4;
|
|
}
|
|
else
|
|
{
|
|
printf("[FSMC] 16MHz timing\r\n");
|
|
readWriteTiming.asyn_data_setuptime = 6;
|
|
readWriteTiming.asyn_address_setuptime = 2;
|
|
writeTiming.asyn_data_setuptime = 1;
|
|
writeTiming.asyn_address_setuptime = 1;
|
|
}
|
|
|
|
nor_init_struct.norsram_region = EXMC_BANK0_NORSRAM_REGION3;
|
|
nor_init_struct.address_data_mux = DISABLE;
|
|
nor_init_struct.memory_type = EXMC_MEMORY_TYPE_SRAM;
|
|
nor_init_struct.databus_width = EXMC_NOR_DATABUS_WIDTH_16B;
|
|
nor_init_struct.burst_mode = DISABLE;
|
|
nor_init_struct.nwait_polarity = EXMC_NWAIT_POLARITY_LOW;
|
|
nor_init_struct.asyn_wait = DISABLE;
|
|
nor_init_struct.wrap_burst_mode = DISABLE;
|
|
nor_init_struct.nwait_config = EXMC_NWAIT_CONFIG_BEFORE;
|
|
nor_init_struct.memory_write = ENABLE;
|
|
nor_init_struct.nwait_signal = DISABLE;
|
|
nor_init_struct.extended_mode = ENABLE;
|
|
nor_init_struct.write_mode = EXMC_ASYN_WRITE;
|
|
nor_init_struct.read_write_timing = &readWriteTiming;
|
|
nor_init_struct.write_timing = &writeTiming;
|
|
exmc_norsram_init(&nor_init_struct);
|
|
exmc_norsram_enable(EXMC_BANK0_NORSRAM_REGION3);
|
|
}
|
|
|
|
void Lcd::hvgaConfig()
|
|
{
|
|
lcddev_.width_ = 480;
|
|
lcddev_.height_ = 800;
|
|
lcddev_.setxcmd_ = 0X2A00;
|
|
lcddev_.setycmd_ = 0X2B00;
|
|
lcddev_.wramcmd_ = 0X2C00;
|
|
}
|
|
|
|
void Lcd::initialCode()
|
|
{
|
|
writeReg(0xF000, 0x55);
|
|
writeReg(0xF001, 0xAA);
|
|
writeReg(0xF002, 0x52);
|
|
writeReg(0xF003, 0x08);
|
|
writeReg(0xF004, 0x01);
|
|
writeReg(0xB000, 0x0D);
|
|
writeReg(0xB001, 0x0D);
|
|
writeReg(0xB002, 0x0D);
|
|
writeReg(0xB600, 0x34);
|
|
writeReg(0xB601, 0x34);
|
|
writeReg(0xB602, 0x34);
|
|
writeReg(0xB100, 0x0D);
|
|
writeReg(0xB101, 0x0D);
|
|
writeReg(0xB102, 0x0D);
|
|
writeReg(0xB700, 0x34);
|
|
writeReg(0xB701, 0x34);
|
|
writeReg(0xB702, 0x34);
|
|
writeReg(0xB200, 0x00);
|
|
writeReg(0xB201, 0x00);
|
|
writeReg(0xB202, 0x00);
|
|
writeReg(0xB800, 0x24);
|
|
writeReg(0xB801, 0x24);
|
|
writeReg(0xB802, 0x24);
|
|
writeReg(0xBF00, 0x01);
|
|
writeReg(0xB300, 0x0F);
|
|
writeReg(0xB301, 0x0F);
|
|
writeReg(0xB302, 0x0F);
|
|
writeReg(0xB900, 0x34);
|
|
writeReg(0xB901, 0x34);
|
|
writeReg(0xB902, 0x34);
|
|
writeReg(0xB500, 0x08);
|
|
writeReg(0xB501, 0x08);
|
|
writeReg(0xB502, 0x08);
|
|
writeReg(0xC200, 0x03);
|
|
writeReg(0xBA00, 0x24);
|
|
writeReg(0xBA01, 0x24);
|
|
writeReg(0xBA02, 0x24);
|
|
writeReg(0xBC00, 0x00);
|
|
writeReg(0xBC01, 0x78);
|
|
writeReg(0xBC02, 0x00);
|
|
writeReg(0xBD00, 0x00);
|
|
writeReg(0xBD01, 0x78);
|
|
writeReg(0xBD02, 0x00);
|
|
writeReg(0xBE00, 0x00);
|
|
writeReg(0xBE01, 0x64);
|
|
writeReg(0xD100, 0x00);
|
|
writeReg(0xD101, 0x33);
|
|
writeReg(0xD102, 0x00);
|
|
writeReg(0xD103, 0x34);
|
|
writeReg(0xD104, 0x00);
|
|
writeReg(0xD105, 0x3A);
|
|
writeReg(0xD106, 0x00);
|
|
writeReg(0xD107, 0x4A);
|
|
writeReg(0xD108, 0x00);
|
|
writeReg(0xD109, 0x5C);
|
|
writeReg(0xD10A, 0x00);
|
|
writeReg(0xD10B, 0x81);
|
|
writeReg(0xD10C, 0x00);
|
|
writeReg(0xD10D, 0xA6);
|
|
writeReg(0xD10E, 0x00);
|
|
writeReg(0xD10F, 0xE5);
|
|
writeReg(0xD110, 0x01);
|
|
writeReg(0xD111, 0x13);
|
|
writeReg(0xD112, 0x01);
|
|
writeReg(0xD113, 0x54);
|
|
writeReg(0xD114, 0x01);
|
|
writeReg(0xD115, 0x82);
|
|
writeReg(0xD116, 0x01);
|
|
writeReg(0xD117, 0xCA);
|
|
writeReg(0xD118, 0x02);
|
|
writeReg(0xD119, 0x00);
|
|
writeReg(0xD11A, 0x02);
|
|
writeReg(0xD11B, 0x01);
|
|
writeReg(0xD11C, 0x02);
|
|
writeReg(0xD11D, 0x34);
|
|
writeReg(0xD11E, 0x02);
|
|
writeReg(0xD11F, 0x67);
|
|
writeReg(0xD120, 0x02);
|
|
writeReg(0xD121, 0x84);
|
|
writeReg(0xD122, 0x02);
|
|
writeReg(0xD123, 0xA4);
|
|
writeReg(0xD124, 0x02);
|
|
writeReg(0xD125, 0xB7);
|
|
writeReg(0xD126, 0x02);
|
|
writeReg(0xD127, 0xCF);
|
|
writeReg(0xD128, 0x02);
|
|
writeReg(0xD129, 0xDE);
|
|
writeReg(0xD12A, 0x02);
|
|
writeReg(0xD12B, 0xF2);
|
|
writeReg(0xD12C, 0x02);
|
|
writeReg(0xD12D, 0xFE);
|
|
writeReg(0xD12E, 0x03);
|
|
writeReg(0xD12F, 0x10);
|
|
writeReg(0xD130, 0x03);
|
|
writeReg(0xD131, 0x33);
|
|
writeReg(0xD132, 0x03);
|
|
writeReg(0xD133, 0x6D);
|
|
writeReg(0xD200, 0x00);
|
|
writeReg(0xD201, 0x33);
|
|
writeReg(0xD202, 0x00);
|
|
writeReg(0xD203, 0x34);
|
|
writeReg(0xD204, 0x00);
|
|
writeReg(0xD205, 0x3A);
|
|
writeReg(0xD206, 0x00);
|
|
writeReg(0xD207, 0x4A);
|
|
writeReg(0xD208, 0x00);
|
|
writeReg(0xD209, 0x5C);
|
|
writeReg(0xD20A, 0x00);
|
|
writeReg(0xD20B, 0x81);
|
|
writeReg(0xD20C, 0x00);
|
|
writeReg(0xD20D, 0xA6);
|
|
writeReg(0xD20E, 0x00);
|
|
writeReg(0xD20F, 0xE5);
|
|
writeReg(0xD210, 0x01);
|
|
writeReg(0xD211, 0x13);
|
|
writeReg(0xD212, 0x01);
|
|
writeReg(0xD213, 0x54);
|
|
writeReg(0xD214, 0x01);
|
|
writeReg(0xD215, 0x82);
|
|
writeReg(0xD216, 0x01);
|
|
writeReg(0xD217, 0xCA);
|
|
writeReg(0xD218, 0x02);
|
|
writeReg(0xD219, 0x00);
|
|
writeReg(0xD21A, 0x02);
|
|
writeReg(0xD21B, 0x01);
|
|
writeReg(0xD21C, 0x02);
|
|
writeReg(0xD21D, 0x34);
|
|
writeReg(0xD21E, 0x02);
|
|
writeReg(0xD21F, 0x67);
|
|
writeReg(0xD220, 0x02);
|
|
writeReg(0xD221, 0x84);
|
|
writeReg(0xD222, 0x02);
|
|
writeReg(0xD223, 0xA4);
|
|
writeReg(0xD224, 0x02);
|
|
writeReg(0xD225, 0xB7);
|
|
writeReg(0xD226, 0x02);
|
|
writeReg(0xD227, 0xCF);
|
|
writeReg(0xD228, 0x02);
|
|
writeReg(0xD229, 0xDE);
|
|
writeReg(0xD22A, 0x02);
|
|
writeReg(0xD22B, 0xF2);
|
|
writeReg(0xD22C, 0x02);
|
|
writeReg(0xD22D, 0xFE);
|
|
writeReg(0xD22E, 0x03);
|
|
writeReg(0xD22F, 0x10);
|
|
writeReg(0xD230, 0x03);
|
|
writeReg(0xD231, 0x33);
|
|
writeReg(0xD232, 0x03);
|
|
writeReg(0xD233, 0x6D);
|
|
writeReg(0xD300, 0x00);
|
|
writeReg(0xD301, 0x33);
|
|
writeReg(0xD302, 0x00);
|
|
writeReg(0xD303, 0x34);
|
|
writeReg(0xD304, 0x00);
|
|
writeReg(0xD305, 0x3A);
|
|
writeReg(0xD306, 0x00);
|
|
writeReg(0xD307, 0x4A);
|
|
writeReg(0xD308, 0x00);
|
|
writeReg(0xD309, 0x5C);
|
|
writeReg(0xD30A, 0x00);
|
|
writeReg(0xD30B, 0x81);
|
|
writeReg(0xD30C, 0x00);
|
|
writeReg(0xD30D, 0xA6);
|
|
writeReg(0xD30E, 0x00);
|
|
writeReg(0xD30F, 0xE5);
|
|
writeReg(0xD310, 0x01);
|
|
writeReg(0xD311, 0x13);
|
|
writeReg(0xD312, 0x01);
|
|
writeReg(0xD313, 0x54);
|
|
writeReg(0xD314, 0x01);
|
|
writeReg(0xD315, 0x82);
|
|
writeReg(0xD316, 0x01);
|
|
writeReg(0xD317, 0xCA);
|
|
writeReg(0xD318, 0x02);
|
|
writeReg(0xD319, 0x00);
|
|
writeReg(0xD31A, 0x02);
|
|
writeReg(0xD31B, 0x01);
|
|
writeReg(0xD31C, 0x02);
|
|
writeReg(0xD31D, 0x34);
|
|
writeReg(0xD31E, 0x02);
|
|
writeReg(0xD31F, 0x67);
|
|
writeReg(0xD320, 0x02);
|
|
writeReg(0xD321, 0x84);
|
|
writeReg(0xD322, 0x02);
|
|
writeReg(0xD323, 0xA4);
|
|
writeReg(0xD324, 0x02);
|
|
writeReg(0xD325, 0xB7);
|
|
writeReg(0xD326, 0x02);
|
|
writeReg(0xD327, 0xCF);
|
|
writeReg(0xD328, 0x02);
|
|
writeReg(0xD329, 0xDE);
|
|
writeReg(0xD32A, 0x02);
|
|
writeReg(0xD32B, 0xF2);
|
|
writeReg(0xD32C, 0x02);
|
|
writeReg(0xD32D, 0xFE);
|
|
writeReg(0xD32E, 0x03);
|
|
writeReg(0xD32F, 0x10);
|
|
writeReg(0xD330, 0x03);
|
|
writeReg(0xD331, 0x33);
|
|
writeReg(0xD332, 0x03);
|
|
writeReg(0xD333, 0x6D);
|
|
writeReg(0xD400, 0x00);
|
|
writeReg(0xD401, 0x33);
|
|
writeReg(0xD402, 0x00);
|
|
writeReg(0xD403, 0x34);
|
|
writeReg(0xD404, 0x00);
|
|
writeReg(0xD405, 0x3A);
|
|
writeReg(0xD406, 0x00);
|
|
writeReg(0xD407, 0x4A);
|
|
writeReg(0xD408, 0x00);
|
|
writeReg(0xD409, 0x5C);
|
|
writeReg(0xD40A, 0x00);
|
|
writeReg(0xD40B, 0x81);
|
|
writeReg(0xD40C, 0x00);
|
|
writeReg(0xD40D, 0xA6);
|
|
writeReg(0xD40E, 0x00);
|
|
writeReg(0xD40F, 0xE5);
|
|
writeReg(0xD410, 0x01);
|
|
writeReg(0xD411, 0x13);
|
|
writeReg(0xD412, 0x01);
|
|
writeReg(0xD413, 0x54);
|
|
writeReg(0xD414, 0x01);
|
|
writeReg(0xD415, 0x82);
|
|
writeReg(0xD416, 0x01);
|
|
writeReg(0xD417, 0xCA);
|
|
writeReg(0xD418, 0x02);
|
|
writeReg(0xD419, 0x00);
|
|
writeReg(0xD41A, 0x02);
|
|
writeReg(0xD41B, 0x01);
|
|
writeReg(0xD41C, 0x02);
|
|
writeReg(0xD41D, 0x34);
|
|
writeReg(0xD41E, 0x02);
|
|
writeReg(0xD41F, 0x67);
|
|
writeReg(0xD420, 0x02);
|
|
writeReg(0xD421, 0x84);
|
|
writeReg(0xD422, 0x02);
|
|
writeReg(0xD423, 0xA4);
|
|
writeReg(0xD424, 0x02);
|
|
writeReg(0xD425, 0xB7);
|
|
writeReg(0xD426, 0x02);
|
|
writeReg(0xD427, 0xCF);
|
|
writeReg(0xD428, 0x02);
|
|
writeReg(0xD429, 0xDE);
|
|
writeReg(0xD42A, 0x02);
|
|
writeReg(0xD42B, 0xF2);
|
|
writeReg(0xD42C, 0x02);
|
|
writeReg(0xD42D, 0xFE);
|
|
writeReg(0xD42E, 0x03);
|
|
writeReg(0xD42F, 0x10);
|
|
writeReg(0xD430, 0x03);
|
|
writeReg(0xD431, 0x33);
|
|
writeReg(0xD432, 0x03);
|
|
writeReg(0xD433, 0x6D);
|
|
writeReg(0xD500, 0x00);
|
|
writeReg(0xD501, 0x33);
|
|
writeReg(0xD502, 0x00);
|
|
writeReg(0xD503, 0x34);
|
|
writeReg(0xD504, 0x00);
|
|
writeReg(0xD505, 0x3A);
|
|
writeReg(0xD506, 0x00);
|
|
writeReg(0xD507, 0x4A);
|
|
writeReg(0xD508, 0x00);
|
|
writeReg(0xD509, 0x5C);
|
|
writeReg(0xD50A, 0x00);
|
|
writeReg(0xD50B, 0x81);
|
|
writeReg(0xD50C, 0x00);
|
|
writeReg(0xD50D, 0xA6);
|
|
writeReg(0xD50E, 0x00);
|
|
writeReg(0xD50F, 0xE5);
|
|
writeReg(0xD510, 0x01);
|
|
writeReg(0xD511, 0x13);
|
|
writeReg(0xD512, 0x01);
|
|
writeReg(0xD513, 0x54);
|
|
writeReg(0xD514, 0x01);
|
|
writeReg(0xD515, 0x82);
|
|
writeReg(0xD516, 0x01);
|
|
writeReg(0xD517, 0xCA);
|
|
writeReg(0xD518, 0x02);
|
|
writeReg(0xD519, 0x00);
|
|
writeReg(0xD51A, 0x02);
|
|
writeReg(0xD51B, 0x01);
|
|
writeReg(0xD51C, 0x02);
|
|
writeReg(0xD51D, 0x34);
|
|
writeReg(0xD51E, 0x02);
|
|
writeReg(0xD51F, 0x67);
|
|
writeReg(0xD520, 0x02);
|
|
writeReg(0xD521, 0x84);
|
|
writeReg(0xD522, 0x02);
|
|
writeReg(0xD523, 0xA4);
|
|
writeReg(0xD524, 0x02);
|
|
writeReg(0xD525, 0xB7);
|
|
writeReg(0xD526, 0x02);
|
|
writeReg(0xD527, 0xCF);
|
|
writeReg(0xD528, 0x02);
|
|
writeReg(0xD529, 0xDE);
|
|
writeReg(0xD52A, 0x02);
|
|
writeReg(0xD52B, 0xF2);
|
|
writeReg(0xD52C, 0x02);
|
|
writeReg(0xD52D, 0xFE);
|
|
writeReg(0xD52E, 0x03);
|
|
writeReg(0xD52F, 0x10);
|
|
writeReg(0xD530, 0x03);
|
|
writeReg(0xD531, 0x33);
|
|
writeReg(0xD532, 0x03);
|
|
writeReg(0xD533, 0x6D);
|
|
writeReg(0xD600, 0x00);
|
|
writeReg(0xD601, 0x33);
|
|
writeReg(0xD602, 0x00);
|
|
writeReg(0xD603, 0x34);
|
|
writeReg(0xD604, 0x00);
|
|
writeReg(0xD605, 0x3A);
|
|
writeReg(0xD606, 0x00);
|
|
writeReg(0xD607, 0x4A);
|
|
writeReg(0xD608, 0x00);
|
|
writeReg(0xD609, 0x5C);
|
|
writeReg(0xD60A, 0x00);
|
|
writeReg(0xD60B, 0x81);
|
|
writeReg(0xD60C, 0x00);
|
|
writeReg(0xD60D, 0xA6);
|
|
writeReg(0xD60E, 0x00);
|
|
writeReg(0xD60F, 0xE5);
|
|
writeReg(0xD610, 0x01);
|
|
writeReg(0xD611, 0x13);
|
|
writeReg(0xD612, 0x01);
|
|
writeReg(0xD613, 0x54);
|
|
writeReg(0xD614, 0x01);
|
|
writeReg(0xD615, 0x82);
|
|
writeReg(0xD616, 0x01);
|
|
writeReg(0xD617, 0xCA);
|
|
writeReg(0xD618, 0x02);
|
|
writeReg(0xD619, 0x00);
|
|
writeReg(0xD61A, 0x02);
|
|
writeReg(0xD61B, 0x01);
|
|
writeReg(0xD61C, 0x02);
|
|
writeReg(0xD61D, 0x34);
|
|
writeReg(0xD61E, 0x02);
|
|
writeReg(0xD61F, 0x67);
|
|
writeReg(0xD620, 0x02);
|
|
writeReg(0xD621, 0x84);
|
|
writeReg(0xD622, 0x02);
|
|
writeReg(0xD623, 0xA4);
|
|
writeReg(0xD624, 0x02);
|
|
writeReg(0xD625, 0xB7);
|
|
writeReg(0xD626, 0x02);
|
|
writeReg(0xD627, 0xCF);
|
|
writeReg(0xD628, 0x02);
|
|
writeReg(0xD629, 0xDE);
|
|
writeReg(0xD62A, 0x02);
|
|
writeReg(0xD62B, 0xF2);
|
|
writeReg(0xD62C, 0x02);
|
|
writeReg(0xD62D, 0xFE);
|
|
writeReg(0xD62E, 0x03);
|
|
writeReg(0xD62F, 0x10);
|
|
writeReg(0xD630, 0x03);
|
|
writeReg(0xD631, 0x33);
|
|
writeReg(0xD632, 0x03);
|
|
writeReg(0xD633, 0x6D);
|
|
writeReg(0xF000, 0x55);
|
|
writeReg(0xF001, 0xAA);
|
|
writeReg(0xF002, 0x52);
|
|
writeReg(0xF003, 0x08);
|
|
writeReg(0xF004, 0x00);
|
|
writeReg(0xB100, 0xCC);
|
|
writeReg(0xB101, 0x00);
|
|
writeReg(0xB600, 0x05);
|
|
writeReg(0xB700, 0x70);
|
|
writeReg(0xB701, 0x70);
|
|
writeReg(0xB800, 0x01);
|
|
writeReg(0xB801, 0x03);
|
|
writeReg(0xB802, 0x03);
|
|
writeReg(0xB803, 0x03);
|
|
writeReg(0xBC00, 0x02);
|
|
writeReg(0xBC01, 0x00);
|
|
writeReg(0xBC02, 0x00);
|
|
writeReg(0xC900, 0xD0);
|
|
writeReg(0xC901, 0x02);
|
|
writeReg(0xC902, 0x50);
|
|
writeReg(0xC903, 0x50);
|
|
writeReg(0xC904, 0x50);
|
|
writeReg(0x3500, 0x00);
|
|
writeReg(0x3A00, 0x55);
|
|
|
|
wrReg(0x1100);
|
|
delay_1ms(120);
|
|
wrReg(0x2900);
|
|
delay_1ms(200);
|
|
}
|
|
|
|
void Lcd::blockWrite(uint16_t xStart, uint16_t xEnd, uint16_t yStart, uint16_t yEnd)
|
|
{
|
|
__DSB();
|
|
regs()->LCD_REG = 0x2A00;
|
|
__DSB();
|
|
regs()->LCD_RAM = (xStart >> 8) & 0xFF;
|
|
__DSB();
|
|
regs()->LCD_REG = 0x2A01;
|
|
__DSB();
|
|
regs()->LCD_RAM = xStart & 0xFF;
|
|
__DSB();
|
|
regs()->LCD_REG = 0x2A02;
|
|
__DSB();
|
|
regs()->LCD_RAM = (xEnd >> 8) & 0xFF;
|
|
__DSB();
|
|
regs()->LCD_REG = 0x2A03;
|
|
__DSB();
|
|
regs()->LCD_RAM = xEnd & 0xFF;
|
|
__DSB();
|
|
regs()->LCD_REG = 0x2B00;
|
|
__DSB();
|
|
regs()->LCD_RAM = (yStart >> 8) & 0xFF;
|
|
__DSB();
|
|
regs()->LCD_REG = 0x2B01;
|
|
__DSB();
|
|
regs()->LCD_RAM = yStart & 0xFF;
|
|
__DSB();
|
|
regs()->LCD_REG = 0x2B02;
|
|
__DSB();
|
|
regs()->LCD_RAM = (yEnd >> 8) & 0xFF;
|
|
__DSB();
|
|
regs()->LCD_REG = 0x2B03;
|
|
__DSB();
|
|
regs()->LCD_RAM = yEnd & 0xFF;
|
|
__DSB();
|
|
}
|
|
|
|
void Lcd::clear(uint16_t color)
|
|
{
|
|
uint32_t totalpoint = (uint32_t)lcddev_.width_ * lcddev_.height_;
|
|
blockWrite(0, lcddev_.width_ - 1, 0, lcddev_.height_ - 1);
|
|
writeRamPrepare();
|
|
for (uint32_t i = 0; i < totalpoint; i++)
|
|
writeRam(color);
|
|
__DSB();
|
|
}
|
|
|
|
void Lcd::clear(Color color)
|
|
{
|
|
clear(static_cast<uint16_t>(color));
|
|
}
|
|
|
|
void Lcd::diagnosticPattern()
|
|
{
|
|
printf("[Diagnostic] ===== Step-by-step diagnostic =====\r\n");
|
|
|
|
printf("\r\n[Diag 1] Read register 0x0000 (Manufacturer ID)...\r\n");
|
|
uint16_t id = readReg(0x0000);
|
|
printf(" [Diag 1] Result: ID=0x%04X\r\n", id);
|
|
delay_1ms(500);
|
|
|
|
printf("\r\n[Diag 2] Read register 0x0A00 (Display status)...\r\n");
|
|
uint16_t disp = readReg(0x0A00);
|
|
printf(" [Diag 2] Result: DISP_STATUS=0x%04X\r\n", disp);
|
|
delay_1ms(500);
|
|
|
|
printf("\r\n[Diag 3] Write a small block to top-left (0,0)-(50,50)...\r\n");
|
|
printf(" Sending BlockWrite + 2500 pixels...\r\n");
|
|
blockWrite(0, 50, 0, 50);
|
|
writeRamPrepare();
|
|
for (uint32_t i = 0; i < 51 * 51; i++)
|
|
{
|
|
writeRam(Color::RED);
|
|
}
|
|
__DSB();
|
|
delay_1ms(1000);
|
|
printf(" [Diag 3] Done, wait 1s...\r\n");
|
|
delay_1ms(1000);
|
|
|
|
printf("\r\n[Diag 4] Re-read register 0x0000 to confirm EXMC still works...\r\n");
|
|
id = readReg(0x0000);
|
|
printf(" [Diag 4] Result: ID=0x%04X\r\n", id);
|
|
delay_1ms(500);
|
|
|
|
printf("\r\n[Diag 5] Write a small block to center (200,200)-(250,250)...\r\n");
|
|
blockWrite(200, 250, 200, 250);
|
|
writeRamPrepare();
|
|
for (uint32_t i = 0; i < 51 * 51; i++)
|
|
{
|
|
writeRam(Color::GREEN);
|
|
}
|
|
__DSB();
|
|
delay_1ms(1000);
|
|
printf(" [Diag 5] Done\r\n");
|
|
|
|
printf("\r\n[Diag 6] Write a small block to bottom (200,750)-(250,799)...\r\n");
|
|
blockWrite(200, 250, 750, 799);
|
|
writeRamPrepare();
|
|
for (uint32_t i = 0; i < 51 * 50; i++)
|
|
{
|
|
writeRam(Color::BLUE);
|
|
}
|
|
__DSB();
|
|
delay_1ms(1000);
|
|
printf(" [Diag 6] Done\r\n");
|
|
|
|
printf("\r\n[Diag 7] Re-read register 0x0000...\r\n");
|
|
id = readReg(0x0000);
|
|
printf(" [Diag 7] Result: ID=0x%04X\r\n", id);
|
|
|
|
printf("\r\n[Diag 8] Read register 0x0A00...\r\n");
|
|
disp = readReg(0x0A00);
|
|
printf(" [Diag 8] Result: DISP_STATUS=0x%04X\r\n", disp);
|
|
|
|
printf("[Diagnostic] ===== Diagnostic complete =====\r\n");
|
|
}
|
|
|
|
void Lcd::setCursor(uint16_t x, uint16_t y)
|
|
{
|
|
writeReg(0x2A00, x >> 8);
|
|
writeReg(0x2A01, x & 0xFF);
|
|
writeReg(0x2A02, (lcddev_.width_ - 1) >> 8);
|
|
writeReg(0x2A03, (lcddev_.width_ - 1) & 0xFF);
|
|
writeReg(0x2B00, y >> 8);
|
|
writeReg(0x2B01, y & 0xFF);
|
|
writeReg(0x2B02, (lcddev_.height_ - 1) >> 8);
|
|
writeReg(0x2B03, (lcddev_.height_ - 1) & 0xFF);
|
|
}
|
|
|
|
void Lcd::setScanDir(ScanDir dir)
|
|
{
|
|
uint16_t regval = 0;
|
|
uint16_t dirreg = 0;
|
|
|
|
switch (dir)
|
|
{
|
|
case L2R_U2D:
|
|
regval |= (0 << 7) | (0 << 6) | (0 << 5);
|
|
break;
|
|
case L2R_D2U:
|
|
regval |= (1 << 7) | (0 << 6) | (0 << 5);
|
|
break;
|
|
case R2L_U2D:
|
|
regval |= (0 << 7) | (1 << 6) | (0 << 5);
|
|
break;
|
|
case R2L_D2U:
|
|
regval |= (1 << 7) | (1 << 6) | (0 << 5);
|
|
break;
|
|
case U2D_L2R:
|
|
regval |= (0 << 7) | (0 << 6) | (1 << 5);
|
|
break;
|
|
case U2D_R2L:
|
|
regval |= (0 << 7) | (1 << 6) | (1 << 5);
|
|
break;
|
|
case D2U_L2R:
|
|
regval |= (1 << 7) | (0 << 6) | (1 << 5);
|
|
break;
|
|
case D2U_R2L:
|
|
regval |= (1 << 7) | (1 << 6) | (1 << 5);
|
|
break;
|
|
}
|
|
regval &= ~(1 << 3);
|
|
|
|
dirreg = 0X3600;
|
|
writeReg(dirreg, regval);
|
|
writeReg(0x2A00, 0);
|
|
writeReg(0x2A01, 0);
|
|
writeReg(0x2A02, (lcddev_.width_ - 1) >> 8);
|
|
writeReg(0x2A03, (lcddev_.width_ - 1) & 0xFF);
|
|
writeReg(0x2B00, 0);
|
|
writeReg(0x2B01, 0);
|
|
writeReg(0x2B02, (lcddev_.height_ - 1) >> 8);
|
|
writeReg(0x2B03, (lcddev_.height_ - 1) & 0xFF);
|
|
}
|
|
|
|
RetCode Lcd::init()
|
|
{
|
|
printf("[Lcd] init start\r\n");
|
|
ctrlLinesConfig();
|
|
fsmcConfig();
|
|
|
|
rstOff();
|
|
delay_1ms(100);
|
|
rstOn();
|
|
delay_1ms(100);
|
|
|
|
lcddev_.id_ = 0x5510;
|
|
sprintf(id_string_, "LCD ID:%04X", lcddev_.id_);
|
|
printf("[Lcd] Skip ReadID, force ID=0x5510\r\n");
|
|
|
|
hvgaConfig();
|
|
initialCode();
|
|
|
|
writeReg(0xC200, 0x01);
|
|
delay_1ms(10);
|
|
|
|
writeReg(0x3A00, 0x55);
|
|
delay_1ms(10);
|
|
|
|
wrReg(0x1300);
|
|
delay_1ms(10);
|
|
|
|
writeReg(0x3600, 0x0000);
|
|
delay_1ms(10);
|
|
|
|
setScanDir(ScanDir::DFT_SCAN_DIR);
|
|
delay_1ms(10);
|
|
blkOn();
|
|
|
|
LcdDma::instance().init();
|
|
printf("[Lcd] init done\r\n");
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
void Lcd::drawPoint(uint16_t x, uint16_t y)
|
|
{
|
|
setCursor(x, y);
|
|
writeRamPrepare();
|
|
writeRam(point_color_);
|
|
}
|
|
|
|
void Lcd::fastDrawPoint(uint16_t x, uint16_t y, uint16_t color)
|
|
{
|
|
setCursor(x, y);
|
|
writeRamPrepare();
|
|
writeRam(color);
|
|
}
|
|
|
|
uint16_t Lcd::readPoint(uint16_t x, uint16_t y)
|
|
{
|
|
uint16_t color;
|
|
|
|
if (lcddev_.id_ == 0x5510)
|
|
{
|
|
wrReg(lcddev_.setxcmd_);
|
|
wrData(x >> 8);
|
|
wrReg(lcddev_.setxcmd_ + 1);
|
|
wrData(x & 0xFF);
|
|
wrReg(lcddev_.setycmd_);
|
|
wrData(y >> 8);
|
|
wrReg(lcddev_.setycmd_ + 1);
|
|
wrData(y & 0xFF);
|
|
}
|
|
else
|
|
{
|
|
setCursor(x, y);
|
|
}
|
|
|
|
wrReg(0x2E00);
|
|
color = rdData();
|
|
return color;
|
|
}
|
|
|
|
void Lcd::showChar(uint16_t x, uint16_t y, uint8_t num, uint8_t size, uint8_t mode)
|
|
{
|
|
uint8_t temp, t1, t;
|
|
uint16_t y0 = y;
|
|
uint8_t csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2);
|
|
|
|
num = num - ' ';
|
|
if (!mode)
|
|
{
|
|
for (t = 0; t < csize; t++)
|
|
{
|
|
if (size == 12)
|
|
temp = asc2_1206[num][t];
|
|
else
|
|
temp = asc2_1608[num][t];
|
|
|
|
for (t1 = 0; t1 < 8; t1++)
|
|
{
|
|
if (temp & 0x80)
|
|
fastDrawPoint(x, y, point_color_);
|
|
else
|
|
fastDrawPoint(x, y, back_color_);
|
|
temp <<= 1;
|
|
y++;
|
|
|
|
if (y >= lcddev_.height_)
|
|
return;
|
|
|
|
if ((y - y0) == size)
|
|
{
|
|
y = y0;
|
|
x++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (t = 0; t < csize; t++)
|
|
{
|
|
if (size == 12)
|
|
temp = asc2_1206[num][t];
|
|
else
|
|
temp = asc2_1608[num][t];
|
|
|
|
for (t1 = 0; t1 < 8; t1++)
|
|
{
|
|
if (temp & 0x80)
|
|
fastDrawPoint(x, y, point_color_);
|
|
temp <<= 1;
|
|
y++;
|
|
|
|
if (y >= lcddev_.height_)
|
|
return;
|
|
|
|
if ((y - y0) == size)
|
|
{
|
|
y = y0;
|
|
x++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Lcd::showString(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t size, uint8_t mode, uint8_t *p)
|
|
{
|
|
while (*p != '\0')
|
|
{
|
|
if (x + size / 2 > lcddev_.width_)
|
|
{
|
|
x = 0;
|
|
y += size;
|
|
}
|
|
|
|
if (y + size > lcddev_.height_)
|
|
return;
|
|
|
|
if (*p == '\n')
|
|
{
|
|
x = 0;
|
|
y += size;
|
|
p++;
|
|
continue;
|
|
}
|
|
|
|
showChar(x, y, *p, size, mode);
|
|
x += size / 2;
|
|
p++;
|
|
}
|
|
}
|
|
|
|
void Lcd::drawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
|
{
|
|
uint16_t t;
|
|
int xerr = 0, yerr = 0, delta_x, delta_y, distance;
|
|
int incx, incy;
|
|
|
|
delta_x = x2 - x1;
|
|
delta_y = y2 - y1;
|
|
|
|
if (delta_x > 0)
|
|
incx = 1;
|
|
else if (delta_x == 0)
|
|
incx = 0;
|
|
else
|
|
{
|
|
incx = -1;
|
|
delta_x = -delta_x;
|
|
}
|
|
|
|
if (delta_y > 0)
|
|
incy = 1;
|
|
else if (delta_y == 0)
|
|
incy = 0;
|
|
else
|
|
{
|
|
incy = -1;
|
|
delta_y = -delta_y;
|
|
}
|
|
|
|
if (delta_x > delta_y)
|
|
distance = delta_x;
|
|
else
|
|
distance = delta_y;
|
|
|
|
for (t = 0; t <= distance; t++)
|
|
{
|
|
fastDrawPoint(x1, y1, point_color_);
|
|
xerr += delta_x;
|
|
yerr += delta_y;
|
|
|
|
if (xerr > distance)
|
|
{
|
|
xerr -= distance;
|
|
x1 += incx;
|
|
}
|
|
|
|
if (yerr > distance)
|
|
{
|
|
yerr -= distance;
|
|
y1 += incy;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Lcd::drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
|
{
|
|
drawLine(x1, y1, x2, y1);
|
|
drawLine(x1, y1, x1, y2);
|
|
drawLine(x1, y2, x2, y2);
|
|
drawLine(x2, y1, x2, y2);
|
|
}
|
|
|
|
void Lcd::fillRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
|
|
{
|
|
uint32_t i, total;
|
|
|
|
if (x1 > x2)
|
|
{
|
|
uint16_t t = x1;
|
|
x1 = x2;
|
|
x2 = t;
|
|
}
|
|
if (y1 > y2)
|
|
{
|
|
uint16_t t = y1;
|
|
y1 = y2;
|
|
y2 = t;
|
|
}
|
|
|
|
total = (uint32_t)(x2 - x1 + 1) * (y2 - y1 + 1);
|
|
blockWrite(x1, x2, y1, y2);
|
|
writeRamPrepare();
|
|
for (i = 0; i < total; i++)
|
|
writeRam(point_color_);
|
|
}
|
|
|
|
void Lcd::fill(uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd, uint16_t color)
|
|
{
|
|
uint32_t i, total;
|
|
|
|
if (xStart > xEnd)
|
|
{
|
|
uint16_t t = xStart;
|
|
xStart = xEnd;
|
|
xEnd = t;
|
|
}
|
|
if (yStart > yEnd)
|
|
{
|
|
uint16_t t = yStart;
|
|
yStart = yEnd;
|
|
yEnd = t;
|
|
}
|
|
|
|
total = (uint32_t)(xEnd - xStart + 1) * (yEnd - yStart + 1);
|
|
blockWrite(xStart, xEnd, yStart, yEnd);
|
|
writeRamPrepare();
|
|
for (i = 0; i < total; i++)
|
|
writeRam(color);
|
|
__DSB();
|
|
}
|
|
|
|
void Lcd::clearDMA(uint16_t color)
|
|
{
|
|
LcdDma::instance().fillBuffer(color);
|
|
uint32_t total = (uint32_t)lcddev_.width_ * lcddev_.height_;
|
|
|
|
blockWrite(0, lcddev_.width_ - 1, 0, lcddev_.height_ - 1);
|
|
writeRamPrepare();
|
|
flushFromSdram(total);
|
|
}
|
|
|
|
void Lcd::clearDMA(Color color)
|
|
{
|
|
clearDMA(static_cast<uint16_t>(color));
|
|
}
|
|
|
|
void Lcd::fillDMA(uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd, uint16_t color)
|
|
{
|
|
if (xStart > xEnd)
|
|
{
|
|
uint16_t t = xStart;
|
|
xStart = xEnd;
|
|
xEnd = t;
|
|
}
|
|
if (yStart > yEnd)
|
|
{
|
|
uint16_t t = yStart;
|
|
yStart = yEnd;
|
|
yEnd = t;
|
|
}
|
|
|
|
uint32_t pixelCount = (uint32_t)(xEnd - xStart + 1) * (yEnd - yStart + 1);
|
|
|
|
LcdDma::instance().fillBuffer(color);
|
|
blockWrite(xStart, xEnd, yStart, yEnd);
|
|
writeRamPrepare();
|
|
flushFromSdram(pixelCount);
|
|
}
|
|
|
|
void Lcd::flushFromSdram(uint32_t pixelCount)
|
|
{
|
|
uint16_t *src = LcdDma::instance().getBuffer();
|
|
uint32_t count = pixelCount;
|
|
while (count--) {
|
|
regs()->LCD_RAM = *src++;
|
|
if ((count & 0x0F) == 0) {
|
|
__DSB();
|
|
}
|
|
}
|
|
__DSB();
|
|
}
|
|
|
|
void Lcd::showNum(uint16_t x, uint16_t y, uint32_t num, uint8_t len, uint8_t size)
|
|
{
|
|
uint8_t buf[12];
|
|
uint8_t i;
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
buf[i] = '0' + (num % 10);
|
|
num /= 10;
|
|
}
|
|
for (i = 0; i < len; i++)
|
|
showChar(x + (len - 1 - i) * (size / 2), y, buf[i], size, 0);
|
|
}
|
|
|
|
void Lcd::showIntNum(uint16_t x, uint16_t y, int32_t num, uint8_t len, uint8_t size)
|
|
{
|
|
uint8_t buf[14];
|
|
uint8_t i, neg = 0;
|
|
|
|
if (num < 0)
|
|
{
|
|
neg = 1;
|
|
num = -num;
|
|
}
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
buf[i] = '0' + (num % 10);
|
|
num /= 10;
|
|
}
|
|
if (neg)
|
|
{
|
|
for (i = 0; i < len; i++)
|
|
showChar(x + (len - i) * (size / 2), y, buf[i], size, 0);
|
|
showChar(x, y, '-', size, 0);
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < len; i++)
|
|
showChar(x + (len - 1 - i) * (size / 2), y, buf[i], size, 0);
|
|
}
|
|
}
|
|
|
|
void Lcd::showFloatNum(uint16_t x, uint16_t y, float num, uint8_t intLen, uint8_t decLen, uint8_t size)
|
|
{
|
|
uint16_t x_offset = 0;
|
|
int32_t intPart = (int32_t)num;
|
|
uint32_t decPart;
|
|
uint8_t i;
|
|
|
|
if (num < 0)
|
|
{
|
|
showChar(x, y, '-', size, 0);
|
|
x_offset = size / 2;
|
|
intPart = -intPart;
|
|
}
|
|
|
|
showIntNum(x + x_offset, y, intPart, intLen, size);
|
|
x_offset += intLen * (size / 2);
|
|
|
|
showChar(x + x_offset, y, '.', size, 0);
|
|
x_offset += size / 2;
|
|
|
|
if (num < 0)
|
|
num = -num;
|
|
decPart = (uint32_t)((num - (int32_t)num) * 1000000);
|
|
|
|
for (i = 0; i < decLen; i++)
|
|
decPart /= 10;
|
|
|
|
showNum(x + x_offset, y, decPart, decLen, size);
|
|
}
|
|
|
|
void Lcd::drawCircle(uint16_t x0, uint16_t y0, uint16_t r)
|
|
{
|
|
int x = 0, y = r;
|
|
int d = 3 - 2 * r;
|
|
|
|
while (x <= y)
|
|
{
|
|
fastDrawPoint(x0 + x, y0 + y, point_color_);
|
|
fastDrawPoint(x0 - x, y0 + y, point_color_);
|
|
fastDrawPoint(x0 + x, y0 - y, point_color_);
|
|
fastDrawPoint(x0 - x, y0 - y, point_color_);
|
|
fastDrawPoint(x0 + y, y0 + x, point_color_);
|
|
fastDrawPoint(x0 - y, y0 + x, point_color_);
|
|
fastDrawPoint(x0 + y, y0 - x, point_color_);
|
|
fastDrawPoint(x0 - y, y0 - x, point_color_);
|
|
|
|
if (d < 0)
|
|
d = d + 4 * x + 6;
|
|
else
|
|
{
|
|
d = d + 4 * (x - y) + 10;
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
}
|
|
|
|
void Lcd::fillCircle(uint16_t x0, uint16_t y0, uint16_t r)
|
|
{
|
|
int x = 0, y = r;
|
|
int d = 3 - 2 * r;
|
|
|
|
while (x <= y)
|
|
{
|
|
drawLine(x0 - x, y0 + y, x0 + x, y0 + y);
|
|
drawLine(x0 - y, y0 + x, x0 + y, y0 + x);
|
|
drawLine(x0 - x, y0 - y, x0 + x, y0 - y);
|
|
drawLine(x0 - y, y0 - x, x0 + y, y0 - x);
|
|
|
|
if (d < 0)
|
|
d = d + 4 * x + 6;
|
|
else
|
|
{
|
|
d = d + 4 * (x - y) + 10;
|
|
y--;
|
|
}
|
|
x++;
|
|
}
|
|
}
|
|
|
|
void Lcd::showImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *p)
|
|
{
|
|
uint32_t i, j;
|
|
uint16_t color;
|
|
const uint16_t *img = (const uint16_t *)p;
|
|
|
|
if (x + width > lcddev_.width_ || y + height > lcddev_.height_)
|
|
return;
|
|
|
|
blockWrite(x, x + width - 1, y, y + height - 1);
|
|
writeRamPrepare();
|
|
|
|
for (i = 0; i < height; i++)
|
|
{
|
|
for (j = 0; j < width; j++)
|
|
{
|
|
color = *img++;
|
|
writeRam(color);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Lcd::showSmallImage(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t *p)
|
|
{
|
|
uint32_t i, j;
|
|
uint16_t color;
|
|
uint8_t r, g, b;
|
|
|
|
if (x + width > lcddev_.width_ || y + height > lcddev_.height_)
|
|
return;
|
|
|
|
blockWrite(x, x + width - 1, y, y + height - 1);
|
|
writeRamPrepare();
|
|
|
|
for (i = 0; i < height; i++)
|
|
{
|
|
for (j = 0; j < width; j++)
|
|
{
|
|
uint8_t pixel = *p++;
|
|
r = (pixel >> 5) & 0x07;
|
|
g = (pixel >> 2) & 0x07;
|
|
b = pixel & 0x03;
|
|
|
|
color = ((r << 13) & 0xF800) | ((g << 8) & 0x07E0) | ((b << 3) & 0x001F);
|
|
writeRam(color);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Lcd::displayOn()
|
|
{
|
|
wrReg(0x2900);
|
|
delay_1ms(50);
|
|
}
|
|
|
|
void Lcd::displayOff()
|
|
{
|
|
wrReg(0x2800);
|
|
delay_1ms(10);
|
|
}
|
|
|
|
void Lcd::backlight(uint8_t brightness)
|
|
{
|
|
if (brightness)
|
|
blkOn();
|
|
else
|
|
blkOff();
|
|
}
|