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); 
		} 
	} 
}