⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于at92rm9200芯片的键盘驱动程序例程
💻 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 + -