Compare commits

..

No commits in common. "549ab46d2fe06e37771ee750d0b7ac8b68ad3451" and "c6d76baa0aab7c6de2e22de3f4854121bc287b8f" have entirely different histories.

16 changed files with 35 additions and 9632 deletions

View File

@ -1,30 +0,0 @@
/**
*********************************************************************
*
* @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,93 +0,0 @@
/**
*********************************************************************
*
* @file cir_buf.h
* @brief Circular buffer header file
*
* @date 2024-04-21 18:36:52
* @author CT
*
* @details Provides an interface for creating and interacting with circular
* buffers.
*
*************************************************************************
**/
#ifndef _CIR_BUF_H_
#define _CIR_BUF_H_
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/// Opaque circular buffer structure
typedef struct circular_buf_t circular_buf_t;
/// Handle type, the way users interact with the API
typedef circular_buf_t* cbuf_handle_t;
/// Pass in a storage buffer and size, returns a circular buffer handle
/// Requires: buffer is not NULL, size > 0 (size > 1 for the threadsafe
// version, because it holds size - 1 elements)
/// Ensures: me has been created and is returned in an empty state
cbuf_handle_t circular_buf_init(uint8_t* buffer, size_t size);
/// Free a circular buffer structure
/// Requires: me is valid and created by circular_buf_init
/// Does not free data buffer; owner is responsible for that
void circular_buf_free(cbuf_handle_t me);
/// Reset the circular buffer to empty, head == tail. Data not cleared
/// Requires: me is valid and created by circular_buf_init
void circular_buf_reset(cbuf_handle_t me);
/// Put that continues to add data if the buffer is full
/// Old data is overwritten
/// Note: if you are using the threadsafe version, this API cannot be used, because
/// it modifies the tail pointer in some cases. Use circular_buf_try_put instead.
/// Requires: me is valid and created by circular_buf_init
void circular_buf_put(cbuf_handle_t me, uint8_t data);
/// Put that rejects new data if the buffer is full
/// Note: if you are using the threadsafe version, *this* is the put you should use
/// Requires: me is valid and created by circular_buf_init
/// Returns 0 on success, -1 if buffer is full
int circular_buf_try_put(cbuf_handle_t me, uint8_t data);
/// Retrieve a value from the buffer
/// Requires: me is valid and created by circular_buf_init
/// Returns 0 on success, -1 if the buffer is empty
int circular_buf_get(cbuf_handle_t me, uint8_t* data);
/// Checks if the buffer is empty
/// Requires: me is valid and created by circular_buf_init
/// Returns true if the buffer is empty
bool circular_buf_empty(cbuf_handle_t me);
/// Checks if the buffer is full
/// Requires: me is valid and created by circular_buf_init
/// Returns true if the buffer is full
bool circular_buf_full(cbuf_handle_t me);
/// Check the capacity of the buffer
/// Requires: me is valid and created by circular_buf_init
/// Returns the maximum capacity of the buffer
size_t circular_buf_capacity(cbuf_handle_t me);
/// Check the number of elements stored in the buffer
/// Requires: me is valid and created by circular_buf_init
/// Returns the current number of elements in the buffer
size_t circular_buf_size(cbuf_handle_t me);
/// Look ahead at values stored in the circular buffer without removing the data
/// Requires:
/// - me is valid and created by circular_buf_init
/// - look_ahead_counter is less than or equal to the value returned by circular_buf_size()
/// Returns 0 if successful, -1 if data is not available
int circular_buf_peek(cbuf_handle_t me, uint8_t* data, unsigned int look_ahead_counter);
// TODO: int circular_buf_get_range(circular_buf_t me, uint8_t *data, size_t len);
// TODO: int circular_buf_put_range(circular_buf_t me, uint8_t * data, size_t len);
#endif /* _CIR_BUF_H_ */

View File

@ -1,26 +0,0 @@
/**
*********************************************************************
*
* @file console.h
* @brief
*
* @date 2024-04-14 19:12:40
* @author CT
*
* @details
*
*************************************************************************
**/
#ifndef _CONSOLE_H_
#define _CONSOLE_H_
#include "main.h"
#include "cir_buf.h"
void console_init(config_data_u_t* config_data);
void console_service(void);
int console_push(uint8_t data);
#endif // _CONOSLE_H_

View File

@ -36,20 +36,7 @@ extern "C" {
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
typedef struct config_data
{
int32_t slider_1;
int32_t slider_2;
int32_t slider_3;
int32_t slider_4;
int32_t slider_5;
} config_data_t;
typedef union config_data_u
{
config_data_t config;
uint8_t data[sizeof(config_data_t)];
} config_data_u_t;
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/

View File

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

View File

@ -1,198 +0,0 @@
/**
*********************************************************************
*
* @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

@ -1,190 +0,0 @@
/**
*********************************************************************
*
* @file cir_buf.c
* @brief Circular buffer header file
*
* @date 2024-04-21 18:36:52
* @author CT
*
* @details Provides an interface for creating and interacting with circular
* buffers.
*
*************************************************************************
**/
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#include "cir_buf.h"
// The definition of our circular buffer structure is hidden from the user
struct circular_buf_t
{
uint8_t* buffer;
size_t head;
size_t tail;
size_t max; // of the buffer
bool full;
};
/* PRIVATE FUNCTIONS */
static inline size_t advance_headtail_value(size_t value, size_t max)
{
return (value + 1) % max;
}
static void advance_head_pointer(cbuf_handle_t me)
{
assert(me);
if(circular_buf_full(me))
{
me->tail = advance_headtail_value(me->tail, me->max);
}
me->head = advance_headtail_value(me->head, me->max);
me->full = (me->head == me->tail);
}
/* API FUNCTIONS */
cbuf_handle_t circular_buf_init(uint8_t* buffer, size_t size)
{
assert(buffer && size);
cbuf_handle_t cbuf = malloc(sizeof(circular_buf_t));
assert(cbuf);
cbuf->buffer = buffer;
cbuf->max = size;
circular_buf_reset(cbuf);
assert(circular_buf_empty(cbuf));
return cbuf;
}
void circular_buf_free(cbuf_handle_t me)
{
assert(me);
free(me);
}
void circular_buf_reset(cbuf_handle_t me)
{
assert(me);
me->head = 0;
me->tail = 0;
me->full = false;
}
size_t circular_buf_size(cbuf_handle_t me)
{
assert(me);
size_t size = me->max;
if(!circular_buf_full(me))
{
if(me->head >= me->tail)
{
size = (me->head - me->tail);
}
else
{
size = (me->max + me->head - me->tail);
}
}
return size;
}
size_t circular_buf_capacity(cbuf_handle_t me)
{
assert(me);
return me->max;
}
void circular_buf_put(cbuf_handle_t me, uint8_t data)
{
assert(me && me->buffer);
me->buffer[me->head] = data;
advance_head_pointer(me);
}
int circular_buf_try_put(cbuf_handle_t me, uint8_t data)
{
int r = -1;
assert(me && me->buffer);
if(!circular_buf_full(me))
{
me->buffer[me->head] = data;
advance_head_pointer(me);
r = 0;
}
return r;
}
int circular_buf_get(cbuf_handle_t me, uint8_t* data)
{
assert(me && data && me->buffer);
int r = -1;
if(!circular_buf_empty(me))
{
*data = me->buffer[me->tail];
me->tail = advance_headtail_value(me->tail, me->max);
me->full = false;
r = 0;
}
return r;
}
bool circular_buf_empty(cbuf_handle_t me)
{
assert(me);
return (!circular_buf_full(me) && (me->head == me->tail));
}
bool circular_buf_full(cbuf_handle_t me)
{
assert(me);
return me->full;
}
int circular_buf_peek(cbuf_handle_t me, uint8_t* data, unsigned int look_ahead_counter)
{
int r = -1;
size_t pos;
assert(me && data && me->buffer);
// We can't look beyond the current buffer size
if(circular_buf_empty(me) || look_ahead_counter > circular_buf_size(me))
{
return r;
}
pos = me->tail;
for(unsigned int i = 0; i < look_ahead_counter; i++)
{
data[i] = me->buffer[pos];
pos = advance_headtail_value(pos, me->max);
}
return 0;
}

View File

@ -1,420 +0,0 @@
/**
*********************************************************************
*
* @file console.c
* @brief
*
* @date 2024-04-14 19:12:40
* @author CT
*
* @details
*
*************************************************************************
**/
/*
Operational Concept:
Sending enter displays the current menu
Simple 1 char command interface
*/
#include <stdint.h>
#include <stdbool.h>
#include "main.h"
#include "console.h"
#include "NVmem.h"
#include "version.h"
#include "usbd_cdc_if.h"
#define CONSOLE_BUF_SIZE (256u)
static cbuf_handle_t m_console_input;
static cbuf_handle_t m_console_output;
static uint8_t m_console_input_buf[CONSOLE_BUF_SIZE] = {0};
static uint8_t m_console_output_buf[CONSOLE_BUF_SIZE] = {0};
static uint8_t tx_buf[CONSOLE_BUF_SIZE];
static uint8_t m_command_buf[16] = {0};
static uint8_t m_command_len = 0;
static bool m_command_ready = false;
static bool m_echo_console = false;
config_data_u_t* configuration_data;
enum console_menu_state{main_menu, slider_1_menu, slider_2_menu, slider_3_menu, slider_4_menu, save_menu, version_menu};
enum console_menu_state console_menu = main_menu;
static void process_incoming(void);
static void process_outgoing(void);
static void process_command(void);
static int console_send(uint8_t* buf, uint32_t len);
static void menu_state_machine(void);
static int parse_input(int32_t* data);
static int32_t read_line(uint8_t data);
// menus
static void print_main_menu(void);
static void print_slider_menu(uint32_t slider);
static void print_saved_menu(int32_t val);
// console control
static void set_console_reset(void);
static void set_console_red(void);
static void set_console_green(void);
static void reset_console(void);
/* PUBLIC FUNCTIONS */
void console_init(config_data_u_t* config_data)
{
configuration_data = config_data;
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);
}
void console_service(void)
{
// if there is received data waiting
process_incoming();
// if there is data waiting to be transmitted
process_outgoing();
// Process command
process_command();
}
/// @brief Attempts to push one byte into the console input buffer
/// @param data byte to be pushed to input
/// @return 0 on success, -1 on failure
int console_push(uint8_t data)
{
int ret = 0;
ret = circular_buf_try_put(m_console_input, data);
return (ret);
}
/* PRIVATE FUNCTIONS */
void process_incoming(void)
{
if (!circular_buf_empty(m_console_input))
{
uint8_t data;
while (!circular_buf_empty(m_console_input))
{
circular_buf_get(m_console_input, &data);
m_command_ready = read_line(data);
if (m_echo_console)
{
circular_buf_try_put(m_console_output, data);
}
}
}
}
void process_outgoing(void)
{
if(!circular_buf_empty(m_console_output))
{
size_t tx_len = circular_buf_size(m_console_output);
for (uint32_t i = 0; i < tx_len; i++)
{
circular_buf_get(m_console_output, &tx_buf[i]);
}
// Note: directly interacts with interface
CDC_Transmit_FS(tx_buf, tx_len);
}
}
void process_command(void)
{
if(m_command_ready)
{
m_command_ready = false;
menu_state_machine();
}
}
int console_send(uint8_t* buf, uint32_t len)
{
int ret = 0;
for (uint32_t i = 0; i < len; i++)
{
ret |= circular_buf_try_put(m_console_output, buf[i]);
}
return (ret);
}
/// @brief Reads in a line terminated by \\n
/// @param data
/// @return 1 if EOL found, 0 otherwise
int32_t read_line(uint8_t data)
{
int32_t ret = 0;
static uint8_t m_command_buf_index = 0;
// if EOL, return on and set length
if((data == '\n') || (data == '\r'))
{
m_command_buf[m_command_buf_index++] = '\n';
// set length of command for use within rest of module
m_command_len = m_command_buf_index;
// reset index
m_command_buf_index = 0;
ret = 1;
}
else if (data == 0x1B) // ESCAPE
{
m_command_len = 1;
m_command_buf[0] = 0x1B;
// reset index
m_command_buf_index = 0;
ret = 1;
}
else
{
if (m_command_buf_index < 16)
{
m_command_buf[m_command_buf_index++] = data;
}
else
{
m_command_buf_index = 0;
}
}
return (ret);
}
// Called when a complete line has been received
void menu_state_machine(void)
{
int32_t success = 1;
switch (console_menu)
{
case main_menu:
if (m_command_buf[0] == '1')
{
print_slider_menu(1);
console_menu = slider_1_menu;
}
else if (m_command_buf[0] == '2')
{
print_slider_menu(2);
console_menu = slider_2_menu;
}
else if (m_command_buf[0] == '3')
{
print_slider_menu(3);
console_menu = slider_3_menu;
}
else if (m_command_buf[0] == '4')
{
print_slider_menu(4);
console_menu = slider_4_menu;
}
else if (m_command_buf[0] == 'S')
{
success = NVmem_write_immediate(configuration_data->data, 0, sizeof(config_data_t));
print_saved_menu(success);
// need to call service because we are blocking all normal execution here
process_outgoing();
// Delay for user to read result
HAL_Delay(3000);
console_menu = main_menu;
print_main_menu();
}
else
{
print_main_menu();
}
break;
case slider_1_menu:
if (m_command_buf[0] == 0x1B) // ESCAPE
{
console_menu = main_menu;
print_main_menu();
}
else
{
// Take input and immediately return to main menu
parse_input(&configuration_data->config.slider_1);
console_menu = main_menu;
print_main_menu();
}
break;
case slider_2_menu:
if (m_command_buf[0] == 0x1B) // ESCAPE
{
console_menu = main_menu;
print_main_menu();
}
else
{
// Take input and immediately return to main menu
parse_input(&configuration_data->config.slider_2);
console_menu = main_menu;
print_main_menu();
}
break;
case slider_3_menu:
if (m_command_buf[0] == 0x1B) // ESCAPE
{
console_menu = main_menu;
print_main_menu();
}
else
{
// Take input and immediately return to main menu
parse_input(&configuration_data->config.slider_3);
console_menu = main_menu;
print_main_menu();
}
break;
case slider_4_menu:
if (m_command_buf[0] == 0x1B) // ESCAPE
{
console_menu = main_menu;
print_main_menu();
}
else
{
// Take input and immediately return to main menu
parse_input(&configuration_data->config.slider_4);
console_menu = main_menu;
print_main_menu();
}
break;
case save_menu:
break;
default:
break;
}
}
/// @brief Parses line for integer
/// @param data parsed out integer
/// @return 1 on success, otherwise fail...kinda
int parse_input(int32_t* data)
{
// TODO check and limit input within bounds
// *data = atoi((char*)m_command_buf);
int ret = sscanf((char*)m_command_buf, "%ld", data);
return (ret);
}
// Also acts as initialization for state
void print_main_menu(void)
{
char buf[256];
m_echo_console = true;
reset_console();
set_console_red();
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, VERSION_STR);
console_send((uint8_t*)buf, len);
}
void print_slider_menu(uint32_t slider)
{
char buf[128];
m_echo_console = true;
reset_console();
set_console_reset();
uint32_t len = snprintf(buf, 128, "Slider %lu Max Value (0-100): ", slider);
console_send((uint8_t*)buf, len);
}
void print_saved_menu(int32_t val)
{
char buf[128];
uint32_t len;
reset_console();
set_console_green();
if (0 == val)
{
len = snprintf(buf, 128, "SAVED!!1!");
}
else
{
len = snprintf(buf, 128, "SAVE FAILED!");
}
console_send((uint8_t*)buf, len);
}
void set_console_reset(void)
{
char buf[16] = {0};
uint32_t len = snprintf(buf, 16, "\x1b[1;0m");
console_send((uint8_t*)buf, len);
}
void set_console_red(void)
{
char buf[16] = {0};
uint32_t len = snprintf(buf, 16, "\x1b[1;31m");
console_send((uint8_t*)buf, len);
}
void set_console_green(void)
{
char buf[16] = {0};
uint32_t len = snprintf(buf, 16, "\x1b[1;32m");
console_send((uint8_t*)buf, len);
}
void reset_console(void)
{
char buf[16] = {0};
uint32_t len = snprintf(buf, 16, "\x1b[2J\x1b[H");
console_send((uint8_t*)buf, len);
}

View File

@ -29,9 +29,6 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdbool.h>
#include "console.h"
#include "NVmem.h"
#include "usbd_cdc_if.h"
#include "version.h"
/* USER CODE END Includes */
@ -55,6 +52,7 @@ typedef struct EMA_Filter
#define PWM_LIMIT (0.5f)
#define BTN_POLL_TIME (100u)
#define UART_LOOP_TIME (1000u)
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
@ -76,9 +74,7 @@ float m_sliders[NUM_SLIDERS];
uint8_t m_buttons = 0;
// char buf[512] = {0};
config_data_u_t pwm_limit;
char buf[512] = {0};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
@ -111,6 +107,7 @@ int main(void)
{
/* USER CODE BEGIN 1 */
uint32_t prev_uart_tick = UART_LOOP_TIME;
uint32_t prev_btn_time = BTN_POLL_TIME;
/* USER CODE END 1 */
@ -143,12 +140,8 @@ int main(void)
MX_USB_Device_Init();
/* USER CODE BEGIN 2 */
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
console_init(&pwm_limit);
// int len = snprintf(buf, 128, "Version: %s\r\n", VERSION_STR);
// CDC_Transmit_FS((uint8_t *)buf, len);
// Initialize EMA filters
for (uint32_t i = 0; i < NUM_SLIDERS; i++)
@ -190,12 +183,6 @@ int main(void)
/* USER CODE BEGIN WHILE */
while (1)
{
// Service the console, not interrupt based
console_service();
// Service the NVmem module
NVmem_service();
if ((m_adc1_filtered_ready) == true && (m_adc2_filtered_ready == true))
{
// Map ADC value to PWM value
@ -216,6 +203,20 @@ int main(void)
m_adc2_filtered_ready = false;
}
// if ((HAL_GetTick() - prev_uart_tick) >= UART_LOOP_TIME)
// {
// prev_uart_tick = HAL_GetTick();
// int len = snprintf(buf, 512, "Master\tCh1\tCh2\tCh3\tCh4\t\r\n");
// len += snprintf((buf + len), (512 - len), "%03.1f\t%03.1f\t%03.1f\t%03.1f\t%03.1f\t\r\n",
// m_sliders[0], m_sliders[1], m_sliders[2], m_sliders[3], m_sliders[4]);
// len += snprintf((buf + len), (512 - len), "Version: %s\r\n", VERSION_STR);
// CDC_Transmit_FS((uint8_t *)buf, len);
// }
if ((HAL_GetTick() - prev_btn_time) >= BTN_POLL_TIME)
{
prev_btn_time = HAL_GetTick();
@ -331,10 +332,10 @@ void filter_adc2(void)
*/
void set_pwm_outputs(void)
{
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 * pwm_limit.config.slider_2) / 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 * pwm_limit.config.slider_4) / 100.0f));
float ch1 = map_clamp(m_sliders[1], 0.0f, 100.0f, 0, (MAX_PWM_VALUE * PWM_LIMIT));
float ch2 = map_clamp(m_sliders[2], 0.0f, 100.0f, 0, (MAX_PWM_VALUE * PWM_LIMIT));
float ch3 = map_clamp(m_sliders[3], 0.0f, 100.0f, 0, (MAX_PWM_VALUE * PWM_LIMIT));
float ch4 = map_clamp(m_sliders[4], 0.0f, 100.0f, 0, (MAX_PWM_VALUE * PWM_LIMIT));
htim1.Instance->CCR1 = (uint32_t)(ch1);
htim1.Instance->CCR2 = (uint32_t)(ch2);

View File

@ -4,7 +4,7 @@ Software for the Sliders McGee project
## Header Pinout
![Board header description](readme_assets/Slides_McGee_Pinout.png)
![Board header description](Slides_McGee_Pinout.png)
## Bootloading Procedure
@ -16,27 +16,5 @@ Procedure:
- Connect USB cable to board and computer
- Board will present itself as a mass storage drive
- Drag and drop new firmware image onto drive
- Wait aproximately 10s, no progress will be indicated
- Wait, no progress will be indicated
- When bootloading is complete, board will launch application and drive will no longer be present on host computer
- Removed wire jumper
## Building This Project
### Prerequisites
VSCode
STM32CubeCLT [here](https://www.st.com/en/development-tools/stm32cubeclt.html)
VSCode STM32 Extention
Once the prerequisites are installed, open VSCode and open the folder containing the project repo.
- On the left side, click the STM32 extention and select "Import CMake project". In the dialog box that opens, select the project root foler and acept the dialog box.
- CMake will do its CMake stuff and ask if the options are correct. The dafualts should be sufficient, click the bottom option to accept the parameters. Now you should see a build gear on the bottom toolbar with the text "Build".
- Click the build button. The newly cloned repo will buuld without error and there will be a SW.hex file in the build folder.
## Console
The console is used to set the maximum PWM values for each slider output and saving the values to non-volatile memory. Option selections are defined by [ ] around the expected input. Inputs not recognized are ignored. Esc is used to back out of a sub-menu without modifiying the value.
When first connecting, press enter to display the main menu. The current values are displayed next to the slider label.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 236 KiB

View File

@ -22,7 +22,7 @@
#include "usbd_cdc_if.h"
/* USER CODE BEGIN INCLUDE */
#include "console.h"
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
@ -263,12 +263,6 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
/* USER CODE BEGIN 6 */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
for (uint32_t i = 0; i < *Len; i++)
{
console_push(Buf[i]);
}
return (USBD_OK);
/* USER CODE END 6 */
}

View File

@ -32,9 +32,6 @@ target_sources(stm32cubemx INTERFACE
../../Core/Src/i2c.c
../../Core/Src/tim.c
../../Core/Src/usart.c
../../Core/Src/cir_buf.c
../../Core/Src/console.c
../../Core/Src/NVmem.c
../../Core/Src/stm32g4xx_it.c
../../Core/Src/stm32g4xx_hal_msp.c
../../USB_Device/Target/usbd_conf.c