Add support for touch controller of LCD

This commit is contained in:
2023-07-06 23:10:02 +02:00
parent 3491d39cd8
commit 06003aeeb6
4 changed files with 106 additions and 5 deletions

View File

@@ -43,10 +43,10 @@ target_link_libraries(ledtest pico_stdlib hardware_pio)
pico_add_extra_outputs(ledtest)
add_executable(lcdtest
src/lcdtest.c src/lcdbus.c src/lcd_ui.c src/ui_radio.c
src/lcdtest.c src/lcdbus.c src/lcd_ui.c src/ui_radio.c src/touch.c
)
pico_generate_pio_header(lcdtest ${CMAKE_CURRENT_LIST_DIR}/src/lcdbus.pio)
target_link_libraries(lcdtest pico_stdlib hardware_pio)
target_link_libraries(lcdtest pico_stdlib hardware_pio hardware_spi)
pico_add_extra_outputs(lcdtest)

View File

@@ -3,6 +3,7 @@
#include "lcdbus.h"
#include "lcd_ui.h"
#include "ui_radio.h"
#include "touch.h"
#include <pico/stdlib.h>
#include <stdio.h>
@@ -18,6 +19,8 @@ int main(void)
lcd_init();
lcd_write_init();
lcd_clear(0);
touch_init();
gpio_init(FRAME_LED);
gpio_set_dir(FRAME_LED, true);
@@ -25,15 +28,41 @@ int main(void)
int freq = 118000;
unsigned last_inc = time_us_32()/1000;
radio_draw_all();
radio_select_input(&radio_vhf1, true);
struct radio_ui *active_radio = NULL;
unsigned touch_stable_time = 0;
int last_hit_x = -1, last_hit_y = -1;
while(true) {
if (lcd_ui_process(false)) {
gpio_put(FRAME_LED, frame_led);
frame_led = !frame_led;
}
unsigned hit_x, hit_y;
if (touch_query(2, 4, &hit_x, &hit_y)) {
struct radio_ui *touched_radio = NULL;
if (hit_x == 0 && hit_y == 0)
touched_radio = &radio_vhf1;
else if (hit_x == 1 && hit_y == 0)
touched_radio = &radio_vhf2;
else if (hit_x == 0 && hit_y == 1)
touched_radio = &radio_ils1;
else if (hit_x == 1 && hit_y == 1)
touched_radio = &radio_ils2;
if (touched_radio != active_radio) {
if (active_radio) {
radio_select_input(active_radio, false);
}
if (touched_radio) {
radio_select_input(touched_radio, true);
}
active_radio = touched_radio;
}
}
if (time_us_32()/1000 - last_inc >= 1000) {
radio_set_standby_freq(&radio_vhf1, freq);
freq += 25;
if (active_radio) {
radio_set_standby_freq(active_radio, freq);
freq += 25;
}
last_inc += 1000;
}
}

65
src/touch.c Normal file
View File

@@ -0,0 +1,65 @@
#include "touch.h"
#include <hardware/spi.h>
#include <pico/stdlib.h>
#define TOUCH_UPPER 3800
#define TOUCH_LOWER 300
#define TOUCH_LEFT 300
#define TOUCH_RIGHT 3800
void touch_init(void)
{
spi_init(spi0, 1000000);
spi_set_format(spi0, 8, SPI_CPHA_0, SPI_CPOL_0, SPI_MSB_FIRST);
gpio_set_function(2, GPIO_FUNC_SPI);
gpio_set_function(3, GPIO_FUNC_SPI);
gpio_set_function(4, GPIO_FUNC_SPI);
gpio_set_function(5, GPIO_FUNC_SIO);
gpio_set_dir(5, true);
gpio_put(5, true);
}
static bool ads7843_xfer(uint16_t *const touch_x, uint16_t *const touch_y)
{
const char outbuf_x[3] = {0xd0, 0x00, 0x00};
const char outbuf_y[3] = {0x90, 0x00, 0x00};
char inbuf[3];
gpio_put(5, false);
spi_write_read_blocking(spi0, outbuf_x, inbuf, 3);
gpio_put(5, true);
const uint16_t x = ((inbuf[1] & 0x7f) << 5) | ((inbuf[2] & 0xf8) >> 3);
gpio_put(5, false);
spi_write_read_blocking(spi0, outbuf_y, inbuf, 3);
gpio_put(5, true);
const uint16_t y = ((inbuf[1] & 0x7f) << 5) | ((inbuf[2] & 0xf8) >> 3);
//printf("X: %hu Y: %hu\n", x, y);
*touch_x = x;
*touch_y = y;
return (x > TOUCH_LEFT) && (x < TOUCH_RIGHT) && (y > TOUCH_LOWER) && (y < TOUCH_UPPER);
}
bool touch_query(unsigned x_boxes, unsigned y_boxes, unsigned *const x, unsigned *const y)
{
static unsigned touch_stable_time = 0;
static int last_hit_x = -1, last_hit_y = -1;
uint16_t touch_x, touch_y;
if (ads7843_xfer(&touch_x, &touch_y)) {
const int hit_x = x_boxes * (touch_x - TOUCH_LEFT) / (TOUCH_RIGHT - TOUCH_LEFT);
const int hit_y = (y_boxes - 1) - y_boxes * (touch_y - TOUCH_LOWER) / (TOUCH_UPPER - TOUCH_LOWER);
if (hit_x != last_hit_x || hit_y != last_hit_y) {
last_hit_x = hit_x;
last_hit_y = hit_y;
touch_stable_time = time_us_32();
}
} else {
last_hit_x = -1;
last_hit_y = -1;
}
if (last_hit_x >= 0 && last_hit_y >= 0 && time_us_32() - touch_stable_time >= 50000) {
*x = last_hit_x;
*y = last_hit_y;
return true;
}
return false;
}

7
src/touch.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
void touch_init(void);
bool touch_query(unsigned x_boxes, unsigned y_boxes, unsigned *const x, unsigned *const y);