📄 touchscreen.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 + -