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

📄 touchscreen.c

📁 AT91SAM9261_EK范例程序
💻 C
字号:
/*
 *  drivers/input/touchscreen/at91_ads7843e_ts.c
 *
 *  Touchscreen driver for AT91SAM9261 toush screen
 *
 *  Copyright (c) 2005 M. Amine SAYA, ATMEL Rousset, France.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 */
#include "AT91SAM9261_init.h"
#include "main.h"
#include <stdio.h>
#include <string.h>
#include "touchscreen.h"
#include "com.h"

volatile unsigned char bPenIRQ = FALSE;

//*----------------------------------------------------------------------------
//* \fn    AT91F_TSC_SPI_SendRecv
//* \brief Generic function to send a command to the touchscreen controller
//*----------------------------------------------------------------------------
unsigned int AT91F_TSC_SPI_SendRecv (unsigned char bCmd)
{
 	static AT91PS_PDC pPdc = (AT91PS_PDC) &(AT91C_BASE_SPI0->SPI_RPR);
 	volatile unsigned int dStatus;

	unsigned int  uResult = 0, uTimeout = 0;
	unsigned char bResult[3];
	
	bResult[0] = bCmd;
	bResult[1] = 0;
	bResult[2] = 0;
	
 	// Send Command and data through the SPI
 	AT91F_PDC_DisableRx(pPdc);
 	AT91F_PDC_SetRx(pPdc, (char *) bResult, 3);

	AT91F_PDC_DisableTx(pPdc);
	AT91F_PDC_SetTx(pPdc, (char *) bResult, 3);

 	AT91F_PDC_EnableRx(pPdc);
	AT91F_PDC_EnableTx(pPdc);


	do {
		dStatus = AT91C_BASE_SPI0->SPI_SR;
		uTimeout++;
	}
 	while ((( dStatus & AT91C_SPI_RXBUFF) != AT91C_SPI_RXBUFF) && (uTimeout < AT91C_TOUCHSCREEN_TIMEOUT));

	AT91F_PDC_DisableTx(pPdc);
	AT91F_PDC_DisableRx(pPdc);	

	uResult = ((unsigned int)bResult[1] << 8) | ((unsigned int)bResult[2]);
	uResult = uResult >> 3;

	return uResult;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_Touchscreen_Init
//* \brief
//*----------------------------------------------------------------------------
void AT91F_Touchscreen_Init(void)
{
	volatile unsigned int uDummy;
		
   	AT91F_PIO_CfgInput(AT91C_BASE_PIOA,	AT91C_PA6_SPI0_NPCS3);	// Avoids conflicts between PA3 and PA6 when booting on dataflash card!!!
   	AT91F_PIO_CfgInput(AT91C_BASE_PIOA,	AT91C_PA3_SPI0_NPCS0);	// Avoids conflicts between PA3 and PA6 when booting on dataflash card!!!

    // Open PIO for SPI0
	AT91F_PIO_CfgPeriph(
		AT91C_BASE_PIOA, // PIO controller base address
		((unsigned int) AT91C_PA0_SPI0_MISO   ) |
		((unsigned int) AT91C_PA2_SPI0_SPCK   ) |
		((unsigned int) AT91C_PA1_SPI0_MOSI   ),
		((unsigned int) AT91C_PA28_SPI0_NPCS2  )); // Peripheral B

    // Enables the SPI0 Clock
    AT91F_SPI0_CfgPMC();

    AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIDIS;
	AT91F_PDC_Close (AT91C_BASE_PDC_SPI0);

    // Reset SPI0
    AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;

    // Configure SPI0 in Master Mode with no CS selected
    AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;

    // Configure CSx
    *(AT91C_SPI0_CSR + 2) = AT91C_SPI_NCPHA |
    						(AT91C_SPI_DLYBS & TS_DLYBS) |
    						(AT91C_SPI_DLYBCT & TS_DLYBCT) |
    						((AT91C_MASTER_CLOCK_FOR_I2S / AT91C_TOUCHSCREEN_SPI_CLK) << 8);	//AT91C_MASTER_CLOCK_FOR_I2S

    // Choose NCS2
    AT91C_BASE_SPI0->SPI_MR &= 0xFFF0FFFF;
    AT91C_BASE_SPI0->SPI_MR |= ((AT91C_SPI_PCS2_DATAFLASH << 16) & AT91C_SPI_PCS);

    // SPI_Enable
    AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;

   	for (uDummy=0; uDummy<100000; uDummy++);

	uDummy = AT91C_BASE_SPI0->SPI_SR;	
	uDummy = AT91C_BASE_SPI0->SPI_RDR;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_IRQ0_Handler
//* \brief
//*----------------------------------------------------------------------------
__arm __irq void AT91F_IRQ0_Handler(void)
{
	bPenIRQ = TRUE;
  AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_Test_TouchScreen
//* \brief Test TouchScreen controller
//*----------------------------------------------------------------------------
unsigned int AT91F_Test_TouchScreenCalibration(unsigned char bPosition)
{
	unsigned int  x_pos, y_pos;
	volatile unsigned int dummy;
	unsigned char bCmd, bNbTry = 0;
	char info[40];


	lcd_clearscreen();
			
	sprintf (info, "TouchScreen Calibration");
	AT91F_DisplayLCD(info, 25, 1*AT91C_FONT_HEIGHT);
	sprintf (info, "Click on the '+'");
	AT91F_DisplayLCD(info, 45, 3*AT91C_FONT_HEIGHT);
	
	if (bPosition == AT91C_TEST_LEFT)
	{
		sprintf (info, "+");
		AT91F_DisplayLCD(info, 10, 19*AT91C_FONT_HEIGHT);

		sprintf (info, "at bottom left");
	}
	else
	{	
	 	sprintf (info, "+");
		AT91F_DisplayLCD(info, 220, 19*AT91C_FONT_HEIGHT);

		sprintf (info, "at bottom right");
	}
		
	AT91F_DisplayLCD(info, 45, 4*AT91C_FONT_HEIGHT);
		
	while (bNbTry++ < 5)
	{
		AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_IRQ0);
		// Tempo to avoid a too fast interrupt
		for (dummy=0; dummy < AT91C_TOUCHSCREEN_TIMEOUT/2; dummy++);

		bPenIRQ = FALSE;		
		while (bPenIRQ == FALSE)
		{
		    if(AT91F_US_RxReady((AT91PS_USART)AT91C_BASE_DBGU))
		    {
		    	dummy = AT91F_US_GetChar((AT91PS_USART)AT91C_BASE_DBGU);
				return FALSE;
			}
		}
		AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_IRQ0);

		// power-up
		bCmd = (1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1 ;
		AT91F_TSC_SPI_SendRecv(bCmd);
	
		// Get X position
		bCmd = (1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1 ;
		x_pos = AT91F_TSC_SPI_SendRecv(bCmd);

		// Get Y position
		bCmd = (5 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1;
		y_pos = AT91F_TSC_SPI_SendRecv(bCmd);

		// power-down
		bCmd = (1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START ;
		AT91F_TSC_SPI_SendRecv(bCmd);

		// power-down
		bCmd = (5 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START ;
		AT91F_TSC_SPI_SendRecv(bCmd);

		if (bPosition == AT91C_TEST_LEFT)
		{
			if ((x_pos > X_LEFT_MIN) && (x_pos < X_LEFT_MAX) &&
				(y_pos > Y_LOW_MIN) && (y_pos < Y_LOW_MAX))
			{
				sprintf(message, "-I- Test Left OK      x_pos : %x   y_pos : %x\n\r", x_pos, y_pos);
			    AT91F_DBGU_Printk(message);
				return TRUE;
			}	
		}
		else
		{
			if ((x_pos > X_RIGHT_MIN) && (x_pos < X_RIGHT_MAX) &&
				(y_pos > Y_LOW_MIN) && (y_pos < Y_LOW_MAX))
			{
				sprintf(message, "-I- Test Right OK     x_pos : %x   y_pos : %x\n\r", x_pos, y_pos);
			    AT91F_DBGU_Printk(message);
				return TRUE;
			}			
		}
		
		sprintf(message, "-I- x_pos :%x    y_pos : %x\n\r", x_pos, y_pos);
	    AT91F_DBGU_Printk(message);
	
		sprintf (info, "FALSE -> Try again");
		AT91F_DisplayLCD(info, 45, 6*AT91C_FONT_HEIGHT);
		sprintf (info, "Still %d try", 5 - bNbTry);
		AT91F_DisplayLCD(info, 65, 7*AT91C_FONT_HEIGHT);

	}

	if (bPosition == AT91C_TEST_LEFT)
		sprintf(message, "-E- Test Left:  last x_pos : %x   last y_pos : %x\n\r", x_pos, y_pos);
	else
		sprintf(message, "-E- Test Right: last x_pos : %x   last y_pos : %x\n\r", x_pos, y_pos);

    AT91F_DBGU_Printk(message);
	
	return FALSE;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_Test_TouchScreen
//* \brief Test TouchScreen controller
//*----------------------------------------------------------------------------
void AT91F_Test_TouchScreen(void)
{
	char bResult = FALSE;
	char info[40];
  typedef void (*Fpvoid)(void);

	AT91F_PIO_CfgPullup(AT91C_BASE_PIOC, 0xFFFFFFFF);
	
	// Init ADS7843E TouchScreen controller
	AT91F_Touchscreen_Init();

	AT91F_PIO_CfgInputFilter(AT91C_BASE_PIOC,AT91C_PC2_IRQ0);
	// Init PIOC2 = PENIRQ
	AT91F_PIO_CfgPeriph(
		AT91C_BASE_PIOC,
		0,
		((unsigned int) AT91C_PC2_IRQ0)); // Peripheral B

	// Configure AIC controller for the next IRQ0 interrupt
	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,   // Level sensitive
		(Fpvoid) AT91F_IRQ0_Handler);
	
	// Enable IRQ0 interrupt in AIC
	AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_IRQ0);

	// Wait
    AT91F_DBGU_Printk("-I- LCD/Touch Screen Panel\n\r");
    AT91F_DBGU_Printk("Use the stylus to click on the '+'...\n\r");
    AT91F_DBGU_Printk("\nNote: If application is in a deadlock, hit a key!!!\n\r");

	if ((AT91F_Test_TouchScreenCalibration(AT91C_TEST_LEFT)  == TRUE) &&
		(AT91F_Test_TouchScreenCalibration(AT91C_TEST_RIGHT) == TRUE))
	{
		bResult = TRUE;
	}
	
	lcd_clearscreen();
		
	sprintf (info, "TouchScreen Calibration");
	AT91F_DisplayLCD(info, 25, 1*AT91C_FONT_HEIGHT);

	if (bResult == TRUE)
	{
		sprintf (info, "TEST OK");
		AT91F_DisplayLCD(info, 80, 3*AT91C_FONT_HEIGHT);

	    AT91F_DBGU_Printk("-I- TEST OK\n\r");
	}
	else
	{
		sprintf (info, "TEST FAIL");
		AT91F_DisplayLCD(info, 80, 3*AT91C_FONT_HEIGHT);
	
	    AT91F_DBGU_Printk("-E- TEST Failed\n\r");
	}
	
	// Disable IRQ0 interrupt in AIC
	AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_IRQ0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -