📄 main.c
字号:
//*----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name : main.c
//* Object : main application written in C
//* Creation : Hi 11/18/2002
//*
//*----------------------------------------------------------------------------
#include "AT91RM9200.h"
#include "lib_AT91RM9200.h"
#include "keyboard.h"
#include <stdio.h>
//* Interrupt Handlers
extern void AT91F_IRQ0_ASM_HANDLER(void);
extern void AT91F_SPI_ASM_HANDLER(void);
extern void AT91F_ST_ASM_HANDLER(void);
extern void AT91F_DBGU_Printk(char *buffer);
extern void AT91F_OpenKeyBoard(AT91PS_KEYBOARD );
extern void AT91F_OpenMouse(AT91PS_MOUSE );
//* Message buffer
char MsgBuffer[50];
//* system timer counter
unsigned int StTick = 0;
//* PS2, KEYBOARD and MOUSE structures
AT91S_PS2CTRL SPs2Ctrl;
AT91S_KEYBOARD SKeyBoard;
AT91S_MOUSE SMouse;
//* Buffer allocated to the PS2 controller
unsigned char PS2Fifo[4] = {0,0,0,0};
//*----------------------------------------------------------------------------
//* \fn AT91F_CfgSPIForPs2
//* \brief Config SPI for PS2 controller
//*----------------------------------------------------------------------------
void AT91F_CfgSPIForPs2 (void)
{
//* Reset the SPI
AT91F_SPI_Reset(AT91C_BASE_SPI);
//* Configure SPI in Master Mode
AT91F_SPI_CfgMode(AT91C_BASE_SPI, AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | 0xD0000);
//* Configure SPI CS1
AT91F_SPI_CfgCs(1, AT91C_SPI_CPOL | (0x78 << 24) | (SPICLK_FOR_PS2 << 8));
//* Enable the SPI
AT91F_SPI_Enable(AT91C_BASE_SPI);
//* Enable the PDC transfert
AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI);
AT91F_PDC_EnableRx(AT91C_BASE_PDC_SPI);
}
//*------------------------------------------------------------------------------
//* \fn AT91F_KEYDETECT_HANDLER
//* \brief This function is invoked by AT91F_IRQ0_ASM_HANDLER
//* This function is for demonstration purpose only
//*------------------------------------------------------------------------------
void AT91F_KEYDETECT_HANDLER(void)
{
// SPI NPCS1 driven at 0
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, AT91C_PIO_PA4);
SPs2Ctrl.IsKeyToRead = AT91C_KEY_PRESSED;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_FlushPs2Controller
//* \brief This function allows to flush the PS2 controller
//* This function is for demonstration purpose only
//*----------------------------------------------------------------------------
void AT91F_FlushPs2Controller(void)
{
int i = 0;
//* 64 dummy write
while(i++ < 64)
*(AT91C_SPI_TDR) = 0;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_KEYBOARD_HANDLER
//* \brief This function is invoked by AT91F_ASM_SPI_Handler
//* This function is for demonstration purpose only
//*----------------------------------------------------------------------------
void AT91F_PS2_HANDLER()
{
// SPI NPCS1 driven at 1
AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, AT91C_PIO_PA4);
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, AT91C_PIO_PA4);
AT91F_SPI_DisableIt(AT91C_BASE_SPI, AT91C_SPI_RXBUFF);
if((SPs2Ctrl.pPs2_Fifo[0] & AT91C_ISKEYBOARD_FRAME) && (SPs2Ctrl.pPs2_Fifo[0] & AT91C_ISKEYUP) )
SKeyBoard.Handler(&SKeyBoard, SPs2Ctrl.pPs2_Fifo);
else
if(!(SPs2Ctrl.pPs2_Fifo[0] & AT91C_ISMOUSE_FRAME))
SMouse.Handler(&SMouse, SPs2Ctrl.pPs2_Fifo);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_InitKeyBoards
//* \brief This function is invoked by main
//* This function is for demonstration purpose only
//*----------------------------------------------------------------------------
void AT91F_InitPS2Ctrl(void)
{
// Init SPI Init for Keyboard interface
AT91F_SPI_CfgPIO();
AT91F_SPI_CfgPMC();
AT91F_CfgSPIForPs2();
// Drive the SPI NPCS1 as an output
AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, AT91C_PIO_PA4);
// NPCS1 output = 1
AT91F_PIO_SetOutput( AT91C_BASE_PIOA, AT91C_PIO_PA4);
// Configure PIOB29 as peripheral
AT91F_PIO_CfgPeriph(
AT91C_BASE_PIOB, // PIO controller base address
((unsigned int) AT91C_PB29_IRQ0),
0); // Peripheral B
AT91F_FlushPs2Controller();
// Configure SPI interrupt
AT91F_AIC_ConfigureIt (
AT91C_BASE_AIC, // AIC base address
AT91C_ID_SPI, // System peripheral ID
AT91C_AIC_PRIOR_HIGHEST, // Max priority
AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE, // Level sensitive
AT91F_SPI_ASM_HANDLER );
// Enable SPI interrupt
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SPI);
AT91F_AIC_ConfigureIt (
AT91C_BASE_AIC, // AIC base address
AT91C_ID_IRQ0, // System peripheral ID
AT91C_AIC_PRIOR_HIGHEST, // Max priority
AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED,
AT91F_IRQ0_ASM_HANDLER );
// Enable IRQ0 interrupt
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_IRQ0);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_OpenPs2Ctrl
//* \brief This function is invoked by main
//* This function is for demonstration purpose only
//*----------------------------------------------------------------------------
void AT91F_OpenPs2Ctrl(AT91PS_PS2CTRL pSPs2Ctrl, AT91PS_KEYBOARD pSkeyboard, AT91PS_MOUSE pSMouse)
{
pSPs2Ctrl->pPs2_Fifo = PS2Fifo;
pSPs2Ctrl->IsKeyToRead = AT91C_KEY_RELEASE;
if (pSkeyboard != NULL) {
pSPs2Ctrl->pSkeyBoard = pSkeyboard;
AT91F_OpenKeyBoard(pSkeyboard);
}
if (pSkeyboard != NULL) {
pSPs2Ctrl->pSMouse = pSMouse;
AT91F_OpenMouse(pSMouse);
}
}
//*----------------------------------------------------------------------------
//* \fn AT91F_ReadPs2
//* \brief This function is invoked by main
//* This function is for demonstration purpose only
//*----------------------------------------------------------------------------
void AT91F_ReadPs2(AT91PS_PS2CTRL pSPs2Ctrl)
{
// Configure the SPI PDC to receive the PS2 frame
AT91F_PDC_SendFrame(AT91C_BASE_PDC_SPI, (char *)(pSPs2Ctrl->pPs2_Fifo), 1, (char *)(pSPs2Ctrl->pPs2_Fifo), 4);
AT91F_PDC_ReceiveFrame(AT91C_BASE_PDC_SPI, (char *)(pSPs2Ctrl->pPs2_Fifo), 1, (char *)(pSPs2Ctrl->pPs2_Fifo), 4);
// Enable the SPI RX buffer full
AT91F_SPI_EnableIt(AT91C_BASE_SPI, AT91C_SPI_RXBUFF);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_ST_HANDLER
//* \brief This function is invoked by main
//* This function is for demonstration purpose only
//*----------------------------------------------------------------------------
void AT91F_ST_HANDLER(void)
{
volatile int StStatus;
// Read the system timer status register
StStatus = *(AT91C_ST_SR);
StTick++;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_PrintMouseKey
//* \brief This function is invoked by main
//* This function is for demonstration purpose only
//*----------------------------------------------------------------------------
void AT91F_PrintMouseKey(int MouseKey)
{
static int OldKey = 0;
if(OldKey == 0)
OldKey = MouseKey & 0x7;
switch((MouseKey & 0x07) | OldKey)
{
case AT91C_LEFT_BUTTONCLICK:
sprintf(MsgBuffer, "\n\r Left Button Down");
break;
case (AT91C_LEFT_BUTTONCLICK << 4):
sprintf(MsgBuffer, "\n\r Left Button Up");
break;
case AT91C_RIGHT_BUTTONCLICK:
sprintf(MsgBuffer, "\n\r Right Button Down");
break;
case (AT91C_RIGHT_BUTTONCLICK << 4):
sprintf(MsgBuffer, "\n\r Right Button Up");
break;
case AT91C_MIDDLE_BUTTONCLICK:
sprintf(MsgBuffer, "\n\r Middle Button Down");
break;
case (AT91C_MIDDLE_BUTTONCLICK << 4):
sprintf(MsgBuffer, "\n\r Middle Button click Up");
break;
default:
sprintf(MsgBuffer, "\n\r XPos= %3d, YPos= %3d",
(MouseKey & 0x0000FF00) >> 8,
(MouseKey & 0x00FF0000) >> 16
);
break;
}
OldKey = (MouseKey & 0x07 )<< 4;
AT91F_DBGU_Printk(MsgBuffer);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_PrintKeyBoardKey
//* \brief This function is invoked by main
//* This function is for demonstration purpose only
//*----------------------------------------------------------------------------
void AT91F_PrintKeyBoardKey(char Key)
{
sprintf(MsgBuffer, "\n\r KeyBoard Key = %c", Key);
AT91F_DBGU_Printk(MsgBuffer);
}
//*----------------------------------------------------------------------------
//* \fn main
//* \brief
//*
//*----------------------------------------------------------------------------
int main()
{
char car = 0;
int NbCarToRead;
int MouseKey;
static int WaitPS2 = 0;
AT91F_DBGU_Printk("\n\n\r-I- ======================================\n\r");
AT91F_DBGU_Printk("-I- AT91RM9200 Keyboard Test\n\r");
AT91F_DBGU_Printk("-I- --------------------------------------\n\r");
//* System Timer initialization
AT91F_ST_SetPeriodInterval(AT91C_BASE_ST, AT91C_ST_PITS);
AT91F_ST_EnableIt(AT91C_BASE_ST, AT91C_ST_PITS);
AT91F_AIC_ConfigureIt (
AT91C_BASE_AIC, // AIC base address
AT91C_ID_SYS, // System peripheral ID
AT91C_AIC_PRIOR_HIGHEST, // Max priority
AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, // Level sensitive
AT91F_ST_ASM_HANDLER );
//* Enable ST interrupt
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);
//* Init Ps2 controller
AT91F_InitPS2Ctrl();
AT91F_OpenPs2Ctrl(&SPs2Ctrl, &SKeyBoard, &SMouse);
while(1)
{
// If a PS2 event is detected ....
if (SPs2Ctrl.IsKeyToRead == AT91C_KEY_PRESSED)
{
// if a key is detected : wait between 50 micros and 5ms before reading the PS2 controller
if(!WaitPS2)
WaitPS2 = StTick+1;
if (StTick >= WaitPS2)
{
AT91F_ReadPs2(&SPs2Ctrl);
SPs2Ctrl.IsKeyToRead = AT91C_KEY_RELEASE;
WaitPS2 = 0;
}
}
if (SKeyBoard.IsKeyPressed(&SKeyBoard))
{
NbCarToRead = SKeyBoard.ReadKey(&SKeyBoard, &car);
AT91F_PrintKeyBoardKey(car);
}
if (SMouse.IsMouseMove(&SMouse))
{
SMouse.ReadMouse(&SMouse, &MouseKey);
AT91F_PrintMouseKey(MouseKey);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -