/************************************************************************ * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved. * @file ctp.c * @author UartTFT Application Team * @version V1.0.0 * @date 2023-02-24 * @brief *************************************************************************/ #include "ctp.h" #include "i2c_drv.h" #include "eport_drv.h" #include "spi_drv.h" #include "tp_drv.h" uint8_t fingerNumber = 0; uint8_t ctp_active_index = 0; uint8_t ctp_press_t; void Checksum(uint8_t *p) // Configuration information check 0x80ff (checked algorithm is correct) { int i = 0; unsigned int sum_buffer = 0; for (; i < 184; i++) { sum_buffer += *(p + i); } *(p + 184) = ~sum_buffer + 1; // printf("%x\r\n", *(p + 184)); } /* Initialization function of IO port related to capacitive touch screen */ void CTP_Init(void) { CTP_io_Init(); gTpInfo.scan = FT5216_Scan; } /*********************************************************************************** * Function Name : CT_Read_Nbyte * Description : Read touch screen register * Input : - sla_add : Device address - t_add : Register address to be read - n : Number of data to be read - *s : Address for storing data to be read * Output : None * Return : Success:1 Fail:0 ************************************************************************************/ uint8_t CT_Read_Nbyte(const uint8_t sla_add, const uint16_t add, uint16_t n, uint8_t *s) { uint8_t temps; uint16_t tempn; I2C_start(); // Start CTI2C bus I2C_write_byte(sla_add | CT_WRITE_MASK); if (gt911flag == 1) I2C_write_byte(add >> 8); I2C_write_byte(add); I2C_stop(); I2C_start(); // Start CTI2C bus again I2C_write_byte(sla_add | CT_READ_MASK); for (tempn = 0; tempn < n; tempn++) { /*If you have read all the data, do not send the reply signal, but send the non-reply bit and stop bit directly */ if (tempn + 1 < n) { temps = I2C_read_byte(0); *(s + tempn) = temps; } } temps = I2C_read_byte(1); *(s + tempn) = temps; I2C_stop(); return CT_COM_OK; } /*********************************************************************************** * Function Name : CT_Write_Nbyte * Description : Write touch screen register * Input : - sla_add : Device address - t_add : Register address to be written - n : Number of data to be written - *s : Address to store data to be written * Output : None * Return : Success:1 Fail:0 ************************************************************************************/ uint8_t CT_Write_Nbyte(const uint8_t sla_add, const uint16_t add, uint16_t n, const uint8_t *s) { uint16_t tempn; I2C_start(); // Start TP bus I2C_write_byte(sla_add | CT_WRITE_MASK); // Send addressing bytes if (gt911flag == 1) I2C_write_byte(add >> 8); I2C_write_byte(add); // Send the starting address to write for (tempn = 0; tempn < n; tempn++) I2C_write_byte(s[tempn]); /*debug for(tempn=0;tempnCT_CACK_TIMEOUT)//在规定时间cack_timeout内收不到应答信号,返回出错信号 return CT_ACK_FAIL; } } */ I2C_stop(); // TP stop return CT_COM_OK; } //---------------------------------Clear write and read buffers-------------------------// void ClearBuff(uint8_t *p) { int i = 0; for (; i < 20; i++) { *(p + i) = 0; } } //----------------------------------------------------------------------------// /*********************************Read XY axis function***************************************/ uint8_t toch_number ; void TP_read_XY(void) { uint16_t x, y, x1 ,y1; uint8_t i = 0 , j=0; uint8_t READ_BUFF[18]; // uint8_t READ_BUFF1[10]; if (ft5216flag == 1) { I2C_start(); // Start CTI2C bus I2C_write_byte(0x70); I2C_write_byte(0x02); I2C_stop(); I2C_start(); // Start CTI2C bus again I2C_write_byte(0x71); fingerNumber = I2C_read_byte(0) & 0xF; // ACK for (i = 0; i < 6; i++) READ_BUFF[i] = I2C_read_byte(0); I2C_read_byte(1); // NACK I2C_stop(); if (READ_BUFF[0] & 0x80) { // printf("(READ_BUFF[0] & 0x80)\r\n"); x = READ_BUFF[0] & 0xF; // Calculate X axis x = x << 8; x += READ_BUFF[1]; y = READ_BUFF[2] & 0xF; y = y << 8; y += READ_BUFF[3]; Backlight_count = 0; Backlight_touch = 1; if (Backlight_flag == 0 && var[2 * 0x700e + 1] == 1) { if (Backlight_first_touch == 0) { if (buzzer) touch_buzzer(); I2C_start(); // Start CTI2C bus I2C_write_byte(0x70); I2C_write_byte(0x02); I2C_stop(); I2C_start(); // Start CTI2C bus again I2C_write_byte(0x71); fingerNumber = I2C_read_byte(0) & 0xF; // ACK for (i = 0; i < 6; i++) READ_BUFF[i] = I2C_read_byte(0); I2C_read_byte(1); // NACK I2C_stop(); if (READ_BUFF[0] & 0x40) { Backlight_touch = 0; gTpInfo.sta = 0; First_press = 0; } } Set_Timer1_Compare_Buffer(gDutyBuf[var[0x7001 * 2 + 1]]); if (var[0x700f * 2 + 1] == 0) Start_PWM1(); Backlight_first_touch = 1; } else { gTpInfo.sta = 1; Backlight_touch = 0; gTpInfo.x[0] = x; gTpInfo.y[0] = y; if (gTpInfo.x[0] > LCD_XSIZE_TFT) gTpInfo.x[0] = LCD_XSIZE_TFT; if (gTpInfo.y[0] > LCD_YSIZE_TFT) gTpInfo.y[0] = LCD_YSIZE_TFT; if(scr_flag == 3) { if(scr_x != 0 || scr_y != 0) LT768_DrawQuadrilateral_Fill(scr_x, scr_y + 3, scr_x + 3, scr_y, gTpInfo.x[0] + 3, gTpInfo.y[0], gTpInfo.x[0], gTpInfo.y[0] + 3, Red); scr_x = gTpInfo.x[0]; scr_y = gTpInfo.y[0]; } if (First_press == 0) { First_press = 1; First_pressX = gTpInfo.x[0]; First_pressY = gTpInfo.y[0]; } } } else if (READ_BUFF[0] & 0x40) { Backlight_touch = 0; gTpInfo.sta = 0; First_press = 0; if(scr_flag == 3) { scr_x = 0; scr_y = 0; } } } if (gt911flag == 1) { I2C_start(); I2C_write_byte(0x28); I2C_write_byte(0x81); I2C_write_byte(0x4E); I2C_stop(); I2C_start(); I2C_write_byte(0x29); for (i = 0; i < 14 ; i++) { READ_BUFF[i] = I2C_read_byte(0); } READ_BUFF[i] = I2C_read_byte(1); I2C_stop(); /************************************************/ // I2C_start(); // I2C_write_byte(0x28); // I2C_write_byte(0x81); // I2C_write_byte(0x58); // I2C_stop(); // I2C_start(); // I2C_write_byte(0x29); // for (j = 0; j < 8; j++) // { // READ_BUFF1[j] = I2C_read_byte(0); // } // // READ_BUFF1[j] = I2C_read_byte(1); // I2C_stop(); /***************************************************/ if (READ_BUFF[0] & 0x80) // buffer status Data is valid only when it is 1 { x = READ_BUFF[3]; x = x << 8 | READ_BUFF[2]; y = READ_BUFF[5]; y = y << 8 | READ_BUFF[4]; x1 = READ_BUFF[11]; x1 = x1 << 8 | READ_BUFF[10]; y1 = READ_BUFF[13]; y1 = y1 << 8 | READ_BUFF[12]; Backlight_count = 0; Backlight_touch = 1; // printf("number of touch points = %d\r\n",READ_BUFF[0] & 0x07); toch_number = READ_BUFF[0] & 0x07; if (Backlight_flag == 0 && var[2 * 0x700e + 1] == 1) { if (Backlight_first_touch == 0) { if (buzzer) touch_buzzer(); } if ((READ_BUFF[0] & 0x0F) == 0) { Backlight_touch = 0; gTpInfo.sta = 0; First_press = 0; Backlight_flag = 1; } Set_Timer1_Compare_Buffer(gDutyBuf[var[0x7001 * 2 + 1]]); if (var[0x700f * 2 + 1] == 0) Start_PWM1(); Backlight_first_touch = 1; } else { Backlight_touch = 0; gTpInfo.x[0] = x * LCD_XSIZE_TFT / X_Output_Max; gTpInfo.y[0] = y * LCD_YSIZE_TFT / Y_Output_Max; gTpInfo.sta = READ_BUFF[0] & 0x0F; if (gTpInfo.x[0] > LCD_XSIZE_TFT) gTpInfo.x[0] = LCD_XSIZE_TFT; if (gTpInfo.y[0] > LCD_YSIZE_TFT) gTpInfo.y[0] = LCD_YSIZE_TFT; gTpInfo.x[1] = x1 * LCD_XSIZE_TFT / X_Output_Max; gTpInfo.y[1] = y1 * LCD_YSIZE_TFT / Y_Output_Max; gTpInfo.sta = READ_BUFF[0] & 0x0F; if (gTpInfo.x[1] > LCD_XSIZE_TFT) gTpInfo.x[1] = LCD_XSIZE_TFT; if (gTpInfo.y[1] > LCD_YSIZE_TFT) gTpInfo.y[1] = LCD_YSIZE_TFT; if (gTpInfo.sta == 1) { if(scr_flag == 3) { if(scr_x != 0 || scr_y != 0) LT768_DrawQuadrilateral_Fill(scr_x, scr_y + 3, scr_x + 3, scr_y, gTpInfo.x[0] + 3, gTpInfo.y[0], gTpInfo.x[0], gTpInfo.y[0] + 3, Red); scr_x = gTpInfo.x[0]; scr_y = gTpInfo.y[0]; } if (First_press == 0) { First_press = 1; First_pressX = gTpInfo.x[0]; First_pressY = gTpInfo.y[0]; } } else { First_press = 0; if(scr_flag == 3) { scr_x = 0; scr_y = 0; } } // printf("******gTpInfo.x[0]=%d gTpInfo.y[0]=%d ******\r\n",gTpInfo.x[0],gTpInfo.y[0]); // printf("******gTpInfo.x[1]=%d gTpInfo.y[1]=%d ******\r\n",gTpInfo.x[1],gTpInfo.y[1]); } I2C_start(); I2C_write_byte(0x28); I2C_write_byte(0x81); I2C_write_byte(0x4E); I2C_write_byte(0x00); I2C_stop(); } } } uint8_t FT5216_Scan(void) { uint8_t i; uint8_t READ_BUFF[10]; if (ctp_active_index == 1) { ctp_press_t = 0; TP_read_XY(); ctp_active_index = 0; return 1; } else { if (ft5216flag == 1) { if (gTpInfo.sta == 1 && ctp_press_t > 2) { I2C_start(); I2C_write_byte(0x70); I2C_write_byte(0x02); I2C_stop(); I2C_start(); I2C_write_byte(0x71); fingerNumber = I2C_read_byte(0) & 0xF; // ACK for (i = 0; i < 6; i++) READ_BUFF[i] = I2C_read_byte(0); I2C_read_byte(1); // NACK I2C_stop(); if (READ_BUFF[0] & 0x40) gTpInfo.sta = 0; // printf("gTpInfo.sta == 1 && ctp_press_t > 2\n"); } } return 0; } } #if IIC_BUS void I2C_Slave_TEST(uint8_t sla_addr) { I2C->CR = 0x0; I2C->CR |= CR_EN; delay(100); I2C->CR |= CR_ACKEN; I2C->CR |= CR_IEN; I2C->CR &= ~CR_MSMOD; I2C->SAHR = sla_addr << 1; /*Configure interrupts in slave mode*/ NVIC_Init(3, 3, I2C_1_IRQn, 2); } uint16_t Rx_len = 0, Tx_len = 0; uint16_t reg_addr = 0; uint8_t flag_IIC_REG[20]; uint16_t ID_IIC_WAV = 0; // IIC slave transceiver interrupt function void I2C1_IRQHandler(void) { volatile uint8_t tmp = 0; static uint16_t curve_rev_val = 0; static uint8_t curve_rev_num = 0; static uint8_t curve_rev_tmp = 0; static uint16_t curve_rev_data = 0; static uint8_t curve_rev_cnt = 0; uint8_t i = 0; uint8_t i2c_status, i2c_hs_status; i2c_status = I2C->CSR; i2c_hs_status = I2C->SHSIR; if ((i2c_hs_status & SLV_HS) != SLV_HS) { if ((i2c_status & SR_AASLV) == SR_AASLV) // The current slave device is addressed by master Slave address matching { I2C->CR &= ~CR_AMIE; // Under normal circumstances, turn off the slave address matching interrupt if ((i2c_status & SR_RC) == SR_RC) // Receiving is interrupted. The received address and data will come in { Tx_len = 0; if ((I2C->CSR & SR_TF) == SR_TF) // Transmission completion interrupt { if (Rx_len == 0) // Upper 8 bits of receiving address { reg_addr = I2C->CDR; } else if (Rx_len == 1) // Lower 8 bits of receiving address { reg_addr = (reg_addr << 8) | I2C->CDR; if (reg_addr >= 0xC001 && reg_addr <= 0xCFFF) // Judge whether it is the curve buffer address, special processing { curve_rev_val = reg_addr & 0xFFF; curve_rev_cnt = 0; curve_rev_num = 0; for (i = 0; i < Curve_Size; i++) { if (curve_rev_val & (1 << i)) curve_rev_num++; // Record how many groups of channels } } } else // receive data { if (reg_addr <= 0x6FFF) // In the variable area { // Direct saving of variable data var[2 * reg_addr + Rx_len - 2] = I2C->CDR; } else if (reg_addr >= 0x7000 && reg_addr <= 0x71FF) // Register region { // WAV register data needs special processing if (2 * reg_addr + Rx_len - 2 == 2 * 0x700a) { ID_IIC_WAV = I2C->CDR; } else if (2 * reg_addr + Rx_len - 2 == 2 * 0x700a + 1) { ID_IIC_WAV = (ID_IIC_WAV << 8) | I2C->CDR; } // The remaining register data is saved directly else { var[2 * reg_addr + Rx_len - 2] = I2C->CDR; } if (Rx_len % 2) // The update flag of the corresponding register will be triggered every time 2Bytes are received { flag_IIC_REG[(2 * (reg_addr - 0x7000) + Rx_len - 2) / 2] = 1; } } else if (reg_addr >= 0xC001 && reg_addr <= 0xCFFF) // Curve channel write data { for (i = curve_rev_cnt; i < Curve_Size; i++) { if (curve_rev_val & (1 << i)) // Poll to detect whether 8 channels have triggered updates { if (Rx_len % 2 == 0) { curve_rev_data = (I2C->CDR) << 8; // Receive the first byte of curve data } else if (Rx_len % 2 == 1) { Curve_buff[i][Curve_count[i]] = curve_rev_data | (I2C->CDR); // Receive the second byte of curve data Curve_count[i]++; if (Curve_count[i] >= 1024) { Curve_count[i] = 0; } curve_update_flag[i] = 1; curve_rev_cnt++; if (curve_rev_cnt >= curve_rev_num) curve_rev_cnt = 0; } break; } } } else // Other addresses only receive but do not process { i = I2C->CDR; } } Rx_len++; I2C->CR |= CR_ACKEN; } else // Received address { Rx_len = 0; I2C->CR |= CR_ACKEN; } } else // No receive interrupt, read signal received { if ((i2c_status & SR_TF) == SR_TF) // Transmission completion interrupt { Rx_len = 0; if ((i2c_status & SR_DACK) == SR_DACK) { // Direct feedback data if (reg_addr <= 0x6FFF) // In the variable area { I2C->CDR = var[2 * reg_addr + Tx_len]; } else if (reg_addr >= 0x7000 && reg_addr <= 0x71FF) // In register area { I2C->CDR = var[2 * reg_addr + Tx_len]; } else { I2C->CDR = 0xFF; } Tx_len++; } else { tmp = I2C->CDR; tmp++; // add for warning } } else { ; } } } else { // asm("bkpt"); } } else { I2C->SSHTR = (I2C->SSHTR & 0xc0) | 0x1; I2C->SSHTR = I2C->SSHTR | 0x1; I2C->SHSIR |= SLV_HS; } } #endif