Skip to content

Instantly share code, notes, and snippets.

@lupyuen
Last active November 20, 2019 13:02
/// Reset Pin for touch controller. Note: NFC antenna pins must be reassigned as GPIO pins for this to work.
const TOUCH_RESET_PIN: i32 = 10; // P0.10/NFC2: TP_RESET
/// Interrupt Pin for touch controller. We listen for the touch controller interrupt and trigger an event.
const TOUCH_INTERRUPT_PIN: i32 = 28; // P0.28/AIN4: TP_INT
/// Reset GPIO Pin
static mut TOUCH_RESET: MynewtGPIO = fill_zero!(MynewtGPIO);
static mut TOUCH_DELAY: MynewtDelay = fill_zero!(MynewtDelay);
/// Initialise the touch controller. NFC antenna pins must already be reassigned as GPIO pins:
/// Set `NFC_PINS_AS_GPIO: 1` in hw/bsp/nrf52/syscfg.yml. To check whether whether NFC antenna
/// pins have been correctly reassigned as GPIO pins, use the `nrf52` crate and check that the output is `fe`:
/// ```rust
/// let peripherals = nrf52::Peripherals::take().unwrap();
/// let nfcpins = peripherals.UICR.nfcpins.read().bits();
/// console::print("nfcpins = "); console::printhex(nfcpins as u8); console::print("\n");
/// ```
pub fn start_touch_sensor() -> MynewtResult<()> {
console::print("Rust touch sensor\n");
// Init GPIO for the Reset Pin
unsafe { TOUCH_RESET.init(TOUCH_RESET_PIN) ? };
// Reset the touch controller by switching the Reset Pin low then high with pauses. Based on https://github.com/lupyuen/hynitron_i2c_cst0xxse/blob/master/cst0xx_core.c#L1017-L1167
unsafe {
TOUCH_RESET.set_low() ? ;
TOUCH_DELAY.delay_ms(20);
TOUCH_RESET.set_high() ? ;
TOUCH_DELAY.delay_ms(200); TOUCH_DELAY.delay_ms(200);
};
// Initialise the touch event with the callback function
unsafe { TOUCH_EVENT.ev_cb = Some( touch_event_callback ) };
// Configure the touch controller interrupt (active when low) to trigger a touch event
let rc = unsafe { hal::hal_gpio_irq_init(
TOUCH_INTERRUPT_PIN, // GPIO pin to be configured
Some( touch_interrupt_handler ), // Call `touch_interrupt_handler()` upon detecting interrupt
core::ptr::null_mut(), // No arguments for `touch_interrupt_handler()`
hal::hal_gpio_irq_trigger_HAL_GPIO_TRIG_FALLING, // Trigger when interrupt goes from high to low
hal::hal_gpio_pull_HAL_GPIO_PULL_UP // Pull up the GPIO pin
) };
assert_eq!(rc, 0, "IRQ init fail");
// Start monitoring for touch controller interrupts
unsafe { hal::hal_gpio_irq_enable(TOUCH_INTERRUPT_PIN) };
Ok(())
}
/// Interrupt handler for the touch controller, triggered when a touch is detected
extern "C" fn touch_interrupt_handler(arg: *mut core::ffi::c_void) {
// We forward a touch event to the Default Event Queue for deferred processing. Don't do any processing here.
unsafe { TOUCH_EVENT.ev_arg = arg };
// Fetch the Default Event Queue. TODO: Use dedicated Event Queue for higher priority processing.
let queue = os::eventq_dflt_get()
.expect("GET fail");
unsafe { os::os_eventq_put(queue, &mut TOUCH_EVENT) }; // Trigger the callback function `touch_event_callback()`
}
/// Callback for the touch event that is triggered when a touch is detected
extern "C" fn touch_event_callback(_event: *mut os_event) {
// console::printhex(unsafe { os::os_time_get() } as u8); console::print(" touch\n");
unsafe {
// Fetch the touch data from the touch controller
read_touchdata(&mut TOUCH_DATA)
.expect("touchdata fail");
// Display the touch data
display::show_touch(
TOUCH_DATA.touches[0].x,
TOUCH_DATA.touches[0].y
).expect("show touch fail");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment