📄 vfd_hw.c
字号:
vVfdClrQueueMark(bAddr);
}
}
#ifdef VFD_LED
static void vVfdLedUpdate(void) large
{
#ifndef LCD_HT1621
if(_bLedPort & 0x80) // the msb indicate that the LED has something change
{
vVfdStrobe(FALSE);
vVfdUpdate(DATA_SET_LED) ; // issue the write data command
vVfdStrobe(FALSE);
vVfdUpdate(_bLedPort & 0x1f); // 16311 at least 5 led ports
vVfdStrobe(TRUE);
_bLedPort &= 0x7f; // mask the msb bit
}
#endif
}
#ifdef VFD_HDCD_LED//peiyu, for WARNING L16: UNCALLED SEGMENT
void vVfdLed(BYTE bLedNum, BOOL fgOn) large
{
#ifndef LCD_HT1621
BYTE bLed;
bLed = _bLedPort;
if(fgOn)
{
bLed |= (1 << bLedNum);
}
else
{
bLed &= (~(1 << bLedNum));
}
if(bLed != (_bLedPort))
{
_bLedPort = (bLed | 0x80); // set the msb to 1 to indicate LED change
}
#endif
}
#endif
#endif
static void vVfdSequenceUpdate(BYTE bSize,BYTE *pbData, WORD wSegInfo) large
{
BYTE bAddr = VFD_ADDR_LIMIT;
BYTE bData;
BYTE i;
for(i = 0; i < bSize; i++)
{
i = i << 1;
if(bAddr != (pbData[i])) // write into share memory
{
if(bAddr != VFD_ADDR_LIMIT) // should update into tmpbuf first
{
vVfdWriteQueue(bAddr, bData);
}
bAddr = pbData[i]; // initial address
bData = bSharedInfo(SI_VFD_TMPBUF_START + bAddr);
}
if(wSegInfo & 0x1)
{
bData = bData | (pbData[i + 1]);
}
else
{
bData = bData & (~pbData[i + 1]);
}
wSegInfo >>= 1;
i >>= 1; // restore the i
}
// update into tmp buf here
vVfdWriteQueue(bAddr, bData);
}
static void vDirectSequenceUpd(BYTE bSize,BYTE *pbData, WORD wSegInfo) large
{
BYTE bAddr;
BYTE bData;
BYTE i;
BYTE bTotalCnt = 0;
WORD wUpdateData;
for(i = 0; i < QUEUEMARKSIZE; i++)
{
_bVfdQueueMark[i] = 0;
}
bAddr = pbData[0];
vVfdSetQueueMark(bAddr);
while(TRUE)
{
wUpdateData = wSegInfo;
bData = 0;
for(i = 0; i < bSize; i++)
{
i = i << 1;
if(bAddr == (pbData[i])) // if address match, then update
{
if(wUpdateData & 0x1)
{
bData = bData | (pbData[i + 1]);
}
else
{
bData = bData & (~pbData[i + 1]);
}
bTotalCnt++;
}
wUpdateData >>= 1;
i >>= 1; // restore the i
}
vVfdDirectWrite(bAddr, bData);
// looking for the next address here
if(bTotalCnt >= bSize)
{
break;
}
else
{
for(i = 0; i < bSize; i++)
{
bData = pbData[i << 1];
if((bData != bAddr) && (!fgVfdQueueMark(bData)))
{
bAddr = bData;
vVfdSetQueueMark(bAddr);
break;
}
}
}
}
}
void vVfdTimerState(BOOL fgPowerDown) large // 20 ms timer routine
{
BYTE bCnt;
if((!fgPowerDown) && (_bVfdTimer))
{
_bVfdTimer--;
if(_bVfdTimer == 0)
{
vVfdRecoverSeg();
return;
}
}
if(fgPowerDown)
{
_bVfdTimer++;
if(_bVfdTimer >= VFD_KEYSCAN_LOOP_CNT)
{
_bVfdTimer = 0;
_bVfdState = VFD_STATE_KEY_SCAN;
}
else
{
return;
}
}
if(_fgVfdFlash)
{
vVfdFlashState();
}
switch(_bVfdState & 0xf)
{
case VFD_STATE_MEM_UPDATE:
vVfdUpdateState();
bCnt = ((_bVfdState & 0xf0) >> 4) + 1;
if(bCnt > VFD_KEYSCAN_LOOP_CNT)
{
_bVfdState = VFD_STATE_KEY_SCAN;
}
else
{
_bVfdState = (_bVfdState & 0xf) + (bCnt << 4);
}
break;
#ifdef VFD_LED
case VFD_STATE_LED_UPDATE:
vVfdLedUpdate();
_bVfdState = VFD_STATE_MEM_UPDATE;
break;
#endif
case VFD_STATE_KEY_SCAN:
vVfdKeyScan(fgPowerDown);
#ifdef VFD_LED
_bVfdState = VFD_STATE_LED_UPDATE;
#else
_bVfdState = VFD_STATE_MEM_UPDATE;
#endif
break;
default:
_bVfdState = VFD_STATE_MEM_UPDATE;
break;
}
}
#ifdef TEST_VFD
extern void DRS232LogB(BYTE bV1, BYTE bV2, BYTE bV3, BYTE bV4);
#endif
static void vVfdKeyScan(BOOL fgPwrDown) large
{
#ifndef LCD_HT1621
BYTE i;
BOOL fgRelease = TRUE;
if(_bVfdKeyScan != IR_NONE) // the Key scan haven't been processed
{
return;
}
vVfdStrobe(FALSE); // begin to write the VFD command
vVfdUpdate(KEY_SCAN);
vVfdClk(TRUE); // waiting for the Twait (1 us)
vVfdData(TRUE); // pull the data inout line to high
vVfdClk(TRUE);
for(i = 0; i < SCANSIZE; i++) // how many bits we should scan here
{
vVfdClk(FALSE);
vVfdClk(FALSE); // may can be removed
vVfdClk(TRUE);
// get the bits from the datout pin
if(DATA_PIN)
{
if(!_fgVfdHold)
{
#ifdef TEST_VFD
if(_bCon_Key_flag)
DRS232LogB(0x0f, 0x0f, i, i) ;
#endif
_bVfdKeyScan = _pbVfdKeyScan[i];
_fgVfdHold = TRUE;
}
fgRelease = FALSE;
}
vVfdClk(TRUE); // to prevent clear clock to fast, maybe can be removed
}
vVfdStrobe(TRUE); // pull the strobe to high
if((_fgVfdHold) && (fgRelease))
{
_fgVfdHold = FALSE; // release the LOCK here
}
if(fgPwrDown)
{
//re key-map here
switch(_bVfdKeyScan)
{
case IR_POWER:
case IR_EJECT:
break;
/* panel play key is power key */
case IR_PLAY:
case IR_PLAY_PAUSE:
case IR_PLAY_ENTER:
_bVfdKeyScan = IR_POWER;
break;
default:
_bVfdKeyScan = IR_NONE;
break;
}
}
#endif
}
void vVfdClearAll(void) large
{
BYTE i;
for(i = 0; i < MAX_VFD_ADDR; i++)
{
vSetSharedInfo(SI_VFD_TMPBUF_START + i, 0); // reset the tmpbuf to zero
vVfdSetQueueMark(i);
// vVfdWrite(i); // initial the display memory(the shadow will also initial here)
// vSetSharedInfo(SI_VFD_SHADOW_START + i, 0);
// vVfdDirectWrite(i, 0);
}
for(i = 0; i < VFD_SEG_BAK_SIZE; i++)
{
vSetSharedInfo(SI_VFD_SEG_BAK + i, 0xff);
}
vSetSharedInfo(SI_VFD_UPDATE_WRIDX, 0);
_bVfdDiscPos = MAX_DISC_NUM;
_bVfdTimer = 0;
}
void vVfdDirectClrAll(void) large
{
BYTE i;
for(i = 0; i < QUEUEMARKSIZE; i++)
{
_bVfdQueueMark[i] = 0;
}
for(i = 0; i < MAX_VFD_ADDR; i++)
{
vVfdDirectWrite(i, 0);
}
_bVfdDiscPos = MAX_DISC_NUM;
_bVfdTimer = 0;
}
// lvl : 0 for 1/16
// 1 for 2/16
// 2 for 4/16
// 3 for 10/16
// 4 for 11/16
// 5 for 12/16
// 6 for 13/16
// 7 for 14/16
void vVfdSetPulseWidth(BYTE bLvl, BOOL fgDispOn) large
{
#ifndef LCD_HT1621
_bVfdPulseLvl = (((BYTE)fgDispOn << 3) + bLvl + 0x80);
vVfdStrobe(FALSE);
vVfdUpdate(_bVfdPulseLvl);
vVfdStrobe(TRUE);
#endif
}
//======================= Test Vfd function============
#ifdef TEST_VFD
void vVfdSetConfigMode(void)large;
#ifdef LCD_HT1621
void vVfdSetNode(BYTE bAddr, BYTE bData) large
{
if(bAddr == 0xff)
{
return;
}
vVfdStrobe(FALSE);
vVfdSendCom(LCD_WRITE,3);
VfdSendAddr(bAddr);
VfdSendData(bData,4);
vVfdStrobe(TRUE);
}
void vVfdSetAllNode(BYTE bOnOff)large
{
BYTE i;
for(i = 0; i < TEST_MAX_VFD_ADDR; i++)
{
vVfdSetNode(i,0xff * bOnOff);
}
}
void vVfdSetConfigMode(void)large
{
}
#else
void vVfdSetNode(BYTE bAddr, BYTE bData) large
{
if(bAddr == 0xff)
{
return;
}
vVfdStrobe(FALSE);
vVfdUpdate(DATA_SET_INC) ; // issue the write data command
vVfdStrobe(TRUE);
vVfdStrobe(FALSE);
vVfdUpdate(ADDR_SET | bAddr); // after setting the address, the strobe need not to pull high
vVfdStrobe(FALSE);
vVfdUpdate(bData); // the final data is written , strobe pull high
vVfdStrobe(TRUE);
}
void vVfdSetAllNode(BYTE bOnOff)large
{
BYTE i;
for(i = 0; i < TEST_MAX_VFD_ADDR; i++)
{
vVfdSetNode(i,0xff * bOnOff);
}
}
void vVfdSetConfigMode(void)large
{
vVfdStrobe(FALSE); // begin to write the VFD command
vVfdUpdate(MODESET);
vVfdStrobe(TRUE);
vVfdStrobe(FALSE); // begin to write the VFD command
vVfdUpdate(VFD_CONTROL);
vVfdStrobe(TRUE);
}
#endif
#endif
//================================
void vVfdFlash(void) large
{
#ifndef LCD_HT1621
_bVfdPulseLvl ^= 0x8;
vVfdStrobe(FALSE);
vVfdUpdate(_bVfdPulseLvl);
vVfdStrobe(TRUE);
#endif
}
static void vVfdFlashState(void) large
{
_bVfdFlashTimer--;
if(_bVfdFlashTimer == 0)
{
vVfdFlash(); // should flash
}
if(_bVfdFlashTimer > FLASH_INTERVAL) // for bug prevention
{
// should be removed
_bVfdFlashTimer = FLASH_INTERVAL;
}
}
// bOption : 0xff => light on all
// bOption : 0 => off all wheel
// bOption : 1 => spin to the next position depends on the style
// bVfdWheelPos : 0xff => light on all, MAX_WHEEL_NUM => all off, others => the current spinning position
// initial , the wheel are all off, and _bVfdDiscPos set as MAX_WHEEL_NUM
void vVfdRotate(BYTE bOption) large
{
BYTE bAddr = VFD_ADDR_LIMIT;
BYTE bData;
BYTE i;
WORD wDiscData;
if(MAX_DISC_NUM == 0)
{
return;
}
switch(bOption)
{
case VFD_DISC_LIGHT_ALL:
wDiscData = 0xffff;
_bVfdDiscPos = 0xff;
break;
case VFD_DISC_LIGHT_OFF:
wDiscData = 0;
_bVfdDiscPos = MAX_DISC_NUM;
break;
case VFD_DISC_SPIN:
if(_bVfdDiscPos >= MAX_DISC_NUM)
{
_bVfdDiscPos = 0;
}
else
{
// may need add more option here
#if (DISC_STYLE == 0)
_bVfdDiscPos++;
if(_bVfdDiscPos == (MAX_DISC_NUM >> 1))
{
_bVfdDiscPos = 0;
}
}
wDiscData = (1 << _bVfdDiscPos) + (1 << (_bVfdDiscPos + (MAX_DISC_NUM >> 1)));
#elif (DISC_STYLE == 1)
_bVfdDiscPos--;
if(_bVfdDiscPos == 0xff)
{
_bVfdDiscPos = ((MAX_DISC_NUM >> 1) - 1);
}
}
wDiscData = (1 << _bVfdDiscPos) + (1 << (_bVfdDiscPos + (MAX_DISC_NUM >> 1)));
#elif (DISC_STYLE == 2)
_bVfdDiscPos++;
if(_bVfdDiscPos == (MAX_DISC_NUM))
{
_bVfdDiscPos = 0;
}
}
wDiscData = (~(1 << _bVfdDiscPos)) & 0xffff;
#elif (DISC_STYLE == 3)
_bVfdDiscPos--;
if(_bVfdDiscPos == 0xff)
{
_bVfdDiscPos = MAX_DISC_NUM - 1;
}
}
wDiscData = (~(1 << _bVfdDiscPos)) & 0xffff;
#elif (DISC_STYLE == 4)
_bVfdDiscPos++;
if(_bVfdDiscPos == (MAX_DISC_NUM >> 1))
{
_bVfdDiscPos = 0;
}
}
wDiscData = (1 << _bVfdDiscPos) + (1 << (_bVfdDiscPos + (MAX_DISC_NUM >> 1)));
wDiscData = (~wDiscData) & 0xffff;
#endif
break;
default:
break;
}
vVfdSequenceUpdate(MAX_DISC_NUM, _pbVfdDisc, wDiscData);
}
#else /* VFD_SUPPORT */
static code BYTE pbVfdHw[1] = { 0 };
void vVfdInit(void) large
{
_bVfdState = pbVfdHw[0];
_bVfdKeyScan = IR_NONE;
}
void vVfdPwrDownInit(BOOL fgCleanAll) large
{
_bVfdState = pbVfdHw[0];
_bVfdKeyScan = IR_NONE;
}
void vVfdTimerState(BOOL fgPowerDown) large // 20 ms timer routine
{
_bVfdKeyScan = IR_NONE; // always IR_NONE
}
#endif /* VFD_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -