#include "stdlib.h"
#include "global.h"
#include "memmap.h"
#include "gpio.h"
#include "func.h"
#include "util.h"
#include "ircmd.h"
#include "graph.h"
#ifdef SUPPORT_BUSLCD_DEVICE
/************************************************************************
* LCD Interface Define *
************************************************************************/
#define LCD_STB 97
#define LCD_DAT 98
#define LCD_ACK 99
#define LCD_STB_HIGH (GPIO_E_SET(LCD_STB, 0))
#define LCD_DAT_HIGH (GPIO_E_SET(LCD_DAT, 0))
#define LCD_ACK_HIGH (GPIO_E_SET(LCD_ACK, 0))
#define LCD_STB_LOW (GPIO_O_SET(LCD_STB, 0)); (GPIO_E_SET(LCD_STB, 1))
#define LCD_DAT_LOW (GPIO_O_SET(LCD_DAT, 0)); (GPIO_E_SET(LCD_DAT, 1))
#define LCD_ACK_LOW (GPIO_O_SET(LCD_ACK, 0)); (GPIO_E_SET(LCD_ACK, 1))
#define LCD_STB_READ (GPIO_I_GET(LCD_STB))
#define LCD_DAT_READ (GPIO_I_GET(LCD_DAT))
#define LCD_ACK_READ (GPIO_I_GET(LCD_ACK))
/************************************************************************
* LCD Bus Variabler *
************************************************************************/
#define FIFO_SEND_FI(d) *(LCDSendFIFO + (LCDSendFI++)) = (d)
#define FIFO_SEND_FO(d) (d) = *(LCDSendFIFO + (LCDSendFO++))
#define FIFO_SEND_FO_BACK(d) *(LCDSendFIFO + (--LCDSendFO)) = (d)
#define FIFO_RECV_FI(d) *(LCDRecvFIFO + (LCDRecvFI++)) = (d)
#define FIFO_RECV_FO(d) (d) = *(LCDRecvFIFO + (LCDRecvFO++))
#define FIFO_SEND_EMPTY (LCDSendFI == LCDSendFO)
#define FIFO_RECV_EMPTY (LCDRecvFI == LCDRecvFO)
#define FIFO_SEND_FULL ((LCDSendFI + 1) == LCDSendFO)
#define FIFO_RECV_FULL ((LCDRecvFI + 1) == LCDRecvFO)
/************************************************************************
* LCD Subroutine *
************************************************************************/
void FinishLCD()
{
LCD_STB_HIGH;
LCD_DAT_HIGH;
LCD_ACK_HIGH;
LCDStep = 0;
LCDBitCount = 0;
LCDTryCount = 10;
LCDSendFlag = FALSE;
}
void LCDInitGPIO()
{
GPIO_M_SET(LCD_STB, 1);
GPIO_M_SET(LCD_DAT, 1);
GPIO_M_SET(LCD_ACK, 1);
GPIO_O_SET(LCD_STB, 0);
GPIO_O_SET(LCD_DAT, 0);
GPIO_O_SET(LCD_ACK, 0);
LCDSendFI = 0;
LCDSendFO = 0;
LCDRecvFI = 0;
LCDRecvFO = 0;
FinishLCD();
}
void LCDSendData(BYTE Comm, BYTE Data)
{
LCDSendDataBackup = (Comm << 8) | Data;
FIFO_SEND_FI(LCDSendDataBackup);
LCDSendDoneFlag = FALSE;
}
#define LCD_TIME_EXPIRED (20) // 20mS
void PollingLCD()
{
if (LCDStep && LCDBitTimer == 0) {
if (LCDSendFlag) {
FIFO_SEND_FO_BACK(LCDDataBackup);
}
FinishLCD();
return;
}
switch (LCDStep) {
case 0x00:
if (LCD_DAT_READ) {
if (!FIFO_SEND_EMPTY && LCDTryCount == 0) {
LCDTryCount = 10;
LCD_DAT_LOW;
FIFO_SEND_FO(LCDData);
LCDDataBackup = LCDData;
LCDSendFlag = TRUE;
LCDStep = 0x10;
}
else
if (LCDTryCount) {
LCDTryCount--;
}
}
else {
LCD_ACK_LOW;
LCDStep = 0x20;
}
LCDBitTimer = LCD_TIME_EXPIRED;
return;
break;
case 0x10:
if (LCD_ACK_READ) return;
LCD_DAT_HIGH;
break;
case 0x11:
if (!LCD_ACK_READ) return;
if (LCDData & 0x8000) { LCD_DAT_HIGH; }
else { LCD_DAT_LOW; }
LCD_STB_LOW;
break;
case 0x12:
if (LCD_ACK_READ) return;
LCD_STB_HIGH;
if (LCDBitCount >= 15) {
LCDBitCount = 0;
LCD_DAT_HIGH;
LCD_ACK_LOW;
}
else {
LCDBitCount++;
LCDData <<= 1;
LCDStep = 0x10;
}
break;
case 0x13:
if (LCD_STB_READ) return;
LCD_ACK_HIGH;
break;
case 0x14:
if (!LCD_STB_READ) return;
#if 0
psprintf(LineBuffer, "LCDS : %04x", LCDDataBackup);
MenuPrintMessage(2);
#endif
if (LCDDataBackup == LCDSendDataBackup) {
LCDSendDoneFlag = TRUE;
}
FinishLCD();
return;
case 0x20:
if (!LCD_DAT_READ) return;
LCD_ACK_HIGH;
break;
case 0x21:
if (LCD_STB_READ) return;
LCDData <<= 1;
if (LCD_DAT_READ) LCDData |= 0x01;
LCD_ACK_LOW;
break;
case 0x22:
if (!LCD_STB_READ) return;
LCD_ACK_HIGH;
if (LCDBitCount >= 15) {
LCDBitCount = 0;
LCD_DAT_HIGH;
}
else {
LCDBitCount++;
LCDStep = 0x20;
}
break;
case 0x23:
if (LCD_ACK_READ) return;
LCD_DAT_HIGH;
LCD_STB_LOW;
break;
case 0x24:
if (!LCD_ACK_READ) return;
FinishLCD();
FIFO_RECV_FI(LCDData);
return;
}
LCDStep++;
LCDBitTimer = LCD_TIME_EXPIRED;
}
/************************************************************************
* Communication Subroutine *
************************************************************************/
void PollingLCDComm()
{
UINT16 CommData;
BYTE Comm, Data;
if (!FIFO_RECV_EMPTY) {
FIFO_RECV_FO(CommData);
Comm = CommData >> 8;
Data = CommData & 0xFF;
#if 0
psprintf(LineBuffer, "LCDR : %04x", CommData);
MenuPrintMessage(3);
#endif
switch (Comm) {
case COMM_VER_HARD:
break;
case COMM_VER_SOFT:
LCDVersion = Data;
break;
case COMM_VER_MISC:
break;
case COMM_KEY_CODE:
LCDProcessKey(Data);
break;
default:
break;
}
}
}
void LCDReset()
{
LCDSendData(COMM_INIT_STATE, 0x00);
}
/************************************************************************
* LCD Display Subroutine *
************************************************************************/
#define LCD_WIN_W 24
#define LCD_WIN_H 4
enum {
LCD_PAGE_STARTUP = 0,
LCD_PAGE_MESSAGE,
LCD_PAGE_STATION,
LCD_PAGE_REPORT,
LCD_PAGE_INFO,
};
const BYTE LCDReportText[][5] = {
{ "报警", },
{ "故障", },
{ "事故", },
{ "路堵", },
{ "纠纷", },
};
const BYTE LCDReportLen[] = {
4,
4,
4,
4,
4,
};
#define LCDReportTextMax 5
void LCDInitVar()
{
LCDMenuPage = LCD_PAGE_STARTUP;
LCDMenuStay = 0;
LCDReportType = 0;
LCDSelectYesNo = 0;
LCDVersion = 0;
memset(LCDDataBuff, ' ', LCD_WIN_W * LCD_WIN_H);
memset(LCDMsgBuff, ' ', LCD_WIN_W * 2);
memset(LCDInfoBuff, ' ', LCD_WIN_W * 2);
}
BYTE TextLinePick(BYTE *Text, BYTE Wide, BYTE Line)
{
BYTE Len;
BYTE Read;
BYTE High;
High = 0;
Read = 0;
while (1) {
if (Line == High) break;
Len = strlen(Text + Read);
if (Len <= Wide) {
Read = 0xFF;
break;
}
strcpychn(LineBuffer, Text + Read, Wide);
Len = strlen(LineBuffer);
Read += Len;
High++;
}
return Read;
}
void LCDSendStr(BYTE x, BYTE y, BYTE *str)
{
BYTE i;
BYTE Len;
Len = strlen(str);
LCDSendData(COMM_LCD_DISPLAY, Len + 2);
LCDSendData(0, x);
LCDSendData(1, y);
for (i = 0; i < Len; i++)
LCDSendData(i + 2, str[i]);
}
void LCDClearLine(BYTE Line)
{
memset(LineBuffer, ' ', LCD_WIN_W);
LCDSendStr(0, Line, LineBuffer);
}
void LCDShowStr(BYTE *Text, BYTE StartLine, BYTE OverLine)
{
BYTE Line, Index;
Line = 0;
while (1) {
Index = TextLinePick(Text, LCD_WIN_W, Line);
if (Index == 0xff) break;
strcpychn(CommTempBuffer, Text + Index, LCD_WIN_W);
memset(LineBuffer, ' ', LCD_WIN_W);
memcpy(LineBuffer, CommTempBuffer, strlen(CommTempBuffer));
LCDSendStr(0, Line + StartLine, LineBuffer);
Line++;
if (Line + StartLine > OverLine) break;
if (Line + StartLine >= LCD_WIN_H) break;
}
if (Line + StartLine < OverLine) {
for (Index = Line + StartLine; Index <= OverLine; Index++)
LCDClearLine(Index);
}
}
/************************************************************************
* LCD MENU Subroutine *
************************************************************************/
void LCECLearAll()
{
memset(LCDDataBuff, ' ', LCD_WIN_W * LCD_WIN_H);
LCDShowStr(LCDDataBuff, 0, 3);
}
void LCDDrawTitle(BYTE *Title)
{
memset(LCDDataBuff, ' ', LCD_WIN_W);
memcp