From aa67c399e617b77ede0e09ce47bdbc9af9185019 Mon Sep 17 00:00:00 2001 From: Eugene Batalov Date: Thu, 7 Jul 2016 23:26:29 +0300 Subject: [PATCH 1/4] car_fmw: add support for car rotation to engine interface --- car_fmw/src/car_engine.h | 46 +++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/car_fmw/src/car_engine.h b/car_fmw/src/car_engine.h index 97a67a39741..5d92d582be6 100644 --- a/car_fmw/src/car_engine.h +++ b/car_fmw/src/car_engine.h @@ -3,21 +3,25 @@ #include "stm32f4_discovery.h" #include "stm32f4xx_conf.h" -//#define CAR_ENGINE_ENABLE +#define CAR_ENGINE_ENABLE #define CAR_ENGINE_GPIO_PORT_CLOCK RCC_AHB1Periph_GPIOB #define CAR_ENGINE_GPIO_PORT GPIOB -#define CAR_ENGINE_ENABLE_PIN GPIO_Pin_4 -#define CAR_ENGINE_DIRECTION_FORWARD_PIN GPIO_Pin_5 -#define CAR_ENGINE_DIRECTION_BACKWARD_PIN GPIO_Pin_6 +#define CAR_ENGINE_ENABLE_PIN GPIO_Pin_3 +#define CAR_ENGINE_LWHEEL_FWD_PIN GPIO_Pin_4 +#define CAR_ENGINE_LWHEEL_BKWD_PIN GPIO_Pin_5 +#define CAR_ENGINE_RWHEEL_FWD_PIN GPIO_Pin_6 +#define CAR_ENGINE_RWHEEL_BKWD_PIN GPIO_Pin_7 inline void engine_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(CAR_ENGINE_GPIO_PORT_CLOCK, ENABLE); GPIO_InitStructure.GPIO_Pin = CAR_ENGINE_ENABLE_PIN - | CAR_ENGINE_DIRECTION_FORWARD_PIN - | CAR_ENGINE_DIRECTION_BACKWARD_PIN; + | CAR_ENGINE_LWHEEL_FWD_PIN + | CAR_ENGINE_LWHEEL_BKWD_PIN + | CAR_ENGINE_RWHEEL_FWD_PIN + | CAR_ENGINE_RWHEEL_BKWD_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; @@ -28,9 +32,11 @@ inline void engine_init(void) inline void engine_stop(void) { GPIO_ResetBits(CAR_ENGINE_GPIO_PORT, 0 - | CAR_ENGINE_DIRECTION_BACKWARD_PIN + | CAR_ENGINE_LWHEEL_BKWD_PIN | CAR_ENGINE_ENABLE_PIN - | CAR_ENGINE_DIRECTION_FORWARD_PIN); + | CAR_ENGINE_LWHEEL_FWD_PIN + | CAR_ENGINE_RWHEEL_FWD_PIN + | CAR_ENGINE_RWHEEL_BKWD_PIN); } #ifdef CAR_ENGINE_ENABLE @@ -38,16 +44,36 @@ inline void engine_forward(void) { engine_stop(); GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_ENABLE_PIN); - GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_DIRECTION_FORWARD_PIN); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_LWHEEL_FWD_PIN); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_RWHEEL_FWD_PIN); } inline void engine_backward(void) { engine_stop(); GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_ENABLE_PIN); - GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_DIRECTION_BACKWARD_PIN); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_LWHEEL_BKWD_PIN); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_RWHEEL_BKWD_PIN); +} + +inline void engine_turn_left(void) +{ + engine_stop(); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_ENABLE_PIN); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_LWHEEL_BKWD_PIN); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_RWHEEL_FWD_PIN); +} + +inline void engine_turn_right(void) +{ + engine_stop(); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_ENABLE_PIN); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_LWHEEL_FWD_PIN); + GPIO_SetBits(CAR_ENGINE_GPIO_PORT, CAR_ENGINE_RWHEEL_BKWD_PIN); } #else #define engine_forward(...); #define engine_backward(...); +#define engine_turn_right(...); +#define engine_turn_left(...); #endif // CAR_ENGINE_ENABLE From c7b88455e576a49a0d015fcf1681f2a4e1eec421 Mon Sep 17 00:00:00 2001 From: Eugene Batalov Date: Thu, 7 Jul 2016 23:27:07 +0300 Subject: [PATCH 2/4] car_fmw: implement 5 demo car programs Demo programs: 1. Go forward 2. Go backward 3. Rotate right 4. Rotate left 5. Complicated route All programs are running in a cycle + Refactor delay.h code to have common code style with main.c --- car_fmw/src/delay.h | 16 --------- car_fmw/src/main.c | 87 +++++++++++++++++++++++++++++++-------------- car_fmw/src/wait.h | 6 ++++ 3 files changed, 67 insertions(+), 42 deletions(-) delete mode 100644 car_fmw/src/delay.h create mode 100644 car_fmw/src/wait.h diff --git a/car_fmw/src/delay.h b/car_fmw/src/delay.h deleted file mode 100644 index 492981a32aa..00000000000 --- a/car_fmw/src/delay.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "stm32f4_discovery.h" -#include "stm32f4xx_conf.h" - -/** - * @brief Delay Function. - * @param nCount:specifies the Delay time length. - * @retval None - */ -inline void Delay(__IO uint32_t nCount) -{ - while(nCount--) - { - } -} diff --git a/car_fmw/src/main.c b/car_fmw/src/main.c index 198cfdff03a..a7bcf4f39df 100644 --- a/car_fmw/src/main.c +++ b/car_fmw/src/main.c @@ -1,10 +1,67 @@ #include "car_leds.h" #include "car_engine.h" -#include "delay.h" +#include "wait.h" + +const uint32_t PROGRAM_DURATION = 0x3FFFFF; +static void program_forward(void) +{ + engine_forward(); + wait(PROGRAM_DURATION); +} + +static void program_backward(void) +{ + engine_backward(); + wait(PROGRAM_DURATION); +} + +static void program_rotation_left(void) +{ + engine_turn_left(); + wait(PROGRAM_DURATION); +} + +static void program_rotation_right(void) +{ + engine_turn_right(); + wait(PROGRAM_DURATION); +} + +static void program_arbitraty_route(void) +{ + const int ROUTE_PIECE_DURATION = 6 * PROGRAM_DURATION; + engine_forward(); + wait(ROUTE_PIECE_DURATION); + + engine_backward(); + wait(ROUTE_PIECE_DURATION); + + engine_forward(); + wait(ROUTE_PIECE_DURATION / 2); + + engine_turn_right(); + wait(ROUTE_PIECE_DURATION); + + engine_forward(); + wait(ROUTE_PIECE_DURATION / 2); + + engine_backward(); + wait(ROUTE_PIECE_DURATION / 2); + + engine_turn_left(); + wait(ROUTE_PIECE_DURATION); + + engine_backward(); + wait(ROUTE_PIECE_DURATION / 2); + + engine_stop(); + wait(ROUTE_PIECE_DURATION / 2); +} + int main(void) { - /*!< At this stage the microcontroller clock setting is already configured, + /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to @@ -14,29 +71,7 @@ int main(void) leds_init(); engine_init(); - const int DELAY = 0x3FFFFF; - while (1) - { - led_set(LED_GREEN, true); - Delay(DELAY); - - engine_forward(); - led_set(LED_ORANGE, true); - Delay(DELAY); - - engine_stop(); - led_set(LED_RED, true); - Delay(DELAY); - - engine_backward(); - led_set(LED_BLUE, true); - Delay(DELAY); - - engine_stop(); - led_set(LED_GREEN, false); - led_set(LED_ORANGE, false); - led_set(LED_RED, false); - led_set(LED_BLUE, false); - Delay(DELAY); + while(1) { + program_forward(); } } diff --git a/car_fmw/src/wait.h b/car_fmw/src/wait.h new file mode 100644 index 00000000000..227b37c9775 --- /dev/null +++ b/car_fmw/src/wait.h @@ -0,0 +1,6 @@ +#pragma once + +inline void wait(uint32_t loops) +{ + while(--loops); +} From d0ea89cbb335e45d159e87fa16620b27b3417568 Mon Sep 17 00:00:00 2001 From: Eugene Batalov Date: Thu, 7 Jul 2016 23:49:43 +0300 Subject: [PATCH 3/4] car_fmw: reuse STM evaluation board library code in car_led library --- car_fmw/src/car_leds.h | 47 +++++++++--------------------------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/car_fmw/src/car_leds.h b/car_fmw/src/car_leds.h index 1d0992d6709..98d12cbe046 100644 --- a/car_fmw/src/car_leds.h +++ b/car_fmw/src/car_leds.h @@ -5,54 +5,27 @@ #include "stm32f4_discovery.h" #include "stm32f4xx_conf.h" -#define CAR_LED_GPIO_PORT_CLOCK RCC_AHB1Periph_GPIOD -#define CAR_LED_GPIO_PORT GPIOD -#define CAR_LED_PIN_GREEN GPIO_Pin_12 -#define CAR_LED_PIN_ORANGE GPIO_Pin_13 -#define CAR_LED_PIN_RED GPIO_Pin_14 -#define CAR_LED_PIN_BLUE GPIO_Pin_15 - inline void leds_init(void) { - GPIO_InitTypeDef GPIO_InitStructure; - RCC_AHB1PeriphClockCmd(CAR_LED_GPIO_PORT_CLOCK, ENABLE); - GPIO_InitStructure.GPIO_Pin = CAR_LED_PIN_GREEN - | CAR_LED_PIN_ORANGE - | CAR_LED_PIN_RED - | CAR_LED_PIN_BLUE; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(CAR_LED_GPIO_PORT, &GPIO_InitStructure); + STM_EVAL_LEDInit(LED4); + STM_EVAL_LEDInit(LED3); + STM_EVAL_LEDInit(LED5); + STM_EVAL_LEDInit(LED6); } typedef enum { - LED_GREEN, - LED_ORANGE, - LED_RED, - LED_BLUE + LED_GREEN = LED4, + LED_ORANGE = LED3, + LED_RED = LED5, + LED_BLUE = LED6 } led_t; inline void led_set(led_t led, bool on) { - int led_pin = CAR_LED_PIN_GREEN; - switch(led) { - case LED_ORANGE: - led_pin = CAR_LED_PIN_ORANGE; - break; - case LED_RED: - led_pin = CAR_LED_PIN_RED; - break; - case LED_BLUE: - led_pin = CAR_LED_PIN_BLUE; - break; - } - if (on) - GPIO_SetBits(CAR_LED_GPIO_PORT, led_pin); + STM_EVAL_LEDOn(led); else - GPIO_ResetBits(CAR_LED_GPIO_PORT, led_pin); + STM_EVAL_LEDOff(led); } From 4cb33ba88f0edd0c99f7a6ccd4f1dec67b6877e7 Mon Sep 17 00:00:00 2001 From: Eugene Batalov Date: Fri, 8 Jul 2016 16:25:49 +0300 Subject: [PATCH 4/4] car_fmw: implement switching of current car program using push button --- car_fmw/src/car_user_btn.h | 26 ++++++++++++++++ car_fmw/src/main.c | 61 +++++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 car_fmw/src/car_user_btn.h diff --git a/car_fmw/src/car_user_btn.h b/car_fmw/src/car_user_btn.h new file mode 100644 index 00000000000..79dccf90c89 --- /dev/null +++ b/car_fmw/src/car_user_btn.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#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); +} diff --git a/car_fmw/src/main.c b/car_fmw/src/main.c index a7bcf4f39df..a24f00545b5 100644 --- a/car_fmw/src/main.c +++ b/car_fmw/src/main.c @@ -1,5 +1,8 @@ +#include + #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(); } }