commit fb48410853668478a318f34fb326e41320af08f4
parent 42285ecbb1797194e5151185da17a976f9eef4f9
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Thu, 19 Mar 2026 00:05:56 -0300
Agregar tarea `task_menu` y archivos `display.*`
Diffstat:
17 files changed, 935 insertions(+), 107 deletions(-)
diff --git a/firmware/.cproject b/firmware/.cproject
@@ -337,4 +337,5 @@
<autodiscovery enabled="false" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
+ <storageModule moduleId="refreshScope"/>
</cproject>
\ No newline at end of file
diff --git a/firmware/Core/Inc/main.h b/firmware/Core/Inc/main.h
@@ -67,8 +67,14 @@ void Error_Handler(void);
#define USART_RX_GPIO_Port GPIOA
#define LD2_Pin GPIO_PIN_5
#define LD2_GPIO_Port GPIOA
+#define D7_Pin GPIO_PIN_6
+#define D7_GPIO_Port GPIOA
+#define D6_Pin GPIO_PIN_7
+#define D6_GPIO_Port GPIOA
#define BTN_B_Pin GPIO_PIN_10
#define BTN_B_GPIO_Port GPIOB
+#define D4_Pin GPIO_PIN_7
+#define D4_GPIO_Port GPIOC
#define BUZZER_Pin GPIO_PIN_8
#define BUZZER_GPIO_Port GPIOA
#define TMS_Pin GPIO_PIN_13
@@ -81,6 +87,12 @@ void Error_Handler(void);
#define BTN_C_GPIO_Port GPIOB
#define BTN_D_Pin GPIO_PIN_5
#define BTN_D_GPIO_Port GPIOB
+#define D5_Pin GPIO_PIN_6
+#define D5_GPIO_Port GPIOB
+#define D9_Pin GPIO_PIN_8
+#define D9_GPIO_Port GPIOB
+#define D8_Pin GPIO_PIN_9
+#define D8_GPIO_Port GPIOB
/* USER CODE BEGIN Private defines */
diff --git a/firmware/Core/Src/main.c b/firmware/Core/Src/main.c
@@ -273,7 +273,13 @@ static void MX_GPIO_Init(void)
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
- HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
+ HAL_GPIO_WritePin(GPIOA, LD2_Pin|D7_Pin|D6_Pin, GPIO_PIN_RESET);
+
+ /*Configure GPIO pin Output Level */
+ HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, GPIO_PIN_RESET);
+
+ /*Configure GPIO pin Output Level */
+ HAL_GPIO_WritePin(GPIOB, D5_Pin|D9_Pin|D8_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
@@ -288,18 +294,39 @@ static void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
+ /*Configure GPIO pins : D7_Pin D6_Pin */
+ GPIO_InitStruct.Pin = D7_Pin|D6_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
/*Configure GPIO pins : BTN_B_Pin BTN_C_Pin BTN_D_Pin */
GPIO_InitStruct.Pin = BTN_B_Pin|BTN_C_Pin|BTN_D_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+ /*Configure GPIO pin : D4_Pin */
+ GPIO_InitStruct.Pin = D4_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(D4_GPIO_Port, &GPIO_InitStruct);
+
/*Configure GPIO pin : BUZZER_Pin */
GPIO_InitStruct.Pin = BUZZER_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(BUZZER_GPIO_Port, &GPIO_InitStruct);
+ /*Configure GPIO pins : D5_Pin D9_Pin D8_Pin */
+ GPIO_InitStruct.Pin = D5_Pin|D9_Pin|D8_Pin;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
diff --git a/firmware/app/inc/display.h b/firmware/app/inc/display.h
@@ -0,0 +1,28 @@
+#ifndef _DISPLAY_H_
+#define _DISPLAY_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ DISPLAY_CONNECTION_GPIO_4BITS,
+ DISPLAY_CONNECTION_GPIO_8BITS,
+} display_connection_t;
+
+typedef struct {
+ display_connection_t connection;
+} display_t;
+
+void display_init(display_connection_t connection);
+void display_set_cursor_pos(uint8_t x, uint8_t y);
+void display_write_string(const char * str);
+void display_clear(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DISPLAY_H_ */
diff --git a/firmware/app/inc/task_buttons.h b/firmware/app/inc/task_buttons.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
* Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ * All rights reserved
*
* See file `LICENSE` for full details
*/
diff --git a/firmware/app/inc/task_menu.h b/firmware/app/inc/task_menu.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * All rights reserved
+ *
+ * See file `LICENSE` for full details
+ */
+
+#ifndef TASK_INC_TASK_MENU_H_
+#define TASK_INC_TASK_MENU_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint32_t g_task_menu_cnt;
+extern volatile uint32_t g_task_menu_tick_cnt;
+
+extern void task_menu_init(void *parameters);
+extern void task_menu_update(void *parameters);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TASK_INC_TASK_MENU_H_ */
diff --git a/firmware/app/inc/task_menu_attribute.h b/firmware/app/inc/task_menu_attribute.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * All rights reserved
+ *
+ * See file `LICENSE` for full details
+ */
+
+#ifndef TASK_INC_TASK_MENU_ATTRIBUTE_H_
+#define TASK_INC_TASK_MENU_ATTRIBUTE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+* Menu Statechart - State Transition Table
+*
+* +----------------+-------+---------+-------------+---------+
+* | Current State | Event | [Guard] | Next State | Actions |
+* +----------------+-------+---------+-------------+---------+
+* | | | | | |
+* | ST_MEN_IDLE | | | ST_MEN_IDLE | |
+* | | | | | |
+* +----------------+-------+---------+-------------+---------+
+*/
+
+/* Events to excite Task Menu */
+typedef enum {
+ EV_MEN_ENT_IDLE,
+ EV_MEN_ENT_ACTIVE,
+ EV_MEN_NEX_IDLE,
+ EV_MEN_NEX_ACTIVE,
+ EV_MEN_ESC_IDLE,
+ EV_MEN_ESC_ACTIVE,
+ EV_MEN_INACTIVE_TIMEOUT
+} task_menu_ev_t;
+
+/* State of Task Menu */
+typedef enum {
+ ST_MEN_IDLE,
+} task_menu_st_t;
+
+typedef struct {
+ uint32_t tick;
+ task_menu_st_t state;
+ task_menu_ev_t event;
+ bool event_flag;
+} task_menu_dta_t;
+
+extern task_menu_dta_t task_menu_dta;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TASK_INC_TASK_MENU_ATTRIBUTE_H_ */
diff --git a/firmware/app/inc/task_menu_interface.h b/firmware/app/inc/task_menu_interface.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ * All rights reserved
+ *
+ * See file `LICENSE` for full details
+ */
+
+#ifndef TASK_INC_TASK_MENU_INTERFACE_H_
+#define TASK_INC_TASK_MENU_INTERFACE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void init_queue_event_task_menu(void);
+extern void put_event_task_menu(task_menu_ev_t event);
+extern task_menu_ev_t get_event_task_menu(void);
+extern bool any_event_task_menu(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TASK_INC_TASK_MENU_INTERFACE_H_ */
diff --git a/firmware/app/inc/task_system_attribute.h b/firmware/app/inc/task_system_attribute.h
@@ -28,7 +28,15 @@ extern "C" {
*/
typedef enum task_system_ev {
- EV_SYS_IDLE
+ EV_SYS_IDLE,
+ EV_SYS_BTN_A_IDLE,
+ EV_SYS_BTN_A_ACTIVE,
+ EV_SYS_BTN_B_IDLE,
+ EV_SYS_BTN_B_ACTIVE,
+ EV_SYS_BTN_C_IDLE,
+ EV_SYS_BTN_C_ACTIVE,
+ EV_SYS_BTN_D_IDLE,
+ EV_SYS_BTN_D_ACTIVE,
} task_system_ev_t;
typedef enum task_system_st {
diff --git a/firmware/app/src/app.c b/firmware/app/src/app.c
@@ -15,6 +15,7 @@
#include "task_actuator.h"
#include "task_temp_sensor.h"
#include "task_buttons.h"
+#include "task_menu.h"
#define G_APP_CNT_INI 0ul
#define G_APP_TICK_CNT_INI 0ul
@@ -37,7 +38,8 @@ const task_cfg_t task_cfg_list[] = {
{task_buttons_init, task_buttons_update, NULL},
{task_temp_sensor_init, task_temp_sensor_update, NULL},
{task_system_init, task_system_update, NULL},
- {task_actuator_init, task_actuator_update, NULL}
+ {task_actuator_init, task_actuator_update, NULL},
+ {task_menu_init, task_menu_update, NULL}
};
#define TASK_QTY (sizeof(task_cfg_list)/sizeof(task_cfg_t))
@@ -132,8 +134,10 @@ void app_update(void)
void HAL_SYSTICK_Callback(void)
{
g_app_tick_cnt++;
+
g_task_buttons_tick_cnt++;
g_task_temp_sensor_tick_cnt++;
g_task_system_tick_cnt++;
g_task_actuator_tick_cnt++;
+ g_task_menu_tick_cnt++;
}
diff --git a/firmware/app/src/display.c b/firmware/app/src/display.c
@@ -0,0 +1,346 @@
+#include "display.h"
+#include "main.h"
+#include <stdbool.h>
+
+// Demo includes
+#include "logger.h"
+#include "dwt.h"
+#include "systick.h"
+
+// Functional states
+#ifndef OFF
+#define OFF 0
+#endif
+#ifndef ON
+#define ON (!OFF)
+#endif
+
+// Electrical states
+#ifndef LOW
+#define LOW 0
+#endif
+#ifndef HIGH
+#define HIGH (!LOW)
+#endif
+
+#define DISPLAY_IR_CLEAR_DISPLAY 0b00000001
+#define DISPLAY_IR_SET_CURSOR_HOME 0b00000010
+#define DISPLAY_IR_ENTRY_MODE_SET 0b00000100
+#define DISPLAY_IR_DISPLAY_CONTROL 0b00001000
+#define DISPLAY_IR_FUNCTION_SET 0b00100000
+#define DISPLAY_IR_SET_DDRAM_ADDR 0b10000000
+
+#define DISPLAY_IR_ENTRY_MODE_SET_INCREMENT 0b00000010
+#define DISPLAY_IR_ENTRY_MODE_SET_DECREMENT 0b00000000
+#define DISPLAY_IR_ENTRY_MODE_SET_SHIFT 0b00000001
+#define DISPLAY_IR_ENTRY_MODE_SET_NO_SHIFT 0b00000000
+
+#define DISPLAY_IR_DISPLAY_CONTROL_DISPLAY_ON 0b00000100
+#define DISPLAY_IR_DISPLAY_CONTROL_DISPLAY_OFF 0b00000000
+#define DISPLAY_IR_DISPLAY_CONTROL_CURSOR_ON 0b00000010
+#define DISPLAY_IR_DISPLAY_CONTROL_CURSOR_OFF 0b00000000
+#define DISPLAY_IR_DISPLAY_CONTROL_BLINK_ON 0b00000001
+#define DISPLAY_IR_DISPLAY_CONTROL_BLINK_OFF 0b00000000
+
+#define DISPLAY_IR_FUNCTION_SET_8BITS 0b00010000
+#define DISPLAY_IR_FUNCTION_SET_4BITS 0b00000000
+#define DISPLAY_IR_FUNCTION_SET_2LINES 0b00001000
+#define DISPLAY_IR_FUNCTION_SET_1LINE 0b00000000
+#define DISPLAY_IR_FUNCTION_SET_5x10DOTS 0b00000100
+#define DISPLAY_IR_FUNCTION_SET_5x8DOTS 0b00000000
+
+#define DISPLAY_20x4_LINE1_FIRST_CHARACTER_ADDRESS 0
+#define DISPLAY_20x4_LINE2_FIRST_CHARACTER_ADDRESS 64
+#define DISPLAY_20x4_LINE3_FIRST_CHARACTER_ADDRESS 20
+#define DISPLAY_20x4_LINE4_FIRST_CHARACTER_ADDRESS 84
+
+#define DISPLAY_RS_INSTRUCTION 0
+#define DISPLAY_RS_DATA 1
+
+#define DISPLAY_RW_WRITE 0
+#define DISPLAY_RW_READ 1
+
+#define DISPLAY_PIN_RS 4
+#define DISPLAY_PIN_RW 5
+#define DISPLAY_PIN_EN 6
+#define DISPLAY_PIN_D0 7
+#define DISPLAY_PIN_D1 8
+#define DISPLAY_PIN_D2 9
+#define DISPLAY_PIN_D3 10
+#define DISPLAY_PIN_D4 11
+#define DISPLAY_PIN_D5 12
+#define DISPLAY_PIN_D6 13
+#define DISPLAY_PIN_D7 14
+
+#define DISPLAY_DEL_37US 37ul
+#define DISPLAY_DEL_US 5ul
+
+static display_t display;
+static bool initial_comm_completed;
+
+// Private functions declaration
+static void display_pin_write(uint8_t pin_name, int value);
+static void display_data_bus_write(uint8_t byte);
+static void display_code_write(bool type, uint8_t data_bus);
+
+// Public functions definition
+void display_init(display_connection_t connection)
+{
+ display.connection = connection;
+
+ initial_comm_completed = false;
+
+ HAL_Delay(50);
+
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_FUNCTION_SET |
+ DISPLAY_IR_FUNCTION_SET_8BITS);
+ HAL_Delay(5);
+
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_FUNCTION_SET |
+ DISPLAY_IR_FUNCTION_SET_8BITS);
+ HAL_Delay(1);
+
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_FUNCTION_SET |
+ DISPLAY_IR_FUNCTION_SET_8BITS);
+ HAL_Delay(1);
+
+ switch(display.connection) {
+ case DISPLAY_CONNECTION_GPIO_8BITS:
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_FUNCTION_SET |
+ DISPLAY_IR_FUNCTION_SET_8BITS |
+ DISPLAY_IR_FUNCTION_SET_2LINES |
+ DISPLAY_IR_FUNCTION_SET_5x8DOTS);
+ HAL_Delay(1);
+ break;
+
+ case DISPLAY_CONNECTION_GPIO_4BITS:
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_FUNCTION_SET |
+ DISPLAY_IR_FUNCTION_SET_4BITS);
+ HAL_Delay(1);
+
+ initial_comm_completed = true;
+
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_FUNCTION_SET |
+ DISPLAY_IR_FUNCTION_SET_4BITS |
+ DISPLAY_IR_FUNCTION_SET_2LINES |
+ DISPLAY_IR_FUNCTION_SET_5x8DOTS);
+ HAL_Delay(1);
+ break;
+ }
+
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_DISPLAY_CONTROL |
+ DISPLAY_IR_DISPLAY_CONTROL_DISPLAY_OFF |
+ DISPLAY_IR_DISPLAY_CONTROL_CURSOR_OFF |
+ DISPLAY_IR_DISPLAY_CONTROL_BLINK_OFF);
+ HAL_Delay(1);
+
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_CLEAR_DISPLAY);
+ HAL_Delay(1);
+
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_ENTRY_MODE_SET |
+ DISPLAY_IR_ENTRY_MODE_SET_INCREMENT |
+ DISPLAY_IR_ENTRY_MODE_SET_NO_SHIFT);
+ HAL_Delay(1);
+
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_DISPLAY_CONTROL |
+ DISPLAY_IR_DISPLAY_CONTROL_DISPLAY_ON |
+ DISPLAY_IR_DISPLAY_CONTROL_CURSOR_OFF |
+ DISPLAY_IR_DISPLAY_CONTROL_BLINK_OFF);
+ HAL_Delay(1);
+}
+
+void display_clear(void)
+{
+ display_code_write(DISPLAY_RS_INSTRUCTION, DISPLAY_IR_CLEAR_DISPLAY);
+
+ HAL_Delay(1);
+}
+
+void display_set_cursor_pos(uint8_t x, uint8_t y)
+{
+ switch(y) {
+ case 0:
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_SET_DDRAM_ADDR |
+ (DISPLAY_20x4_LINE1_FIRST_CHARACTER_ADDRESS + x));
+ //HAL_Delay(1);
+ break;
+
+ case 1:
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_SET_DDRAM_ADDR |
+ (DISPLAY_20x4_LINE2_FIRST_CHARACTER_ADDRESS + x));
+ //HAL_Delay(1);
+ break;
+
+ case 2:
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_SET_DDRAM_ADDR |
+ (DISPLAY_20x4_LINE3_FIRST_CHARACTER_ADDRESS + x));
+ //HAL_Delay(1);
+ break;
+
+ case 3:
+ display_code_write(DISPLAY_RS_INSTRUCTION,
+ DISPLAY_IR_SET_DDRAM_ADDR |
+ (DISPLAY_20x4_LINE4_FIRST_CHARACTER_ADDRESS + x));
+ //HAL_Delay(1);
+ break;
+ }
+}
+
+void display_write_string(const char *str)
+{
+ while (*str) {
+ display_code_write(DISPLAY_RS_DATA, *str++);
+ }
+}
+
+// Private functions definitions
+static void display_code_write( bool type, uint8_t data_bus )
+{
+ if (type == DISPLAY_RS_INSTRUCTION)
+ {
+ display_pin_write(DISPLAY_PIN_RS, DISPLAY_RS_INSTRUCTION);
+ }
+ else
+ {
+ display_pin_write(DISPLAY_PIN_RS, DISPLAY_RS_DATA);
+ }
+
+ display_pin_write(DISPLAY_PIN_RW, DISPLAY_RW_WRITE);
+ display_data_bus_write(data_bus);
+ systick_delay_us(DISPLAY_DEL_37US);
+}
+
+static void display_pin_write(uint8_t pin_name, int value)
+{
+ switch(display.connection)
+ {
+ /*
+ case DISPLAY_CONNECTION_GPIO_8BITS:
+ switch(pin_name)
+ {
+ case DISPLAY_PIN_D0:
+ HAL_GPIO_WritePin(D0_GPIO_Port, D0_Pin, value);
+ break;
+ case DISPLAY_PIN_D1:
+ HAL_GPIO_WritePin(D1_GPIO_Port, D1_Pin, value);
+ break;
+ case DISPLAY_PIN_D2:
+ HAL_GPIO_WritePin(D2_GPIO_Port, D2_Pin, value);
+ break;
+ case DISPLAY_PIN_D3:
+ HAL_GPIO_WritePin(D3_GPIO_Port, D3_Pin, value);
+ break;
+ case DISPLAY_PIN_D4:
+ HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, value);
+ break;
+ case DISPLAY_PIN_D5:
+ HAL_GPIO_WritePin(D5_GPIO_Port, D5_Pin, value);
+ break;
+ case DISPLAY_PIN_D6:
+ HAL_GPIO_WritePin(D6_GPIO_Port, D6_Pin, value);
+ break;
+ case DISPLAY_PIN_D7:
+ HAL_GPIO_WritePin(D7_GPIO_Port, D7_Pin, value);
+ break;
+ case DISPLAY_PIN_RS:
+ HAL_GPIO_WritePin(D8_GPIO_Port, D8_Pin, value);
+ break;
+ case DISPLAY_PIN_EN:
+ HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, value);
+ break;
+ case DISPLAY_PIN_RW:
+ default:
+ break;
+ }
+ break;
+ */
+
+ case DISPLAY_CONNECTION_GPIO_4BITS:
+ switch(pin_name)
+ {
+ case DISPLAY_PIN_D4:
+ HAL_GPIO_WritePin(D4_GPIO_Port, D4_Pin, value);
+ break;
+ case DISPLAY_PIN_D5:
+ HAL_GPIO_WritePin(D5_GPIO_Port, D5_Pin, value);
+ break;
+ case DISPLAY_PIN_D6:
+ HAL_GPIO_WritePin(D6_GPIO_Port, D6_Pin, value);
+ break;
+ case DISPLAY_PIN_D7:
+ HAL_GPIO_WritePin(D7_GPIO_Port, D7_Pin, value);
+ break;
+ case DISPLAY_PIN_RS:
+ HAL_GPIO_WritePin(D8_GPIO_Port, D8_Pin, value);
+ break;
+ case DISPLAY_PIN_EN:
+ HAL_GPIO_WritePin(D9_GPIO_Port, D9_Pin, value);
+ break;
+
+ case DISPLAY_PIN_RW:
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void display_data_bus_write(uint8_t data_bus)
+{
+ display_pin_write(DISPLAY_PIN_EN, OFF);
+ display_pin_write(DISPLAY_PIN_D7, data_bus & 0b10000000);
+ display_pin_write(DISPLAY_PIN_D6, data_bus & 0b01000000);
+ display_pin_write(DISPLAY_PIN_D5, data_bus & 0b00100000);
+ display_pin_write(DISPLAY_PIN_D4, data_bus & 0b00010000);
+
+ switch(display.connection)
+ {
+ case DISPLAY_CONNECTION_GPIO_8BITS:
+ display_pin_write(DISPLAY_PIN_D3, data_bus & 0b00001000);
+ display_pin_write(DISPLAY_PIN_D2, data_bus & 0b00000100);
+ display_pin_write(DISPLAY_PIN_D1, data_bus & 0b00000010);
+ display_pin_write(DISPLAY_PIN_D0, data_bus & 0b00000001);
+ break;
+
+ case DISPLAY_CONNECTION_GPIO_4BITS:
+ if (true == initial_comm_completed)
+ {
+ display_pin_write(DISPLAY_PIN_EN, ON);
+ //HAL_Delay(1);
+ systick_delay_us(DISPLAY_DEL_US);
+
+ display_pin_write(DISPLAY_PIN_EN, OFF);
+ //HAL_Delay(1);
+ systick_delay_us(DISPLAY_DEL_US);
+
+ display_pin_write(DISPLAY_PIN_D7, data_bus & 0b00001000);
+ display_pin_write(DISPLAY_PIN_D6, data_bus & 0b00000100);
+ display_pin_write(DISPLAY_PIN_D5, data_bus & 0b00000010);
+ display_pin_write(DISPLAY_PIN_D4, data_bus & 0b00000001);
+ }
+ default:
+ break;
+ }
+
+ display_pin_write(DISPLAY_PIN_EN, ON);
+ //HAL_Delay(1);
+ systick_delay_us(DISPLAY_DEL_US);
+
+ display_pin_write(DISPLAY_PIN_EN, OFF);
+ //HAL_Delay(1);
+ systick_delay_us(DISPLAY_DEL_US);
+}
diff --git a/firmware/app/src/task_buttons.c b/firmware/app/src/task_buttons.c
@@ -15,6 +15,8 @@
#include "task_buttons_attribute.h"
#include "task_system_attribute.h"
#include "task_system_interface.h"
+#include "task_menu_attribute.h"
+#include "task_menu_interface.h"
#define G_TASK_SEN_TICK_CNT_INI 0ul
@@ -23,10 +25,10 @@
#define DEL_BTN_XX_MAX 50ul
const task_buttons_cfg_t task_buttons_cfg_list[] = {
- {ID_BTN_A, BTN_A_GPIO_Port, BTN_A_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
- {ID_BTN_B, BTN_B_GPIO_Port, BTN_B_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
- {ID_BTN_C, BTN_C_GPIO_Port, BTN_C_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
- {ID_BTN_D, BTN_D_GPIO_Port, BTN_D_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_SYS_IDLE, EV_SYS_IDLE},
+ {ID_BTN_A, BTN_A_GPIO_Port, BTN_A_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_MEN_ENT_ACTIVE, EV_MEN_ENT_IDLE},
+ {ID_BTN_B, BTN_B_GPIO_Port, BTN_B_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_MEN_ENT_ACTIVE, EV_MEN_ENT_IDLE},
+ {ID_BTN_C, BTN_C_GPIO_Port, BTN_C_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_MEN_NEX_ACTIVE, EV_MEN_NEX_IDLE},
+ {ID_BTN_D, BTN_D_GPIO_Port, BTN_D_Pin, BTN_A_PRESSED, DEL_BTN_XX_MAX, EV_MEN_ESC_ACTIVE, EV_MEN_ESC_IDLE},
};
#define BUTTONS_CFG_QTY (sizeof(task_buttons_cfg_list)/sizeof(task_buttons_cfg_t))
@@ -43,18 +45,20 @@ task_buttons_dta_t task_buttons_dta_list[] = {
// this variable is incremented by 1 on every ms by HAL_SysTick
volatile uint32_t g_task_buttons_tick_cnt;
+// Private functions declaration
+void task_buttons_statechart(void);
+
void task_buttons_init(void *parameters)
{
- const task_buttons_cfg_t *p_task_buttons_cfg;
task_buttons_dta_t *p_task_buttons_dta;
LOGGER_INFO("Initializing `task_buttons`...");
for (uint32_t index = 0; BUTTONS_DTA_QTY > index; index++)
{
- p_task_buttons_cfg = &task_buttons_cfg_list[index];
p_task_buttons_dta = &task_buttons_dta_list[index];
+ p_task_buttons_dta->tick = DEL_BTN_XX_MIN;
p_task_buttons_dta->state = ST_BTN_XX_UP;
p_task_buttons_dta->event = EV_BTN_XX_UP;
}
@@ -64,9 +68,6 @@ void task_buttons_init(void *parameters)
void task_buttons_update(void *parameters)
{
- const task_buttons_cfg_t *p_task_buttons_cfg;
- task_buttons_dta_t *p_task_buttons_dta;
-
bool b_time_update_required = false;
__asm("CPSID i");
@@ -135,9 +136,8 @@ void task_buttons_statechart(void)
if (0 == p_task_buttons_dta->tick) {
p_task_buttons_dta->state = ST_BTN_XX_UP;
}
-
- if (p_task_buttons_dta->tick > 0) {
- p_task_buttons_dta->state = ST_BTN_XX_FALLING;
+ else
+ {
p_task_buttons_dta->tick--;
}
}
@@ -146,10 +146,10 @@ void task_buttons_statechart(void)
{
if (0 == p_task_buttons_dta->tick) {
p_task_buttons_dta->state = ST_BTN_XX_DOWN;
- put_event_task_system(p_task_buttons_cfg->signal_down);
+ put_event_task_menu(p_task_buttons_cfg->signal_down);
}
-
- if (p_task_buttons_dta->tick > 0) {
+ else
+ {
p_task_buttons_dta->tick--;
}
}
@@ -167,11 +167,11 @@ void task_buttons_statechart(void)
if (EV_BTN_XX_UP == p_task_buttons_dta->event)
{
if (0 == p_task_buttons_dta->tick) {
- put_event_task_system(p_task_buttons_cfg->signal_up);
+ put_event_task_menu(p_task_buttons_cfg->signal_up);
p_task_buttons_dta->state = ST_BTN_XX_UP;
}
-
- if (p_task_buttons_dta->tick > 0) {
+ else
+ {
p_task_buttons_dta->tick--;
}
}
@@ -181,13 +181,9 @@ void task_buttons_statechart(void)
if (0 == p_task_buttons_dta->tick) {
p_task_buttons_dta->state = ST_BTN_XX_DOWN;
}
-
- if (p_task_buttons_dta->tick > 0) {
p_task_buttons_dta->tick--;
}
- }
break;
-
default: break;
}
}
diff --git a/firmware/app/src/task_menu.c b/firmware/app/src/task_menu.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * All rights reserved
+ *
+ * See file `LICENSE` for full details
+ */
+
+#include "main.h"
+
+#include "logger.h"
+#include "dwt.h"
+
+#include "board.h"
+#include "app.h"
+#include "task_menu_attribute.h"
+#include "task_menu_interface.h"
+#include "display.h"
+
+#define G_TASK_MEN_CNT_INI 0ul
+#define G_TASK_MEN_TICK_CNT_INI 0ul
+#define DEL_MEN_XX_MIN 0ul
+
+task_menu_dta_t task_menu_dta = {
+ DEL_MEN_XX_MIN, ST_MEN_IDLE, EV_MEN_ENT_IDLE, false
+};
+
+#define MENU_DTA_QTY (sizeof(task_menu_dta)/sizeof(task_menu_dta_t))
+
+typedef struct {
+ bool power, spin;
+ uint8_t speed;
+} motor_data_t;
+
+// Private functions declaration
+void task_menu_statechart(void);
+
+// Private variables
+bool g_display_update = false;
+task_menu_st_t g_menu_prev_state;
+
+// Public variables
+uint32_t g_task_menu_cnt;
+volatile uint32_t g_task_menu_tick_cnt;
+
+// Public functions
+void task_menu_init(void *parameters)
+{
+ task_menu_dta_t *p_task_menu_dta;
+ task_menu_st_t state;
+ task_menu_ev_t event;
+
+ LOGGER_INFO("Initializing `task_menu`...");
+
+ g_task_menu_cnt = G_TASK_MEN_CNT_INI;
+
+ init_queue_event_task_menu();
+
+ p_task_menu_dta = &task_menu_dta;
+
+ state = ST_MEN_IDLE;
+ p_task_menu_dta->state = state;
+ g_menu_prev_state = state;
+
+ p_task_menu_dta->event = EV_MEN_ENT_IDLE;
+ p_task_menu_dta->event_flag = false;
+
+ display_init(DISPLAY_CONNECTION_GPIO_4BITS);
+ g_display_update = true;
+
+ LOGGER_INFO("Done initializing `task_menu`");
+}
+
+void task_menu_update(void *parameters)
+{
+ bool b_time_update_required = false;
+
+ __asm("CPSID i");
+ if (G_TASK_MEN_TICK_CNT_INI < g_task_menu_tick_cnt)
+ {
+ /* Update Tick Counter */
+ g_task_menu_tick_cnt--;
+ b_time_update_required = true;
+ }
+ __asm("CPSIE i");
+
+ while (b_time_update_required)
+ {
+ g_task_menu_cnt++;
+
+ task_menu_statechart();
+
+ __asm("CPSID i");
+ if (G_TASK_MEN_TICK_CNT_INI < g_task_menu_tick_cnt)
+ {
+ g_task_menu_tick_cnt--;
+ b_time_update_required = true;
+ }
+ else
+ {
+ b_time_update_required = false;
+ }
+ __asm("CPSIE i");
+ }
+}
+
+void menu_set_state(task_menu_st_t new_state)
+{
+ task_menu_dta_t *p_task_menu_dta;
+ p_task_menu_dta = &task_menu_dta;
+
+ g_menu_prev_state = p_task_menu_dta->state;
+ p_task_menu_dta->state = new_state;
+
+ g_display_update = true;
+}
+
+void task_menu_statechart(void)
+{
+ task_menu_dta_t *p_task_menu_dta;
+ char menu_row_str[16 + 4];
+
+ p_task_menu_dta = &task_menu_dta;
+
+ if (true == any_event_task_menu())
+ {
+ p_task_menu_dta->event_flag = true;
+ p_task_menu_dta->event = get_event_task_menu();
+ }
+
+
+ if ((true == p_task_menu_dta->event_flag)
+ && (p_task_menu_dta->event == EV_MEN_INACTIVE_TIMEOUT)
+ && (p_task_menu_dta->state != ST_MEN_IDLE))
+ {
+ menu_set_state(ST_MEN_IDLE);
+ }
+
+ switch (p_task_menu_dta->state)
+ {
+ case ST_MEN_IDLE:
+
+ if (g_display_update)
+ {
+ g_display_update = false;
+ display_clear();
+ sprintf(menu_row_str, "Hello%cC", 0xDF);
+ display_write_string(menu_row_str);
+ }
+
+ if (true == p_task_menu_dta->event_flag)
+ {
+ p_task_menu_dta->event_flag = false;
+ switch (p_task_menu_dta->event)
+ {
+ case EV_MEN_ENT_ACTIVE:
+ case EV_MEN_NEX_ACTIVE:
+ case EV_MEN_ESC_ACTIVE:
+ menu_set_state(ST_MEN_IDLE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ break;
+
+ default:
+
+ p_task_menu_dta->tick = DEL_MEN_XX_MIN;
+ p_task_menu_dta->state = ST_MEN_IDLE;
+ p_task_menu_dta->event = EV_MEN_ENT_IDLE;
+ p_task_menu_dta->event_flag = false;
+ g_display_update = false;
+
+ break;
+ }
+}
diff --git a/firmware/app/src/task_menu_interface.c b/firmware/app/src/task_menu_interface.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * All rights reserved
+ *
+ * See file `LICENSE` for full details
+ */
+
+/* Project includes */
+#include "main.h"
+
+/* Demo includes */
+#include "logger.h"
+#include "dwt.h"
+
+/* Application & Tasks includes */
+#include "board.h"
+#include "app.h"
+#include "task_menu_attribute.h"
+
+#define EVENT_UNDEFINED (255)
+#define MAX_EVENTS (16)
+
+static struct
+{
+ uint32_t head;
+ uint32_t tail;
+ uint32_t count;
+ task_menu_ev_t queue[MAX_EVENTS];
+} task_menu_event_queue;
+
+// External functions definition
+void init_queue_event_task_menu(void)
+{
+ uint32_t i;
+
+ task_menu_event_queue.head = 0;
+ task_menu_event_queue.tail = 0;
+ task_menu_event_queue.count = 0;
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ task_menu_event_queue.queue[i] = EVENT_UNDEFINED;
+}
+
+void put_event_task_menu(task_menu_ev_t event)
+{
+ task_menu_event_queue.count++;
+ task_menu_event_queue.queue[task_menu_event_queue.head++] = event;
+
+ if (MAX_EVENTS == task_menu_event_queue.head)
+ {
+ task_menu_event_queue.head = 0;
+ }
+}
+
+task_menu_ev_t get_event_task_menu(void)
+{
+ task_menu_ev_t event;
+
+ task_menu_event_queue.count--;
+ event = task_menu_event_queue.queue[task_menu_event_queue.tail];
+ task_menu_event_queue.queue[task_menu_event_queue.tail++] = EVENT_UNDEFINED;
+
+ if (MAX_EVENTS == task_menu_event_queue.tail)
+ {
+ task_menu_event_queue.tail = 0;
+ }
+
+ return event;
+}
+
+bool any_event_task_menu(void)
+{
+ return (task_menu_event_queue.head != task_menu_event_queue.tail);
+}
diff --git a/firmware/app/src/task_system.c b/firmware/app/src/task_system.c
@@ -91,15 +91,11 @@ void task_system_statechart(void)
{
task_system_dta_t *p_task_system_dta = &task_system_dta;
- /*
- // system events unused
-
if (true == any_event_task_system())
{
p_task_system_dta->flag = true;
p_task_system_dta->event = get_event_task_system();
}
- */
switch (p_task_system_dta->state)
{
diff --git a/firmware/app/src/task_system_interface.c b/firmware/app/src/task_system_interface.c
@@ -1,66 +1,72 @@
-/*
- * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
- * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
- *
- * See file `LICENSE` for full details
- */
-
-#include "main.h"
-
-#include "logger.h"
-#include "dwt.h"
-
-#include "board.h"
-#include "app.h"
-#include "task_system_attribute.h"
-
-#define EVENT_UNDEFINED (255)
-#define MAX_EVENTS (16)
-
-struct
-{
- uint32_t head;
- uint32_t tail;
- uint32_t count;
- task_system_ev_t queue[MAX_EVENTS];
-} queue_task_a;
-
-void init_queue_event_task_system(void)
-{
- uint32_t i;
-
- queue_task_a.head = 0;
- queue_task_a.tail = 0;
- queue_task_a.count = 0;
-
- for (i = 0; i < MAX_EVENTS; i++)
- queue_task_a.queue[i] = EVENT_UNDEFINED;
-}
-
-void put_event_task_system(task_system_ev_t event)
-{
- queue_task_a.count++;
- queue_task_a.queue[queue_task_a.head++] = event;
-
- if (MAX_EVENTS == queue_task_a.head)
- queue_task_a.head = 0;
-}
-
-task_system_ev_t get_event_task_system(void)
-{
- task_system_ev_t event;
-
- queue_task_a.count--;
- event = queue_task_a.queue[queue_task_a.tail];
- queue_task_a.queue[queue_task_a.tail++] = EVENT_UNDEFINED;
-
- if (MAX_EVENTS == queue_task_a.tail)
- queue_task_a.tail = 0;
-
- return event;
-}
-
-bool any_event_task_system(void)
-{
- return (queue_task_a.head != queue_task_a.tail);
-}
+/*
+ * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
+ * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
+ *
+ * See file `LICENSE` for full details
+ */
+
+#include "main.h"
+
+#include "logger.h"
+#include "dwt.h"
+
+#include "board.h"
+#include "app.h"
+#include "task_system_attribute.h"
+
+#define EVENT_UNDEFINED (255)
+#define MAX_EVENTS (16)
+
+static struct
+{
+ uint32_t head;
+ uint32_t tail;
+ uint32_t count;
+ task_system_ev_t queue[MAX_EVENTS];
+} task_system_event_queue;
+
+void init_queue_event_task_system(void)
+{
+ uint32_t i;
+
+ task_system_event_queue.head = 0;
+ task_system_event_queue.tail = 0;
+ task_system_event_queue.count = 0;
+
+ for (i = 0; i < MAX_EVENTS; i++)
+ {
+ task_system_event_queue.queue[i] = EVENT_UNDEFINED;
+ }
+}
+
+void put_event_task_system(task_system_ev_t event)
+{
+ task_system_event_queue.count++;
+ task_system_event_queue.queue[task_system_event_queue.head++] = event;
+
+ if (MAX_EVENTS == task_system_event_queue.head)
+ {
+ task_system_event_queue.head = 0;
+ }
+}
+
+task_system_ev_t get_event_task_system(void)
+{
+ task_system_ev_t event;
+
+ task_system_event_queue.count--;
+ event = task_system_event_queue.queue[task_system_event_queue.tail];
+ task_system_event_queue.queue[task_system_event_queue.tail++] = EVENT_UNDEFINED;
+
+ if (MAX_EVENTS == task_system_event_queue.tail)
+ {
+ task_system_event_queue.tail = 0;
+ }
+
+ return event;
+}
+
+bool any_event_task_system(void)
+{
+ return (task_system_event_queue.head != task_system_event_queue.tail);
+}
diff --git a/firmware/tdse-tf_3-02.ioc b/firmware/tdse-tf_3-02.ioc
@@ -38,22 +38,28 @@ Mcu.Name=STM32F103R(8-B)Tx
Mcu.Package=LQFP64
Mcu.Pin0=PC13-TAMPER-RTC
Mcu.Pin1=PC14-OSC32_IN
-Mcu.Pin10=PA9
-Mcu.Pin11=PA13
-Mcu.Pin12=PA14
-Mcu.Pin13=PB3
-Mcu.Pin14=PB4
-Mcu.Pin15=PB5
-Mcu.Pin16=VP_SYS_VS_Systick
+Mcu.Pin10=PB10
+Mcu.Pin11=PC7
+Mcu.Pin12=PA8
+Mcu.Pin13=PA9
+Mcu.Pin14=PA13
+Mcu.Pin15=PA14
+Mcu.Pin16=PB3
+Mcu.Pin17=PB4
+Mcu.Pin18=PB5
+Mcu.Pin19=PB6
Mcu.Pin2=PC15-OSC32_OUT
+Mcu.Pin20=PB8
+Mcu.Pin21=PB9
+Mcu.Pin22=VP_SYS_VS_Systick
Mcu.Pin3=PD0-OSC_IN
Mcu.Pin4=PD1-OSC_OUT
Mcu.Pin5=PA2
Mcu.Pin6=PA3
Mcu.Pin7=PA5
-Mcu.Pin8=PB10
-Mcu.Pin9=PA8
-Mcu.PinsNb=17
+Mcu.Pin8=PA6
+Mcu.Pin9=PA7
+Mcu.PinsNb=23
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103RBTx
@@ -107,6 +113,16 @@ PA5.GPIO_PuPd=GPIO_NOPULL
PA5.GPIO_Speed=GPIO_SPEED_FREQ_LOW
PA5.Locked=true
PA5.Signal=GPIO_Output
+PA6.GPIOParameters=GPIO_PuPd,GPIO_Label
+PA6.GPIO_Label=D7
+PA6.GPIO_PuPd=GPIO_PULLUP
+PA6.Locked=true
+PA6.Signal=GPIO_Output
+PA7.GPIOParameters=GPIO_PuPd,GPIO_Label
+PA7.GPIO_Label=D6
+PA7.GPIO_PuPd=GPIO_PULLUP
+PA7.Locked=true
+PA7.Signal=GPIO_Output
PA8.GPIOParameters=GPIO_Label
PA8.GPIO_Label=BUZZER
PA8.Locked=true
@@ -132,6 +148,23 @@ PB5.GPIO_Label=BTN_D
PB5.GPIO_PuPd=GPIO_PULLUP
PB5.Locked=true
PB5.Signal=GPIO_Input
+PB6.GPIOParameters=GPIO_PuPd,GPIO_Label
+PB6.GPIO_Label=D5
+PB6.GPIO_PuPd=GPIO_PULLUP
+PB6.Locked=true
+PB6.Signal=GPIO_Output
+PB8.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
+PB8.GPIO_Label=D9
+PB8.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
+PB8.GPIO_PuPd=GPIO_PULLUP
+PB8.Locked=true
+PB8.Signal=GPIO_Output
+PB9.GPIOParameters=GPIO_PuPd,GPIO_Label,GPIO_ModeDefaultOutputPP
+PB9.GPIO_Label=D8
+PB9.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_PP
+PB9.GPIO_PuPd=GPIO_PULLUP
+PB9.Locked=true
+PB9.Signal=GPIO_Output
PC13-TAMPER-RTC.GPIOParameters=GPIO_PuPd,GPIO_Label
PC13-TAMPER-RTC.GPIO_Label=B1 [Blue PushButton]
PC13-TAMPER-RTC.GPIO_PuPd=GPIO_NOPULL
@@ -143,6 +176,11 @@ PC14-OSC32_IN.Signal=RCC_OSC32_IN
PC15-OSC32_OUT.Locked=true
PC15-OSC32_OUT.Mode=LSE-External-Oscillator
PC15-OSC32_OUT.Signal=RCC_OSC32_OUT
+PC7.GPIOParameters=GPIO_PuPd,GPIO_Label
+PC7.GPIO_Label=D4
+PC7.GPIO_PuPd=GPIO_PULLUP
+PC7.Locked=true
+PC7.Signal=GPIO_Output
PD0-OSC_IN.Locked=true
PD0-OSC_IN.Mode=HSE-External-Clock-Source
PD0-OSC_IN.Signal=RCC_OSC_IN
@@ -171,8 +209,8 @@ ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
-ProjectManager.ProjectFileName=tdse-tf_3-02_sensors.ioc
-ProjectManager.ProjectName=tdse-tf_3-02_sensors
+ProjectManager.ProjectFileName=tdse-tf_3-02.ioc
+ProjectManager.ProjectName=tdse-tf_3-02
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400