[DemoCode下载] NUC123的PS2模式

[复制链接]
604|11
 楼主| huahuagg 发表于 2019-8-28 23:18 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V2.00
  4. * $Revision: 12 $
  5. * $Date: 15/07/02 11:18a $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    Demonstrate how to control PS/2 mouse movement on the screen.
  7. * @note
  8. * Copyright (C) 2014~2015 Nuvoton Technology Corp. All rights reserved.
  9. *
  10. ******************************************************************************/
  11. #include <stdio.h>
  12. #include "NUC123.h"

  13. #define PLLCON_SETTING      CLK_PLLCON_72MHz_HXT
  14. #define PLL_CLOCK           72000000

  15. #define DEVICE_ID                   0x00

  16. #define PS2CMD_RESET                0xFF
  17. #define PS2CMD_RESEND               0xFE
  18. #define PS2CMD_SET_DEFAULTS         0xF6
  19. #define PS2CMD_DISABLE_DATA_REPORT  0xF5
  20. #define PS2CMD_ENABLE_DATA_REPORT   0xF4
  21. #define PS2CMD_SET_SAMPLE_RATE      0xF3
  22. #define PS2CMD_GET_DEVICE_ID        0xF2
  23. #define PS2CMD_SET_REMOTE_MODE      0xF0
  24. #define PS2CMD_SET_WARP_MODE        0xEE
  25. #define PS2CMD_RESET_WARP_MODE      0xEC
  26. #define PS2CMD_READ_DATA            0xEB
  27. #define PS2CMD_SET_STREAM_MODE      0xEA
  28. #define PS2CMD_STATUS_REQUEST       0xE9
  29. #define PS2CMD_SET_RESOLUTION       0xE8
  30. #define PS2CMD_SET_SCALLING2        0xE7
  31. #define PS2CMD_SET_SCALLING1        0xE6

  32. #define PS2MOD_RESET    0x0
  33. #define PS2MOD_STREAM   0x1
  34. #define PS2MOD_REMOTE   0x2
  35. #define PS2MOD_WARP     0x3

  36. void SYS_Init(void);
  37. void UART0_Init(void);
  38. void PS2_Init(void);

  39. uint8_t g_CMD_RESET = 0;
  40. uint8_t g_opMode = PS2MOD_RESET;
  41. uint8_t g_sampleRate = 0;
  42. uint8_t g_resolution = 0;
  43. uint8_t g_scalling = 0;
  44. uint8_t g_dataReportEnable = 0;
  45. uint32_t g_mouseData = 0;
  46. uint8_t g_cmd[2] = {0};

  47. uint32_t u32PS2ACK = 0xFA;
  48. uint32_t u32PS2PASS = 0xAA;
  49. uint32_t u32TxData;

  50. uint32_t g_cnt = 0;

  51. void SysTick_Handler(void)
  52. {
  53.     if(g_opMode == PS2MOD_STREAM && g_dataReportEnable)
  54.     {
  55.         if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  56.         {
  57.             /* Calculate cursor moving data */
  58.             g_cnt++;
  59.             if(g_cnt < 101)
  60.                 g_mouseData = (0x0 << 16) | (0x01 << 8) | 0x08;  // move right */
  61.             else if(g_cnt < 201)
  62.                 g_mouseData = (0xFF << 16) | (0x00 << 8) | 0x28; // move down */
  63.             else if(g_cnt < 301)
  64.                 g_mouseData = (0x0 << 16) | (0xFF << 8) | 0x18;  // move left */
  65.             else if(g_cnt < 401)
  66.                 g_mouseData = (0x1 << 16) | (0x00 << 8) | 0x08;  // move up */
  67.             else if(g_cnt > 401)
  68.                 g_cnt = 1;

  69.             /* Transmit data*/
  70.             PS2_Write(&g_mouseData, 3);

  71.             if((g_cnt & 0x0F) == 0)
  72.                 printf("Device->Host: Data report 0x%06x\n", g_mouseData);
  73.         }
  74.     }
  75. }

  76. void PS2_IRQHandler(void)
  77. {
  78.     uint32_t u32RxData;

  79.     /* RXINT */
  80.     if(PS2_GET_INT_FLAG(PS2_PS2INTID_RXINT_Msk))
  81.     {
  82.         /* Clear PS2 Receive Interrupt flag */
  83.         PS2_CLR_RX_INT_FLAG();

  84.         /* Get Receive Data */
  85.         u32RxData = PS2_Read();

  86.         printf("\n u32RxData = 0x%x \n", u32RxData);

  87.         if(g_cmd[0])
  88.         {
  89.             /* If g_cmd[0] is not 0, it should be in data phase */
  90.             if(g_cmd[0] == PS2CMD_SET_SAMPLE_RATE)
  91.             {
  92.                 printf("Host->Device: Set sample rate data %d\n", u32RxData);

  93.                 if(u32RxData < 10)   u32RxData = 10;
  94.                 if(u32RxData > 200) u32RxData = 200;
  95.                 g_sampleRate = u32RxData;
  96.                 g_cmd[0] = 0;

  97.                 /* Wait Tx ready */
  98.                 if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  99.                 {
  100.                     printf("Device->Host: ACK\n");

  101.                     PS2_Write(&u32PS2ACK, 1);
  102.                 }
  103.                 else
  104.                 {
  105.                     printf("Something wrong!! Stop code!\n");

  106.                     PS2_SET_CLK_LOW();
  107.                     PS2_SET_DATA_HIGH();
  108.                     PS2_ENABLE_OVERRIDE();

  109.                     while(1);
  110.                 }

  111.             }
  112.             else if(g_cmd[0] == PS2CMD_SET_RESOLUTION)
  113.             {
  114.                 printf("Host->Device: Set resolution data %d\n", u32RxData);

  115.                 if(u32RxData < 1) u32RxData = 1;
  116.                 if(u32RxData > 3) u32RxData = 3;
  117.                 g_resolution = (1 << u32RxData);
  118.                 g_cmd[0] = 0;

  119.                 /* Wait Tx ready */
  120.                 if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  121.                 {
  122.                     PS2_Write(&u32PS2ACK, 1);

  123.                     printf("Device->Host: ACK\n");
  124.                 }
  125.                 else
  126.                 {
  127.                     printf("Something Wrong!! Stop code!\n");

  128.                     PS2_SET_CLK_LOW();
  129.                     PS2_SET_DATA_HIGH();
  130.                     PS2_ENABLE_OVERRIDE();

  131.                     while(1);
  132.                 }
  133.             }
  134.         }
  135.         else
  136.         {
  137.             /* Only support PS2CMD_DISABLE_DATA_REPORT command when data report enabled */
  138.             if((u32RxData == PS2CMD_RESET) || (u32RxData == PS2CMD_DISABLE_DATA_REPORT) || (g_dataReportEnable == 0))
  139.             {
  140.                 /* Process the command phase */
  141.                 if(u32RxData == PS2CMD_RESET)
  142.                 {
  143.                     printf("Host->Device: Reset\n");

  144.                     /* Reset command */
  145.                     g_opMode = PS2MOD_RESET;
  146.                     g_cmd[0] = 0;

  147.                     /* Clear FIFO */
  148.                     PS2_CLEAR_TX_FIFO();

  149.                     /* Wait Tx ready */
  150.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  151.                     {
  152.                         u32TxData = u32PS2ACK;
  153.                         PS2_Write(&u32TxData, 1);

  154.                         printf("Device->Host: ACK\n");

  155.                         g_CMD_RESET = 1;
  156.                     }

  157.                 }
  158.                 else if(u32RxData == PS2CMD_SET_SAMPLE_RATE)
  159.                 {
  160.                     printf("Host->Device: Set sample rate\n");

  161.                     /* Set sample rate */
  162.                     g_cmd[0] = PS2CMD_SET_SAMPLE_RATE;

  163.                     /* Wait Tx ready */
  164.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  165.                     {
  166.                         PS2_Write(&u32PS2ACK, 1);

  167.                         printf("Device->Host: ACK\n");
  168.                     }
  169.                 }
  170.                 else if(u32RxData == PS2CMD_GET_DEVICE_ID)
  171.                 {
  172.                     printf("Host->Device: Get device ID\n");

  173.                     g_cmd[0] = 0;

  174.                     printf("(PS2->STATUS).TXEMPTY is (%0x)\n", ((PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk) >> PS2_PS2STATUS_TXEMPTY_Pos));

  175.                     /* Wait Tx ready */
  176.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  177.                     {
  178.                         u32TxData = ((DEVICE_ID << 8) | u32PS2ACK);
  179.                         PS2_Write(&u32TxData, 2);

  180.                         printf("Device->Host: ACK + Device ID(0x%x)\n", DEVICE_ID);
  181.                     }
  182.                 }
  183.                 else if(u32RxData == PS2CMD_SET_SCALLING2)
  184.                 {
  185.                     printf("Host->Device: Set scaling 2\n");

  186.                     g_scalling = 2;
  187.                     g_cmd[0] = 0;

  188.                     /* Wait Tx ready */
  189.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  190.                     {
  191.                         PS2_Write(&u32PS2ACK, 1);

  192.                         printf("Device->Host: ACK\n");
  193.                     }
  194.                 }
  195.                 else if(u32RxData == PS2CMD_SET_SCALLING1)
  196.                 {
  197.                     printf("Host->Device: Set scaling 1\n");

  198.                     g_scalling = 1;
  199.                     g_cmd[0] = 0;

  200.                     /* Wait Tx ready */
  201.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  202.                     {
  203.                         PS2_Write(&u32PS2ACK, 1);

  204.                         printf("Device->Host: ACK\n");
  205.                     }
  206.                 }
  207.                 else if(u32RxData == PS2CMD_ENABLE_DATA_REPORT)
  208.                 {
  209.                     printf("Host->Device: Enable data report\n");

  210.                     g_dataReportEnable = 1;
  211.                     g_cmd[0] = 0;

  212.                     /* Set the timer for g_sampleRate */
  213.                     /* The sample rate could be 10 ~ 200 samples/sec */
  214.                     SysTick_Config(SystemCoreClock / g_sampleRate);

  215.                     /* Wait Tx ready */
  216.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  217.                     {
  218.                         PS2_Write(&u32PS2ACK, 1);

  219.                         printf("Device->Host: ACK\n");
  220.                     }
  221.                 }
  222.                 else if(u32RxData == PS2CMD_DISABLE_DATA_REPORT)
  223.                 {
  224.                     printf("Host->Device: Disable data report\n");

  225.                     g_dataReportEnable = 0;
  226.                     g_cmd[0] = 0;

  227.                     SysTick->CTRL = 0;

  228.                     /* Wait Tx ready */
  229.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  230.                     {
  231.                         PS2_Write(&u32PS2ACK, 1);

  232.                         printf("Device->Host: ACK\n");
  233.                     }
  234.                 }
  235.                 else if(u32RxData == PS2CMD_SET_RESOLUTION)
  236.                 {
  237.                     printf("Host->Device: Set resolution\n");

  238.                     g_cmd[0] = PS2CMD_SET_RESOLUTION;

  239.                     /* Wait Tx ready */
  240.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  241.                     {
  242.                         PS2_Write(&u32PS2ACK, 1);

  243.                         printf("Device->Host: ACK\n");
  244.                     }
  245.                 }
  246.                 else if(u32RxData == PS2CMD_STATUS_REQUEST)
  247.                 {
  248.                     printf("Host->Device: PS2CMD_STATUS_REQUEST\n");

  249.                     g_cmd[0] = 0;

  250.                     /* Wait Tx ready */
  251.                     if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  252.                     {
  253.                         u32TxData = ((0x64 << 24) | u32PS2ACK);
  254.                         PS2_Write(&u32TxData, 4);

  255.                         printf("Device->Host: ACK\n");
  256.                     }
  257.                 }
  258.             }
  259.         }
  260.     }

  261.     /* TXINT */
  262.     if(PS2_GET_INT_FLAG(PS2_PS2INTID_TXINT_Msk))
  263.     {
  264.         PS2_CLR_TX_INT_FLAG();
  265.     }

  266. }


  267. void SYS_Init(void)
  268. {
  269.     /*---------------------------------------------------------------------------------------------------------*/
  270.     /* Init System Clock                                                                                       */
  271.     /*---------------------------------------------------------------------------------------------------------*/

  272.     /* Enable XT1_OUT (PF0) and XT1_IN (PF1) */
  273.     SYS->GPF_MFP |= SYS_GPF_MFP_PF0_XT1_OUT | SYS_GPF_MFP_PF1_XT1_IN;

  274.     /* Enable Internal RC 22.1184MHz clock */
  275.     CLK_EnableXtalRC(CLK_PWRCON_OSC22M_EN_Msk);

  276.     /* Waiting for Internal RC clock ready */
  277.     CLK_WaitClockReady(CLK_CLKSTATUS_OSC22M_STB_Msk);

  278.     /* Switch HCLK clock source to Internal RC and HCLK source divide 1 */
  279.     CLK_SetHCLK(CLK_CLKSEL0_HCLK_S_HIRC, CLK_CLKDIV_HCLK(1));

  280.     /* Enable external XTAL 12MHz clock */
  281.     CLK_EnableXtalRC(CLK_PWRCON_XTL12M_EN_Msk);

  282.     /* Waiting for external XTAL clock ready */
  283.     CLK_WaitClockReady(CLK_CLKSTATUS_XTL12M_STB_Msk);

  284.     /* Set core clock as PLL_CLOCK from PLL */
  285.     CLK_SetCoreClock(PLL_CLOCK);

  286.     /* Enable UART module clock */
  287.     CLK_EnableModuleClock(UART0_MODULE);

  288.     /* Enable UART module clock */
  289.     CLK_EnableModuleClock(PS2_MODULE);

  290.     /* Select IP clock source */
  291.     CLK->CLKSEL1 &= ~CLK_CLKSEL1_UART_S_Msk;
  292.     CLK->CLKSEL1 |= CLK_CLKSEL1_UART_S_HXT;

  293.     /* Update System Core Clock */
  294.     SystemCoreClockUpdate();

  295.     /*---------------------------------------------------------------------------------------------------------*/
  296.     /* Init I/O Multi-function                                                                                 */
  297.     /*---------------------------------------------------------------------------------------------------------*/
  298.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  299.     SYS->GPB_MFP = SYS_GPB_MFP_PB0_UART0_RXD | SYS_GPB_MFP_PB1_UART0_TXD;

  300.     /* Set PF multi-function pins for PS2 PS2_DAT and PS2_CLK */
  301.     SYS->GPF_MFP |= (SYS_GPF_MFP_PF2_PS2_DAT | SYS_GPF_MFP_PF3_PS2_CLK);
  302. }

  303. void UART0_Init(void)
  304. {
  305.     /*---------------------------------------------------------------------------------------------------------*/
  306.     /* Init UART                                                                                               */
  307.     /*---------------------------------------------------------------------------------------------------------*/
  308.     UART_Open(UART0, 115200);
  309. }

  310. void PS2_Init(void)
  311. {
  312.     PS2_Open();

  313.     PS2_EnableInt(PS2_PS2CON_RXINTEN_Msk | PS2_PS2CON_TXINTEN_Msk);
  314.     NVIC_EnableIRQ(PS2_IRQn);
  315. }

  316. int main(void)
  317. {
  318.     /* Unlock protected registers */
  319.     SYS_UnlockReg();

  320.     /* Init System, IP clock and multi-function I/O */
  321.     SYS_Init();

  322.     /* Lock protected registers */
  323.     SYS_LockReg();

  324.     /* Init UART0 for printf */
  325.     UART0_Init();

  326.     /* Init PS2 device */
  327.     PS2_Init();

  328.     g_cmd[0] = 0;

  329.     printf("\n\n");
  330.     printf("+-----------------------------------------------------------+\n");
  331.     printf("|  PS2 Demo Code Test                                       |\n");
  332.     printf("+-----------------------------------------------------------+\n");
  333.     printf("|  Description :                                            |\n");
  334.     printf("|    The demo code will show the cursor moving on the       |\n");
  335.     printf("|    screen.                                                |\n");
  336.     printf("+-----------------------------------------------------------+\n");

  337.     while(1)
  338.     {
  339.         if(g_opMode == PS2MOD_RESET)
  340.         {
  341.             if(g_CMD_RESET)
  342.             {
  343.                 g_CMD_RESET = 0;

  344.                 /* Delay 500ms*/
  345.                 CLK_SysTickDelay(500000);

  346.                 if(PS2_GET_STATUS() & PS2_PS2STATUS_TXEMPTY_Msk)
  347.                 {
  348.                     /* Transmit PASS & Device ID */
  349.                     u32TxData = ((DEVICE_ID << 8) | u32PS2PASS);
  350.                     PS2_Write(&u32TxData, 2);
  351.                     printf("Device->Host: DEVICE ID\n");

  352.                     /* TXINT */
  353.                     while(PS2_GET_INT_FLAG(PS2_PS2INTID_TXINT_Msk))
  354.                     {
  355.                         PS2_CLR_TX_INT_FLAG();
  356.                     }
  357.                 }
  358.             }
  359.             else
  360.             {
  361.                 /* Reset to default configuration */
  362.                 g_sampleRate = 100;
  363.                 g_resolution = 4;
  364.                 g_scalling = 1;
  365.                 g_dataReportEnable = 0;

  366.                 /* Enter Stream mode */
  367.                 g_opMode = PS2MOD_STREAM;
  368.             }
  369.         }
  370.     }
  371. }






 楼主| huahuagg 发表于 2019-8-28 23:19 | 显示全部楼层
USB支持热插拨,而PS2接口不可以,所以论便捷性USB完胜PS2,其次就是鼠标USB接口的传输率比PS2要高一些,主要体现在游戏里的鼠标移动上,不过一般来说感觉不出来,至于键盘接口是USB或者是PS2那就没什么区别了,不过最主要还是USB支持热插拨,这点很重要,而且USB接口也是主流标准了,PS2已经完全失去意义了。包括价格上USB也比PS2贵不了多少钱,所以USB接口完胜。
但:

在键位组合上,PS/2可以实现全无冲突,USB下只能是最多6个可以同时按下。

为什么?  简单来说: USB键盘的一个数据包只有8个字节(为什么只有8个,这是因为协议规定,为什么协议这么规定,是因为早期的时候USB速度慢,使用中断传输一个包最大就8个字节),其中2个字节标记状态,其余6个字节用来记录当前按下或者弹起的按键的扫描码,所以,USB键盘最多同时描述6个按键的状态。

在稳定上,PS/2还是要好过USB的,当然USB的话虽没有PS/2的稳定,可有不错的扩展。如可以在USB的键盘中加入USB HUB
 楼主| huahuagg 发表于 2019-8-28 23:19 | 显示全部楼层
不过PS2可以支持老型号的键盘和鼠标,而且更加通用。
 楼主| huahuagg 发表于 2019-8-28 23:20 | 显示全部楼层
所以在支持老设备上PS2更好,很多老的电脑,不支持开机使用USB,想配置BIOS都要用PS2键盘。
zhuotuzi 发表于 2019-8-28 23:57 | 显示全部楼层
这是通过PS2跟电脑通信,还是跟键盘通信
yiy 发表于 2019-8-28 23:58 | 显示全部楼层
看样子是读取的鼠标信息。
yiy 发表于 2019-8-28 23:59 | 显示全部楼层
也就是作为主机,跟PS2设备通信。
zhuotuzi 发表于 2019-8-29 00:01 | 显示全部楼层
通过PS2鼠标控制一个变量,来改变光标的位置。
mintspring 发表于 2019-8-29 00:27 | 显示全部楼层
看起来有点小复杂。
玛尼玛尼哄 发表于 2019-8-29 00:30 | 显示全部楼层
这个数据过来是什么格式呢。
phosphate 发表于 2019-8-30 15:39 | 显示全部楼层
现在鼠标键盘基本上都是USB的了吧
 楼主| huahuagg 发表于 2019-9-5 15:08 | 显示全部楼层
phosphate 发表于 2019-8-30 15:39
现在鼠标键盘基本上都是USB的了吧

是的,只不过可以用单片机实现这个功能,不足为奇,这个PS2协议很简单的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

159

主题

1430

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部