STM32H750VB_LCD/Core/Src/otm8009a_lcd.c

136 lines
6.5 KiB
C

#include "otm8009a_lcd.h"
uint16_t otm8009a_800480_16b_init_sequence[] = {
0x0001, 0xff00, 0x0080, 0x0001, 0xff01, 0x0009, 0x0001, 0xff02, 0x0001,
0x0001, 0xff80, 0x0080, 0x0001, 0xff81, 0x0009, 0x0001, 0xff03, 0x0001,
0x0001, 0xf5b6, 0x0006, 0x0001, 0xc480, 0x0030, 0x0001, 0xc48a, 0x0040,
0x0001, 0xc0a3, 0x001B, 0x0001, 0xc0ba, 0x0050, 0x0001, 0xc181, 0x0066,
0x0001, 0xc1a1, 0x000E, 0x0001, 0xc481, 0x0083, 0x0001, 0xc582, 0x0083,
0x0001, 0xc590, 0x0096, 0x0001, 0xc591, 0x002B, 0x0001, 0xc592, 0x0001,
0x0001, 0xc594, 0x0033, 0x0001, 0xc595, 0x0034, 0x0001, 0xc5b1, 0x00a9,
0x0001, 0xce80, 0x0086, 0x0001, 0xce81, 0x0001, 0x0001, 0xce82, 0x0000,
0x0001, 0xce83, 0x0085, 0x0001, 0xce84, 0x0001, 0x0001, 0xce85, 0x0000,
0x0001, 0xce86, 0x0000, 0x0001, 0xce87, 0x0000, 0x0001, 0xce88, 0x0000,
0x0001, 0xce89, 0x0000, 0x0001, 0xce8A, 0x0000, 0x0001, 0xce8B, 0x0000,
0x0001, 0xcea0, 0x0018, 0x0001, 0xcea1, 0x0004, 0x0001, 0xcea2, 0x0003,
0x0001, 0xcea3, 0x0021, 0x0001, 0xcea4, 0x0000, 0x0001, 0xcea5, 0x0000,
0x0001, 0xcea6, 0x0000, 0x0001, 0xcea7, 0x0018, 0x0001, 0xcea8, 0x0003,
0x0001, 0xcea9, 0x0003, 0x0001, 0xceaa, 0x0022, 0x0001, 0xceab, 0x0000,
0x0001, 0xceac, 0x0000, 0x0001, 0xcead, 0x0000, 0x0001, 0xceb0, 0x0018,
0x0001, 0xceb1, 0x0002, 0x0001, 0xceb2, 0x0003, 0x0001, 0xceb3, 0x0023,
0x0001, 0xceb4, 0x0000, 0x0001, 0xceb5, 0x0000, 0x0001, 0xceb6, 0x0000,
0x0001, 0xceb7, 0x0018, 0x0001, 0xceb8, 0x0001, 0x0001, 0xceb9, 0x0003,
0x0001, 0xceba, 0x0024, 0x0001, 0xcebb, 0x0000, 0x0001, 0xcebc, 0x0000,
0x0001, 0xcebd, 0x0000, 0x0001, 0xcfc0, 0x0001, 0x0001, 0xcfc1, 0x0001,
0x0001, 0xcfc2, 0x0020, 0x0001, 0xcfc3, 0x0020, 0x0001, 0xcfc4, 0x0000,
0x0001, 0xcfc5, 0x0000, 0x0001, 0xcfc6, 0x0001, 0x0001, 0xcfc7, 0x0000,
0x0001, 0xcfc8, 0x0000, 0x0001, 0xcfc9, 0x0000, 0x0001, 0xcfd0, 0x0000,
0x0001, 0xcbc0, 0x0000, 0x0001, 0xcbc1, 0x0004, 0x0001, 0xcbc2, 0x0004,
0x0001, 0xcbc3, 0x0004, 0x0001, 0xcbc4, 0x0004, 0x0001, 0xcbc5, 0x0004,
0x0001, 0xcbc6, 0x0000, 0x0001, 0xcbc7, 0x0000, 0x0001, 0xcbc8, 0x0000,
0x0001, 0xcbc9, 0x0000, 0x0001, 0xcbca, 0x0000, 0x0001, 0xcbcb, 0x0000,
0x0001, 0xcbcc, 0x0000, 0x0001, 0xcbcd, 0x0000, 0x0001, 0xcbce, 0x0000,
0x0001, 0xcbd0, 0x0000, 0x0001, 0xcbd1, 0x0000, 0x0001, 0xcbd2, 0x0000,
0x0001, 0xcbd3, 0x0000, 0x0001, 0xcbd4, 0x0000, 0x0001, 0xcbd5, 0x0000,
0x0001, 0xcbd6, 0x0004, 0x0001, 0xcbd7, 0x0004, 0x0001, 0xcbd8, 0x0004,
0x0001, 0xcbd9, 0x0004, 0x0001, 0xcbda, 0x0004, 0x0001, 0xcbdb, 0x0000,
0x0001, 0xcbdc, 0x0000, 0x0001, 0xcbdd, 0x0000, 0x0001, 0xcbde, 0x0000,
0x0001, 0xcbe0, 0x0000, 0x0001, 0xcbe1, 0x0000, 0x0001, 0xcbe2, 0x0000,
0x0001, 0xcbe3, 0x0000, 0x0001, 0xcbe4, 0x0000, 0x0001, 0xcbe5, 0x0000,
0x0001, 0xcbe6, 0x0000, 0x0001, 0xcbe7, 0x0000, 0x0001, 0xcbe8, 0x0000,
0x0001, 0xcbe9, 0x0000, 0x0001, 0xcc80, 0x0000, 0x0001, 0xcc81, 0x0026,
0x0001, 0xcc82, 0x0009, 0x0001, 0xcc83, 0x000B, 0x0001, 0xcc84, 0x0001,
0x0001, 0xcc85, 0x0025, 0x0001, 0xcc86, 0x0000, 0x0001, 0xcc87, 0x0000,
0x0001, 0xcc88, 0x0000, 0x0001, 0xcc89, 0x0000, 0x0001, 0xcc90, 0x0000,
0x0001, 0xcc91, 0x0000, 0x0001, 0xcc92, 0x0000, 0x0001, 0xcc93, 0x0000,
0x0001, 0xcc94, 0x0000, 0x0001, 0xcc95, 0x0000, 0x0001, 0xcc96, 0x0000,
0x0001, 0xcc97, 0x0000, 0x0001, 0xcc98, 0x0000, 0x0001, 0xcc99, 0x0000,
0x0001, 0xcc9a, 0x0000, 0x0001, 0xcc9b, 0x0026, 0x0001, 0xcc9c, 0x000A,
0x0001, 0xcc9d, 0x000C, 0x0001, 0xcc9e, 0x0002, 0x0001, 0xcca0, 0x0025,
0x0001, 0xcca1, 0x0000, 0x0001, 0xcca2, 0x0000, 0x0001, 0xcca3, 0x0000,
0x0001, 0xcca4, 0x0000, 0x0001, 0xcca5, 0x0000, 0x0001, 0xcca6, 0x0000,
0x0001, 0xcca7, 0x0000, 0x0001, 0xcca8, 0x0000, 0x0001, 0xcca9, 0x0000,
0x0001, 0x3a00, 0x0057
};
otm_ret_t _otm_lcd_init_seq(otm_t *lcd) {
uint16_t i = 0;
while(i < (sizeof(OTM_PANEL_SELECTION) / sizeof(otm_data_t))) {
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, &OTM_PANEL_SELECTION[i + 1], OTM_PANEL_SELECTION[i] + 1));
i += OTM_PANEL_SELECTION[i] + 2;
}
return OTM_OK;
}
otm_ret_t _otm_lcd_sleep(otm_t *lcd, uint8_t sleep) {
uint16_t reg = sleep ? 0x1000 : 0x1100; // SLPIN : SLPOUT
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, &reg, 0x01));
OTM_ERROR_CHECK(lcd->cb.delay_cb(lcd->user_data, 10000)); // 5ms delay.
return OTM_OK;
}
otm_ret_t _otm_lcd_window(otm_t *lcd, uint16_t x_start, uint16_t x_end, uint16_t y_start, uint16_t y_end) {
uint16_t reg[] = { 0x2A00, x_start >> 0x08U };
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
reg[0] = 0x2A01; reg[1] = x_start & 0xFFU;
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
reg[0] = 0x2A02; reg[1] = x_end >> 0x08U;
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
reg[0] = 0x2A03; reg[1] = x_end & 0xFFU;
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
reg[0] = 0x2B00; reg[1] = y_start >> 0x08U;
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
reg[0] = 0x2B01; reg[1] = y_start & 0xFFU;
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
reg[0] = 0x2B02; reg[1] = y_end >> 0x08U;
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
reg[0] = 0x2B03; reg[1] = y_end & 0xFFU;
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
return OTM_OK;
}
otm_ret_t otm_lcd_init(otm_t *lcd) {
OTM_ERROR_CHECK(lcd->cb.delay_cb(lcd, 100000)); //50ms
OTM_ERROR_CHECK(_otm_lcd_init_seq(lcd));
OTM_ERROR_CHECK(_otm_lcd_sleep(lcd, 0));
OTM_ERROR_CHECK(otm_lcd_display(lcd, 1));
return OTM_OK;
}
otm_ret_t otm_lcd_display(otm_t *lcd, uint8_t on) {
uint16_t reg = on ? 0x2900 : 0x2800; // DISPON : DISPOFF
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, &reg, 0x01));
return OTM_OK;
}
otm_ret_t otm_lcd_upload(otm_t *lcd, uint16_t x1, uint16_t x2, uint16_t y1, uint16_t y2, uint16_t *data) {
OTM_ERROR_CHECK(_otm_lcd_window(lcd, x1, x2, y1, y2));
uint32_t pixels = (y2 - y1 + 1) * (x2 - x1 + 1);
uint16_t reg = 0x2C00;
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, &reg, 0x01));
OTM_ERROR_CHECK(lcd->cb.write_data_cb(lcd->user_data, data, pixels * 2));
return OTM_OK;
}
otm_ret_t otm_lcd_direction(otm_t *lcd, otm_direction_t direction) {
uint16_t reg[] = { 0x3600, (1U << 5U) | (1U << 6U) };
switch(direction) {
case OTM_HORIZONTAL_INV:
reg[1] = (1U << 7U) | (1U << 5U);
break;
case OTM_HORIZONTAL:
default:
break;
}
OTM_ERROR_CHECK(lcd->cb.write_reg_cb(lcd->user_data, reg, 0x02));
lcd->direction = direction;
return OTM_OK;
}