147 lines
5.1 KiB
C
147 lines
5.1 KiB
C
#include "regs.h"
|
|
|
|
#include "hal_interface.h"
|
|
#include "stm32f1xx_hal_rtc_ex.h"
|
|
#include "eeprom.h"
|
|
#include "version.h"
|
|
|
|
|
|
extern RTC_HandleTypeDef hrtc;
|
|
|
|
static uint8_t regs[REG_ID_LAST] = {0};
|
|
static uint32_t eeprom_refresh_counter;
|
|
|
|
static uint32_t regs_unsync[(REG_ID_LAST / 32) + 1] = {0};
|
|
#define REGS_UNSYNC_SET(x) regs_unsync[(x / 32)] |= (uint32_t)(1U << (x % 32))
|
|
#define REGS_UNSYNC_UNSET(x) regs_unsync[(x / 32)] &= ~((uint32_t)(1U << (x % 32)))
|
|
#define REGS_UNSYNC_GET(x) ((regs_unsync[(x / 32)] >> (x % 32)) & (uint32_t)0x1)
|
|
|
|
inline uint8_t reg_get_value(enum reg_id reg) {
|
|
if (reg >= REG_ID_LAST)
|
|
return 0;
|
|
|
|
return regs[reg];
|
|
}
|
|
|
|
inline uint8_t* reg_raw_access(void) {
|
|
return regs;
|
|
}
|
|
|
|
inline void reg_set_value(enum reg_id reg, uint8_t value) {
|
|
if (reg >= REG_ID_LAST)
|
|
return;
|
|
|
|
regs[reg] = value;
|
|
REGS_UNSYNC_SET(reg);
|
|
eeprom_refresh_counter = uptime_ms();
|
|
}
|
|
|
|
inline uint8_t reg_is_bit_set(enum reg_id reg, uint8_t bit) {
|
|
if (reg >= REG_ID_LAST)
|
|
return 0;
|
|
|
|
return regs[reg] & bit;
|
|
}
|
|
|
|
inline void reg_set_bit(enum reg_id reg, uint8_t bit) {
|
|
if (reg >= REG_ID_LAST)
|
|
return;
|
|
|
|
regs[reg] |= bit;
|
|
REGS_UNSYNC_SET(reg);
|
|
eeprom_refresh_counter = uptime_ms();
|
|
}
|
|
|
|
/*
|
|
* | Bit | Name | Description |
|
|
* | ------ |:----------------:| ------------------------------------------------------------------:|
|
|
* | 7 | CFG_USE_MODS | Should Alt, Sym and the Shift keys modify the keys being reported. |
|
|
* | 6 | CFG_REPORT_MODS | Should Alt, Sym and the Shift keys be reported as well. |
|
|
* | 5 | CFG_PANIC_INT | Currently not implemented. |
|
|
* | 4 | CFG_KEY_INT | Should an interrupt be generated when a key is pressed. |
|
|
* | 3 | CFG_NUMLOCK_INT | Should an interrupt be generated when Num Lock is toggled. |
|
|
* | 2 | CFG_CAPSLOCK_INT | Should an interrupt be generated when Caps Lock is toggled. |
|
|
* | 1 | CFG_OVERFLOW_INT | Should an interrupt be generated when a FIFO overflow happens. |
|
|
* | 0 | CFG_OVERFLOW_ON | When a FIFO overflow happens, should the new entry still be pushed,|
|
|
* | | | overwriting the oldest one. If 0 then new entry is lost. |
|
|
*/
|
|
void reg_init(void) {
|
|
uint32_t buff;
|
|
|
|
regs[REG_ID_VER] = (uint8_t)((VERSION_MAJOR << 4) | VERSION_MINOR); // 1.2 => (0x1 << 4) | 0x2
|
|
|
|
EEPROM_ReadVariable(REG_ID_SYS_CFG, (EEPROM_Value*)&buff);
|
|
regs[REG_ID_SYS_CFG] = (uint8_t)((buff >> 8) & 0xFF);
|
|
regs[REG_ID_INT_CFG] = (uint8_t)(buff & 0xFF);
|
|
|
|
EEPROM_ReadVariable(EEPROM_VAR_KBD, (EEPROM_Value*)&buff);
|
|
//regs[REG_ID_DEB] = (uint8_t)((buff >> 8) & 0xFF);
|
|
regs[REG_ID_FRQ] = (uint8_t)(buff & 0xFF);
|
|
|
|
EEPROM_ReadVariable(EEPROM_VAR_BCKL, (EEPROM_Value*)&buff);
|
|
regs[REG_ID_BKL] = (uint8_t)((buff >> 8) & 0xFF);
|
|
regs[REG_ID_BK2] = (uint8_t)(buff & 0xFF);
|
|
|
|
buff = 0;
|
|
buff |= HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);
|
|
buff |= HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3) << 16;
|
|
regs[REG_ID_RTC_CFG] = (uint8_t)(buff & 0xFF);
|
|
rtc_alarm_time.raw = (uint8_t)((buff >> 8) & 0xFFFFFF);
|
|
|
|
buff = 0;
|
|
buff |= HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4);
|
|
buff |= HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR5) << 16;
|
|
rtc_alarm_date.raw = buff;
|
|
|
|
regs[REG_ID_BAT] = 0; //default .no battery ,no charging
|
|
|
|
regs[REG_ID_TYP] = 0xCA; // That's me :3
|
|
|
|
eeprom_refresh_counter = uptime_ms();
|
|
}
|
|
|
|
uint32_t reg_check_and_save_eeprom(void) {
|
|
uint32_t result = EEPROM_SUCCESS;
|
|
uint8_t need_save = 0;
|
|
|
|
for (size_t i = 0; i < REG_ID_LAST; i++)
|
|
if (REGS_UNSYNC_GET(i) == 1) {
|
|
need_save = 1;
|
|
break;
|
|
}
|
|
|
|
if (need_save == 1) {
|
|
if (REGS_UNSYNC_GET(REG_ID_SYS_CFG) == 1)
|
|
result |= EEPROM_WriteVariable(EEPROM_VAR_CFG, (EEPROM_Value)(uint16_t)((regs[REG_ID_SYS_CFG] << 8) | regs[REG_ID_INT_CFG]), EEPROM_SIZE16);
|
|
|
|
if (REGS_UNSYNC_GET(REG_ID_DEB) == 1 || REGS_UNSYNC_GET(REG_ID_FRQ) == 1)
|
|
result |= EEPROM_WriteVariable(EEPROM_VAR_KBD, (EEPROM_Value)(uint32_t)((keyboard_get_hold_period() << 16) | regs[REG_ID_FRQ]), EEPROM_SIZE32);
|
|
|
|
if (REGS_UNSYNC_GET(REG_ID_BKL) == 1 || REGS_UNSYNC_GET(REG_ID_BK2) == 1)
|
|
result |= EEPROM_WriteVariable(EEPROM_VAR_BCKL, (EEPROM_Value)(uint16_t)((regs[REG_ID_BKL] << 8) | regs[REG_ID_BK2]), EEPROM_SIZE16);
|
|
|
|
if (REGS_UNSYNC_GET(REG_ID_RTC_ALARM_TIME) == 1 || REGS_UNSYNC_GET(REG_ID_RTC_CFG) == 1) {
|
|
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, ((rtc_alarm_time.raw & 0xFF) << 8) | regs[REG_ID_RTC_CFG]);
|
|
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, rtc_alarm_time.raw >> 16);
|
|
}
|
|
|
|
if (REGS_UNSYNC_GET(REG_ID_RTC_ALARM_DATE) == 1) {
|
|
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, rtc_alarm_date.raw & 0xFFFF);
|
|
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, rtc_alarm_date.raw >> 16);
|
|
}
|
|
|
|
for (size_t i = 0; i < REG_ID_LAST; i++)
|
|
REGS_UNSYNC_UNSET(i);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void reg_sync(void) {
|
|
// Save user registers in EEPROM if unsynced every 1.5s
|
|
if (uptime_ms() - eeprom_refresh_counter > 1500) {
|
|
reg_check_and_save_eeprom();
|
|
eeprom_refresh_counter = uptime_ms();
|
|
}
|
|
}
|