/***********************************(AQM1248A_v5.c)*******
* AQM1248A グラフィックライブラリ(spi-vRam付き)
**********************************************************/
#include "myProject.h"
#include "Font_5x7.h"
#define VRAM_ADR 0x80000
#define LCG_C_SIZE 128
//--- フォントデータアドレス(GT20L16J1Y) (EEPROM)
#define F_HALF 0x3E7E0 // 半角 0x00200
#define F_SYM 0x00000 // 記号 0x01000
#define F_SYM2 0x00BC0 // 記号2 0x01C00
#define F_NUM 0x01960 // 数字 0x01E00
#define F_ASC 0x01B80 // ASC(大) 0x02000
#define F_ASC2 0x01F80 // ASC2(小) 0x02400
#define F_HIRA 0x02340 // ひらかな 0x02800
#define F_KATA 0x02F00 // カタカナ 0x03260
#define F_KAN1 0x0AA40 // 漢字1水準 0x04000
#define F_KAN2 0x21CE0 // 漢字2水準 -------
#define U_MAP 0x8BC00 // usrFontMap 0x00C00
#define U_FONT 0x8C000 // usrFontDat 0x1C000
#define H_BLANK 0x007F0
static uint8_t vBf[32]; // フォントパターン用バッファー
static uint8_t uMap[128];
const char Z_Small_o[]= // フォントスモール'o'
{0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x10,
0x10,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x08,
0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x00 };
//--- 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遅延
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 LCD_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 + F_HALF;
}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 gLCD_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 read_UsrMap(uint8_t p){
uint32_t ad;
ad = U_MAP + p * 128;
SPI_Mem_NRead(ad,uMap,128);
}
//--- ユーザー文字格納アドレス取得
uint32_t get_UFntAdr(uint16_t kCode){
uint8_t pg,i;
uint16_t *usrP;
usrP = (uint16_t*)uMap;
for(pg = 0; pg < 8; pg++){
read_UsrMap(pg);
for(i = 0; i < 64; i++){
if(*usrP == 0xFFFF) return 0;
if(*usrP == kCode) return U_FONT + pg * 2048 + i * 32;
usrP++;
}
}
return 0;
}
/*--- JISー>シフトJIS変換
uint16_t Jis2SJis(uint16_t jCd){
uint8_t hi,lo;
hi = jCd >> 8;
lo = (uint8_t)jCd;
if(hi && 1){
if(lo < 0x60) lo = lo + 0x1F;
else lo = lo + 0x20;
}else{ lo = lo + 0x7E;
}
if(hi < 0x5F) hi = (hi + 0xE1) >> 1;
else hi = (hi + 0x161) >> 1;
return (hi * 256 + lo);
}
*/
//---- シフトJISー>JIS変換
uint16_t SJis2Jis(uint16_t sCd){
uint8_t hi,lo;
hi = sCd >> 8;
lo = (uint8_t)sCd;
if(hi <= 0x9F){
if(lo < 0x9F) hi = hi * 2 - 0xE1;
else hi = hi * 2 - 0xE0;
}else{
if(lo < 0x9F) hi = (hi - 0xB0) * 2 - 1;
else hi = (hi - 0xB0) * 2;
}
if(lo < 0x7F) lo = lo - 0x1F;
else{
if(lo < 0x9F) lo = lo - 0x20;
else lo = lo - 0x7E;
}
return (hi * 256 + lo);
}
//--- 全角(漢字)フォントアドレス取得)
uint32_t KfntAdr(uint16_t kCode){
uint8_t msb, lsb;
uint32_t lmsb, llsb;
msb = kCode >> 8;
lsb = (uint8_t)kCode & 0x000FF;
lmsb = (uint32_t)msb;
llsb = (uint32_t)lsb;
if(msb>=0x21 & msb<0x30){
if(msb==0x21){ // 記号1
if(lsb>=0x21 & lsb<=0x7E) return F_SYM + (lsb-0x21)*32;
else return get_UFntAdr(kCode);
}else if(msb==0x22){ // 記号2
if(lsb>=0x21 & lsb<=0x2E) return F_SYM2 + (lsb-0x21)*32;
else return get_UFntAdr(kCode);
}else if(msb==0x23){ // ASCII
if(lsb>=0x30 & lsb<=0x39) return F_NUM + (lsb-0x30)*32;
if(lsb>=0x41 & lsb<=0x5A) return F_ASC + (lsb-0x41)*32;
if(lsb>=0x61 & lsb<=0x7A) return F_ASC2 + (lsb-0x61)*32;
else return get_UFntAdr(kCode);
}else if(msb==0x24){ // ひらかな
if(lsb>=0x21 & lsb<=0x73) return F_HIRA + (lsb-0x21)*32;
else return get_UFntAdr(kCode);
}else if(msb==0x25){ // カタカナ
if(lsb>=0x21 & lsb<=0x76) return F_KATA + (lsb-0x21)*32;
else return get_UFntAdr(kCode);
}
}else if(msb<0x50){ // 漢字(第1水準)
if(lsb>=0x21 & lsb<=0x7E) return F_KAN1 + (lmsb-0x30)*3008+(llsb-0x21)*32;
else return get_UFntAdr(kCode);
}else if(msb<0x75){ // 漢字(第2水準)GT20L16J1Y使用時のみ
if(lsb>=0x21 & lsb<=0x7E) return F_KAN2 + (lmsb-0x50)*3008+(llsb-0x21)*32;
else return get_UFntAdr(kCode);
}
return get_UFntAdr(kCode);
}
//---- バイト一単位で全角(漢字)文字表示
uint8_t gLCD_ZchrX(uint8_t xpos, uint8_t ypos, uint16_t kCd,uint8_t ed){
uint32_t adr;
uint16_t kk;
uint8_t h,l;
if(ed & 0x01){
h = (uint8_t)(kCd>>8);
l = (uint8_t)kCd;
kCd = l*256+h;
}
// if(kCd == 0x828F) return gLCD_nk16X(xpos,ypos,(char *)Z_Small_o,16);
if(ed < 2) kk = SJis2Jis(kCd);
else kk = kCd;
if(kk == 0x236F) return gLCD_nk16X(xpos,ypos,(char *)Z_Small_o,16);
adr = KfntAdr(kk);
// printf(" %X %lX\r",kk,adr);
SPI_Mem_NRead(adr,(uint8_t *)vBf,32);
if(adr) return gLCD_nk16X(xpos,ypos,(char *)vBf,16);
return xpos;
}
//---- バイト単位位置で全角(漢字)文字列表示
uint8_t LCD_ZstrX(uint8_t xpos, uint8_t ypos, char *str,uint8_t ed){
uint16_t cd, *kjP;
kjP = (uint16_t *)str;
while(*kjP & 0xFF){
xpos = gLCD_ZchrX(xpos,ypos,*kjP,ed);
kjP++;
}
return xpos;
}
/****** ドット単位位置で描画 ******/
//----------ドット単位で点を描く----------------------
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 + F_HALF;
}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; //次表示位置を返す
}
//---- ドット単位で全角(漢字)文字表示
uint8_t Put_ZchrX(uint8_t xpos, uint8_t ypos, uint16_t kCd, uint8_t ed, uint8_t col){
uint32_t adr;
uint16_t kk;
uint8_t h,l;
if(ed & 0x01){
h = (uint8_t)(kCd>>8);
l = (uint8_t)kCd;
kCd = l*256+h;
}
if(ed < 2) kk = SJis2Jis(kCd);
else kk = kCd;
if(kk == 0x236F)
return Put_nK16(xpos,ypos,(char *)Z_Small_o,16, col);
adr = KfntAdr(kk);
SPI_Mem_NRead(adr,(uint8_t *)vBf,32);
if(adr) return Put_nK16(xpos,ypos,(char *)vBf,16, col);
return xpos;
}
//---- ドット単位で全角(漢字)文字列表示
uint8_t Put_ZstrX(uint8_t xpos, uint8_t ypos, char *str, uint8_t ed, uint8_t col){
uint16_t cd, *kjP;
kjP = (uint16_t *)str;
while(*kjP & 0xFF){
xpos = Put_ZchrX(xpos,ypos,*kjP,ed,col);
kjP++;
}
return xpos;
}
/***** End of File *****/
|