Skip to content

Commit 6c585f5

Browse files
bors[bot]Srg213
andauthored
Merge #527
527: Touchscreen driver r=burrbull a=Srg213 Added example to use the ft6x06 touchpanel controller. This example works on STM32F412-G and STM32F413-H discovery boards. It configures the i2c bus and uses ft6x06 crate to get touch coordinates data. Co-authored-by: Shantanu <[email protected]>
2 parents 6d0c292 + fdf8f20 commit 6c585f5

File tree

3 files changed

+256
-0
lines changed

3 files changed

+256
-0
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3535
### Added
3636

3737
- Serial Tx, Rx containing pins [#514] [#515] [#540]
38+
- example of using ft6x06 touchscreen driver for stm32f412 and stm32f413 [#527]
39+
- Serial Tx, Rx containing pins [#514] [#515]
3840
- Implementation of From trait for Pin-to-PartiallyErasedPin [#507]
3941
- Implementation of From trait for Pin-to-ErasedPin [#507]
4042
- Implementation of From trait for PartiallyErasedPin-to-ErasedPin [#507]
@@ -61,6 +63,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
6163
[#534]: https://github.com/stm32-rs/stm32f4xx-hal/pull/529
6264
[#540]: https://github.com/stm32-rs/stm32f4xx-hal/pull/540
6365
[#542]: https://github.com/stm32-rs/stm32f4xx-hal/pull/542
66+
[#527]: https://github.com/stm32-rs/stm32f4xx-hal/pull/527
6467

6568
## [v0.13.2] - 2022-05-16
6669

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ smart-leds = "0.3.0"
8282
ws2812-spi = { version = "0.4.0", features = [] }
8383
hd44780-driver = "0.4.0"
8484
display-interface = "0.4"
85+
ft6x06 = "0.1.2"
8586

8687
[dev-dependencies.time]
8788
version = "0.3"
@@ -368,6 +369,10 @@ debug = true
368369
lto = true
369370
opt-level = "s"
370371

372+
[[example]]
373+
name= "display_touch"
374+
required-features = ["fsmc_lcd", "stm32f412"] #or stm32f413
375+
371376
[[example]]
372377
name = "blinky-timer-irq"
373378
required-features = ["tim2"] # stm32f411

examples/display_touch.rs

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
//!
2+
//! Demonstrates use of I2C bus to configure and use FT6x06 touchscreen controller
3+
//!
4+
//! Hardware Required: STM32F412G-DISCO board or STM32F413H-DISCO board
5+
//!
6+
//! Procedure: Compile this example, load it onto the microcontroller, and run it.
7+
//!
8+
//! Example run command: `cargo run --release --features stm32f412,fsmc_lcd --example display_touch`
9+
//!
10+
//! Expected behavior: The display draws circle with its center around the touch. The co-ordinates of the touch
11+
//! are printed on screen.
12+
13+
#![no_main]
14+
#![no_std]
15+
#![allow(unused_variables)]
16+
17+
use cortex_m;
18+
use cortex_m_rt::entry;
19+
use rtt_target::{rprintln, rtt_init_print};
20+
#[cfg(feature = "stm32f412")]
21+
use stm32f4xx_hal::fsmc_lcd::ChipSelect1;
22+
#[cfg(feature = "stm32f413")]
23+
use stm32f4xx_hal::fsmc_lcd::ChipSelect3;
24+
use stm32f4xx_hal::{
25+
fsmc_lcd::{FsmcLcd, LcdPins, Timing},
26+
gpio::Speed,
27+
pac,
28+
prelude::*,
29+
rcc::Rcc,
30+
};
31+
32+
use embedded_graphics::{
33+
pixelcolor::Rgb565,
34+
prelude::*,
35+
primitives::{Circle, PrimitiveStyle},
36+
};
37+
38+
#[cfg(feature = "stm32f413")]
39+
use stm32f4xx_hal::fmpi2c::FMPI2c;
40+
#[cfg(feature = "stm32f412")]
41+
use stm32f4xx_hal::i2c::I2c;
42+
43+
#[allow(unused_imports)]
44+
use panic_semihosting;
45+
46+
use ft6x06::{long_hard_reset, Ft6X06};
47+
48+
use st7789::*;
49+
50+
/// A simple example to connect to the FT6x06 crate and get the values for
51+
/// x and y positions of touch.
52+
#[entry]
53+
fn main() -> ! {
54+
rtt_init_print!();
55+
rprintln!("Started");
56+
57+
let p = pac::Peripherals::take().unwrap();
58+
let cp = cortex_m::Peripherals::take().unwrap();
59+
60+
let rcc: Rcc = p.RCC.constrain();
61+
62+
let clocks = rcc.cfgr.sysclk(100.MHz()).freeze();
63+
let mut delay = cp.SYST.delay(&clocks);
64+
65+
let gpiob = p.GPIOB.split();
66+
let gpioc = p.GPIOC.split();
67+
let gpiod = p.GPIOD.split();
68+
let gpioe = p.GPIOE.split();
69+
let gpiof = p.GPIOF.split();
70+
let gpiog = p.GPIOG.split();
71+
72+
// Pins connected to the LCD on the board
73+
let lcd_pins = LcdPins {
74+
data: (
75+
gpiod.pd14.into_alternate(),
76+
gpiod.pd15.into_alternate(),
77+
gpiod.pd0.into_alternate(),
78+
gpiod.pd1.into_alternate(),
79+
gpioe.pe7.into_alternate(),
80+
gpioe.pe8.into_alternate(),
81+
gpioe.pe9.into_alternate(),
82+
gpioe.pe10.into_alternate(),
83+
gpioe.pe11.into_alternate(),
84+
gpioe.pe12.into_alternate(),
85+
gpioe.pe13.into_alternate(),
86+
gpioe.pe14.into_alternate(),
87+
gpioe.pe15.into_alternate(),
88+
gpiod.pd8.into_alternate(),
89+
gpiod.pd9.into_alternate(),
90+
gpiod.pd10.into_alternate(),
91+
),
92+
address: gpiof.pf0.into_alternate(),
93+
read_enable: gpiod.pd4.into_alternate(),
94+
write_enable: gpiod.pd5.into_alternate(),
95+
#[cfg(feature = "stm32f413")]
96+
chip_select: ChipSelect3(gpiog.pg10.into_alternate()),
97+
#[cfg(feature = "stm32f412")]
98+
chip_select: ChipSelect1(gpiod.pd7.into_alternate()),
99+
};
100+
101+
// Enable backlight
102+
#[cfg(feature = "stm32f413")]
103+
let mut backlight_control = gpioe.pe5.into_push_pull_output();
104+
105+
#[cfg(feature = "stm32f412")]
106+
let mut backlight_control = gpiof.pf5.into_push_pull_output();
107+
108+
backlight_control.set_high();
109+
110+
// Setup the RESET pin
111+
#[cfg(feature = "stm32f413")]
112+
let mut lcd_reset = gpiob.pb13.into_push_pull_output().speed(Speed::VeryHigh);
113+
114+
#[cfg(feature = "stm32f412")]
115+
let lcd_reset = gpiod.pd11.into_push_pull_output().speed(Speed::VeryHigh);
116+
117+
#[cfg(feature = "stm32f412")]
118+
let mut ts_reset = gpiof.pf12.into_push_pull_output().speed(Speed::VeryHigh);
119+
120+
// Workaround on STM32F413:
121+
// - On the STM32F413 the touchscreen shares the reset GPIO pin w/ the LCD.
122+
// - The ST7789 driver uses a fast (10uS) reset.
123+
// - The touchscreen controller needs 5mS:
124+
// https://www.displayfuture.com/Display/datasheet/controller/FT6206.pdf
125+
//
126+
// Perform a longer reset here first.
127+
//
128+
#[cfg(feature = "stm32f412")]
129+
long_hard_reset(&mut ts_reset, &mut delay).expect("long hard reset");
130+
#[cfg(feature = "stm32f413")]
131+
long_hard_reset(&mut lcd_reset, &mut delay).expect("long hard reset");
132+
133+
// We're not using the "tearing" signal from the display
134+
let mut _te = gpiob.pb14.into_floating_input();
135+
136+
// Set up timing
137+
let write_timing = Timing::default().data(3).address_setup(3).bus_turnaround(0);
138+
let read_timing = Timing::default().data(8).address_setup(8).bus_turnaround(0);
139+
140+
// Initialise FSMC memory provider
141+
let (_fsmc, interface) = FsmcLcd::new(p.FSMC, lcd_pins, &read_timing, &write_timing);
142+
143+
// Pass display-interface instance ST7789 driver to setup a new display
144+
let mut disp = ST7789::new(
145+
interface,
146+
Some(lcd_reset),
147+
Some(backlight_control),
148+
240,
149+
240,
150+
);
151+
152+
// Initialise the display and clear the screen
153+
disp.init(&mut delay).unwrap();
154+
disp.clear(Rgb565::BLACK).unwrap();
155+
156+
// Orientation set is default. The touch coordinates data changes as per orientation.
157+
// The touch coordinates and shapes are adjusted accordingly.
158+
rprintln!("The orientation set is {}", disp.orientation() as u8);
159+
160+
// Intializing the i2c bus for touchscreen
161+
rprintln!("Connecting to I2c");
162+
163+
// Declare the pins for i2c address bus on each board.
164+
// STM32F412 uses I2c1 type for i2c bus.
165+
// The pins are mentioned in documentation -um2135-discovery-kit-with-stm32f412zg-mcu-stmicroelectronics
166+
#[cfg(feature = "stm32f412")]
167+
let mut i2c = {
168+
I2c::new(
169+
p.I2C1,
170+
(
171+
gpiob.pb6.into_alternate_open_drain(), //scl pin
172+
gpiob.pb7.into_alternate_open_drain(), //sda pin
173+
),
174+
400.kHz(),
175+
&clocks,
176+
)
177+
};
178+
179+
// STM32F413 uses FMPI2C1 type.
180+
// The pins are mentioned in documentation -um2135-discovery-kit-with-stm32f413zh-mcu-stmicroelectronics
181+
#[cfg(feature = "stm32f413")]
182+
let mut i2c = {
183+
FMPI2c::new(
184+
p.FMPI2C1,
185+
(
186+
gpioc.pc6.into_alternate_open_drain(), // scl pin
187+
gpioc.pc7.into_alternate_open_drain(), // sda pin
188+
),
189+
400.kHz(),
190+
)
191+
};
192+
193+
#[cfg(feature = "stm32f412")]
194+
let ts_int = gpiog.pg5.into_pull_down_input();
195+
#[cfg(feature = "stm32f413")]
196+
let ts_int = gpioc.pc1.into_pull_down_input();
197+
198+
// Create a struct of ft6x06 driver for touchscreen.
199+
let mut touch = Ft6X06::new(&i2c, 0x38, ts_int).unwrap();
200+
201+
// Run internal calibration of touchscreen
202+
let tsc = touch.ts_calibration(&mut i2c, &mut delay);
203+
match tsc {
204+
Err(e) => rprintln!("Error {} from ts_calibration", e),
205+
Ok(u) => rprintln!("ts_calibration returned {}", u),
206+
}
207+
rprintln!("If nothing happens - touch the screen!");
208+
209+
// Loop to get the touch data
210+
loop {
211+
let t = touch.detect_touch(&mut i2c);
212+
let mut num: u8 = 0;
213+
match t {
214+
Err(_e) => rprintln!("Error from fetching number of touches"),
215+
Ok(n) => {
216+
num = n;
217+
if num != 0 {
218+
rprintln!("Number of touches: {}", num)
219+
};
220+
}
221+
}
222+
223+
if num > 0 {
224+
let t = touch.get_touch(&mut i2c, 1);
225+
226+
match t {
227+
Err(_e) => rprintln!("Error fetching touch data"),
228+
Ok(n) => {
229+
// Prints the touch coordinates.
230+
rprintln!(
231+
"Touch: {:>3}x{:>3} - weight: {:>3} misc: {}",
232+
n.x,
233+
n.y,
234+
n.weight,
235+
n.misc
236+
);
237+
238+
// Circle with 1 pixel wide white stroke with top-left point at (10, 20) with a diameter of 3
239+
// The touchscreen coordinates are flipped and have an offset. The following conversion gives correct orientation.
240+
Circle::new(Point::new(i32::from(n.y), 240 - i32::from(n.x)), 20)
241+
.into_styled(PrimitiveStyle::with_stroke(Rgb565::RED, 1))
242+
.draw(&mut disp)
243+
.unwrap();
244+
}
245+
}
246+
}
247+
}
248+
}

0 commit comments

Comments
 (0)