4

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

 2 years ago
source link: http://yiiyee.cn/blog/2021/02/13/uefi%e5%bc%80%e5%8f%91%e6%8e%a2%e7%b4%a277-yie001pcie%e5%bc%80%e5%8f%91%e6%9d%bf%ef%bc%8810-%e6%8b%a8%e5%8a%a8%e5%bc%80%e5%85%b3%e5%8f%8a%e6%98%be%e7%a4%ba%ef%bc%89/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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) 获取拨动开关状态,更新拨动开关状态的显示。

编译命令如下:

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-exolorer
项目所用ROM文件位于:/ 77 YIE1Key下

154 total views, 1 views today

210c9a4d410d265665667a36fbe0f529?s=49&d=identicon&r=g作者 罗冰(Robin)发布于 2021年2月13日2021年2月13日分类 BIOS/UEFI


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK