Add support for touch controller of LCD
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -19,21 +20,49 @@ int main(void)
|
||||
lcd_write_init();
|
||||
lcd_clear(0);
|
||||
|
||||
touch_init();
|
||||
|
||||
gpio_init(FRAME_LED);
|
||||
gpio_set_dir(FRAME_LED, true);
|
||||
bool frame_led = false;
|
||||
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
65
src/touch.c
Normal 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
7
src/touch.h
Normal 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);
|
||||
Reference in New Issue
Block a user