console #2

Merged
chris merged 3 commits from console into main 2024-07-29 19:04:34 -05:00
8 changed files with 4631 additions and 24 deletions
Showing only changes of commit fbed28ea1e - Show all commits

30
Core/Inc/NVmem.h Normal file
View File

@ -0,0 +1,30 @@
/**
*********************************************************************
*
* @file NVmem.h
* @brief
*
* @date 2024-07-13 12:24:17
* @author CT
*
* @details
*
*************************************************************************
**/
#ifndef _NVMEM_H_
#define _NVMEM_H_
#include <stdint.h>
#define WRITE_TIMEOUT (6000u) // 6s
#define NVMEM_SIZE (2048u) // in bytes
#define NVMEM_ADDR (0x8050000)
int32_t NVmem_init(void);
void NVmem_service(void);
int32_t NVmem_write(uint8_t* data, uint32_t addr, uint32_t len);
int32_t NVmem_write_immediate(uint8_t* data, uint32_t addr, uint32_t len);
int32_t NVmem_read(uint8_t* data, uint32_t addr, uint32_t len);
#endif // _NVMEM_H_

View File

@ -1,9 +1,9 @@
#ifndef _VERSION_H #ifndef _VERSION_H
#define _VERSION_H #define _VERSION_H
#define VERSION_MAJOR (1) #define VERSION_MAJOR (1u)
#define VERSION_MINOR (1) #define VERSION_MINOR (1u)
#define VERSION_PATCH (0) #define VERSION_PATCH (1u)
#define VERSION_STR "V1.1.0" #define VERSION_STR "V1.1.1"
#endif #endif

198
Core/Src/NVmem.c Normal file
View File

@ -0,0 +1,198 @@
/**
*********************************************************************
*
* @file NVmem.c
* @brief
*
* @date 2024-07-13 12:24:17
* @author CT
*
* @details Provides an interface for reading and writting to non-volatile memory
* Operates with a shadow buffer and write timeout to minimize writes to NV-memory
*
*************************************************************************
**/
#include <stdint.h>
#include "stm32g4xx_hal.h"
#include "NVmem.h"
// write timeout
static uint32_t m_last_write = 0;
//
static int32_t m_shadow_buf_synced = 0;
//
static uint8_t m_shadow_buf[NVMEM_SIZE] = {0};
// non-volatile memory location
uint8_t __attribute__((section (".ConfigData"))) config_data[NVMEM_SIZE] __attribute__ ((aligned (2048)));
static int write_flash(void);
static uint32_t get_bank(uint32_t addr);
int32_t NVmem_init(void)
{
// TODO add CRC over section stored at end
// copy flash to shadow buffer
for (uint32_t i = 0; i < NVMEM_SIZE; i++)
{
m_shadow_buf[i] = config_data[i];
}
return (0);
}
void NVmem_service(void)
{
// if the write timeout has expried and the shadow buffer has not been synced to NVmem
if (((HAL_GetTick() - m_last_write) >= WRITE_TIMEOUT) && (!m_shadow_buf_synced))
{
// write shadow buffer to nvmem
write_flash();
// set synced flag
m_shadow_buf_synced = 1;
}
}
int32_t NVmem_write(uint8_t* data, uint32_t addr, uint32_t len)
{
// bound check
if (addr + len >= NVMEM_SIZE)
return (-1);
// write data to shadow buf
uint32_t data_index = 0;
for (uint32_t i = addr; i < len; i++)
{
m_shadow_buf[i] = data[data_index++];
}
// set sync flag to out of sync
m_shadow_buf_synced = 0;
return (0);
}
int32_t NVmem_write_immediate(uint8_t* data, uint32_t addr, uint32_t len)
{
int32_t ret = 0;
// bound check
if (addr + len >= NVMEM_SIZE)
return (-1);
// write data to shadow buf
uint32_t data_index = 0;
for (uint32_t i = addr; i < len; i++)
{
m_shadow_buf[i] = data[data_index++];
}
// write shadow buffer to nvmem
ret = write_flash();
// set synced flag
m_shadow_buf_synced = 1;
return (ret);
}
int32_t NVmem_read(uint8_t* data, uint32_t addr, uint32_t len)
{
// bound check
if (addr + len >= NVMEM_SIZE)
return (-1);
// copy data using provided pointer
uint32_t index = 0;
for (uint32_t i = addr; i < len; i++)
{
data[index++] = m_shadow_buf[i];
}
return (0);
}
/* PRIVATE FUNCTIONS */
// Read from flash
// Write to flash
int write_flash(void)
{
uint32_t page_error = 0;
HAL_StatusTypeDef status;
HAL_FLASH_Unlock();
// Erase flash area
FLASH_EraseInitTypeDef erase_init_struct;
erase_init_struct.TypeErase = FLASH_TYPEERASE_PAGES;
erase_init_struct.Banks = get_bank(NVMEM_ADDR);
erase_init_struct.Page = (NVMEM_ADDR - FLASH_BASE) / FLASH_PAGE_SIZE;
erase_init_struct.NbPages = 1;
status = HAL_FLASHEx_Erase(&erase_init_struct, &page_error);
if (HAL_OK != status)
{
HAL_FLASH_Lock();
return (-1);
}
uint64_t buf;
uint32_t len = NVMEM_SIZE;
uint32_t prog_addr = NVMEM_ADDR;
uint32_t index = 0;
while (len >= 8)
{
buf = (uint64_t)m_shadow_buf[index];
buf |= ((uint64_t)m_shadow_buf[index + 1] << 8);
buf |= ((uint64_t)m_shadow_buf[index + 2] << 16);
buf |= ((uint64_t)m_shadow_buf[index + 3] << 24);
buf |= ((uint64_t)m_shadow_buf[index + 4] << 32);
buf |= ((uint64_t)m_shadow_buf[index + 5] << 40);
buf |= ((uint64_t)m_shadow_buf[index + 6] << 48);
buf |= ((uint64_t)m_shadow_buf[index + 7] << 56);
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, prog_addr, buf);
index += 8;
prog_addr += 8;
len -= 8;
}
HAL_FLASH_Lock();
return ((int)status);
}
uint32_t get_bank(uint32_t addr)
{
uint32_t bank = 0;
uint32_t val = 0;
val = (addr - FLASH_BASE) / FLASH_BANK_SIZE;
if (0 == val)
{
bank = FLASH_BANK_1;
}
else
{
bank = FLASH_BANK_2;
}
return (bank);
}

View File

@ -22,7 +22,7 @@
#include "main.h" #include "main.h"
#include "console.h" #include "console.h"
// #include "NVmem.h" #include "NVmem.h"
#include "version.h" #include "version.h"
#include "usbd_cdc_if.h" #include "usbd_cdc_if.h"
@ -75,9 +75,6 @@ void console_init(config_data_u_t* config_data)
m_console_input = circular_buf_init(m_console_input_buf, CONSOLE_BUF_SIZE); m_console_input = circular_buf_init(m_console_input_buf, CONSOLE_BUF_SIZE);
m_console_output = circular_buf_init(m_console_output_buf, CONSOLE_BUF_SIZE); m_console_output = circular_buf_init(m_console_output_buf, CONSOLE_BUF_SIZE);
// for this demonstratior, load example values from nvmem
// NVmem_read(configuration_data->data, 0, 12);
} }
@ -240,7 +237,7 @@ void menu_state_machine(void)
} }
else if (m_command_buf[0] == 'S') else if (m_command_buf[0] == 'S')
{ {
// success = NVmem_write_immediate(configuration_data->data, 0, 12); success = NVmem_write_immediate(configuration_data->data, 0, sizeof(config_data_t));
print_saved_menu(success); print_saved_menu(success);
// need to call service because we are blocking all normal execution here // need to call service because we are blocking all normal execution here
process_outgoing(); process_outgoing();
@ -331,6 +328,7 @@ void menu_state_machine(void)
/// @return 1 on success, otherwise fail...kinda /// @return 1 on success, otherwise fail...kinda
int parse_input(int32_t* data) int parse_input(int32_t* data)
{ {
// TODO check and limit input within bounds
// *data = atoi((char*)m_command_buf); // *data = atoi((char*)m_command_buf);
int ret = sscanf((char*)m_command_buf, "%ld", data); int ret = sscanf((char*)m_command_buf, "%ld", data);
@ -347,8 +345,8 @@ void print_main_menu(void)
reset_console(); reset_console();
set_console_red(); set_console_red();
uint32_t len = snprintf(buf, 256, "Main Menu:\r\nSlider [1]: \"%li\"\r\nSlider [2]: \"%li\"\r\n[3]Slider [3]: \"%li\"\r\n[3]Slider [4]: \"%li\"\r\n[3]Slider [5]: \"%li\"\r\n[S]ave\r\nVersion: %s\r\nEnter Selection: ", uint32_t len = snprintf(buf, 256, "Main Menu:\r\nSlider [1]: \"%li\"\r\nSlider [2]: \"%li\"\r\nSlider [3]: \"%li\"\r\nSlider [4]: \"%li\"\r\n[S]ave\r\nVersion: %s\r\nEnter Selection: ",
configuration_data->config.slider_1, configuration_data->config.slider_2, configuration_data->config.slider_3, configuration_data->config.slider_4, configuration_data->config.slider_4, VERSION_STR); configuration_data->config.slider_1, configuration_data->config.slider_2, configuration_data->config.slider_3, configuration_data->config.slider_4, VERSION_STR);
console_send((uint8_t*)buf, len); console_send((uint8_t*)buf, len);
} }
@ -362,7 +360,7 @@ void print_slider_menu(uint32_t slider)
reset_console(); reset_console();
set_console_reset(); set_console_reset();
uint32_t len = snprintf(buf, 128, "Slider %lu Max Value: ", slider); uint32_t len = snprintf(buf, 128, "Slider %lu Max Value (0-100): ", slider);
console_send((uint8_t*)buf, len); console_send((uint8_t*)buf, len);
} }

View File

@ -31,6 +31,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "console.h" #include "console.h"
#include "NVmem.h"
#include "usbd_cdc_if.h" #include "usbd_cdc_if.h"
#include "version.h" #include "version.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
@ -77,7 +78,7 @@ uint8_t m_buttons = 0;
// char buf[512] = {0}; // char buf[512] = {0};
config_data_u_t config_data; config_data_u_t pwm_limit;
/* USER CODE END PV */ /* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
@ -142,11 +143,12 @@ int main(void)
MX_USB_Device_Init(); MX_USB_Device_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
// TODO Load configuration data from NV-memory NVmem_init();
// Load configuration data from NV-memory
NVmem_read(pwm_limit.data, 0, sizeof(config_data_t));
// Initialize the console and pass a pointer to our configuration data location // Initialize the console and pass a pointer to our configuration data location
console_init(&config_data); console_init(&pwm_limit);
// Initialize EMA filters // Initialize EMA filters
for (uint32_t i = 0; i < NUM_SLIDERS; i++) for (uint32_t i = 0; i < NUM_SLIDERS; i++)
@ -191,8 +193,8 @@ int main(void)
// Service the console, not interrupt based // Service the console, not interrupt based
console_service(); console_service();
// TODO Service the NVmem module // Service the NVmem module
NVmem_service();
if ((m_adc1_filtered_ready) == true && (m_adc2_filtered_ready == true)) if ((m_adc1_filtered_ready) == true && (m_adc2_filtered_ready == true))
{ {
@ -329,10 +331,10 @@ void filter_adc2(void)
*/ */
void set_pwm_outputs(void) void set_pwm_outputs(void)
{ {
float ch1 = map_clamp(m_sliders[1], 0.0f, 100.0f, 0, ((MAX_PWM_VALUE * config_data.config.slider_1) / 100.0f)); float ch1 = map_clamp(m_sliders[1], 0.0f, 100.0f, 0, ((MAX_PWM_VALUE * pwm_limit.config.slider_1) / 100.0f));
float ch2 = map_clamp(m_sliders[2], 0.0f, 100.0f, 0, ((MAX_PWM_VALUE * config_data.config.slider_2) / 100.0f)); float ch2 = map_clamp(m_sliders[2], 0.0f, 100.0f, 0, ((MAX_PWM_VALUE * pwm_limit.config.slider_2) / 100.0f));
float ch3 = map_clamp(m_sliders[3], 0.0f, 100.0f, 0, ((MAX_PWM_VALUE * config_data.config.slider_3) / 100.0f)); float ch3 = map_clamp(m_sliders[3], 0.0f, 100.0f, 0, ((MAX_PWM_VALUE * pwm_limit.config.slider_3) / 100.0f));
float ch4 = map_clamp(m_sliders[4], 0.0f, 100.0f, 0, ((MAX_PWM_VALUE * config_data.config.slider_4) / 100.0f)); float ch4 = map_clamp(m_sliders[4], 0.0f, 100.0f, 0, ((MAX_PWM_VALUE * pwm_limit.config.slider_4) / 100.0f));
htim1.Instance->CCR1 = (uint32_t)(ch1); htim1.Instance->CCR1 = (uint32_t)(ch1);
htim1.Instance->CCR2 = (uint32_t)(ch2); htim1.Instance->CCR2 = (uint32_t)(ch2);

4371
Releases/FW_1-1-1.hex Normal file

File diff suppressed because it is too large Load Diff

View File

@ -55,19 +55,26 @@ ENTRY(Reset_Handler)
/* Highest address of the user mode stack */ /* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */ _estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */ /* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Heap_Size = 0x400; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */ _Min_Stack_Size = 0x800; /* required amount of stack */
/* Specify the memory areas */ /* Specify the memory areas */
MEMORY MEMORY
{ {
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 256K FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 256K
CONFIG (r) : ORIGIN = 0x8050000, LENGTH = 2K
} }
/* Define output sections */ /* Define output sections */
SECTIONS SECTIONS
{ {
/* Application NV configuration data */
.ConfigData (NOLOAD) :
{
KEEP(*(.ConfigData))
} >CONFIG
/* The startup code goes first into FLASH */ /* The startup code goes first into FLASH */
.isr_vector : .isr_vector :
{ {

View File

@ -34,6 +34,7 @@ target_sources(stm32cubemx INTERFACE
../../Core/Src/usart.c ../../Core/Src/usart.c
../../Core/Src/cir_buf.c ../../Core/Src/cir_buf.c
../../Core/Src/console.c ../../Core/Src/console.c
../../Core/Src/NVmem.c
../../Core/Src/stm32g4xx_it.c ../../Core/Src/stm32g4xx_it.c
../../Core/Src/stm32g4xx_hal_msp.c ../../Core/Src/stm32g4xx_hal_msp.c
../../USB_Device/Target/usbd_conf.c ../../USB_Device/Target/usbd_conf.c