Implemented settings module for storing AIOC settings in a register map format

pull/25/head
Simon Kueppers 2023-09-10 18:33:58 +02:00
rodzic ae56bc7af4
commit 3c2e4d7849
7 zmienionych plików z 242 dodań i 12 usunięć

Wyświetl plik

@ -6,6 +6,4 @@
#define AIOC_IRQ_PRIO_SERIAL 3
#define AIOC_IRQ_PRIO_AUDIO 2
//#define AIOC_ENABLE_PTT2
#endif /* AIOC_H_ */

Wyświetl plik

@ -1,5 +1,6 @@
#include "stm32f3xx_hal.h"
#include "aioc.h"
#include "settings.h"
#include "led.h"
#include "ptt.h"
#include "usb.h"
@ -178,6 +179,8 @@ int main(void)
SystemReset();
SystemClock_Config();
Settings_Init();
LED_Init();
LED_MODE(0, LED_MODE_SLOWPULSE2X);
LED_MODE(1, LED_MODE_SLOWPULSE2X);

Wyświetl plik

@ -26,7 +26,6 @@ static inline void PTT_Control(uint8_t pttMask)
LED_SET(1, 0);
}
#if AIOC_ENABLE_PTT2
if (pttMask & PTT_MASK_PTT2) {
PTT_GPIO->BSRR = PTT_PIN_PTT2;
LED_SET(0, 1);
@ -34,7 +33,6 @@ static inline void PTT_Control(uint8_t pttMask)
PTT_GPIO->BRR = PTT_PIN_PTT2;
LED_SET(0, 0);
}
#endif
__enable_irq();
}

Wyświetl plik

@ -0,0 +1,105 @@
#include "settings.h"
#include <assert.h>
#include "stm32f3xx_hal.h"
uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE] = {[0 ... (SETTINGS_REGMAP_SIZE-1)] = 0};
void Settings_Init()
{
Settings_Recall();
}
uint8_t Settings_RegWrite(uint8_t address, const uint8_t * buffer, uint8_t bufsize)
{
if (address < SETTINGS_REGMAP_SIZE) {
assert(bufsize == sizeof(uint32_t));
uint32_t data = ( (((uint32_t) buffer[0]) << 0) |
(((uint32_t) buffer[1]) << 8) |
(((uint32_t) buffer[2]) << 16) |
(((uint32_t) buffer[3]) << 24) );
settingsRegMap[address] = data;
return bufsize;
}
return 0;
}
uint8_t Settings_RegRead(uint8_t address, uint8_t * buffer, uint8_t bufsize)
{
if (address < SETTINGS_REGMAP_SIZE) {
assert(bufsize == sizeof(uint32_t));
uint64_t data = settingsRegMap[address];
buffer[0] = (uint8_t) (data >> 0);
buffer[1] = (uint8_t) (data >> 8);
buffer[2] = (uint8_t) (data >> 16);
buffer[3] = (uint8_t) (data >> 24);
return bufsize;
}
}
void Settings_Store(void)
{
HAL_FLASH_Unlock();
uint32_t pageError = 0;
FLASH_EraseInitTypeDef eraseInitStruct = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.PageAddress = SETTINGS_FLASH_ADDRESS,
.NbPages = (SETTINGS_REGMAP_SIZE * sizeof(uint32_t) + FLASH_PAGE_SIZE-1) / FLASH_PAGE_SIZE
};
if (HAL_FLASHEx_Erase(&eraseInitStruct, &pageError) != HAL_OK) {
uint32_t flashError = HAL_FLASH_GetError();
return;
}
uint32_t wordAddress = SETTINGS_FLASH_ADDRESS;
uint32_t wordCount = SETTINGS_REGMAP_SIZE;
uint32_t * wordPtr = settingsRegMap;
while (wordCount--) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, wordAddress, *wordPtr) != HAL_OK) {
uint32_t flashError = HAL_FLASH_GetError();
return;
}
wordPtr++;
wordAddress += sizeof(uint32_t);
}
HAL_FLASH_Lock();
}
void Settings_Recall(void)
{
uint32_t wordAddress = SETTINGS_FLASH_ADDRESS;
uint32_t wordCount = SETTINGS_REGMAP_SIZE;
uint32_t * wordPtr = settingsRegMap;
uint32_t magic = (*(__IO uint32_t *) wordAddress);
if ( magic == SETTINGS_REG_MAGIC_DEFAULT ) {
while (wordCount--) {
*wordPtr++ = *(__IO uint32_t *) wordAddress;
wordAddress += sizeof(uint32_t);
}
} else {
/* Magic token not found, assume flash is unprogrammed */
Settings_Default();
}
}
void Settings_Default(void)
{
settingsRegMap[SETTINGS_REG_MAGIC] = SETTINGS_REG_MAGIC_DEFAULT;
settingsRegMap[SETTINGS_REG_PTT1] = SETTINGS_REG_PTT1_DEFAULT;
settingsRegMap[SETTINGS_REG_PTT2] = SETTINGS_REG_PTT2_DEFAULT;
}

Wyświetl plik

@ -0,0 +1,43 @@
#ifndef SETTINGS_H_
#define SETTINGS_H_
#include <stdint.h>
#define SETTINGS_REGMAP_SIZE 256
#define SETTINGS_FLASH_ADDRESS 0x0801F000UL
extern uint32_t settingsRegMap[SETTINGS_REGMAP_SIZE];
#define SETTINGS_REG_MAGIC 0x00
#define SETTINGS_REG_MAGIC_DEFAULT ( (((uint32_t) 'A') << 0) | (((uint32_t) 'I') << 8) | (((uint32_t) 'O') << 16) | (((uint32_t) 'C') << 24) )
#define SETTINGS_REG_PTT1 0x10
#define SETTINGS_REG_PTT1_DEFAULT (SETTINGS_REG_PTT1_SRC_CM108GPIO3_MASK | SETTINGS_REG_PTT1_SRC_SERIALDTRNRTS_MASK)
#define SETTINGS_REG_PTT1_SRC_CM108GPIO1_MASK 0x00000100UL
#define SETTINGS_REG_PTT1_SRC_CM108GPIO2_MASK 0x00000200UL
#define SETTINGS_REG_PTT1_SRC_CM108GPIO3_MASK 0x00000400UL
#define SETTINGS_REG_PTT1_SRC_CM108GPIO4_MASK 0x00000800UL
#define SETTINGS_REG_PTT1_SRC_SERIALDTR_MASK 0x00010000UL
#define SETTINGS_REG_PTT1_SRC_SERIALRTS_MASK 0x00020000UL
#define SETTINGS_REG_PTT1_SRC_SERIALDTRNRTS_MASK 0x00040000UL
#define SETTINGS_REG_PTT1_SRC_SERIALNDTRRTS_MASK 0x00080000UL
#define SETTINGS_REG_PTT2 0x11
#define SETTINGS_REG_PTT2_DEFAULT (SETTINGS_REG_PTT2_SRC_CM108GPIO4_MASK)
#define SETTINGS_REG_PTT2_SRC_CM108GPIO1_MASK 0x00000100ULL
#define SETTINGS_REG_PTT2_SRC_CM108GPIO2_MASK 0x00000200ULL
#define SETTINGS_REG_PTT2_SRC_CM108GPIO3_MASK 0x00000400ULL
#define SETTINGS_REG_PTT2_SRC_CM108GPIO4_MASK 0x00000800ULL
#define SETTINGS_REG_PTT2_SRC_SERIALDTR_MASK 0x00010000ULL
#define SETTINGS_REG_PTT2_SRC_SERIALRTS_MASK 0x00020000ULL
#define SETTINGS_REG_PTT2_SRC_SERIALDTRNRTS_MASK 0x00040000ULL
#define SETTINGS_REG_PTT2_SRC_SERIALNDTRRTS_MASK 0x00080000ULL
void Settings_Init();
uint8_t Settings_RegWrite(uint8_t address, const uint8_t * buffer, uint8_t bufsize);
uint8_t Settings_RegRead(uint8_t address, uint8_t * buffer, uint8_t bufsize);
void Settings_Store(void);
void Settings_Recall(void);
void Settings_Default(void);
#endif /* SETTINGS_H_ */

Wyświetl plik

@ -1,6 +1,7 @@
#include "usb_hid.h"
#include "tusb.h"
#include "ptt.h"
#include "settings.h"
#include "usb_descriptors.h"
#define USB_HID_INOUT_REPORT_LEN 4
@ -26,9 +27,39 @@ static void SendReport(void)
static void ControlPTT(uint8_t gpio)
{
/* PTT1 on GPIO 3, PTT2 on GPIO4 */
uint8_t pttMask = (gpio & 0x04 ? PTT_MASK_PTT1 : 0) |
(gpio & 0x08 ? PTT_MASK_PTT2 : 0);
uint8_t pttMask = PTT_MASK_NONE;
if (settingsRegMap[SETTINGS_REG_PTT1] & SETTINGS_REG_PTT1_SRC_CM108GPIO1_MASK) {
pttMask |= gpio & 0x01 ? PTT_MASK_PTT1 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT1] & SETTINGS_REG_PTT1_SRC_CM108GPIO2_MASK) {
pttMask |= gpio & 0x02 ? PTT_MASK_PTT1 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT1] & SETTINGS_REG_PTT1_SRC_CM108GPIO3_MASK) {
pttMask |= gpio & 0x04 ? PTT_MASK_PTT1 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT1] & SETTINGS_REG_PTT1_SRC_CM108GPIO4_MASK) {
pttMask |= gpio & 0x08 ? PTT_MASK_PTT1 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT2] & SETTINGS_REG_PTT2_SRC_CM108GPIO1_MASK) {
pttMask |= gpio & 0x01 ? PTT_MASK_PTT2 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT2] & SETTINGS_REG_PTT2_SRC_CM108GPIO2_MASK) {
pttMask |= gpio & 0x02 ? PTT_MASK_PTT2 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT2] & SETTINGS_REG_PTT2_SRC_CM108GPIO3_MASK) {
pttMask |= gpio & 0x04 ? PTT_MASK_PTT2 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT2] & SETTINGS_REG_PTT2_SRC_CM108GPIO4_MASK) {
pttMask |= gpio & 0x08 ? PTT_MASK_PTT2 : 0;
}
PTT_Control(pttMask);
}
@ -51,8 +82,7 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
return USB_HID_INOUT_REPORT_LEN;
case HID_REPORT_TYPE_FEATURE:
/* Custom extension for configuring the AIOC */
break;
return Settings_RegRead(report_id, buffer, reqlen);
default:
TU_BREAKPOINT();
@ -94,7 +124,28 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
break;
case HID_REPORT_TYPE_FEATURE:
/* Custom extension for configuring the AIOC */
if (report_id == 0) {
/* Special HID feature report case. Not a valid register map address to write.
* It is used for other functions (store, recall, defaults...) */
uint32_t data = ( (((uint32_t) buffer[0]) << 0) |
(((uint32_t) buffer[1]) << 8) |
(((uint32_t) buffer[2]) << 16) |
(((uint32_t) buffer[3]) << 24) );
if (data & 0x00000010UL) {
Settings_Default();
}
if (data & 0x00000040UL) {
Settings_Recall();
}
if (data & 0x00000080UL) {
Settings_Store();
}
} else {
Settings_RegWrite(report_id, buffer, bufsize);
}
break;
default:

Wyświetl plik

@ -4,6 +4,7 @@
#include "tusb.h"
#include "led.h"
#include "ptt.h"
#include "settings.h"
#include "usb_descriptors.h"
void USB_SERIAL_UART_IRQ(void)
@ -167,8 +168,39 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
{
TU_ASSERT(itf == 0, /**/);
/* PTT Encoding logic */
uint8_t pttMask = ((dtr && !rts) ? PTT_MASK_PTT1 : 0);
uint8_t pttMask = PTT_MASK_NONE;
if (settingsRegMap[SETTINGS_REG_PTT1] & SETTINGS_REG_PTT1_SRC_SERIALDTR_MASK) {
pttMask |= dtr ? PTT_MASK_PTT1 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT1] & SETTINGS_REG_PTT1_SRC_SERIALRTS_MASK) {
pttMask |= rts ? PTT_MASK_PTT1 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT1] & SETTINGS_REG_PTT1_SRC_SERIALDTRNRTS_MASK) {
pttMask |= (dtr && !rts) ? PTT_MASK_PTT1 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT1] & SETTINGS_REG_PTT1_SRC_SERIALNDTRRTS_MASK) {
pttMask |= (!dtr && rts) ? PTT_MASK_PTT1 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT2] & SETTINGS_REG_PTT2_SRC_SERIALDTR_MASK) {
pttMask |= dtr ? PTT_MASK_PTT2 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT2] & SETTINGS_REG_PTT2_SRC_SERIALRTS_MASK) {
pttMask |= rts ? PTT_MASK_PTT2 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT2] & SETTINGS_REG_PTT2_SRC_SERIALDTRNRTS_MASK) {
pttMask |= (dtr && !rts) ? PTT_MASK_PTT2 : 0;
}
if (settingsRegMap[SETTINGS_REG_PTT2] & SETTINGS_REG_PTT2_SRC_SERIALNDTRRTS_MASK) {
pttMask |= (!dtr && rts) ? PTT_MASK_PTT2 : 0;
}
if (! (USB_SERIAL_UART->CR1 & USART_CR1_TE) ) {
/* Enable PTT only when UART transmitter is not currently transmitting */