www.pudn.com > AT91RM9200-BasicSPIKeyboard-ARM1_2-2_0.zip > 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//* 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); } } }