@@ -51,11 +51,14 @@ void SystemClock_Config(void);
5151static void MX_GPIO_Init (void );
5252static void MX_USART2_UART_Init (void );
5353/* USER CODE BEGIN PFP */
54+ #define EVQ_SIZE 10
55+
5456enum event
5557{
5658 ev_none = 0 ,
57- ev_button_press ,
58- ev_state_timeout
59+ ev_button_press = 1 ,
60+ ev_state_timeout = 2 ,
61+ ev_error = -99
5962};
6063
6164enum state
@@ -70,14 +73,67 @@ enum state
7073 s_cars_ready
7174};
7275
76+ enum event evq [ EVQ_SIZE ];
77+
78+ int evq_count = 0 ;
79+ int evq_front_ix = 0 ;
80+ int evq_rear_ix = 0 ;
81+
7382void set_traffic_lights (enum state s );
7483int is_button_pressed ();
84+ void evq_push_back (enum event e );
85+ enum event evq_pop_front ();
86+ void my_systick_handler ();
87+ void evq_init ();
7588
7689/* USER CODE END PFP */
7790
7891/* Private user code ---------------------------------------------------------*/
7992/* USER CODE BEGIN 0 */
8093
94+ void evq_init () {
95+ for (int i = 0 ; i < EVQ_SIZE ; i ++ ) {
96+ evq [i ] = ev_error ;
97+ }
98+ }
99+
100+ int systick_count = 0 ;
101+ void my_systick_handler ()
102+ {
103+ systick_count ++ ;
104+ if (systick_count == 1000 )
105+ {
106+ HAL_GPIO_TogglePin (LD2_GPIO_Port , LD2_Pin );
107+ systick_count = 0 ;
108+ }
109+ }
110+
111+ void evq_push_back (enum event e )
112+ {
113+ // if queue is full, ignore e
114+ if ( evq_count < EVQ_SIZE )
115+ {
116+ evq [evq_rear_ix ] = e ;
117+ evq_rear_ix ++ ;
118+ evq_rear_ix %= EVQ_SIZE ;
119+ evq_count ++ ;
120+ }
121+ }
122+
123+ enum event evq_pop_front ()
124+ {
125+ enum event e = ev_none ;
126+ if ( evq_count > 0 )
127+ {
128+ e = evq [evq_front_ix ];
129+ evq [evq_front_ix ] = ev_error ; // detect stupidity
130+ evq_front_ix ++ ;
131+ evq_front_ix %= EVQ_SIZE ;
132+ evq_count -- ;
133+ }
134+ return e ;
135+ }
136+
81137// returns 1 if blue button is pressed
82138// return 0 if blue button isn't pressed
83139int is_button_pressed () {
@@ -209,7 +265,7 @@ int main(void)
209265 /* Infinite loop */
210266 /* USER CODE BEGIN WHILE */
211267 enum state current_state = s_init ;
212- enum event current_event = ev_none ;
268+ evq_init () ;
213269
214270 uint32_t ticks_left_in_state = 0 ;
215271 uint32_t curr_tick = 0 ;
@@ -218,9 +274,6 @@ int main(void)
218274 int curr_press = is_button_pressed ();
219275 int last_press = curr_press ;
220276
221- // uint32_t ticks_left_in_state = 0;
222- // uint32_t curr_tick = 0;
223- // uint32_t last_tick = 0;
224277 while (1 )
225278 {
226279
@@ -233,10 +286,13 @@ int main(void)
233286 }
234287 else
235288 {
289+ // Garanterar att knapptryckning inte är aktiv om nuvarande tillstånd inte är s_init eller s_cars_go
236290 curr_press = 0 ;
237291 }
238292
239293 // Lys upp en diod vid knapptryckning
294+ // Lampan kommer alltid lysa när vi trycker
295+ // Knappen kommer enbart ha inverkan vid aktuella tillstånd
240296 if (is_button_pressed ())
241297 {
242298 HAL_GPIO_WritePin (LD2_GPIO_Port , LD2_Pin , GPIO_PIN_SET );
@@ -248,21 +304,19 @@ int main(void)
248304
249305 // Kontrollera om det har skett en positiv flank på knappen
250306 if (curr_press && !last_press ) {
251- current_event = ev_button_press ;
252- } else {
253- current_event = ev_none ;
254- }
307+ evq_push_back (ev_button_press );
308+ }
255309
256310 // Kontrollera om det är dags att generera en ev_state_timeout
257311 if (ticks_left_in_state == 0 && current_state != s_init && current_state != s_cars_go ) {
258- current_event = ev_state_timeout ;
312+ evq_push_back ( ev_state_timeout ) ;
259313 }
260314
261315 // Hantera nästa tillstånd baserat på nuvarande tillstånd och händelse
262316 switch (current_state ) {
263317 case s_init :
264318 // Hantera händelser i s_init-tillståndet
265- if (current_event == ev_button_press ) {
319+ if (evq_pop_front () == ev_button_press ) {
266320 // Gå till nästa tillstånd
267321 current_state = s_cars_stopped ;
268322 set_traffic_lights (current_state );
@@ -277,19 +331,18 @@ int main(void)
277331
278332 case s_cars_stopping :
279333 // Hantera händelser i s_cars_stopping-tillståndet
280- if (current_event == ev_state_timeout ) {
334+ if (evq_pop_front () == ev_state_timeout ) {
281335 // Gå till nästa tillstånd
282336 current_state = s_cars_stopped ;
283337 set_traffic_lights (current_state );
284338 // Sätt timeout för nästa tillstånd
285339 ticks_left_in_state = 3000 ;
286-
287340 }
288341 break ;
289342
290343 case s_cars_stopped :
291344 // Hantera händelser i s_cars_stopped-tillståndet
292- if (current_event == ev_state_timeout ) {
345+ if (evq_pop_front () == ev_state_timeout ) {
293346 // Gå till nästa tillstånd
294347 current_state = s_pedestrian_walk ;
295348 set_traffic_lights (current_state );
@@ -300,7 +353,7 @@ int main(void)
300353
301354 case s_pedestrian_walk :
302355 // Hantera händelser i s_pedestrian_walk-tillståndet
303- if (current_event == ev_state_timeout ) {
356+ if (evq_pop_front () == ev_state_timeout ) {
304357 // Gå till nästa tillstånd
305358 current_state = s_pedestrian_stop ;
306359 set_traffic_lights (current_state );
@@ -311,7 +364,7 @@ int main(void)
311364
312365 case s_pedestrian_stop :
313366 // Hantera händelser i s_pedestrian_stop-tillståndet
314- if (current_event == ev_state_timeout ) {
367+ if (evq_pop_front () == ev_state_timeout ) {
315368 // Gå till nästa tillstånd
316369 current_state = s_cars_ready ;
317370 set_traffic_lights (current_state );
@@ -322,7 +375,7 @@ int main(void)
322375
323376 case s_cars_ready :
324377 // Hantera händelser i s_cars_ready-tillståndet
325- if (current_event == ev_state_timeout ) {
378+ if (evq_pop_front () == ev_state_timeout ) {
326379 // Gå till nästa tillstånd
327380 current_state = s_cars_go ;
328381 set_traffic_lights (current_state );
@@ -333,7 +386,7 @@ int main(void)
333386
334387 case s_cars_go :
335388 // Hantera händelser i s_cars_go-tillståndet
336- if (current_event == ev_button_press ) {
389+ if (evq_pop_front () == ev_button_press ) {
337390 // Gå till nästa tillstånd
338391 current_state = s_pushed_wait ;
339392 set_traffic_lights (current_state );
@@ -348,7 +401,7 @@ int main(void)
348401
349402 case s_pushed_wait :
350403 // Hantera händelser i s_pushed_wait-tillståndet
351- if (current_event == ev_state_timeout ) {
404+ if (evq_pop_front () == ev_state_timeout ) {
352405 // Gå till nästa tillstånd
353406 current_state = s_cars_stopping ;
354407 // Sätt timeout för nästa tillstånd
0 commit comments