UEFI开发探索77- YIE001PCIe开发板(10 拨动开关及显示)

请保留-> 【原文:  https://blog.csdn.net/luobing4365 和 http://yiiyee.cn/blog/author/luobing/】

YIE001上有两个拨动开关,可通过对应的寄存器位得知它们的状态,以实现交互控制。这篇尝试将按键获取,以及图形显示的编码。

1 获取拨动开关状态

UEFI开发探索第75篇中,列出了YIE001开发板的硬件资源。板子上提供了两个拨动开关,分别对应CH366的GPI1和GPI2。

对照CH366的芯片手册,定义其相关的宏定义:

#define CH366GPIR 0x02

#define KEY1 1   //GPI1 -- GPIR(IO基地址+02h) bit 1
#define KEY2 2   //GPI2 -- GPIR(IO基地址+02h) bit 2

在开发板YIE001上,拨动开关拨下(也即靠近PCIE槽的方向),对应的寄存器位值为0;拨上后对应的寄存器值为1。实现代码如下:

/**
  获取开发板YIE001上拨动开关的状态.
  
  @param  IoBaseAddress     YIE001上PCIE芯片的基地址
  @param  KeyNum            拨动开关的标识,Key1和Key2
  @retval 1           拨下(靠近PCIE插槽)
          0           拨上    
**/
UINT8 GetYIE001Key(UINT16 IoBaseAddress,UINT8 KeyNum)
{
  UINT8 regValue=0;

  regValue = IoRead8(MyIoBaseAddr+CH366GPIR);   //GPIR
  if(KeyNum == KEY1)
    regValue &=0x02;
  if(KeyNum == KEY2)
    regValue &=0x04;
  if(regValue)
    return 1;
  else
    return 0;
}

2 显示开关状态

为了显示拨动开关的状态,复用了上一篇博客中的代码。本篇博客的示例工程为YIE1Key,结合了访问YIE001开发板和图形显示的代码。

看代码比较容易明白实现的功能:

VOID HelloMyROM(VOID)
{
  EFI_INPUT_KEY key={0,0};
  UINT64 flag;
  UINT8 *s_text1 = "欢迎进入UEFI的世界!";
  UINT8 *s_text2 = "按'ESC'键或'1'退出此界面";
  UINT8 *s_key1str1 = "拨动开关1拨下!";
  UINT8 *s_key1str2 = "拨动开关1拨上!";
  UINT8 *s_key2str1 = "拨动开关2拨下!";
  UINT8 *s_key2str2 = "拨动开关2拨上!";
  UINT8 tempKey1;
  UINT8 tempKey2;
  //图形显示测试
  flag = InintGloabalProtocols(GRAPHICS_OUTPUT);
	Print(L"flag=%x\n",flag);
  SwitchGraphicsMode(TRUE);
	SetBKG(&(gColorTable[DEEPBLUE]));
  draw_string(s_text1, 120, 100, &MyFontArray, &(gColorTable[YELLOW]));
  draw_string(s_text2, 120, 140, &MyFontArray, &(gColorTable[YELLOW]));
  tempKey1 = GetYIE001Key(MyIoBaseAddr,KEY1);
  tempKey2 = GetYIE001Key(MyIoBaseAddr,KEY2);
  if(tempKey1)
    draw_string(s_key1str1, 120, 200, &MyFontArray, &(gColorTable[WHITE]));
  else
    draw_string(s_key1str2, 120, 200, &MyFontArray, &(gColorTable[WHITE]));
  if(tempKey2)
    draw_string(s_key2str1, 120, 230, &MyFontArray, &(gColorTable[WHITE]));
  else
    draw_string(s_key2str2, 120, 230, &MyFontArray, &(gColorTable[WHITE]));
  while(key.ScanCode!=0x17)	//ESC
  {
    GetKey(&key);
    if(key.UnicodeChar == 0x31)   
      break;
    if(GetYIE001Key(MyIoBaseAddr,KEY1)!=tempKey1)
    {
      if(tempKey1)
      {
        tempKey1 = 0;
        draw_string(s_key1str1, 120, 200, &MyFontArray, &(gColorTable[DEEPBLUE]));  //消除显示
        draw_string(s_key1str2, 120, 200, &MyFontArray, &(gColorTable[WHITE]));
        SetLed(MyIoBaseAddr,LED1,LEDON);
      }
      else
      {
        tempKey1 = 1;
        draw_string(s_key1str2, 120, 200, &MyFontArray, &(gColorTable[DEEPBLUE]));  //消除显示
        draw_string(s_key1str1, 120, 200, &MyFontArray, &(gColorTable[WHITE]));
        SetLed(MyIoBaseAddr,LED1,LEDOFF);
      }
      Delayms(200);
    }
    if(GetYIE001Key(MyIoBaseAddr,KEY2)!=tempKey2)
    {
      if(tempKey2)
      {
        tempKey2 = 0;
        draw_string(s_key2str1, 120, 230, &MyFontArray, &(gColorTable[DEEPBLUE]));  //消除显示
        draw_string(s_key2str2, 120, 230, &MyFontArray, &(gColorTable[WHITE]));
        SetLed(MyIoBaseAddr,LED2,LEDON);
      }
      else
      {
        tempKey2 = 1;
        draw_string(s_key2str2, 120, 230, &MyFontArray, &(gColorTable[DEEPBLUE]));  //消除显示
        draw_string(s_key2str1, 120, 230, &MyFontArray, &(gColorTable[WHITE]));
        SetLed(MyIoBaseAddr,LED2,LEDOFF);
      }
      Delayms(200);
    }
  }
  SetMyMode(OldGraphicsMode);
  SwitchGraphicsMode(FALSE);
}

修改了框架代码中的HelloMyROM()函数,主要的功能如下:
(1) 初始化图形显示,并在屏幕上打印相应的提示字符串;
(2) 进入按键获取的循环,只有接收到用户按’ESC’或’1’,才会退出循环;
(3) 获取拨动开关状态,更新拨动开关状态的显示。

3 测试

编译命令如下:

C:\UEFIWorkspace>build -t VS2015x86 -p RobinPkg\RobinPkg.dsc -m  RobinPkg\Drivers\YIE1Key\YIE1Key.inf -a X6

Option ROM的界面显示如图1所示。

图1 YIE1Key显示界面

拨动相应的开关后,界面会显示目前的拨动开关状态。结合YIE001的这种拨动开关交互机制,可以试着实现更丰富的有趣效果。

Gitee地址:https://gitee.com/luobing4365/uefi-explorer
项目所用ROM文件位于:/ 77 YIE1Key下

1,377 total views, 1 views today

发表评论

电子邮件地址不会被公开。