car_fmw: implement switching of current car program using push button

This commit is contained in:
Eugene Batalov
2016-07-08 16:25:49 +03:00
parent d0ea89cbb3
commit 4cb33ba88f
2 changed files with 86 additions and 1 deletions
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include <stdbool.h>
#include "stm32f4_discovery.h"
typedef void (*user_btn_handler_t)(void);
static user_btn_handler_t user_btn_handler;
// @handler can be NULL
inline void user_btn_init(user_btn_handler_t handler)
{
user_btn_handler = handler;
STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);
}
inline bool user_btn_is_pushed(void)
{
return STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET;
}
void EXTI0_IRQHandler(void)
{
if (user_btn_handler)
user_btn_handler();
EXTI_ClearITPendingBit(USER_BUTTON_EXTI_LINE);
}
+60 -1
View File
@@ -1,5 +1,8 @@
#include <stddef.h>
#include "car_leds.h"
#include "car_engine.h"
#include "car_user_btn.h"
#include "wait.h"
const uint32_t PROGRAM_DURATION = 0x3FFFFF;
@@ -58,6 +61,59 @@ static void program_arbitraty_route(void)
wait(ROUTE_PIECE_DURATION / 2);
}
typedef void (*car_program_code_t)(void);
typedef struct car_program_desc {
car_program_code_t code;
struct {
bool green : 1;
bool orange : 1;
bool red : 1;
bool blue : 1;
} leds;
} car_program_desc_t;
static car_program_desc_t const PROGRAMS[] = {
{ .code = program_forward, .leds = { .green = 1 } },
{ .code = program_backward, .leds = { .orange = 1 } },
{ .code = program_rotation_left, .leds = { .red = 1 } },
{ .code = program_rotation_right, .leds = { .blue = 1 } },
{ .code = program_arbitraty_route, .leds = { .green = 1, .orange = 1 } }
};
static const size_t PROGRAMS_CNT = sizeof(PROGRAMS) / sizeof(PROGRAMS[0]);
static size_t cur_program_ix;
static __IO bool next_program_pending = false;
static void set_cur_program(size_t program_ix)
{
cur_program_ix = program_ix;
led_set(LED_GREEN, false);
led_set(LED_ORANGE, false);
led_set(LED_RED, false);
led_set(LED_BLUE, false);
const car_program_desc_t *cpd = &PROGRAMS[cur_program_ix];
if (cpd->leds.green)
led_set(LED_GREEN, true);
if (cpd->leds.orange)
led_set(LED_ORANGE, true);
if (cpd->leds.red)
led_set(LED_RED, true);
if (cpd->leds.blue)
led_set(LED_BLUE, true);
}
void proc_next_program_pending(void)
{
if (!next_program_pending)
return;
next_program_pending = false;
set_cur_program((cur_program_ix + 1) % PROGRAMS_CNT);
}
void set_next_program_pending(void)
{
next_program_pending = true;
}
int main(void)
{
@@ -70,8 +126,11 @@ int main(void)
leds_init();
engine_init();
user_btn_init(set_next_program_pending);
set_cur_program(0);
while(1) {
program_forward();
proc_next_program_pending();
PROGRAMS[cur_program_ix].code();
}
}