本文章介紹如何移植LVGL graphic library 到STM32上,另外說明有關LCD-TFT的driver使用STM32F4xx 的FSMC介面,STM32透過FSMC external memory access的方式驅動LCD-TFT。
一、使用硬體:
- LCD-TFT

二、STM32F4xx Bus matrix:
CPU or DMA透過Bus Matrix可直接存取FSMC。
三、STM407xx memory map:
五、LCD-TFT Command&DATA address
本文章專案的FSMC設定如下圖:
LCD register select使用A18, 16 bits Data。因此A18為low時Address 為0x6000 0000代表command(D/CX low),。當A18為high 時Address 為0x6008 0000代表Data。六、移植LVGL library到STM32上:
- copy lvgl中的scr資料夾與lvgl.h和lv_conf.h(由lv_conf_template.h更改檔名)檔案到專案中,並將檔案加到include paths中。
- 設定定期呼叫lv_tick_inc(x)的timer,本專案設定為5ms。
- 在main loop:定期呼叫lv_timer_handler()。
- 呼叫lv_init()並設定display與input device的driver。
- lcd_fsmc.c
#include <lcd_fsmc.h> #include <stdlib.h> #include <stdio.h> static uint8_t LCD_Orientation=0; static uint16_t lcd_width = LCD_WIDTH; //default 240 static uint16_t lcd_height = LCD_HEIGHT; //default 320 // MADCTL register: MY,MX,MV,ML,BGR,MH,x,x static uint8_t LCD_MADCTL_PORTRAIT = 0b01001000; static uint8_t LCD_MADCTL_LANDSCAPE = 0b00101000; static uint8_t LCD_MADCTL_PORTRAIT_MIRROR = 0b10001000; static uint8_t LCD_MADCTL_LANDSCAPE_MIRROR = 0b11101000; void lcd_cmd_write(unsigned char command) { LCD_CMD_WRITE(command); } void lcd_data_write(unsigned short data) { LCD_DATA_WRITE(data); } uint16_t lcd_get_width() { return lcd_width; } uint16_t lcd_get_height() { return lcd_height; } static void lcd_reset(void) { lcd_cmd_write(LCD_SOFTRESET); HAL_Delay(50); } void lcd_set_window(unsigned short x0, unsigned short y0, unsigned short x1, unsigned short y1) { lcd_cmd_write(LCD_COLADDRSET); lcd_data_write((x0 >> 8) & 0xFF); lcd_data_write(x0 & 0xFF); lcd_data_write((x1 >> 8) & 0xFF); lcd_data_write(x1 & 0xFF); lcd_cmd_write(LCD_PAGEADDRSET); lcd_data_write((y0 >> 8) & 0xFF); lcd_data_write(y0 & 0xFF); lcd_data_write((y1 >> 8) & 0xFF); lcd_data_write(y1 & 0xFF); lcd_cmd_write(LCD_MEMORYWRITE); } void lcd_init(void) { lcd_reset(); lcd_cmd_write(LCD_DISPLAYOFF); lcd_cmd_write(0xCF); lcd_data_write(0x00); lcd_data_write(0x83); lcd_data_write(0x30); lcd_cmd_write(0xED); lcd_data_write(0x64); lcd_data_write(0x03); lcd_data_write(0x12); lcd_data_write(0x81); lcd_cmd_write(0xE8); lcd_data_write(0x85); lcd_data_write(0x01); lcd_data_write(0x79); lcd_cmd_write(0xCB); lcd_data_write(0x39); lcd_data_write(0x2C); lcd_data_write(0x00); lcd_data_write(0x34); lcd_data_write(0x02); lcd_cmd_write(0xF7); lcd_data_write(0x20); lcd_cmd_write(0xEA); lcd_data_write(0x00); lcd_data_write(0x00); lcd_cmd_write(LCD_POWERCONTROL1); lcd_data_write(0x26); lcd_cmd_write(LCD_POWERCONTROL2); lcd_data_write(0x11); lcd_cmd_write(LCD_VCOMCONTROL1); lcd_data_write(0x35); lcd_data_write(0x3E); lcd_cmd_write(LCD_VCOMCONTROL2); lcd_data_write(0xBE); lcd_cmd_write(LCD_MEMCONTROL); lcd_data_write(LCD_MADCTL_PORTRAIT); LCD_Orientation = LCD_ORIENTATION_PORTRAIT; // set TFT orientation default lcd_cmd_write(LCD_PIXELFORMAT); lcd_data_write(0x55); lcd_cmd_write(LCD_FRAMECONTROLNORMAL); lcd_data_write(0x00); lcd_data_write(0x1B); lcd_cmd_write(0xF2); lcd_data_write(0x08); lcd_cmd_write(LCD_GAMMASET); lcd_data_write(0x01); lcd_cmd_write(LCD_POSITIVEGAMMCORR); lcd_data_write(0x1F); lcd_data_write(0x1A); lcd_data_write(0x18); lcd_data_write(0x0A); lcd_data_write(0x0F); lcd_data_write(0x06); lcd_data_write(0x45); lcd_data_write(0x87); lcd_data_write(0x32); lcd_data_write(0x0A); lcd_data_write(0x07); lcd_data_write(0x02); lcd_data_write(0x07); lcd_data_write(0x05); lcd_data_write(0x00); lcd_cmd_write(LCD_NEGATIVEGAMMCORR); lcd_data_write(0x00); lcd_data_write(0x25); lcd_data_write(0x27); lcd_data_write(0x05); lcd_data_write(0x10); lcd_data_write(0x09); lcd_data_write(0x3A); lcd_data_write(0x78); lcd_data_write(0x4D); lcd_data_write(0x05); lcd_data_write(0x18); lcd_data_write(0x0D); lcd_data_write(0x38); lcd_data_write(0x3A); lcd_data_write(0x1F); lcd_cmd_write(LCD_COLADDRSET); lcd_data_write(0x00); lcd_data_write(0x00); lcd_data_write(0x00); lcd_data_write(0xEF); lcd_cmd_write(LCD_PAGEADDRSET); lcd_data_write(0x00); lcd_data_write(0x00); lcd_data_write(0x01); lcd_data_write(0x3F); lcd_cmd_write(LCD_ENTRYMODE); lcd_data_write(0x07); lcd_cmd_write(LCD_DISPLAYFUNC); lcd_data_write(0x0A); lcd_data_write(0x82); lcd_data_write(0x27); lcd_data_write(0x00); lcd_cmd_write(LCD_SLEEPOUT); HAL_Delay(100); lcd_cmd_write(LCD_DISPLAYON); HAL_Delay(100); lcd_cmd_write(LCD_MEMORYWRITE); } void lcd_set_orientation(uint8_t Orientation) { LCD_Orientation = Orientation; lcd_cmd_write(LCD_MEMCONTROL); switch (LCD_Orientation) { case LCD_ORIENTATION_PORTRAIT: lcd_data_write(LCD_MADCTL_PORTRAIT); lcd_width = LCD_WIDTH; lcd_height = LCD_HEIGHT; break; case LCD_ORIENTATION_PORTRAIT_MIRROR: lcd_data_write(LCD_MADCTL_PORTRAIT_MIRROR); lcd_width = LCD_WIDTH; lcd_height = LCD_HEIGHT; break; case LCD_ORIENTATION_LANDSCAPE: lcd_data_write(LCD_MADCTL_LANDSCAPE); lcd_width = LCD_HEIGHT; lcd_height = LCD_WIDTH; break; case LCD_ORIENTATION_LANDSCAPE_MIRROR: lcd_data_write(LCD_MADCTL_LANDSCAPE_MIRROR); lcd_width = LCD_HEIGHT; lcd_height = LCD_WIDTH; break; default: break; } lcd_cmd_write(LCD_MEMORYWRITE); lcd_set_window(0, 0, lcd_width - 1, lcd_height - 1); } void lcd_backlight_off(void) { LCD_BL_OFF(); } void lcd_backlight_on(void) { LCD_BL_ON(); } void lcd_display_off(void) { lcd_cmd_write(LCD_DISPLAYOFF); LCD_BL_OFF(); } void lcd_display_on(void) { lcd_cmd_write(LCD_DISPLAYON); LCD_BL_ON(); } uint8_t lcd_get_orientation(void) { return LCD_Orientation; } void lcd_fill_RGB(uint16_t color, uint16_t x, uint16_t y, uint16_t width, uint16_t height) { lcd_set_window(x, y, x+width - 1, y+height - 1); int dimensions = width * height; while(dimensions--) { lcd_data_write(color); } }
- lcd_fsmc.h
#ifndef __LCD_FSMC_H_ #define __LCD_FSMC_H_ #include "main.h" #include <stdbool.h> #define LCD_WIDTH 240 #define LCD_HEIGHT 320 #define LCD_BL_ON() HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_RESET) #define LCD_BL_OFF() HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_SET) #define LCD_CMD_BASE ((uint32_t)0x60000000) #define LCD_DATA_BASE ((uint32_t)0x60080000) #define LCD_CMD_WRITE(command) *(volatile uint16_t *) (LCD_CMD_BASE) = (command) #define LCD_DATA_WRITE(data) *(volatile uint16_t *) (LCD_DATA_BASE) = (data) #define LCD_REGISTER_READ() *(volatile uint16_t *) (LCD_CMD_BASE) #define LCD_DATA_READ() *(volatile uint16_t *) (LCD_DATA_BASE) enum { LCD_ORIENTATION_PORTRAIT = 0, LCD_ORIENTATION_LANDSCAPE = 1, LCD_ORIENTATION_PORTRAIT_MIRROR = 2, LCD_ORIENTATION_LANDSCAPE_MIRROR = 3 }; // LCD registers #define LCD_NOP 0x00 #define LCD_SOFTRESET 0x01 #define LCD_READID 0x04 #define LCD_READSTATUS 0x09 #define LCD_READPOWERMODE 0x0A #define LCD_READMADCTL 0x0B #define LCD_READPIXELFORMAT 0x0C #define LCD_READIMAGEFORMAT 0x0D #define LCD_READSIGNALMODE 0x0E #define LCD_READSELFDIAGNOSTIC 0x0F #define LCD_SLEEPIN 0x10 #define LCD_SLEEPOUT 0x11 #define LCD_PARTIALMODE 0x12 #define LCD_NORMALDISP 0x13 #define LCD_INVERTOFF 0x20 #define LCD_INVERTON 0x21 #define LCD_GAMMASET 0x26 #define LCD_DISPLAYOFF 0x28 #define LCD_DISPLAYON 0x29 #define LCD_COLADDRSET 0x2A #define LCD_PAGEADDRSET 0x2B #define LCD_MEMORYWRITE 0x2C #define LCD_COLORSET 0x2D #define LCD_MEMORYREAD 0x2E #define LCD_PARTIALAREA 0x30 #define LCD_VERTICALSCROLING 0x33 #define LCD_TEARINGEFFECTOFF 0x34 #define LCD_TEARINGEFFECTON 0x35 #define LCD_MEMCONTROL 0x36 #define LCD_VSCROLLSTARTADDRESS 0x37 #define LCD_IDLEMODEOFF 0x38 #define LCD_IDLEMODEON 0x39 #define LCD_PIXELFORMAT 0x3A #define LCD_WRITEMEMCONTINUE 0x3C #define LCD_READMEMCONTINUE 0x3E #define LCD_SETSCANLINE 0x44 #define LCD_GETSCANLINE 0x45 #define LCD_WRITEBRIGHTNESS 0x51 #define LCD_READBRIGHTNESS 0x52 #define LCD_WRITECTRL 0x53 #define LCD_READCTRL 0x54 #define LCD_WRITECABC 0x55 #define LCD_READCABC 0x56 #define LCD_WRITECABCMIN 0x5E #define LCD_READCABCMIN 0x5F #define LCD_RGBSIGNALCONTROL 0xB0 #define LCD_FRAMECONTROLNORMAL 0xB1 #define LCD_FRAMECONTROLIDLE 0xB2 #define LCD_FRAMECONTROLPARTIAL 0xB3 #define LCD_INVERSIONCONTROL 0xB4 #define LCD_BLANKINGPORCHCONT 0xB5 #define LCD_DISPLAYFUNC 0xB6 #define LCD_ENTRYMODE 0xB7 #define LCD_BACKLIGHTCONTROL1 0xB8 #define LCD_BACKLIGHTCONTROL2 0xB9 #define LCD_BACKLIGHTCONTROL3 0xBA #define LCD_BACKLIGHTCONTROL4 0xBB #define LCD_BACKLIGHTCONTROL5 0xBC #define LCD_BACKLIGHTCONTROL7 0xBE #define LCD_BACKLIGHTCONTROL8 0xBF #define LCD_POWERCONTROL1 0xC0 #define LCD_POWERCONTROL2 0xC1 #define LCD_VCOMCONTROL1 0xC5 #define LCD_VCOMCONTROL2 0xC7 #define LCD_NVMEMORYWRITE 0xD0 #define LCD_NVMEMORYKEY 0xD1 #define LCD_NVMEMORYSTATUSREAD 0xD2 #define LCD_READID4 0xD3 #define LCD_READID1 0xDA #define LCD_READID2 0xDB #define LCD_READID3 0xDC #define LCD_POSITIVEGAMMCORR 0xE0 #define LCD_NEGATIVEGAMMCORR 0xE1 #define LCD_DIGITALGAMMCONTROL1 0xE2 #define LCD_DIGITALGAMMCONTROL2 0xE3 #define LCD_INTERFACECONTROL 0xF6 // LCD Registers void lcd_init(void); void lcd_fill_RGB(uint16_t color, uint16_t x, uint16_t y, uint16_t width, uint16_t height); void lcd_set_orientation(uint8_t Orientation); void lcd_set_window(unsigned short x0, unsigned short y0, unsigned short x1, unsigned short y1); void lcd_display_off(void); void lcd_display_on(void); void lcd_data_write(unsigned short data); void lcd_cmd_write(unsigned char command); void lcd_backlight_on(); void lcd_backlight_off(); uint16_t lcd_get_width(); uint16_t lcd_get_height(); uint8_t lcd_get_orientation(); #endif /* __LCD_FSMC_H_ */
- lcd_lvgl.c
#include <lcd_lvgl.h> /* Memory-to-memory DMA Handler */ extern DMA_HandleTypeDef hdma_memtomem_dma2_stream0; extern uint8_t test_with_dma; void tft_lvgl_draw_bitmap(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t *bitmap) { uint32_t total_pixels = (x2-x1+1) * (y2-y1+1); lcd_set_window(x1, y1, x2, y2); // use memory-to-memory DMA HAL_DMA_Start(&hdma_memtomem_dma2_stream0, (uint32_t)bitmap, (LCD_DATA_BASE), total_pixels); HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream0, HAL_DMA_FULL_TRANSFER, 1000); // if not use DMA translation // for (int i=0; i < total_pixels; i++) { // lcd_data_write(*(bitmap+i)); // } } void tft_lvgl_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p) { tft_lvgl_draw_bitmap( (uint16_t)(area->x1), (uint16_t)(area->y1), (uint16_t)(area->x2), (uint16_t)(area->y2), (uint16_t*)color_p ); lv_disp_flush_ready(disp); /* Indicate you are ready with the flushing*/ } void lvgl_init() { lv_init(); static lv_disp_draw_buf_t draw_buf; static lv_color_t buf1[LCD_WIDTH * LCD_HEIGHT / 10]; /*Declare a buffer for 1/10 screen size*/ lv_disp_draw_buf_init(&draw_buf, buf1, NULL, LCD_WIDTH * LCD_HEIGHT / 10); /*Initialize the display buffer.*/ static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ lv_disp_drv_init(&disp_drv); /*Basic initialization*/ disp_drv.flush_cb = tft_lvgl_disp_flush; /*Set your driver function*/ disp_drv.draw_buf = &draw_buf; /*Assign the buffer to the display*/ disp_drv.hor_res = lcd_get_width(); /*Set the horizontal resolution of the display*/ disp_drv.ver_res = lcd_get_height(); /*Set the vertical resolution of the display*/ lv_disp_drv_register(&disp_drv); /*Finally register the driver*/ } void lvgl_xpt2046_read_cb(lv_indev_drv_t * drv, lv_indev_data_t*data) { static uint16_t x, y; if(XPT2046_TouchPressed()) { XPT2046_TouchGetCoordinates(&x, &y); data->point.x = x; data->point.y = y; data->state = LV_INDEV_STATE_PRESSED; } else { data->state = LV_INDEV_STATE_RELEASED; } } void lvgl_xpt2046_touch_init() { static lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); /*Basic initialization*/ indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = lvgl_xpt2046_read_cb; /*Register the driver in LVGL and save the created input device object*/ lv_indev_drv_register(&indev_drv); }
- lcd_lvgl.h
#ifndef __LCD_LVGL_H #define __LCD_LVGL_H #include <lcd_fsmc.h> #include <lvgl.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include "XPT2046_touch.h" void lvgl_init(); void lvgl_xpt2046_touch_init(); #endif /*__LCD_LVGL_H */
- XPT2046_touch.c
#include <lcd_fsmc.h> #include <stdio.h> #include <stdlib.h> #include "XPT2046_touch.h" #define READ_X 0xD0 #define READ_Y 0x90 uint16_t cRawX_min = XPT2046_MIN_RAW_X; uint16_t cRawX_max = XPT2046_MAX_RAW_X; uint16_t cRawY_min = XPT2046_MIN_RAW_Y; uint16_t cRawY_max = XPT2046_MAX_RAW_Y; static void XPT2046_TouchSelect() { HAL_GPIO_WritePin(XPT2046_CS_GPIO_Port, XPT2046_CS_Pin, GPIO_PIN_RESET); } void XPT2046_TouchUnselect() { HAL_GPIO_WritePin(XPT2046_CS_GPIO_Port, XPT2046_CS_Pin, GPIO_PIN_SET); } bool XPT2046_TouchPressed() { return HAL_GPIO_ReadPin(XPT2046_IRQ_GPIO_Port, XPT2046_IRQ_Pin) == GPIO_PIN_RESET; } bool XPT2046_TouchGetCoordinates(uint16_t* x, uint16_t* y) { bool ret_value=false; uint16_t tx,ty; uint32_t raw_x; uint32_t raw_y; if (XPT2046_TouchGetRawCoordinates(&raw_x, &raw_y)) { if(raw_x < cRawX_min) raw_x = cRawX_min; if(raw_x > cRawX_max) raw_x = cRawX_max; if(raw_y < cRawY_min) raw_y = cRawY_min; if(raw_y > cRawY_max) raw_y = cRawY_max; tx = (raw_x - cRawX_min) * XPT2046_SCALE_X / (cRawX_max - cRawX_min); ty = (raw_y - cRawY_min) * XPT2046_SCALE_Y / (cRawY_max - cRawY_min); uint8_t lot = lcd_get_orientation(); switch (lot) { case LCD_ORIENTATION_PORTRAIT: *x=tx; *y=ty; break; case LCD_ORIENTATION_LANDSCAPE: *x=ty; *y=LCD_WIDTH-tx; break; case LCD_ORIENTATION_PORTRAIT_MIRROR: *x=LCD_WIDTH-tx; *y=LCD_HEIGHT-ty; break; case LCD_ORIENTATION_LANDSCAPE_MIRROR: *x=LCD_HEIGHT-ty; *y=tx; break; } ret_value =true; } return ret_value; } bool XPT2046_TouchGetRawCoordinates(uint32_t* raw_x, uint32_t* raw_y) { static const uint8_t cmd_read_x[] = { READ_X }; static const uint8_t cmd_read_y[] = { READ_Y }; static const uint8_t zeroes_tx[] = { 0x00, 0x00 }; static const uint8_t SAMPLES=16; //if (!XPT2046_TouchPressed()) return false; //HAL_Delay(10); XPT2046_TouchSelect(); uint32_t avg_x = 0; uint32_t avg_y = 0; uint8_t nsamples = 0; for(uint8_t i = 0; i < SAMPLES; i++) { if(!XPT2046_TouchPressed()) { break; } nsamples++; HAL_SPI_Transmit(&XPT2046_SPI_PORT, (uint8_t*)cmd_read_y, sizeof(cmd_read_y), HAL_MAX_DELAY); uint8_t y_raw[2]; HAL_SPI_TransmitReceive(&XPT2046_SPI_PORT, (uint8_t*)zeroes_tx, y_raw, sizeof(y_raw), HAL_MAX_DELAY); HAL_SPI_Transmit(&XPT2046_SPI_PORT, (uint8_t*)cmd_read_x, sizeof(cmd_read_x), HAL_MAX_DELAY); uint8_t x_raw[2]; HAL_SPI_TransmitReceive(&XPT2046_SPI_PORT, (uint8_t*)zeroes_tx, x_raw, sizeof(x_raw), HAL_MAX_DELAY); avg_x += (((uint16_t)x_raw[0]) << 8) | ((uint16_t)x_raw[1]); avg_y += (((uint16_t)y_raw[0]) << 8) | ((uint16_t)y_raw[1]); } XPT2046_TouchUnselect(); if(nsamples < SAMPLES) return false; *raw_x = (avg_x / SAMPLES); *raw_y = (avg_y / SAMPLES); return true; } bool XPT2046_TouchCalibration() { uint32_t x0=0,y0=0,x1=0,y1=0,x2=0,y2=0,x3=0,y3=0; bool correct=true; uint32_t width, height; uint8_t lot = lcd_get_orientation(); lcd_set_orientation(LCD_ORIENTATION_PORTRAIT); width = lcd_get_width(); height = lcd_get_height(); lcd_fill_RGB(0x0000, 0, 0, width-1, height-1); lcd_fill_RGB(0xffff, 0, 0, 6,6); lcd_set_window(20,100 ,20 ,100); // set LCD cursor to (20,100) while(!XPT2046_TouchPressed()) ; if (!XPT2046_TouchGetRawCoordinates(&x0, &y0)) { lcd_set_orientation(lot); return false; } lcd_fill_RGB(0x0000, 0, 0, width-1, height-1); lcd_fill_RGB(0xffff, 0, height-7, 6, 6); while(XPT2046_TouchPressed()); HAL_Delay(1); lcd_set_window(20, 100, 20, 100); while(!XPT2046_TouchPressed()); if(!XPT2046_TouchGetRawCoordinates(&x1, &y1)) { lcd_set_orientation(lot); return false; } lcd_fill_RGB(0x0000, 0, 0, width-1, height-1); lcd_fill_RGB(0xffff,width-7, height-7, 6, 6); while(XPT2046_TouchPressed()); HAL_Delay(1); lcd_set_window(20, 100, 20, 100); while(!XPT2046_TouchPressed()); if (!XPT2046_TouchGetRawCoordinates(&x2, &y2)) { lcd_set_orientation(lot); return false; } lcd_fill_RGB(0x0000, 0, 0, width-1, height-1); lcd_fill_RGB(0xffff, width-7, 0, 6, 6); while(XPT2046_TouchPressed()); HAL_Delay(1); lcd_set_window(20, 100, 20, 100); while(!XPT2046_TouchPressed()); if (!XPT2046_TouchGetRawCoordinates(&x3, &y3)) { lcd_set_orientation(lot); return false; } while(XPT2046_TouchPressed()); if (abs(x0-x1) > XTP2046_CALI_DIFF) correct = false; if (abs(x2-x3) > XTP2046_CALI_DIFF) correct = false; if (abs(y1-y2) > XTP2046_CALI_DIFF) correct = false; if (abs(y0-y3) > XTP2046_CALI_DIFF) correct = false; if (correct) { cRawX_min = (x0+x1)/2; cRawX_max = (x2+x3)/2; cRawY_min = (y0+y3)/2; cRawY_max = (y1+y2)/2; } lcd_fill_RGB(0x0000, 0, 0, width-1, height-1); lcd_set_window(20, 100, 20, 100); lcd_set_orientation(lot); return correct; }
- XPT2046_touch.h
#ifndef XPT2046_TOUCH_H_ #define XPT2046_TOUCH_H_ #include "main.h" #include <stdbool.h> /*** Redefine if necessary ***/ // Warning! Use SPI bus with < 2.5 Mbit speed, better ~650 Kbit to be save. #define XPT2046_SPI_PORT hspi2 extern SPI_HandleTypeDef XPT2046_SPI_PORT; #define XPT2046_IRQ_Pin T_IRQ_Pin #define XPT2046_IRQ_GPIO_Port T_IRQ_GPIO_Port #define XPT2046_CS_Pin T_CS_Pin #define XPT2046_CS_GPIO_Port T_CS_GPIO_Port // change depending on screen orientation #define XPT2046_SCALE_X 240 #define XPT2046_SCALE_Y 320 #define XPT2046_MIN_RAW_X 1860 #define XPT2046_MAX_RAW_X 29650 #define XPT2046_MIN_RAW_Y 1830 #define XPT2046_MAX_RAW_Y 29350 //#define XPT2046_MIN_RAW_X 2000 //#define XPT2046_MAX_RAW_X 30000 //#define XPT2046_MIN_RAW_Y 1500 //#define XPT2046_MAX_RAW_Y 29000 #define XTP2046_CALI_DIFF 2500 // call before initializing any SPI devices void XPT2046_TouchUnselect(void); bool XPT2046_TouchPressed(void); bool XPT2046_TouchGetCoordinates(uint16_t* x, uint16_t* y); bool XPT2046_TouchGetRawCoordinates(uint32_t* raw_, uint32_t* raw_y); bool XPT2046_TouchCalibration(void); #endif /* XPT2046_TOUCH_H_ */