Implimented NV memory storage. Increased stack and heap size by 2x.
This commit is contained in:
parent
853e4333c3
commit
fbed28ea1e
30
Core/Inc/NVmem.h
Normal file
30
Core/Inc/NVmem.h
Normal 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_
|
|
@ -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
198
Core/Src/NVmem.c
Normal 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);
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
4371
Releases/FW_1-1-1.hex
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -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 :
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user