// RA8806 driver
#include "RA8806.h"
#include "stm32f10x.h"
//==============================================================================
#define rs_bit_cmd() GPIOA->BSRR = 0x00000100
#define rs_bit_dat() GPIOA->BRR = 0x0100
#define rd_bit_clr() GPIOB->BRR = 0x4000
#define rd_bit_set() GPIOB->BSRR = 0x00004000
#define wt_bit_clr() GPIOB->BRR = 0x8000
#define wt_bit_set() GPIOB->BSRR = 0x00008000
#define rls_port() GPIOA->CRL = 0x44444444
#define rd_byte() (uint16_t)GPIOA->IDR
#define wt_byte(x) do {\
GPIOA->BSRR = 0x00FF0000 | (uint8_t)(x);\
GPIOA->CRL = 0x33333333;\
} while (0)
//==============================================================================
// base I/O operation
//==============================================================================
static uint8_t ra8806_bus_rd(void){
while (!lcd_ioBusy());
rd_bit_clr();
wt_bit_set();
uint8_t rd_data = rd_byte();
rd_bit_set();
wt_bit_set();
return rd_data;
}
//------------------------------------------------------------------------------
static void ra8806_bus_wt(uint8_t wt_data){
while (!lcd_ioBusy());
rd_bit_set();
wt_bit_clr();
wt_byte(wt_data);
rd_bit_set();
wt_bit_set();
rls_port();
}
//==============================================================================
uint8_t ra8806_status_rd(void){
rs_bit_cmd();
return ra8806_bus_rd();
}
//------------------------------------------------------------------------------
static uint8_t re8806_data_rd(void){
rs_bit_dat();
return ra8806_bus_rd();
}
//------------------------------------------------------------------------------
static void ra8806_cmd_wt(uint8_t wt_data){
rs_bit_cmd();
ra8806_bus_wt(wt_data);
}
//------------------------------------------------------------------------------
static void ra8806_dat_wt(uint8_t wt_data){
rs_bit_dat();
ra8806_bus_wt(wt_data);
}
//==============================================================================
//==============================================================================
// control base
//==============================================================================
uint8_t lcd_regRead(uint8_t reg){
ra8806_cmd_wt(reg);
return re8806_data_rd();
}
//------------------------------------------------------------------------------
void lcd_regWrite(uint8_t reg, uint8_t wt_data){
ra8806_cmd_wt(reg);
ra8806_dat_wt(wt_data);
}
//------------------------------------------------------------------------------
void lcd_regBitsSet(uint8_t reg, uint8_t wt_bits){
uint8_t tmp_byte = lcd_regRead(reg) | wt_bits;
lcd_regWrite(reg, tmp_byte);
}
//------------------------------------------------------------------------------
void lcd_regBitsClr(uint8_t reg, uint8_t wt_bits){
uint8_t tmp_byte = lcd_regRead(reg) & ~wt_bits;
lcd_regWrite(reg, tmp_byte);
}
//==============================================================================
// control function
//------------------------------------------------------------------------------
void lcdSleep(void){
uint8_t tmp_byte = lcd_regRead(WLCR) & ~ZDOFF | PWRMD; // sleep mode, lcd off
lcd_regWrite(WLCR, tmp_byte);
}
//------------------------------------------------------------------------------
void lcdAccessPage(ACCESS_PAGE page){
uint8_t tmp_byte = lcd_regRead(MAMR) & ~MW_MD | page;
lcd_regWrite(MAMR, tmp_byte);
}
//------------------------------------------------------------------------------
void lcdGotoXY(uint8_t x, uint8_t y){
lcd_regWrite(CURX, x & CURX_BITS);
lcd_regWrite(CURY, y);
}
//------------------------------------------------------------------------------
void getLcdXY(uint8_t * x, uint8_t * y){
*x = lcd_regRead(CURX);
*y = lcd_regRead(CURY);
}
//------------------------------------------------------------------------------
_Bool locateTouchPoint(uint16_t * locate_x, uint16_t * locate_y){
uint8_t tmp = lcd_regRead(TPZR);
uint16_t x = (uint16_t)lcd_regRead(TPXR) << 2 | (tmp & TPZ_X);
uint16_t y = (uint16_t)lcd_regRead(TPYR) << 2 | (tmp & TPZ_Y) >> 2;
if (x < 72 || x >= 931 || y < 94 || y >= 914) return FALSE;
// *locate_x = (uint32_t)x * 320 / 1024;
*locate_x = (uint32_t)(x - 72) * 320 / (931 - 72);
// *locate_y = (uint32_t)y * 240 / 1024;
*locate_y = (uint32_t)(y - 94) * 240 / (914 - 94);
return TRUE;
}
//------------------------------------------------------------------------------
void fillScreen(uint8_t fillByte){
lcd_regWrite(PNTR, fillByte);
lcd_regBitsSet(FNCR, MCLR);
}
//------------------------------------------------------------------------------
void setWorkArea(uint8_t st_x, uint8_t st_y, uint8_t end_x, uint8_t end_y){
lcd_regWrite(AWTR, st_y); // active window top
lcd_regWrite(AWBR, end_y); // active window bottom
lcd_regWrite(AWLR, st_x); // active window left
lcd_regWrite(AWRR, end_x); // active window rigth
}
//------------------------------------------------------------------------------
void fontSize(uint8_t x){
switch (x){
case 2 :
lcd_regWrite(FVHT, lcd_regRead(FVHT) & 0x0F | 0x50);
break;
case 3 :
lcd_regWrite(FVHT, lcd_regRead(FVHT) & 0x0F | 0xA0);
break;
case 4 :
lcd_regWrite(FVHT, lcd_regRead(FVHT) | 0xF0);
break;
default :
lcd_regWrite(FVHT, lcd_regRead(FVHT) & 0x0F);
}
}
//==============================================================================
//==============================================================================
// display base
//------------------------------------------------------------------------------
void lcd_memBitsSet(uint8_t wt_bits){
lcd_curIncDis();
uint8_t tmp_byte = lcd_memRdByte() | wt_bits;
lcd_curIncEn();
lcd_memWtByte(tmp_byte);
}
//------------------------------------------------------------------------------
void lcd_memBitsClr(uint8_t wt_bits){
lcd_curIncDis();
uint8_t tmp_byte = lcd_memRdByte() & ~wt_bits;
lcd_curIncEn();
lcd_memWtByte(tmp_byte);
}
//==============================================================================
void lcd_memRead(uint8_t * dest, uint16_t length){
ra8806_cmd_wt(MRCR);
rs_bit_dat();
while (length--) *dest++ = ra8806_bus_rd();
}
//------------------------------------------------------------------------------
void lcd_memWrite(uint8_t * src, uint16_t length){
while (lcd_memBusy());
ra8806_cmd_wt(MWCR);
rs_bit_dat();
while (length--) ra8806_bus_wt(*src++);
}
//==============================================================================
// grephic mode functions
//------------------------------------------------------------------------------
void dispPicture(uint16_t st_x, uint8_t st_y, uint16_t pic_w, uint8_t pic_h, uint8_t * picName){
//lcd_grephicMode(); // graphic mode
lcd_regWrite(AWLR, (uint8_t)(st_x / 8)); // active window define
lcd_regWrite(AWRR, (uint8_t)((st_x + pic_w) / 8 - 1));
lcd_regWrite(AWTR, st_y);
lcd_regWrite(AWBR, st_y + pic_h - 1);
lcdGotoXY(0, 0);
lcd_memWrite(picName, pic_w * pic_h / 8); // sizeof(picName) = pic_w * pic_h / 8
lcd_regWrite(AWLR, 0x00); // reset active window
lcd_regWrite(AWRR, 0x27);
lcd_regWrite(AWTR, 0x00);
lcd_regWrite(AWBR, 0xEF);
}
//------------------------------------------------------------------------------
void lineHorizontal(uint16_t st_x, uint16_t end_x, uint8_t y){
if (st_x > end_x){uint16_t tmp_x = st_x; st_x = end_x; end_x = tmp_x;}
uint8_t adj_st_x = st_x / 8;
uint8_t adj_end_x = end_x / 8;
if (adj_st_x == adj_end_x){
lcdGotoXY(adj_st_x, y);
lcd_memBitsSet((0x0100 >> st_x % 8) - (0x0100 >> end_x % 8 + 1));
return;
}
else {
lcdGotoXY(adj_st_x, y);
lcd_memBitsSet((0x0100 >> st_x % 8) - 1); // first byte write
for (uint8_t k = adj_st_x + 1; k < adj_end_x; k++) ra8806_bus_wt(0xFF);
lcd_memBitsSet(0xFF00 >> end_x % 8 + 1); // last byte write
}
}
//--------------------------------------------------