Simon Says implementation

master
Ondřej Hruška 8 years ago
parent 2093a48bed
commit 85590593ce
  1. 8
      .idea/f103-bluepill.iml
  2. 1
      .idea/inspectionProfiles/Project_Default.xml
  3. 4
      .idea/misc.xml
  4. 10
      .mxproject
  5. 10
      Inc/mxconstants.h
  6. 16
      Src/gpio.c
  7. 11
      User/handlers.c
  8. 2
      User/handlers.h
  9. 20
      User/init.c
  10. 277
      User/user_main.c
  11. 2
      User/user_main.h
  12. 64
      User/utils/ws2812.c
  13. 92
      User/utils/ws2812.h
  14. 40
      f103-bluepill.ioc

@ -5,11 +5,13 @@
<sourceFolder url="file://$MODULE_DIR$/CMakeLists.txt" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/debug.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/timebase.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/ws2812.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/debug.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/timebase.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/syscalls.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/malloc_safe.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/debounce.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/ws2812.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/malloc_safe.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/utils/debounce.h" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/user_main.h" isTestSource="false" />
@ -19,26 +21,26 @@
<sourceFolder url="file://$MODULE_DIR$/User/init.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/User/handlers.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/f103.cmake" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/Src/stm32f1xx_hal_msp.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/Src/gpio.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/Src/stm32f1xx_it.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/Src/main.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/Src/usart.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/Src/stm32f1xx_hal_msp.c" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/STM32F103C8Tx_FLASH.ld" isTestSource="false" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library name="Header Search Paths">
<CLASSES>
<root url="file:///usr/arm-none-eabi/include" />
<root url="file:///usr/lib/gcc/arm-none-eabi/6.1.1/include-fixed" />
<root url="file:///usr/lib/gcc/arm-none-eabi/6.1.1/include" />
<root url="file:///usr/arm-none-eabi/include" />
<root url="file://$MODULE_DIR$/Drivers" />
</CLASSES>
<SOURCES>
<root url="file:///usr/arm-none-eabi/include" />
<root url="file:///usr/lib/gcc/arm-none-eabi/6.1.1/include-fixed" />
<root url="file:///usr/lib/gcc/arm-none-eabi/6.1.1/include" />
<root url="file:///usr/arm-none-eabi/include" />
<root url="file://$MODULE_DIR$/Drivers" />
</SOURCES>
</library>

@ -2,5 +2,6 @@
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="EndlessLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="FormatSpecifiers" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
</profile>
</component>

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$USER_HOME$/devel/f103-bluepill" />
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
<component name="CidrRootsConfiguration">
<libraryRoots>
<file path="$USER_HOME$/devel/f103-bluepill/Drivers" />
<file path="$PROJECT_DIR$/Drivers" />
</libraryRoots>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">

@ -1,12 +1,12 @@
[PreviousLibFiles]
LibFiles=Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102x6.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103x6.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xg.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101x6.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f107xc.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f105xc.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xg.h;
[PreviousGenFiles]
HeaderPath=/home/ondra/devel/f103-bluepill/Inc
SourcePath=/home/ondra/devel/f103-bluepill/Src
HeaderPath=/home/ondra/devel/f103-simon/Inc
SourcePath=/home/ondra/devel/f103-simon/Src
SourceFiles=gpio.h;usart.h;stm32f1xx_it.h;stm32f1xx_hal_conf.h;mxconstants.h;gpio.c;usart.c;stm32f1xx_it.c;stm32f1xx_hal_msp.c;main.c;
HeaderFiles=gpio.h;usart.h;stm32f1xx_it.h;stm32f1xx_hal_conf.h;mxconstants.h;
[PreviousLibFiles]
LibFiles=Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h;Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h;Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;Drivers/CMSIS/Include/core_cmInstr.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/arm_const_structs.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_cmFunc.h;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/arm_math.h;Drivers/CMSIS/Include/cmsis_armcc_V6.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cmSimd.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/arm_common_tables.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102x6.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103x6.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f100xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xg.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101x6.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xe.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f107xc.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f105xc.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f102xb.h;Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f101xg.h;
[PreviousUsedRideFiles]
HeaderPath=../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Include;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;
SourceFiles=../Src/main.c;../Src/gpio.c;../Src/usart.c;../Src/stm32f1xx_it.c;../Src/stm32f1xx_hal_msp.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c;../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c;../Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/system_stm32f1xx.c;../Drivers/CMSIS/Device/ST/STM32F1xx/Source/Templates/gcc/startup_stm32f103xb.s;

@ -43,6 +43,16 @@
#define LED1_Pin GPIO_PIN_13
#define LED1_GPIO_Port GPIOC
#define WSDATA_Pin GPIO_PIN_11
#define WSDATA_GPIO_Port GPIOB
#define BTN1_Pin GPIO_PIN_5
#define BTN1_GPIO_Port GPIOB
#define BTN2_Pin GPIO_PIN_6
#define BTN2_GPIO_Port GPIOB
#define BTN3_Pin GPIO_PIN_7
#define BTN3_GPIO_Port GPIOB
#define BTN4_Pin GPIO_PIN_8
#define BTN4_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */

@ -60,17 +60,33 @@ void MX_GPIO_Init(void)
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(WSDATA_GPIO_Port, WSDATA_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = LED1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = WSDATA_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(WSDATA_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : PBPin PBPin PBPin PBPin */
GPIO_InitStruct.Pin = BTN1_Pin|BTN2_Pin|BTN3_Pin|BTN4_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */

@ -3,20 +3,11 @@
//
#include <common.h>
#include "utils/ws2812.h"
#include "utils/timebase.h"
#include "utils/debug.h"
#include "handlers.h"
/**
* @brief Handle a button press. Delete if not needed - a possible callback for debouncer.
* @param button: button identifier
* @param press: press state (1 = just pressed, 0 = just released)
*/
void ButtonHandler(uint32_t button, bool press)
{
dbg("Button %d, state %d", button, press);
}
/**
* Increment timebase counter each ms.
* This is called by HAL, weak override.

@ -7,8 +7,6 @@
#include <common.h>
void ButtonHandler(uint32_t button, bool press);
void user_Error_Handler();
void user_assert_failed(uint8_t* file, uint32_t line);

@ -5,7 +5,7 @@
#include <common.h>
#include "utils/debounce.h"
#include "init.h"
#include "handlers.h"
#include "user_main.h"
static void init_buttons()
{
@ -15,9 +15,21 @@ static void init_buttons()
debo.GPIOx = GPIOB; // All buttons are on port B
debo.callback = ButtonHandler;
//debo.pin = BTN1_Pin;
//debo.cb_payload = 1;
//debo_register_pin(&debo);
debo.pin = BTN1_Pin;
debo.cb_payload = 0;
debo_register_pin(&debo);
debo.pin = BTN2_Pin;
debo.cb_payload = 1;
debo_register_pin(&debo);
debo.pin = BTN3_Pin;
debo.cb_payload = 2;
debo_register_pin(&debo);
debo.pin = BTN4_Pin;
debo.cb_payload = 3;
debo_register_pin(&debo);
}
/** Init the application */

@ -3,10 +3,221 @@
//
#include <common.h>
#include <string.h>
#include "init.h"
#include "utils/ws2812.h"
#include "utils/timebase.h"
#include "utils/debug.h"
#include "user_main.h"
#include "init.h"
//region Colors
#define C_DARK rgb(0,0,0)
#define C_DIMWHITE rgb(15,15,15)
#define C_OKGREEN rgb(5,40,0)
#define C_CRIMSON rgb(140,0,3)
#define C_DIMRED rgb(20,0,0)
#define C_DIMGREEN rgb(0,20,0)
#define C_DIMBLUE rgb(0,0,35)
#define C_DIMYELLOW rgb(15,10,0)
#define C_BRTRED rgb(120,0,0)
#define C_BRTGREEN rgb(2,80,0)
#define C_BRTBLUE rgb(0,0,180)
#define C_BRTYELLOW rgb(70,60,0)
// assign to positions
#define C_DIM1 C_DIMRED
#define C_DIM2 C_DIMGREEN
#define C_DIM3 C_DIMBLUE
#define C_DIM4 C_DIMYELLOW
#define C_BRT1 C_BRTRED
#define C_BRT2 C_BRTGREEN
#define C_BRT3 C_BRTBLUE
#define C_BRT4 C_BRTYELLOW
//endregion
/** Current game state */
enum GameState_enum {
STATE_NEW_GAME, // new game, waiting for key
STATE_REPLAY, // showing sequence
STATE_USER_INPUT, // waiting for user input of repeated sequence
STATE_SUCCESS_EFFECT, // entered OK, show some fireworks
STATE_FAIL_EFFECT, // entered wrong, show FAIL animation, then reset.
} GameState = STATE_NEW_GAME;
/** Screen colors */
uint32_t screen[4] = {0, 0, 0, 0};
const uint32_t brt[4] = {C_BRT1, C_BRT2, C_BRT3, C_BRT4};
const uint32_t dim[4] = {C_DIM1, C_DIM2, C_DIM3, C_DIM4};
const uint32_t dark[4] = {C_DARK, C_DARK, C_DARK, C_DARK};
#define REPLAY_INTERVAL 400
#define REPLAY_INTERVAL_GAP 75
#define SUC_EFF_TIME 500
#define FAIL_EFF_TIME 1000
/** Sequence of colors to show. Seed is constant thorough a game.
* rng_state is used by rand_r() for building the sequence. */
uint32_t game_seed;
unsigned int game_rng_state;
/** Nr of revealed colors in sequence */
uint32_t game_revealed_n;
/** Nr of next color to replay/input */
uint32_t game_replay_n;
/** Nr of succ repeated colors */
uint32_t game_repeat_n;
void enter_state(enum GameState_enum state);
/** Show current screen colors */
void show_screen()
{
ws2812_send(WSDATA_GPIO_Port, WSDATA_Pin, screen, 4);
}
/** Prepare rng sequence for replay / test */
void reset_sequence()
{
game_rng_state = game_seed;
}
/** Get next item in the sequence */
uint32_t get_next_item()
{
return (uint32_t) rand_r(&game_rng_state) & 0x03;
}
/** Enter state - callback for delayed state change */
void deferred_enter_state(void *state)
{
enter_state((enum GameState_enum) state);
}
/** Future task CB in replay seq */
void replay_callback(void *onOff)
{
bool on = (bool) onOff;
screen[0] = C_DARK;
screen[1] = C_DARK;
screen[2] = C_DARK;
screen[3] = C_DARK;
if (on) {
uint32_t color = get_next_item();
game_replay_n++;
screen[color] = brt[color];
show_screen();
schedule_task(replay_callback, (void *) 0, REPLAY_INTERVAL, false);
} else {
// turning off
show_screen();
// Schedule next turning ON
if (game_replay_n < game_revealed_n) {
schedule_task(replay_callback, (void *) 1, REPLAY_INTERVAL_GAP, false);
} else {
enter_state(STATE_USER_INPUT);
//schedule_task(deferred_enter_state, (void *) STATE_USER_INPUT, 50, false);
}
}
}
/** SUCCESS effect */
void suc_eff_callback(void *onOff)
{
bool on = (bool) onOff;
if (on) {
for (int i = 0; i < 4; i++) screen[i] = C_OKGREEN;
schedule_task(suc_eff_callback, 0, SUC_EFF_TIME, false);
} else {
for (int i = 0; i < 4; i++) screen[i] = C_DARK;
schedule_task(deferred_enter_state, (void *) STATE_REPLAY, 200, false);
}
show_screen();
}
/** ERROR effect */
void fail_eff_callback(void *onOff)
{
bool on = (bool) onOff;
if (on) {
for (int i = 0; i < 4; i++) screen[i] = C_CRIMSON;
schedule_task(fail_eff_callback, 0, FAIL_EFF_TIME, false);
} else {
for (int i = 0; i < 4; i++) screen[i] = C_DARK;
schedule_task(deferred_enter_state, (void *) STATE_NEW_GAME, 200, false);
}
show_screen();
}
/**
* @brief Enter a game state
* @param state
*/
void enter_state(enum GameState_enum state)
{
GameState = state;
switch (state) {
case STATE_NEW_GAME:
// new game - idle state before new game is started
// all dimly lit
for (int i = 0; i < 4; i++) screen[i] = C_DIMWHITE;
break;
case STATE_REPLAY:
game_replay_n = 0;
reset_sequence();
// Start replay
replay_callback((void *) 1);
break;
case STATE_USER_INPUT:
memcpy(screen, dim, sizeof(screen));
// Start entering & checking
game_repeat_n = 0;
reset_sequence();
break;
case STATE_SUCCESS_EFFECT:
memcpy(screen, dim, sizeof(screen));
//suc_eff_callback((void *) 1);
schedule_task(suc_eff_callback, (void *) 1, 250, false);
break;
case STATE_FAIL_EFFECT:
memcpy(screen, dim, sizeof(screen));
//fail_eff_callback((void *) 1);
schedule_task(fail_eff_callback, (void *) 1, 250, false);
break;
}
show_screen();
}
/** Prepare new sequence, using time for seed. */
void prepare_sequence()
{
game_seed = ms_now();
game_rng_state = game_seed;
}
/** Main function, called from MX-generated main.c */
void user_main()
@ -15,6 +226,9 @@ void user_main()
user_init();
enter_state(STATE_NEW_GAME);
// we'll init the sequence when user first presses a button - the time is used as a seed
ms_time_t counter1 = 0;
while (1) {
if (ms_loop_elapsed(&counter1, 1000)) {
@ -23,3 +237,64 @@ void user_main()
}
}
}
/**
* @brief Handle a button press. Callback for debouncer.
* @param button: button identifier
* @param press: press state (1 = just pressed, 0 = just released)
*/
void ButtonHandler(uint32_t button, bool press)
{
dbg("Button %d, state %d", button, press);
switch (GameState) {
case STATE_NEW_GAME:
if (!press) { // released
// user wants to start playing
prepare_sequence();
game_revealed_n = 1; // start with 1 revealed
// darken
memcpy(screen, dark, sizeof(screen));
show_screen();
// start playback with a delay
// this makes it obvious the playback is not a feedback to the pressed button
schedule_task(deferred_enter_state, (void *) STATE_REPLAY, 250, false);
//enter_state(STATE_REPLAY);
}
break;
case STATE_USER_INPUT:
// user is entering a color
memcpy(screen, dim, sizeof(screen));
if (press) {
// Button is down
screen[button] = brt[button];
} else {
// Button is released
// Verify correctness
uint32_t expected = get_next_item();
if (expected == button) {
// good!
game_repeat_n++;
if (game_repeat_n == game_revealed_n) {
// repeated all, good work!
game_revealed_n++;
enter_state(STATE_SUCCESS_EFFECT);
}
} else {
enter_state(STATE_FAIL_EFFECT);
}
}
show_screen();
break;
default:
// discard button press, not expecting input now
break;
}
}

@ -7,6 +7,8 @@
#include <common.h>
void ButtonHandler(uint32_t button, bool press);
void user_main();
#endif //MPORK_USER_MAIN_H

@ -0,0 +1,64 @@
#include "ws2812.h"
#include "utils/timebase.h"
#define LONG_DELAY() for (volatile uint32_t __j = 4; __j > 0; __j--)
#define SHORT_DELAY() for (volatile uint32_t __j = 1; __j > 0; __j--)
static inline
__attribute__((always_inline))
void ws2812_byte(GPIO_TypeDef *GPIOx, uint16_t pin, uint8_t b)
{
for (register volatile uint8_t i = 0; i < 8; i++) {
GPIOx->BSRR = pin; // set pin high
// duty cycle determines bit value
if (b & 0x80) {
LONG_DELAY();
GPIOx->BRR = pin; // set pin low
SHORT_DELAY();
} else {
SHORT_DELAY();
GPIOx->BRR = pin; // set pin low
LONG_DELAY();
}
b <<= 1; // shift to next bit
}
}
/** Set many RGBs */
void ws2812_send(GPIO_TypeDef *GPIOx, uint16_t pin, uint32_t *rgbs, uint32_t count)
{
__disable_irq();
for (int i = 0; i < count; i++) {
uint32_t rgb = *rgbs++;
ws2812_byte(GPIOx, pin, rgb_g(rgb));
ws2812_byte(GPIOx, pin, rgb_r(rgb));
ws2812_byte(GPIOx, pin, rgb_b(rgb));
}
__enable_irq();
ws2812_flip(); // show
}
/** Send a single color. */
void ws2812_single(GPIO_TypeDef *GPIOx, uint16_t pin, uint32_t rgb)
{
__disable_irq();
ws2812_byte(GPIOx, pin, rgb_g(rgb));
ws2812_byte(GPIOx, pin, rgb_r(rgb));
ws2812_byte(GPIOx, pin, rgb_b(rgb));
__enable_irq();
}
/**
* @brief Wait the necessary time for the colors sent using ws2812_single() to show.
*/
void ws2812_flip()
{
delay_us(50); // show
}

@ -0,0 +1,92 @@
#ifndef MPORK_WS2812_H
#define MPORK_WS2812_H
/* Includes ------------------------------------------------------------------*/
#include <common.h>
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
// PB8 - WS2812B data line
#define COLORLED_GPIO GPIOC
#define COLORLED_PIN GPIO15
#define RGB_RED rgb(255, 0, 0)
#define RGB_ORANGE rgb(255, 110, 0)
#define RGB_YELLOW rgb(255, 255, 0)
#define RGB_LIME rgb(160, 255, 0)
#define RGB_GREEN rgb( 0, 255, 0)
#define RGB_CYAN rgb( 0, 255, 120)
#define RGB_BLUE rgb( 0, 0, 255)
#define RGB_MAGENTA rgb(255, 0, 255)
#define RGB_WHITE rgb(255, 255, 255)
#define RGB_BLACK rgb( 0, 0, 0)
/* Exported macros -----------------------------------------------------------*/
/**
* @brief Compose an RGB color.
* @param r, g, b - components 0xFF
* @returns integer 0xRRGGBB
*/
#define rgb(r, g, b) (((0xFF & (r)) << 16) | ((0xFF & (g)) << 8) | (0xFF & (b)))
/* Get components */
#define rgb_r(rgb) (((rgb) >> 16) & 0xFF)
#define rgb_g(rgb) (((rgb) >> 8) & 0xFF)
#define rgb_b(rgb) ((rgb) & 0xFF)
/* Exported functions --------------------------------------------------------*/
/**
* @brief Struct for easy manipulation of RGB colors.
*
* Set components in the xrgb.r (etc.) and you will get
* the hex in xrgb.num.
*/
typedef union {
/** Struct for access to individual color components */
struct __attribute__((packed)) {
uint8_t b;
uint8_t g;
uint8_t r;
};
/** RGB color as a single uint32_t */
uint32_t num;
} ws2812_rgb_t;
/**
* @brief Macro to compose the RGB struct.
*
* You can also use {.num = 0xFF0000} to set the hex directly.
*/
#define WS2812_RGB(r, g, b) {.num = (((r) & 0xFF) << 16) | (((g) & 0xFF) << 8) | ((b) & 0xFF)}
/**
* @brief Send a sequence of colors, then display it.
* @param GPIOx
* @param pin
* @param rgbs : array of colors
* @param count : array length
*/
void ws2812_send(GPIO_TypeDef *GPIOx, uint16_t pin, uint32_t *rgbs, uint32_t count);
/**
* @brief Send a single color.
* @param GPIOx
* @param pin
* @param rgb : color to show
*/
void ws2812_single(GPIO_TypeDef *GPIOx, uint16_t pin, uint32_t rgb);
/**
* @brief Wait the necessary time for the colors sent using ws2812_single() to show.
*/
void ws2812_flip();
#endif //MPORK_WS2812_H

@ -11,14 +11,19 @@ Mcu.Name=STM32F103C(8-B)Tx
Mcu.Package=LQFP48
Mcu.Pin0=PC13-TAMPER-RTC
Mcu.Pin1=PC14-OSC32_IN
Mcu.Pin10=PB7
Mcu.Pin11=PB8
Mcu.Pin12=VP_SYS_VS_ND
Mcu.Pin13=VP_SYS_VS_Systick
Mcu.Pin2=PC15-OSC32_OUT
Mcu.Pin3=PD0-OSC_IN
Mcu.Pin4=PD1-OSC_OUT
Mcu.Pin5=PA9
Mcu.Pin6=PA10
Mcu.Pin7=VP_SYS_VS_ND
Mcu.Pin8=VP_SYS_VS_Systick
Mcu.PinsNb=9
Mcu.Pin5=PB11
Mcu.Pin6=PA9
Mcu.Pin7=PA10
Mcu.Pin8=PB5
Mcu.Pin9=PB6
Mcu.PinsNb=14
Mcu.UserConstants=
Mcu.UserName=STM32F103C8Tx
MxCube.Version=4.16.0
@ -37,6 +42,31 @@ PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB11.GPIOParameters=GPIO_Speed,GPIO_Label
PB11.GPIO_Label=WSDATA
PB11.GPIO_Speed=GPIO_SPEED_FREQ_MEDIUM
PB11.Locked=true
PB11.Signal=GPIO_Output
PB5.GPIOParameters=GPIO_PuPd,GPIO_Label
PB5.GPIO_Label=BTN1
PB5.GPIO_PuPd=GPIO_PULLUP
PB5.Locked=true
PB5.Signal=GPIO_Input
PB6.GPIOParameters=GPIO_PuPd,GPIO_Label
PB6.GPIO_Label=BTN2
PB6.GPIO_PuPd=GPIO_PULLUP
PB6.Locked=true
PB6.Signal=GPIO_Input
PB7.GPIOParameters=GPIO_PuPd,GPIO_Label
PB7.GPIO_Label=BTN3
PB7.GPIO_PuPd=GPIO_PULLUP
PB7.Locked=true
PB7.Signal=GPIO_Input
PB8.GPIOParameters=GPIO_PuPd,GPIO_Label
PB8.GPIO_Label=BTN4
PB8.GPIO_PuPd=GPIO_PULLUP
PB8.Locked=true
PB8.Signal=GPIO_Input
PC13-TAMPER-RTC.GPIOParameters=GPIO_Label
PC13-TAMPER-RTC.GPIO_Label=LED1
PC13-TAMPER-RTC.Locked=true

Loading…
Cancel
Save