Simon Says implementation
This commit is contained in:
Generated
+5
-3
@@ -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>
|
||||
|
||||
+1
@@ -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>
|
||||
Generated
+2
-2
@@ -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">
|
||||
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
[PreviousGenFiles]
|
||||
HeaderPath=/home/ondra/devel/f103-bluepill/Inc
|
||||
SourcePath=/home/ondra/devel/f103-bluepill/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;
|
||||
|
||||
[PreviousGenFiles]
|
||||
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;
|
||||
|
||||
[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 */
|
||||
|
||||
+16
@@ -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 */
|
||||
|
||||
+1
-10
@@ -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);
|
||||
|
||||
+16
-4
@@ -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 */
|
||||
|
||||
+276
-1
@@ -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
|
||||
+35
-5
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user