Thanks to visit codestin.com
Credit goes to lib.rs

#touchscreen #gt911 #gt9147 #gt928

nightly no-std gt9x

A no_std driver for the GT9x series of capacitive touch screen controllers, supporting both async and blocking interfaces

1 unstable release

Uses new Rust 2024

0.1.0 Aug 28, 2025

#1238 in Embedded development

34 downloads per month

Apache-2.0

26KB
387 lines

GT9x Touch Screen Controller Driver

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).


English

Supported Chips

  • GT911 (5 points)
  • GT928 (10 points)
  • GT9147 (5 points)

Features

  • 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.

Usage

Asynchronous Driver

The asynchronous driver can be used with or without an interrupt pin.

Polling Mode

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
    }
}
Interrupt Mode

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
    }
}

Blocking Driver

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
    }
}

Cache Maintenance

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.


中文说明

支持的芯片

  • GT911 (5点触摸)
  • GT928 (10点触摸)
  • GT9147 (5点触摸)

功能特性 (Features)

  • 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() {
        // ... 处理触摸点
    }
}

缓存维护 (Cache Maintenance)

对于带有数据缓存(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 目录以获取更完整的使用示例。

Dependencies

~0.8–1.4MB
~29K SLoC