| Crates.io | gt9x |
| lib.rs | gt9x |
| version | 0.1.0 |
| created_at | 2025-08-28 15:43:01.720247+00 |
| updated_at | 2025-08-28 15:43:01.720247+00 |
| description | A no_std driver for the GT9x series of capacitive touch screen controllers, supporting both async and blocking interfaces. |
| homepage | https://github.com/jnshuiji/gt9x |
| repository | https://github.com/jnshuiji/gt9x |
| max_upload_size | |
| id | 1814260 |
| size | 41,651 |
no_std driver for the GT9x series of capacitive touch screen controllers.
This crate provides a no_std driver for the GT9x series of capacitive touch screen controllers. It supports both asynchronous (embedded-hal-async) and blocking (embedded-hal) I2C communication. It also provides support for cache maintenance, which is useful for MCUs with data caches (like ARM Cortex-M7).
async: (Default) Enables the asynchronous driver based on embedded-hal-async.blocking: Enables the blocking driver based on embedded-hal.defmt: Enables logging with defmt.The asynchronous driver can be used with or without an interrupt pin.
In polling mode, the driver will check the status register for new touch data in a loop.
// From example/src/bin/common.rs
use gt9x::{Gt911, Gt9x};
let mut gt9x = Gt9x::<Gt911, _, _, _>::new(i2c, &mut buf);
gt9x.init().await.unwrap();
loop {
if let Ok(points) = gt9x.get_touches().await {
// ... process points
}
}
In interrupt mode, the driver will wait for a rising edge on the interrupt pin before reading touch data. This is more efficient than polling.
// From example/src/bin/int.rs
use gt9x::{Gt911, Gt9x};
let mut gt9x_int = Gt9x::<Gt911, _, _, _>::new_int(i2c, &mut buf, int_pin);
gt9x_int.init().await.unwrap();
loop {
if let Ok(points) = gt9x_int.get_touches().await {
// ... process points
}
}
The blocking driver polls the status register to get touch data.
// From example/src/bin/blocking.rs
use gt9x::{Gt911, Gt9xBlocking};
let mut gt9x = Gt9xBlocking::<Gt911, _>::new(i2c, &mut buf);
gt9x.init().unwrap();
loop {
if let Ok(points) = gt9x.get_touches() {
// ... process points
}
}
The buffer must be aligned to the cache line size, and its length must be a multiple of the alignment.
// From example/src/bin/int_cache.rs
use gt9x::{Gt9x, Gt9147, CacheMaintenance};
struct MyCache;
impl CacheMaintenance for MyCache {
fn required_alignment(&self) -> Option<usize> {
Some(32) // D-Cache line size for STM32H7
}
fn invalidate_dcache_by_slice(&self, slice: &mut [u8]) {
// Invalidate D-Cache for the given slice
// e.g., using cortex_m::SCB::invalidate_dcache_by_slice
}
}
// Buffer needs to be aligned
#[repr(align(32))]
struct Aligned32<T>(T);
#[link_section = ".axisram"]
static mut BUF: Aligned32<[u8; 64]> = Aligned32([0; 64]);
let mut gt9x = Gt9x::new_int_cache(i2c, unsafe { &mut BUF.0 }, int_pin, MyCache);
See the examples folder for more complete usage.
async: (默认) 启用基于 embedded-hal-async 的异步驱动。blocking: 启用基于 embedded-hal 的阻塞驱动。defmt: 启用 defmt 日志。异步驱动支持中断模式和轮询模式。
在轮询模式下,驱动会循环查询状态寄存器以获取新的触摸数据。
// 来自 example/src/bin/common.rs
use gt9x::{Gt911, Gt9x};
let mut gt9x = Gt9x::<Gt911, _, _, _>::new(i2c, &mut buf);
gt9x.init().await.unwrap();
loop {
if let Ok(points) = gt9x.get_touches().await {
// ... 处理触摸点
}
}
在中断模式下,驱动会等待中断引脚的上升沿信号,然后再读取触摸数据。这种方式比轮询更高效。
// 来自 example/src/bin/int.rs
use gt9x::{Gt911, Gt9x};
let mut gt9x_int = Gt9x::<Gt911, _, _, _>::new_int(i2c, &mut buf, int_pin);
gt9x_int.init().await.unwrap();
loop {
if let Ok(points) = gt9x_int.get_touches().await {
// ... 处理触摸点
}
}
阻塞驱动通过轮询状态寄存器来获取触摸数据。
// 来自 example/src/bin/blocking.rs
use gt9x::{Gt911, Gt9xBlocking};
let mut gt9x = Gt9xBlocking::<Gt911, _>::new(i2c, &mut buf);
gt9x.init().unwrap();
loop {
if let Ok(points) = gt9x.get_touches() {
// ... 处理触摸点
}
}
对于带有数据缓存(Data Cache)的 MCU,提供给驱动所使用的缓冲区位于由缓存管理的内存区域时,可以实现 CacheMaintenance trait 来处理缓存失效操作。
缓冲区必须按缓存行大小对齐,并且其长度必须是该对齐值的倍数。
// 来自 example/src/bin/int_cache.rs
use gt9x::{Gt9x, Gt9147, CacheMaintenance};
struct MyCache;
impl CacheMaintenance for MyCache {
fn required_alignment(&self) -> Option<usize> {
Some(32) // STM32H7 的 D-Cache 行大小
}
fn invalidate_dcache_by_slice(&self, slice: &mut [u8]) {
// 使给定的 slice 对应的 D-Cache 失效
// 例如,使用 cortex_m::SCB::invalidate_dcache_by_slice
}
}
// 缓冲区地址需要对齐
#[repr(align(32))]
struct Aligned32<T>(T);
#[link_section = ".axisram"]
static mut BUF: Aligned32<[u8; 64]> = Aligned32([0; 64]);// 缓冲区大小要对齐
// let i2c = ...;
// let int_pin = ...;
let mut gt9x = Gt9x::new_int_cache(i2c, unsafe { &mut BUF.0 }, int_pin, MyCache);
请参阅 examples 目录以获取更完整的使用示例。