Last active
November 20, 2019 13:02
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// 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