Now i am using a chip imx6ull and run the platform without OS, i tried to config the module TSC following the code "imx6ull_tsc.c" , BUT:
a) i always got zero when reading register TSC->INT_STATUS.
b) i measured the TSC pin by oscilloscope,there only a level change form 0 to 3.3 when i touch the panel
So, i doubt maybe something wrong ,Can anybody please review my following code to see what was the problem ? or does anyone have the sample code(no os code ) to let it work properly ?
by the way, the other modules ,such as UART\GPIO \DDR works properly now.
Any help from you will be greatly apprecitated !
/*!
* @}
*/ /* end of group ADC_Register_Masks */
/* ADC - Peripheral instance base addresses */
/** Peripheral ADC1 base address */
#define ADC1_BASE (0x2198000u)
/** Peripheral ADC1 base pointer */
#define ADC1 ((ADC_Type *)ADC1_BASE)
/** Array initializer of ADC peripheral base addresses */
#define ADC_BASE_ADDRS { 0u, ADC1_BASE }
/** Array initializer of ADC peripheral base pointers */
#define ADC_BASE_PTRS { (ADC_Type *)0u, ADC1 }
/** Interrupt vectors for the ADC peripheral type */
#define ADC_IRQS { NotAvail_IRQn, ADC1_IRQn }
/*!
* @}
*/ /* end of group ADC_Peripheral_Access_Layer */
/*!
* @}
*/ /* end of group TSC_Register_Masks */
/* TSC - Peripheral instance base addresses */
/** Peripheral TSC base address */
#define TSC_BASE (0x2040000u)
/** Peripheral TSC base pointer */
#define TSC ((TSC_Type *)TSC_BASE)
/** Array initializer of TSC peripheral base addresses */
#define TSC_BASE_ADDRS { TSC_BASE }
/** Array initializer of TSC peripheral base pointers */
#define TSC_BASE_PTRS { TSC }
/** Interrupt vectors for the TSC peripheral type */
#define TSC_IRQS { TSC_IRQn }
/*!
* @}
*/ /* end of group TSC_Peripheral_Access_Layer */
/* ADC configuration registers field define */
#define ADC_AIEN (0x1 << 7)
#define ADC_CONV_DISABLE 0x1F
#define ADC_CAL (0x1 << 7)
#define ADC_CALF 0x2
#define ADC_12BIT_MODE (0x2 << 2)
#define ADC_IPG_CLK 0x00
#define ADC_CLK_DIV_8 (0x03 << 5)
#define ADC_SHORT_SAMPLE_MODE (0x0 << 4)
#define ADC_HARDWARE_TRIGGER (0x1 << 13)
#define SELECT_CHANNEL_4 0x04
#define SELECT_CHANNEL_1 0x01
#define DISABLE_CONVERSION_INT (0x0 << 7)
/*
* TSC module need ADC to get the measure value. So
* before config TSC, we should initialize ADC module.
*/
static int imx6ul_adc_init(void)
{
printf("\r\n%s \r\n",__FUNCTION__);
ADC1->CFG |= ADC_12BIT_MODE | ADC_IPG_CLK;
ADC1->CFG |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE;
ADC1->CFG &= ~ADC_HARDWARE_TRIGGER;
/* enable calibration interrupt */
ADC1->HC[0] |= ADC_AIEN;
ADC1->HC[0] |= ADC_CONV_DISABLE;
/* start ADC calibration */
ADC1->GC |= ADC_CAL;
if (ADC1->GS & ADC_CALF) {
printf("\r\n ADC calibration failed\n");
return -1;
}
/* TSC need the ADC work in hardware trigger */
ADC1->CFG |= ADC_HARDWARE_TRIGGER;
return 0;
}
/*
* This is a TSC workaround. Currently TSC misconnect two
* ADC channels, this function remap channel configure for
* hardware trigger.
*/
static void imx6ul_tsc_channel_config(void)
{
ADC1->HC[0] = DISABLE_CONVERSION_INT;
ADC1->HC[1] = DISABLE_CONVERSION_INT | SELECT_CHANNEL_4;
ADC1->HC[2] = DISABLE_CONVERSION_INT;
ADC1->HC[3] = DISABLE_CONVERSION_INT | SELECT_CHANNEL_1;
ADC1->HC[4] = DISABLE_CONVERSION_INT;
}
/* TSC registers */
#define REG_TSC_BASIC_SETING 0x00
#define REG_TSC_PRE_CHARGE_TIME 0x10
#define REG_TSC_FLOW_CONTROL 0x20
#define REG_TSC_MEASURE_VALUE 0x30
#define REG_TSC_INT_EN 0x40
#define REG_TSC_INT_SIG_EN 0x50
#define REG_TSC_INT_STATUS 0x60
#define REG_TSC_DEBUG_MODE 0x70
#define REG_TSC_DEBUG_MODE2 0x80
/* TSC configuration registers field define */
#define DETECT_4_WIRE_MODE (0x0 << 4)
#define AUTO_MEASURE 0x1
#define MEASURE_SIGNAL 0x1
#define DETECT_SIGNAL (0x1 << 4)
#define VALID_SIGNAL (0x1 << 8)
#define MEASURE_INT_EN 0x1
#define MEASURE_SIG_EN 0x1
#define VALID_SIG_EN (0x1 << 8)
#define DE_GLITCH_2 (0x2 << 29)
#define START_SENSE (0x1 << 12)
#define TSC_DISABLE (0x1 << 16)
#define DETECT_MODE 0x2
/*
* TSC setting, confige the pre-charge time and measure delay time.
* different touch screen may need different pre-charge time and
* measure delay time.
*/
static void imx6ul_tsc_set()
{
int basic_setting = 0;
int start;
TSC->BASIC_SETTING |= 0xFFFFU << 8;
TSC->BASIC_SETTING |= DETECT_4_WIRE_MODE | AUTO_MEASURE;
TSC->DEBUG_MODE2 |= DE_GLITCH_2;
TSC->PS_INPUT_BUFFER_ADDR |= 0xFFFFU;
TSC->INT_EN |= 0xFFFFU;
TSC->INT_SIG_EN |= MEASURE_INT_EN; /* 测量信号使能 */
TSC->INT_SIG_EN |= MEASURE_SIG_EN; /* 有效信号使能 */
TSC->INT_SIG_EN |= VALID_SIG_EN; /* 有效信号使能 */
/* start sense detection */
TSC->FLOW_CONTROL |= START_SENSE; /* 启动触摸检测, 当检测到触摸时,开始测量 */
TSC->FLOW_CONTROL &= ~TSC_DISABLE; /* 使能TSC */
}
static bool imx6ull_tsc_gpio_init()
{
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO01_GPIO1_IO01,0);
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO02_GPIO1_IO02,0);
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO03_GPIO1_IO03,0);
IOMUXC_SetPinMux(IOMUXC_GPIO1_IO04_GPIO1_IO04,0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO01_GPIO1_IO01,0xB0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO02_GPIO1_IO02,0xB0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO03_GPIO1_IO03,0xB0);
IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO04_GPIO1_IO04,0xB0);
}
/* Delay some time (max 2ms), wait the pre-charge done. */
static bool tsc_wait_detect_mode()
{
unsigned int count = 0;
unsigned int state_machine;
do {
if (count > 10) // 10 * 200 Us
return false;
delayus(200);
count ++;
state_machine = (TSC->DEBUG_MODE2 >> 20) & 0x7; /**/
} while (state_machine != 0x02); /* */
delayus(200);
return true;
}
void imx6ull_tsc_get_tsc(int *nX, int*nY, int* event)
{
int status;
int value;
int x, y;
int start;
status = TSC->INT_STATUS;
printf("\r\n%s, status[%x]\r\n",__FUNCTION__, status);
/* write 1 to clear the bit measure-signal */
TSC->INT_STATUS |= MEASURE_SIGNAL;
TSC->INT_STATUS |= DETECT_SIGNAL;
/* It's a HW self-clean bit. Set this bit and start sense detection */
TSC->FLOW_CONTROL |= START_SENSE;
*event = 0;
if (status & MEASURE_SIGNAL) {
value = TSC->MEASEURE_VALUE;
x = (value >> 16) & 0x0fff;
y = value & 0x0fff;
/*
* In detect mode, we can get the xnur gpio value,
* otherwise assume contact is stiull active.
*/
if (!tsc_wait_detect_mode()) {
printf("\r\n %s touch on x[%d] y[%d]\r\n",__FUNCTION__ ,x ,y );
*nX = x;
*nY = y;
*event = 1;
} else {
printf("\r\n %s touch off \r\n",__FUNCTION__ );
}
}
}
int imx6ull_tsc_init()
{
int err;
imx6ull_tsc_gpio_init();
err = imx6ul_adc_init();
if (err){
printf("\r\n%s init fail\r\n",__FUNCTION__);
return err;
}
imx6ul_tsc_channel_config();
imx6ul_tsc_set();
return 0;
}