5
5
#![ no_std]
6
6
#![ no_main]
7
7
8
- use core:: fmt:: Write ;
8
+ mod ui;
9
+
9
10
use embassy_executor:: Spawner ;
10
11
use embassy_rp:: bind_interrupts;
11
- use embassy_rp:: i2c:: { self , Blocking , Config , I2c } ;
12
- use embassy_rp:: peripherals:: I2C1 ;
12
+ use embassy_rp:: i2c:: { self , Config } ;
13
13
use embassy_rp:: peripherals:: USB ;
14
14
use embassy_rp:: usb:: { Driver , InterruptHandler as USBInterruptHandler } ;
15
15
use embassy_sync:: blocking_mutex:: raw:: ThreadModeRawMutex ;
16
16
use embassy_sync:: mutex:: Mutex ;
17
- use embedded_graphics:: image:: { Image , ImageRaw } ;
18
- use embedded_graphics:: mono_font:: ascii:: FONT_6X12 ;
19
- use embedded_graphics:: mono_font:: MonoTextStyle ;
20
- use embedded_graphics:: text:: Text ;
21
- use embedded_graphics:: { pixelcolor:: BinaryColor , prelude:: * } ;
22
- use ssd1306:: mode:: BufferedGraphicsMode ;
23
- use ssd1306:: { prelude:: * , I2CDisplayInterface , Ssd1306 } ;
24
17
use { defmt_rtt as _, panic_probe as _} ;
25
18
19
+ use self :: ui:: { draw_ui_task, UiScreen , UiState } ;
20
+
26
21
bind_interrupts ! ( struct Irqs {
27
22
USBCTRL_IRQ => USBInterruptHandler <USB >;
28
23
} ) ;
29
24
30
- const DISPLAY_FRAME_TIME : u64 = 1000 / 4 ;
31
-
32
- const RUST_LOGO_BYTES : & [ u8 ] = include_bytes ! ( "../assets/rust.raw" ) ;
33
-
34
- type Display = Ssd1306 <
35
- I2CInterface < I2c < ' static , I2C1 , Blocking > > ,
36
- DisplaySize128x64 ,
37
- BufferedGraphicsMode < DisplaySize128x64 > ,
38
- > ;
39
-
40
25
type Resource < R > = Mutex < ThreadModeRawMutex , Option < R > > ;
41
26
42
- enum UiScreen {
43
- HelloWorld ,
44
- RustLogo ,
45
- }
46
-
47
- impl UiScreen {
48
- fn draw ( & self , display : & mut Display ) {
49
- display. clear_buffer ( ) ;
50
-
51
- match self {
52
- UiScreen :: HelloWorld => {
53
- display. clear_buffer ( ) ;
54
-
55
- Text :: new (
56
- "Hello, World!" ,
57
- Point :: new ( 4 , 12 ) ,
58
- MonoTextStyle :: new ( & FONT_6X12 , BinaryColor :: On ) ,
59
- )
60
- . draw ( display)
61
- . unwrap ( ) ;
62
- }
63
- UiScreen :: RustLogo => {
64
- display. clear_buffer ( ) ;
65
-
66
- let raw: ImageRaw < BinaryColor > = ImageRaw :: new ( RUST_LOGO_BYTES , 64 ) ;
67
- let im = Image :: new ( & raw , Point :: new ( 32 , 0 ) ) ;
68
-
69
- im. draw ( display) . unwrap ( ) ;
70
- }
71
- }
72
-
73
- display. flush ( ) . unwrap ( ) ;
74
- }
75
- }
76
-
77
- struct UiState {
78
- display : Display ,
79
- screen : UiScreen ,
80
- }
81
-
82
- impl UiState {
83
- fn new ( i2c : I2c < ' static , I2C1 , Blocking > ) -> Self {
84
- let interface = I2CDisplayInterface :: new ( i2c) ;
85
- let mut display =
86
- Ssd1306 :: new ( interface, DisplaySize128x64 , DisplayRotation :: Rotate0 )
87
- . into_buffered_graphics_mode ( ) ;
88
- display. init ( ) . unwrap ( ) ;
89
-
90
- Self {
91
- display,
92
- screen : UiScreen :: HelloWorld ,
93
- }
94
- }
95
-
96
- fn draw ( & mut self ) {
97
- self . screen . draw ( & mut self . display ) ;
98
- }
99
- }
100
-
27
+ const DISPLAY_FRAME_TIME : u64 = 1000 / 4 ;
101
28
static UI_STATE : Resource < UiState > = Resource :: new ( None ) ;
102
29
103
30
#[ embassy_executor:: task]
104
31
async fn logger_task ( driver : Driver < ' static , USB > ) {
105
32
embassy_usb_logger:: run!( 1024 , log:: LevelFilter :: Info , driver) ;
106
33
}
107
34
108
- #[ embassy_executor:: task]
109
- async fn draw_ui_task ( ui : & ' static Resource < UiState > ) {
110
- let mut frame_ticker = embassy_time:: Ticker :: every (
111
- embassy_time:: Duration :: from_millis ( DISPLAY_FRAME_TIME ) ,
112
- ) ;
113
-
114
- loop {
115
- {
116
- let mut ui = ui. lock ( ) . await ;
117
- ui. as_mut ( ) . unwrap ( ) . draw ( ) ;
118
- }
119
-
120
- frame_ticker. next ( ) . await ;
121
- }
122
- }
123
-
124
35
#[ embassy_executor:: main]
125
36
async fn main ( spawner : Spawner ) {
126
37
let p = embassy_rp:: init ( Default :: default ( ) ) ;
@@ -131,11 +42,15 @@ async fn main(spawner: Spawner) {
131
42
let sda = p. PIN_14 ;
132
43
let scl = p. PIN_15 ;
133
44
134
- let i2c = i2c :: I2c :: new_blocking ( p . I2C1 , scl , sda , Config :: default ( ) ) ;
45
+ // build the UI state
135
46
{
136
- * ( UI_STATE . lock ( ) . await ) = Some ( UiState :: new ( i2c) ) ;
47
+ * ( UI_STATE . lock ( ) . await ) = Some ( UiState :: new ( i2c:: I2c :: new_blocking (
48
+ p. I2C1 ,
49
+ scl,
50
+ sda,
51
+ Config :: default ( ) ,
52
+ ) ) ) ;
137
53
}
138
-
139
54
spawner. spawn ( draw_ui_task ( & UI_STATE ) ) . unwrap ( ) ;
140
55
141
56
// switch between screens every 2 seconds
0 commit comments