暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.rs 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. #![no_main]
  2. #![no_std]
  3. mod board;
  4. mod assets {
  5. include!(concat!(env!("OUT_DIR"), "/assets.rs"));
  6. }
  7. use cortex_m_semihosting::{debug, hprintln};
  8. use mkl25z4_hal as hal;
  9. use panic_semihosting as _;
  10. use mkl25z4_hal::gpio::GpioExt;
  11. use mkl25z4_hal::spi::{Phase, Polarity, Spi};
  12. use mkl25z4_hal::time::{NonCopyableMonoTimer, U32Ext};
  13. use mkl25z4_hal::timer::{Timer, TimerInterrupt};
  14. use embedded_hal::digital::v2::OutputPin;
  15. use embedded_epd::{gui, Display};
  16. use embedded_epd as epd;
  17. use nb::block;
  18. use embedded_hal::timer::CountDown;
  19. use board::led;
  20. struct EPDTimer<Timer> {
  21. timer: Timer,
  22. }
  23. impl<Timer> CountDown for EPDTimer<Timer>
  24. where
  25. Timer: CountDown<Time = hal::time::Hertz>,
  26. {
  27. type Time = epd::Hertz;
  28. fn start<T>(&mut self, timeout: T)
  29. where
  30. T: Into<epd::Hertz>,
  31. {
  32. self.timer.start(hal::time::Hertz(timeout.into().0))
  33. }
  34. fn wait(&mut self) -> nb::Result<(), void::Void> {
  35. self.timer.wait()
  36. }
  37. }
  38. #[rtfm::app(device = mkl25z4_hal::mkl25z4, peripherals = true)]
  39. const APP: () = {
  40. struct Resources {
  41. }
  42. #[init]
  43. fn init(ctx: init::Context) {
  44. let mut sim = ctx.device.SIM;
  45. mkl25z4_hal::watchdog::disable(&mut sim);
  46. let clocks = mkl25z4_hal::clocks::init();
  47. let mut gpiob = ctx.device.GPIOB.split(&mut sim);
  48. let mut gpioc = ctx.device.GPIOC.split(&mut sim);
  49. let mut gpiod = ctx.device.GPIOD.split(&mut sim);
  50. let mut led = led::Led {
  51. red: gpiob.pb18.into_push_pull_output(&mut gpiob.pddr),
  52. green: gpiob.pb19.into_push_pull_output(&mut gpiob.pddr),
  53. blue: gpiod.pd1.into_push_pull_output(&mut gpiod.pddr),
  54. };
  55. //led::init(&p.device.PORTB, &p.device.GPIOB, &p.device.PORTD, &p.device.GPIOD, &p.device.SIM);
  56. led.set_color(true, true, true);
  57. /*for _ in 0..2 {
  58. time.delay_ms(1000);
  59. led.set_color(false, false, true);
  60. time.delay_ms(1000);
  61. led.set_color(false, true, false);
  62. }*/
  63. let mosi = gpioc.pc6.into_alternate(&mut gpioc.pddr);
  64. let miso = gpioc.pc7.into_alternate(&mut gpioc.pddr);
  65. let sck = gpioc.pc5.into_alternate(&mut gpioc.pddr);
  66. let mode = hal::spi::Mode {
  67. polarity: Polarity::IdleLow,
  68. phase: Phase::CaptureOnFirstTransition,
  69. };
  70. let spi0 = Spi::spi0(ctx.device.SPI0, mosi, miso, sck, mode, &mut sim);
  71. // Initialize the display.
  72. let busy = gpioc.pc3.into_floating_input(&mut gpioc.pddr);
  73. let mut reset = gpioc.pc2.into_push_pull_output(&mut gpioc.pddr);
  74. reset.set_high().unwrap();
  75. let mut data_cmd = gpioc.pc1.into_push_pull_output(&mut gpioc.pddr);
  76. data_cmd.set_high().unwrap();
  77. let mut cs = gpioc.pc0.into_push_pull_output(&mut gpioc.pddr);
  78. cs.set_high().unwrap();
  79. let t = EPDTimer {
  80. timer: Timer::pit(ctx.device.PIT, hal::time::Hertz(1), clocks, &mut sim),
  81. };
  82. let mut display = epd::gdew042z15::GDEW042Z15::new(spi0, busy, reset, data_cmd, cs, t);
  83. block!(display.init()).ok();
  84. block!(display.start_frame()).ok();
  85. led.set_color(false, false, false);
  86. let layout = gui::Layout::new(
  87. 400,
  88. 300,
  89. gui::VerticalSplit::expand_bottom(
  90. 24,
  91. gui::Fill::new(epd::Color::White),
  92. gui::VerticalSplit::expand_bottom(
  93. 1,
  94. gui::Fill::new(epd::Color::Black),
  95. gui::HorizontalSplit::expand_right(
  96. 48,
  97. gui::Fill::new(epd::Color::White),
  98. //gui::Image::new(&assets::ALARM_CLOCK_36),
  99. gui::HorizontalSplit::expand_right(
  100. 1,
  101. gui::Fill::new(epd::Color::Black),
  102. gui::HorizontalSplit::expand_left(
  103. 49,
  104. gui::VerticalSplit::expand_bottom(
  105. 132,
  106. gui::Align::new(
  107. gui::HorizontalAlign::Center,
  108. gui::VerticalAlign::Top,
  109. gui::Text::new("12:34", &assets::ROBOTO_100),
  110. ),
  111. gui::Align::new(
  112. gui::HorizontalAlign::Center,
  113. gui::VerticalAlign::Top,
  114. gui::HorizontalSplit::expand_right(
  115. 36,
  116. gui::Image::new(&assets::ALARM_CLOCK_36),
  117. gui::Text::new("Do. 8:00", &assets::ROBOTO_30),
  118. ),
  119. ),
  120. ),
  121. gui::Fill::new(epd::Color::White),
  122. ),
  123. ),
  124. ),
  125. ),
  126. ),
  127. );
  128. let mut row_buffer = [0u8; 400 / 8];
  129. layout.render(&mut display, &mut row_buffer);
  130. display.end_frame();
  131. led.set_color(true, true, false);
  132. let (_, _, _, _, _, mut t) = display.destroy();
  133. /*let pit_ = display.time.deactivate(&mut p.device.SIM);*/
  134. t.start(epd::Hertz(1));
  135. t.timer.enable_interrupt();
  136. let mut nvic = ctx.core.NVIC;
  137. nvic.enable(mkl25z4::Interrupt::PIT);
  138. led.set_color(true, true, true);
  139. }
  140. #[idle]
  141. fn idle(_cx: idle::Context) -> ! {
  142. // Sleep
  143. loop {
  144. // wfi needs to be disabled for GDB
  145. /*// add some side effect to prevent this from turning into a UDF instruction
  146. // see rust-lang/rust#28728 for details
  147. atomic::compiler_fence(Ordering::SeqCst);*/
  148. cortex_m::asm::wfi();
  149. }
  150. }
  151. };
  152. /*#![no_main]
  153. #![no_std]
  154. extern crate cortex_m;
  155. extern crate cortex_m_rt as rt;
  156. //extern crate cortex_m_rtfm as rtfm;
  157. extern crate embedded_epd as epd;
  158. extern crate embedded_hal;
  159. extern crate mkl25z4;
  160. extern crate mkl25z4_hal as hal;
  161. //extern crate panic_halt;
  162. extern crate panic_semihosting;
  163. extern crate void;
  164. #[macro_use(block)]
  165. extern crate nb;
  166. extern crate bme280;
  167. mod board;
  168. mod assets {
  169. include!(concat!(env!("OUT_DIR"), "/assets.rs"));
  170. }
  171. use bme280::BME280;
  172. use board::led;
  173. use embedded_hal::prelude::*;
  174. use embedded_hal::timer::CountDown;
  175. use epd::{gui, Display};
  176. use hal::gpio::GpioExt;
  177. use hal::i2c::BlockingI2c;
  178. use hal::spi::{Phase, Polarity, Spi};
  179. use hal::time::{NonCopyableMonoTimer, U32Ext};
  180. use hal::timer::{Timer, TimerInterrupt};
  181. use rt::pre_init;
  182. use rtfm::{app, Threshold};
  183. /*use core::sync::atomic;
  184. use core::sync::atomic::Ordering;*/
  185. struct EPDTimer<Timer> {
  186. timer: Timer,
  187. }
  188. impl<Timer> CountDown for EPDTimer<Timer>
  189. where
  190. Timer: CountDown<Time = hal::time::Hertz>,
  191. {
  192. type Time = epd::Hertz;
  193. fn start<T>(&mut self, timeout: T)
  194. where
  195. T: Into<epd::Hertz>,
  196. {
  197. self.timer.start(hal::time::Hertz(timeout.into().0))
  198. }
  199. fn wait(&mut self) -> nb::Result<(), void::Void> {
  200. self.timer.wait()
  201. }
  202. }
  203. #[pre_init]
  204. unsafe fn disable_watchdog() {
  205. use mkl25z4::SIM;
  206. (*SIM::ptr()).copc.write(|w| w.bits(0));
  207. }
  208. app! {
  209. device: mkl25z4,
  210. resources: {
  211. static ON: bool = false;
  212. static pit: hal::timer::Timer<mkl25z4::PIT>;
  213. static rgb_led: led::Led;
  214. },
  215. tasks: {
  216. PIT: {
  217. path: pit_handler,
  218. resources: [pit, rgb_led, ON],
  219. },
  220. },
  221. }
  222. fn init(mut p: init::Peripherals, _r: init::Resources) -> init::LateResources {
  223. mkl25z4_hal::watchdog::disable(&mut p.device.SIM);
  224. let clocks = mkl25z4_hal::clocks::init();
  225. //let time = hal::time::MonoTimer::new(p.device.PIT, clocks, &mut p.device.SIM);
  226. let mut gpiob = p.device.GPIOB.split(&mut p.device.SIM);
  227. let mut gpioc = p.device.GPIOC.split(&mut p.device.SIM);
  228. let mut gpiod = p.device.GPIOD.split(&mut p.device.SIM);
  229. let mut led = led::Led {
  230. red: gpiob.pb18.into_push_pull_output(&mut gpiob.pddr),
  231. green: gpiob.pb19.into_push_pull_output(&mut gpiob.pddr),
  232. blue: gpiod.pd1.into_push_pull_output(&mut gpiod.pddr),
  233. };
  234. //led::init(&p.device.PORTB, &p.device.GPIOB, &p.device.PORTD, &p.device.GPIOD, &p.device.SIM);
  235. led.set_color(true, true, true);
  236. let timer = NonCopyableMonoTimer::new(p.device.PIT, clocks, &mut p.device.SIM);
  237. let scl = gpiob.pb2.into_alternate(&mut gpiob.pddr);
  238. let sda = gpiob.pb3.into_alternate(&mut gpiob.pddr);
  239. let i2c0 = BlockingI2c::i2c0(
  240. p.device.I2C0,
  241. sda,
  242. scl,
  243. 100000u32.hz(),
  244. timer,
  245. clocks,
  246. &mut p.device.SIM,
  247. 1000000,
  248. 10,
  249. 1000000,
  250. 1000000,
  251. );
  252. let mut bme280 = BME280::new_primary(i2c0);
  253. let (_, _, _, timer) = i2c0.free(&mut p.device.SIM);
  254. let pit_ = timer.free(&mut p.device.SIM);
  255. /*for _ in 0..2 {
  256. time.delay_ms(1000);
  257. led.set_color(false, false, true);
  258. time.delay_ms(1000);
  259. led.set_color(false, true, false);
  260. }*/
  261. let mosi = gpioc.pc6.into_alternate(&mut gpioc.pddr);
  262. let miso = gpioc.pc7.into_alternate(&mut gpioc.pddr);
  263. let sck = gpioc.pc5.into_alternate(&mut gpioc.pddr);
  264. let mode = hal::spi::Mode {
  265. polarity: Polarity::IdleLow,
  266. phase: Phase::CaptureOnFirstTransition,
  267. };
  268. let spi0 = Spi::spi0(p.device.SPI0, mosi, miso, sck, mode, &mut p.device.SIM);
  269. // Initialize the display.
  270. let busy = gpioc.pc3.into_floating_input(&mut gpioc.pddr);
  271. let mut reset = gpioc.pc2.into_push_pull_output(&mut gpioc.pddr);
  272. reset.set_high();
  273. let mut data_cmd = gpioc.pc1.into_push_pull_output(&mut gpioc.pddr);
  274. data_cmd.set_high();
  275. let mut cs = gpioc.pc0.into_push_pull_output(&mut gpioc.pddr);
  276. cs.set_high();
  277. let t = EPDTimer {
  278. timer: Timer::pit(pit_, hal::time::Hertz(1), clocks, &mut p.device.SIM),
  279. };
  280. let mut display = epd::gdew042z15::GDEW042Z15::new(spi0, busy, reset, data_cmd, cs, t);
  281. block!(display.init()).ok();
  282. block!(display.start_frame()).ok();
  283. led.set_color(false, false, false);
  284. let layout = gui::Layout::new(
  285. 400,
  286. 300,
  287. gui::VerticalSplit::expand_bottom(
  288. 24,
  289. gui::Fill::new(epd::Color::White),
  290. gui::VerticalSplit::expand_bottom(
  291. 1,
  292. gui::Fill::new(epd::Color::Black),
  293. gui::HorizontalSplit::expand_right(
  294. 48,
  295. gui::Fill::new(epd::Color::White),
  296. //gui::Image::new(&assets::ALARM_CLOCK_36),
  297. gui::HorizontalSplit::expand_right(
  298. 1,
  299. gui::Fill::new(epd::Color::Black),
  300. gui::HorizontalSplit::expand_left(
  301. 49,
  302. gui::VerticalSplit::expand_bottom(
  303. 132,
  304. gui::Align::new(
  305. gui::HorizontalAlign::Center,
  306. gui::VerticalAlign::Top,
  307. gui::Text::new("12:34", &assets::ROBOTO_100),
  308. ),
  309. gui::Align::new(
  310. gui::HorizontalAlign::Center,
  311. gui::VerticalAlign::Top,
  312. gui::HorizontalSplit::expand_right(
  313. 36,
  314. gui::Image::new(&assets::ALARM_CLOCK_36),
  315. gui::Text::new("Do. 8:00", &assets::ROBOTO_30),
  316. ),
  317. ),
  318. ),
  319. gui::Fill::new(epd::Color::White),
  320. ),
  321. ),
  322. ),
  323. ),
  324. ),
  325. );
  326. let mut row_buffer = [0u8; 400 / 8];
  327. layout.render(&mut display, &mut row_buffer);
  328. display.end_frame();
  329. led.set_color(true, true, false);
  330. let (_, _, _, _, _, mut t) = display.destroy();
  331. /*let pit_ = display.time.deactivate(&mut p.device.SIM);*/
  332. t.start(epd::Hertz(1));
  333. t.timer.enable_interrupt();
  334. p.core.NVIC.enable(mkl25z4::Interrupt::PIT);
  335. led.set_color(true, true, true);
  336. init::LateResources {
  337. pit: t.timer,
  338. rgb_led: led,
  339. }
  340. }
  341. fn idle() -> ! {
  342. // Sleep
  343. loop {
  344. // wfi needs to be disabled for GDB
  345. /*// add some side effect to prevent this from turning into a UDF instruction
  346. // see rust-lang/rust#28728 for details
  347. atomic::compiler_fence(Ordering::SeqCst);*/
  348. rtfm::wfi();
  349. }
  350. }
  351. // TASKS
  352. // Toggle the state of the LED
  353. fn pit_handler(_t: &mut Threshold, mut r: PIT::Resources) {
  354. if *r.ON {
  355. r.rgb_led.set_color(false, false, true);
  356. } else {
  357. r.rgb_led.set_color(true, false, false);
  358. }
  359. r.pit.wait().ok();
  360. *r.ON = !*r.ON;
  361. }*/