⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfd_hw.c

📁 mtk1389L latest sourcecode enjoy
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************    MTK CONFIDENTIAL & COPYRIGHTED     ****************/
/***************                                       ****************/
/*************** Description : VFD Driver Routine      ****************/
/***************                                       ****************/
/***************                                       ****************/
/***************     Company : MediaTek Inc.           ****************/
/***************  Programmer : Harrison Hsieh          ****************/
/**********************************************************************/
#define _VFD_HW_C_

#pragma NOAREGS

#include "8032api.h"
#include VFD_CUS_H
#include "vfd_hw.h"

#ifdef VFD_SUPPORT

#include "vfd.h"

#ifdef LCD_HT1621
static void vVfdSendCom(BYTE bVal, BYTE bCnt) large;
static void VfdSendAddr(BYTE Addr) large;
static void VfdSendData(BYTE bData,BYTE bCnt) large;
#endif
//BOOL _fgAa = FALSE;

void vVfdInit(void) large
{
  BYTE i;
#ifdef LCD_HT1621
 //for SYS_EN
  vVfdStrobe(FALSE); 
  vVfdSendCom(LCD_CMD, 3);
  vVfdSendCom(LCD_SYS_EN, 8);
  vVfdSendCom(0, 1);
  vVfdStrobe(TRUE); 

  //for LCD_ON
  vVfdStrobe(FALSE); 
  vVfdSendCom(LCD_CMD, 3);
  vVfdSendCom(LCD_ON, 8);
  vVfdSendCom(0, 1);
  vVfdStrobe(TRUE); 
  
  //for TIMER_EN
  vVfdStrobe(FALSE); 
  vVfdSendCom(LCD_CMD, 3);
  vVfdSendCom(LCD_TIMER_EN, 8);
  vVfdSendCom(0, 1);
  vVfdStrobe(TRUE); 
  
   //for  rc 256k
  vVfdStrobe(FALSE); 
  vVfdSendCom(LCD_CMD, 3);
  vVfdSendCom(LCD_RC_256K, 8);
  vVfdSendCom(0, 1);
  vVfdStrobe(TRUE);
  
  //for bias 1/3, 4com
  vVfdStrobe(FALSE); 
  vVfdSendCom(LCD_CMD, 3);
  vVfdSendCom(LCD_BIAS13_COM4, 8);
  vVfdSendCom(0, 1);
  vVfdStrobe(TRUE);
  
  //for TNORMAL 
  vVfdStrobe(FALSE); 
  vVfdSendCom(LCD_CMD, 3);
  vVfdSendCom(LCD_TNORMAL, 8);
  vVfdSendCom(0, 1);
  vVfdStrobe(TRUE);
  vVfdDirectClrAll();
  vVfdShowMsg(SEG_MSG_HELLO, TRUE);
  for(i = 0; i < MAX_VFD_ADDR; i++)
  {
    vSetSharedInfo(SI_VFD_SHADOW_START + i, 0xff);  // reset the tmpbuf to zero
  }
   vVfdClearAll();
  
   _bVfdState = 0;
  _bVfdKeyScan = IR_NONE;

#else
  vVfdDirectClrAll();
  vVfdShowMsg(SEG_MSG_HELLO, TRUE);
  vVfdStrobe(FALSE);         // begin to write the VFD command
  vVfdUpdate(MODESET);
  vVfdStrobe(TRUE);          // strobe pull high to release the mode set
  
  vVfdStrobe(FALSE);         // begin to write the VFD command
  vVfdUpdate(VFD_CONTROL);
  _bVfdPulseLvl = VFD_CONTROL;
  vVfdStrobe(TRUE);          // strobe pull high to release the mode set

  for(i = 0; i < MAX_VFD_ADDR; i++)
  {
    vSetSharedInfo(SI_VFD_SHADOW_START + i, 0xff);  // reset the tmpbuf to zero
  }


  vVfdClearAll();

/*
  for(i = 0; i < MAX_VFD_ADDR; i++)
  {
//    vSetSharedInfo(SI_VFD_TMPBUF_START + i, 0);  // reset the tmpbuf to zero
    vSetSharedInfo(SI_VFD_SHADOW_START + i, 0);
  }
*/

  vVfdSetFlash(FALSE);
  _bVfdState = 0;
  _bVfdKeyScan = IR_NONE;
#endif
}

void vVfdPwrDownInit(BOOL fgCleanAll) large
{
  BYTE i;

#ifdef LCD_HT1621
  if(fgCleanAll)
  {
    for(i = 0; i < MAX_VFD_ADDR; i++)
    {
      vVfdDirectWrite(i, 0);
    }
    vVfdStrobe(FALSE);         // begin to write the VFD command
    vVfdSendCom(LCD_CMD, 3);
    vVfdSendCom(LCD_OFF, 8);
    vVfdSendCom(0, 1);
    vVfdStrobe(TRUE);   
  }
  _bVfdState = 0;
  _bVfdKeyScan = IR_NONE;
#else
  vVfdStrobe(FALSE);         // begin to write the VFD command
  vVfdUpdate(MODESET);
  vVfdStrobe(TRUE);          // strobe pull high to release the mode set


  if(fgCleanAll)
  {
    for(i = 0; i < MAX_VFD_ADDR; i++)
    {
      vVfdDirectWrite(i, 0);
    }

    vVfdStrobe(FALSE);         // begin to write the VFD command
    vVfdUpdate(0x80);
    vVfdStrobe(TRUE);          // strobe pull high to release the mode set
  }
  vVfdSetFlash(FALSE);
  _bVfdState = 0;
  _bVfdKeyScan = IR_NONE;
#endif
}


#ifdef LCD_HT1621
static void vVfdSendCom(BYTE bVal, BYTE bCnt) large
{
  BYTE i;
  bVal <<=(8-bCnt);
  for (i = 0; i < bCnt; i++)
  {
    vVfdClk(FALSE);
      
    DATA_PIN = (bVal & 0x80);
    _nop_(); _nop_();
    bVal <<= 1;
    
    vVfdClk(TRUE);
    _nop_(); _nop_(); _nop_(); _nop_();
  }
}

static void VfdSendAddr(BYTE Addr) large
{
  BYTE i; 

  Addr <<= 2;
  for (i = 0; i < 6; i++)
  {
    vVfdClk(FALSE);
    if(Addr & 0x80)
    {
      DATA_PIN = 1;
    }
    else
    {
      DATA_PIN = 0;
    }
    _nop_(); _nop_(); _nop_(); _nop_();
    Addr <<= 1;
    
    vVfdClk(TRUE);
    _nop_(); _nop_(); _nop_(); _nop_();
  }
}

static void VfdSendData(BYTE bData,BYTE bCnt) large
{
  BYTE i;
  
  for (i = 0; i < bCnt; i++)
  {
     vVfdClk(FALSE);
     DATA_PIN = (bData & 0x01);
     bData >>= 1;
    _nop_(); _nop_(); _nop_(); _nop_();
     vVfdClk(TRUE);
    _nop_(); _nop_(); _nop_(); _nop_();
  }
  _nop_(); _nop_(); _nop_(); _nop_();
  vVfdData(TRUE);
}
#else

static void vVfdUpdate(BYTE bTmp) large
{
  BYTE i;

  for (i = 0; i < 8; i++)
  {
    vVfdClk(FALSE);

    vVfdCombineBit(bTmp);
    bTmp >>= 1;

    vVfdClk(TRUE);
  }

  vVfdData(TRUE);
}
#endif
// should use increamental address and add a check to see that if we need to update address again

static void vVfdWrite(BYTE bAddr) large
{
  BYTE bCnt = 0;
  BYTE bData;

#ifdef LCD_HT1621
  vVfdStrobe(FALSE);
  vVfdSendCom(LCD_WRITE,3);
  VfdSendAddr(bAddr);
  while(TRUE)
  {
    bCnt++;
    bData = bSharedInfo(SI_VFD_TMPBUF_START + bAddr);  // get the data from the shadow

    VfdSendData(bData,4);
     
    vSetSharedInfo(SI_VFD_SHADOW_START + bAddr, bData);  // set the data in the display buf
    vVfdClrQueueMark(bAddr);    // after updating, clear the queue mark
    bAddr++;   // update the address to next
    if(bAddr == VFD_MAX_ADDR)
    {
      bAddr = 0;   //reset to 0;
    }

    if((bCnt >= VFD_MAX_UPDATE_CNT) || (!fgVfdQueueMark(bAddr)))
    {
      break;
    }
  }
  vVfdStrobe(TRUE);
#else

  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);


  while(TRUE)
  {
    bCnt++;
    bData = bSharedInfo(SI_VFD_TMPBUF_START + bAddr);  // get the data from the shadow

    vVfdUpdate(bData);   // the final data is written , strobe pull high
  
    vSetSharedInfo(SI_VFD_SHADOW_START + bAddr, bData);  // set the data in the display buf
    vVfdClrQueueMark(bAddr);    // after updating, clear the queue mark
    bAddr++;   // update the address to next
    if(bAddr == VFD_MAX_ADDR)
    {
      bAddr = 0;   //reset to 0;
    }

    if((bCnt >= VFD_MAX_UPDATE_CNT) || (!fgVfdQueueMark(bAddr)))
    {
      break;
    }
  }
  vVfdStrobe(TRUE);
#endif
}

void vVfdSegDisplay(BYTE SegPos, BYTE bNum, BOOL fgDirect) large
{
#if ((SEG_SIZE == 10) || (SEG_SIZE == 14))
  WORD wSegInfo;
#else
  BYTE bSegInfo;
#endif  
  
  BYTE i;
  BYTE bData;
  BYTE bAddr = VFD_ADDR_LIMIT;   // a initial unknown value in VFD memory

  if(!fgDirect)
  {    
    if((_bVfdTimer) || (bSharedInfo(SI_VFD_SEG_BAK + SegPos) == bNum))
    return;
  }


#if ((SEG_SIZE == 10) || (SEG_SIZE == 14))
  wSegInfo = _pbSegUnit[bNum] + (_pbSegUnitHi[bNum] << 8);
  if(fgDirect)
  {
    vDirectSequenceUpd(SEG_SIZE, _pbVfdSeg[SegPos], wSegInfo);  
  }
  else
  {
    vVfdSequenceUpdate(SEG_SIZE, _pbVfdSeg[SegPos], wSegInfo);  
  }
#else
  bSegInfo = _pbSegUnit[bNum];        // segment size = 7/8
  if(fgDirect)
  {
    vDirectSequenceUpd(SEG_SIZE, _pbVfdSeg[SegPos], (WORD)bSegInfo);  
  }
  else
  {
    vVfdSequenceUpdate(SEG_SIZE, _pbVfdSeg[SegPos], (WORD)bSegInfo);  
  }
#endif  
  

  // update into tmp buf here
  if(!fgDirect)
  {
    vSetSharedInfo(SI_VFD_SEG_BAK + SegPos, bNum);
  }
//  vVfdWriteQueue(bAddr, bData);  
}


// bTime one unit for half seconds

#if(defined(VFD_TEMP_TEXT)||defined(VFD_MESSAGE_FR)||defined(VFD_MESSAGE_PAUSE)||defined(VFD_MESSAGE_FR))
//peiyu,For UNCALLED SEGMENT
void vVfdShowTempMsg(BYTE bMsgId, BYTE b20msCnt) large
{
  BYTE i;

  for(i = 0; i < MAX_SEG_SEQ_NUM; i++)
  {
    vSetSharedInfo(SI_VFD_SEG_ORG + i, bSharedInfo(SI_VFD_SEG_BAK + i));  // backup the original
  }

  vVfdShowMsg(bMsgId, FALSE);

  _bVfdTimer = b20msCnt;  
}

#endif
static void vVfdRecoverSeg(void) large
{
  BYTE i;
  BYTE bSeg;

  for(i = 0; i < MAX_SEG_SEQ_NUM; i++)
  {
    bSeg = _pbSegSequence[i];
    vVfdSegDisplay(bSeg, bSharedInfo(SI_VFD_SEG_ORG + bSeg), FALSE);
  }
}


void vVfdShowMsg(BYTE bMsgIdIdx, BOOL fgDirect) large
{
  BYTE bPos; 
  BYTE bBound;
  BYTE i;
  WORD wMsgId;

  wMsgId = _pwMsgTable[bMsgIdIdx];
  
  if(_bVfdTimer)     // temp msg is still showed, do not cover it
  {
    return;
  }

  if(fgDirect)
  {
#ifndef LCD_HT1621
    vVfdStrobe(FALSE);         // begin to write the VFD command
    vVfdUpdate(MODESET);
    vVfdStrobe(TRUE);          // strobe pull high to release the mode set

    vVfdStrobe(FALSE);         // begin to write the VFD command
    vVfdUpdate(VFD_CONTROL);
    _bVfdPulseLvl = VFD_CONTROL;
    vVfdStrobe(TRUE);          // strobe pull high to release the mode set
#endif
  }
  
  bPos = (_pbVfdMsg[wMsgId] & 0xf0) >> 4;

  bBound = bPos + (_pbVfdMsg[wMsgId] & 0xf);

  for(i = 0; i < MAX_SEG_SEQ_NUM; i++)
  {
    if((i >= bPos) && (i < bBound))
    {
      vVfdSegDisplay(_pbSegSequence[i], _pbVfdMsg[wMsgId + i - bPos + 1], fgDirect);
    }
    else
    {
      vVfdSegDisplay(_pbSegSequence[i], SEG_CLEAN, fgDirect);
    }
  }

#ifdef DIRECT_CROSS_TABLE  
  if(fgDirect)
  {
    bPos = _pbMsgDirectTable[bMsgIdIdx];   // start position

    if(bPos == 0xff)
    {
      return;
    }

    bBound = _pbVfdDirectMsg[bPos];
 
    for(i = 0; i < bBound; i++)
    {
      i = i << 1;
      vVfdDirectWrite(_pbVfdDirectMsg[bPos + 1 + i], _pbVfdDirectMsg[bPos + 1 + i + 1]);

      i = i >> 1;
    }
  }

#endif
}




void vVfdSetMode(BYTE bMode, BOOL fgEnable) large
{
  BYTE bData;

  if(_pbVfdMode[bMode] == VFD_UNKNOWN_ADDR)
  {
    return;     // ignore this command
  }

  bData = bSharedInfo(SI_VFD_TMPBUF_START + _pbVfdMode[bMode]);

  if(fgEnable)
  {  
    bData = bData | _pbVfdMode[bMode + 1];
  }
  else
  {
    bData = bData & (~_pbVfdMode[bMode + 1]);
  }

  vVfdWriteQueue(_pbVfdMode[bMode], bData);
}


static void vVfdUpdateState(void) large // update into the VFD display memory
{
  BYTE i;
  BYTE bCnt = 0;    // initial value to 0
  BYTE bLimit;

  i = bSharedInfo(SI_VFD_UPDATE_WRIDX);
  bLimit = i;

  while(TRUE)
  {
    if(bCnt > VFD_MAX_UPDATE_CNT)
    {
      vSetSharedInfo(SI_VFD_UPDATE_WRIDX, i);
      break;
    }

    if(fgVfdQueueMark(i))
    {
      vVfdWrite(i);
      bCnt++;
    }    

    i++;

    if(i == VFD_MAX_ADDR)
    {
      i = 0;    // reset i to 0, wrap around to the head of the ring buffer
    }
    
    if(i == bLimit)    // all loop finish
    {
      break;   // write index not change in this case
    }
  }

}

static void vVfdDirectWrite(BYTE bAddr, BYTE bData) large
{
  if(bAddr == 0xff)
  {
    return;
  }
#ifdef LCD_HT1621
  vVfdStrobe(FALSE);
  vVfdSendCom(LCD_WRITE,3);
  VfdSendAddr(bAddr);
  VfdSendData(bData,4);
  vVfdStrobe(TRUE);
#else
  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);
#endif
}


static void vVfdWriteQueue(BYTE bAddr, BYTE bData) large
{
  BYTE bShadowData;

  if(bAddr == 0xff)
  {
    return;
  }

  bShadowData = bSharedInfo(SI_VFD_SHADOW_START + bAddr);

  if(bShadowData != bData)  // if it is the same as VFD display data, ignore this command
  {
    vSetSharedInfo(SI_VFD_TMPBUF_START + bAddr, bData);   // set the tmp buf data

    if(!fgVfdQueueMark(bAddr))  // the position is not in update queue already
    {
      vVfdSetQueueMark(bAddr);  // add the queue mark
    }
  }
  else
  {
    vSetSharedInfo(SI_VFD_TMPBUF_START + bAddr, bShadowData);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -