/***********************************(AQM1248A_v3.c)*******
* AQM1248A グラフィックライブラリ(spi-vRam付き)
**********************************************************/
#include "myProject.h"
#include "Font_5x7.h"
#define VRAM_ADR 0x80000
#define LCG_C_SIZE 128
#define HASC_OFS 0x00200
#define H_BLANK 0x007F0
static uint8_t vBf[32]; // フォントパターン用バッファー
//--- SPI-vRam アクセス関数
uint8_t vRam_read(uint8_t xpos, uint8_t ypos){
uint32_t adr;
adr = VRAM_ADR + (uint32_t)ypos * LCG_C_SIZE + xpos;
return SPI_Mem_Read(adr);
}
void vRam_write(uint8_t xpos, uint8_t ypos, uint8_t dat){
uint32_t adr;
adr = VRAM_ADR + (uint32_t)ypos * LCG_C_SIZE + xpos;
SPI_Mem_Write(adr, dat);
}
void vRam_Nread(uint8_t xpos,uint8_t ypos,char *ptn,uint8_t n){
uint32_t adr;
adr = VRAM_ADR + (uint32_t)ypos * LCG_C_SIZE + xpos;
SPI_Mem_NRead(adr,(uint8_t *)ptn,n);
}
void vRam_Nwrite(uint8_t xpos,uint8_t ypos,char *ptn,uint8_t n){
uint32_t adr;
adr = VRAM_ADR + (uint32_t)ypos * LCG_C_SIZE + xpos;
SPI_Mem_NWrite(adr,(uint8_t *)ptn,n);
}
//-------- G-LCDを初期化 ------------------------------------
void gLCD_int (void){
gCS_SetLow(); // gLCDセレクト有効
gRS_SetLow(); // コマンドデータ指定
SPI1_ExchangeByte(0xAE); // Display = OFF
SPI1_ExchangeByte(0xA0); // ADC = normal
SPI1_ExchangeByte(0xC8); // C.output = revers
SPI1_ExchangeByte(0xA3); // bias = 1/7
SPI1_ExchangeByte(0x2C); // power control 1
__delay_ms(2); // 2mS遅延
SPI1_ExchangeByte(0x2E); // power control 2
__delay_ms(2); // 2mS遅延v
SPI1_ExchangeByte(0x2F); // power control 3
SPI1_ExchangeByte(0x23); // Vo ratio set
SPI1_ExchangeByte(0x81); // E-volume mode
SPI1_ExchangeByte(0x1C); // E-volume value
SPI1_ExchangeByte(0xA4); // 全点灯しない
SPI1_ExchangeByte(0x40); // start line = 0
SPI1_ExchangeByte(0xA6); // 白黒反転しない
SPI1_ExchangeByte(0xAF); // Display = ON
gCS_SetHigh(); // gLCDセレクト無効
}
//-------- G-LCDのデータを全消去(指定データで埋める)---
void gLCD_clr (char dat){
uint8_t x, y;
gCS_SetLow(); // gLCDセレクト有効
for(y = 0; y < 6; y++){
gRS_SetLow(); // コマンド指定
SPI1_ExchangeByte(0xB0 + y);
SPI1_ExchangeByte(0x10);
SPI1_ExchangeByte(0x00);
gRS_SetHigh(); // 表示データ指定
for(x = 0; x < 128; x++){
SPI1_ExchangeByte(dat);
}
}
gCS_SetHigh(); // gLCDセレクト無効
for(y = 0; y < 6; y++){
for(x = 0; x < 128; x++){
vRam_write(x,y,dat); // vRamクリア
}
}
}
//-------- カーソル位置指定 -----------------------------------
void gLCD_posXY(uint8_t xpos, uint8_t ypos){
gCS_SetLow(); // チップセレクト有効
gRS_SetLow(); // コマンド指定
SPI1_ExchangeByte(0xB0 | (ypos >> 3));
SPI1_ExchangeByte(0x10 | (xpos >> 4));
SPI1_ExchangeByte(xpos & 0x0F);
gCS_SetHigh(); // チップセレクト無効
}
//-------- バイト単位で文字表示(次xpos位置を返す) ---------
uint8_t gLCD_chrX(uint8_t xpos, uint8_t ypos, char chr){
uint8_t i, sx, yAdr, ptn;
chr -= 0x20; //配列アドレスを計算
gLCD_posXY(xpos, ypos); //表示位置を指定
sx = xpos; // posxを保存
yAdr = ypos >> 3;
gCS_SetLow(); // チップセレクト有効
gRS_SetHigh(); // 表示データ指定
for(i = 0; i < 5; i++) { //データを順に取得
ptn = Font[chr][i];
if(ptn == 0xFF) break; //幅狭文字なら抜ける
vBf[i] = ptn;
SPI1_ExchangeByte(ptn);
xpos++;
}
vBf[i] = 0;
SPI1_ExchangeByte(0); //文字間隔を空ける
xpos++;
gCS_SetHigh(); // チップセレクト無効
vRam_Nwrite(sx,ypos,(char *)vBf, i); // vRamに書き込む
return xpos; //次表示位置を返す
}
//-------- バイト単位で文字列表示(次xpos位置を返す)-----
uint8_t gLCD_strX(uint8_t xpos, uint8_t ypos, char *str){
while(*str) xpos = gLCD_chrX(xpos, ypos, *str++);
return xpos; //次表示位置を返す
}
//-------- バイト単位でパターンを表示(次xpos位置を返す)
uint8_t gLCD_ptnX(uint8_t xpos, uint8_t ypos, char *ptn, uint8_t n){
uint8_t i, yAdr;
gLCD_posXY(xpos, ypos); // 表示位置を指定
gCS_SetLow(); // チップセレクト有効
gRS_SetHigh(); // 表示データ指定
yAdr = ypos >> 3;
for(i = 0; i < n; i++){
SPI1_ExchangeByte(*(ptn + i));
}
gCS_SetHigh(); // チップセレクト無効
vRam_Nwrite(xpos,ypos,ptn,n);
return xpos + n; // 次表示位置を返す
}
//---- バイト単位でn個の指定データで埋める(次xpos位置を返す)
uint8_t gLCD_clrX(uint8_t xpos, uint8_t ypos, char dat, uint8_t n){
uint8_t i, yAdr;
gLCD_posXY(xpos,ypos); // 表示位置を指定
gCS_SetLow(); // チップセレクト有効
gRS_SetHigh(); // 表示データ指定
yAdr = ypos >> 3;
for(i = 0; i < n; i++) {
SPI1_ExchangeByte(dat);
}
gCS_SetHigh(); // チップセレクト無効
for(i=0;i<// 次開始位置を返す
}
//---- バイト単位で(縦)16ドットパターン(漢字など)の表示
/* xpos: X位置、 ypos: Y位置
* *pKj: 漢字パターンデータポインタ、 cdt: 漢字横ドット数
*---------------------------------------------------- */
uint8_t gLCD_nk16X(uint8_t xpos, uint8_t ypos, char *pKj, uint8_t cdt){
gLCD_ptnX(xpos, ypos,(char *)pKj, cdt);
xpos = gLCD_ptnX(xpos, ypos+8, (char *)(pKj + cdt),cdt);
return xpos;
}
//---- 半角(8x16)文字表示(次xpos位置を返す)-----
uint8_t gLCD_HchrX(uint8_t xpos, uint8_t ypos, uint8_t chCode){
uint32_t adr;
if((chCode >= 0x20) & (chCode < 0x7F)){
adr = (chCode - 0x20) * 16 + HASC_OFS;
}else{
adr = H_BLANK; // 半角ブランク表示
}
SPI_Mem_NRead(adr,(uint8_t *)vBf,16);
xpos = gLCD_nk16X(xpos, ypos, (char *)vBf, 8);
return xpos;
}
//-------- バイト単位で半角文字列表示(次xpos位置を返す)-----
uint8_t LCD_HstrX(uint8_t xpos, uint8_t ypos, char *str){
while(*str) xpos = gLCD_HchrX(xpos, ypos, *str++);
return xpos; //次表示位置を返す
}
//--- 行をクリアして半角文字列表示(次xpos位置を返す)
uint8_t prtHstr_LnClr(uint8_t xpos, uint8_t ypos,char* str){
gLCD_clrX(0,ypos ,0,LCG_C_SIZE);
#ifdef FONT_ROM
gLCD_clrX(0,ypos+8,0,LCG_C_SIZE);
return gLCD_HstrX(xpos,ypos,str);
#else
return gLCD_strX(xpos,ypos,str);
#endif
}
/****** ドット単位位置で描画 ******/
//----------ドット単位で点を描く----------------------
void gLCD_PSet(uint8_t xpos, uint8_t ypos, uint8_t col){
uint8_t yAdr, yBit; // yアドレス、ビット位置
uint8_t ptn = 0x01; // ビットパターン
uint8_t dat;
if((xpos > 127) || (ypos > 47)) return;
dat = vRam_read(xpos, ypos);
yAdr = ypos >> 3; yBit = ypos & 0x07;
ptn <<= yBit;
switch(col){
case 0: dat &= (~ptn); break;
case 1: dat |= ptn; break;
case 8: dat ^= ptn; break;
}
gLCD_posXY(xpos,ypos);
gCS_SetLow(); // チップセレクト有効
gRS_SetHigh(); // 表示データ指定
SPI1_ExchangeByte(dat);
gCS_SetHigh(); // チップセレクト無効
vRam_write(xpos, ypos, dat);
}
//-------ドット単位で文字を描く(次xpos位置を返す)-------
uint8_t gLCD_PutChr(uint8_t xpos, uint8_t ypos, char ch, uint8_t col){
uint8_t i, j, ptn, msk; //ビットマスクデータ
//有効フォントデータでないなら何もしない
if((ch < 0x20)||(ch > 0x7f)) return xpos;
ch -= 0x20; //配列アドレスを計算
for(i = 0; i < 5; i++){
msk = 0x01;
ptn = (uint8_t)Font[ch][i];
if(ptn == 0xFF) break; //幅狭文字なら抜ける
for(j = 0; j < 8; j++){
if(ptn & msk) gLCD_PSet(xpos + i,ypos + j,col);
msk <<= 1;
}
}
return xpos + i + 1;
}
//-------ドット単位で文字列を描く(次xpos位置を返す)---
uint8_t gLCD_PutStr(uint8_t xpos, uint8_t ypos, char * str, uint8_t col){
while(*str) //文字列終端まで継続
xpos = gLCD_PutChr(xpos,ypos,*str++,col);
return xpos; //次表示位置を返す
}
//-------ドット単位でパターンを描く(次xpos位置を返す)-------
uint8_t gLCD_PutPtn(uint8_t xpos, uint8_t ypos, char * ptn, uint8_t n, uint8_t col){
uint8_t i, j, msk; //ビットマスクデータ
for(i = 0; i < n; i++){
msk = 0x01;
for(j = 0; j < 8; j++){
if(*ptn & msk) gLCD_PSet(xpos+i,ypos+j,col);
msk <<= 1;
}
ptn++;
}
return xpos + i;
}
// --- ABS、SWAP関数定義
void swap_uint8_t(uint8_t *a, uint8_t *b){
uint8_t tmp; tmp = *a; *a = *b; *b = tmp;
}
#define ABS(a) (((a)>0) ? (a) : -(a))
//----------ドット単位で直線を描く-------------------
void gLCD_Line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t col){
uint8_t steep, x, y, tmp;
int ystep, deltax, deltay, error;
steep = (ABS(y1 - y0) > ABS(x1 - x0));
if(steep){ swap_uint8_t(&x0,&y0); swap_uint8_t(&x1,&y1); }
if(x0 > x1){ swap_uint8_t(&x0,&x1); swap_uint8_t(&y0,&y1); }
deltax = x1 - x0; // 傾き計算
deltay = abs(y1 - y0);
error = 0;
y = y0;
if(y0 < y1) ystep = 1; else ystep = -1;
for(x = x0; x < x1 + 1; x++){
if(steep) gLCD_PSet(y,x,col);
else gLCD_PSet(x,y,col);
error += deltay;
if((error << 1) >= deltax){
y += ystep;
error -= deltax;
}
}
}
//---- ドット単位で(縦)16ドットパターンの表示(次xpos位置を返す)
/* xpos: X位置、 ypos: Y位置, col: 表示モード
* *pKj: 漢字パターンデータポインタ、 cdt: 漢字横ドット数
*---------------------------------------------------- */
uint8_t Put_nK16(uint8_t xpos, uint8_t ypos, char *pKj, uint8_t cdt, uint8_t col){
gLCD_PutPtn(xpos, ypos, (char *)pKj, cdt, col);
xpos = gLCD_PutPtn(xpos, ypos+8, (char *)(pKj + cdt),cdt, col);
return xpos;
}
//---- ドット単位で半角文字表示(次xpos位置を返す)
uint8_t Put_HchrX(uint8_t xpos, uint8_t ypos, uint8_t chCode,uint8_t col){
uint32_t adr;
if((chCode >= 0x20) & (chCode < 0x7F)){
adr = (chCode - 0x20) * 16 + HASC_OFS;
}else{
adr = H_BLANK; // 半角ブランク
}
SPI_Mem_NRead(adr,(uint8_t *)vBf,16);
xpos = Put_nK16(xpos, ypos, (char *)vBf, 8, col);
return xpos;
}
//---- ドット単位で半角文字列を表示(次xpos位置を返す)
uint8_t Put_HstrX(uint8_t xpos, uint8_t ypos, char *str, uint8_t col){
while(*str) xpos = Put_HchrX(xpos, ypos, *str++, col);
return xpos; //次表示位置を返す
}
|