Compare commits

..

No commits in common. "master" and "v0.4" have entirely different histories.
master ... v0.4

21 changed files with 340 additions and 915 deletions

View File

@ -324,8 +324,8 @@ uint8_t AXP2101_isDropWarningLevel1Irq(void);
uint8_t AXP2101_isVbusRemoveIrq(void); uint8_t AXP2101_isVbusRemoveIrq(void);
uint8_t AXP2101_isBatInsertIrq(void); uint8_t AXP2101_isBatInsertIrq(void);
uint8_t AXP2101_isBatRemoveIrq(void); uint8_t AXP2101_isBatRemoveIrq(void);
uint8_t AXP2101_isPkeyShortPressIrq(void); uint8_t AXP2101_isPekeyShortPressIrq(void);
uint8_t AXP2101_isPkeyLongPressIrq(void); uint8_t AXP2101_isPekeyLongPressIrq(void);
uint8_t AXP2101_isBatChargeDoneIrq(void); uint8_t AXP2101_isBatChargeDoneIrq(void);
uint8_t AXP2101_isBatChargeStartIrq(void); uint8_t AXP2101_isBatChargeStartIrq(void);

View File

@ -11,7 +11,7 @@
#define EEPROM_VAR_ID (0) // 16b: Init ID: 0xCA1C #define EEPROM_VAR_ID (0) // 16b: Init ID: 0xCA1C
#define EEPROM_VAR_CFG (1) // 16b: CFG(15:8) + INT_CFG(7:0) reg #define EEPROM_VAR_CFG (1) // 16b: CFG(15:8) + INT_CFG(7:0) reg
#define EEPROM_VAR_KBD (2) // 32b: DEB(15:0) + 0x00 + FRQ(7:0) regs #define EEPROM_VAR_KBD (2) // 32b: DEB(15:0) + 0x00 + FRQ(7:0) regs
#define EEPROM_VAR_BCKL (3) // 16b: LCD(15:8) + KBD(7:0) backlight step indice #define EEPROM_VAR_BCKL (3) // 16b: LCD(15:8) + KBD(7:0) backlight step indice
//-------------------------------------------library configuration------------------------------------------- //-------------------------------------------library configuration-------------------------------------------

View File

@ -27,7 +27,9 @@
#include "stm32f1xx_ll_utils.h" #include "stm32f1xx_ll_utils.h"
#include "stm32f1xx_ll_pwr.h" #include "stm32f1xx_ll_pwr.h"
#include "stm32f1xx_ll_dma.h" #include "stm32f1xx_ll_dma.h"
#include "stm32f1xx_ll_rtc.h"
#include "stm32f1xx_ll_gpio.h" #include "stm32f1xx_ll_gpio.h"
#include "stm32f1xx_ll_tim.h"
#ifndef HAL_INTERFACE_H_ #ifndef HAL_INTERFACE_H_
@ -128,30 +130,12 @@ extern "C" {
#define PICO_SDA_GPIO_Port GPIOB #define PICO_SDA_GPIO_Port GPIOB
// Structure definition ---------------------------------------------------------------
typedef union {
uint32_t raw;
RTC_TimeTypeDef _s;
} RTC_TimeTypeDef_u;
typedef union {
uint32_t raw;
RTC_DateTypeDef _s;
} RTC_DateTypeDef_u;
// Global variables definition -------------------------------------------------------- // Global variables definition --------------------------------------------------------
extern volatile uint32_t systicks_counter; extern volatile uint32_t systicks_counter;
extern volatile uint8_t pmu_irq; extern volatile uint8_t pmu_irq;
extern volatile uint8_t stop_mode_active;
extern volatile uint8_t rtc_reg_xor_events;
extern volatile RTC_TimeTypeDef_u rtc_alarm_time;
extern volatile RTC_DateTypeDef_u rtc_alarm_date;
// Global functions definition -------------------------------------------------------- // Global functions definition --------------------------------------------------------
void SystemClock_Config(void);
HAL_StatusTypeDef HAL_Interface_init(void); HAL_StatusTypeDef HAL_Interface_init(void);
__STATIC_INLINE uint32_t uptime_ms(void) { return systicks_counter; } __STATIC_INLINE uint32_t uptime_ms(void) { return systicks_counter; }

View File

@ -1,20 +0,0 @@
#include "stm32f1xx_hal.h"
#ifndef I2CS_H_
#define I2CS_H_
#define I2CS_REARM_TIMEOUT 500
enum i2cs_state {
//I2CS_STATE_HALT,
I2CS_STATE_IDLE,
I2CS_STATE_REG_REQUEST,
I2CS_STATE_REG_ANSWER
};
extern enum i2cs_state i2cs_state;
extern uint32_t i2cs_rearm_counter;
#endif /* I2CS_H_ */

View File

@ -8,73 +8,44 @@ enum reg_id {
REG_ID_TYP = 0x00, //!< firmware type (0=official, others=custom) REG_ID_TYP = 0x00, //!< firmware type (0=official, others=custom)
REG_ID_VER = 0x01, //!< fw version (7:4=Major, 3:0=Minor) REG_ID_VER = 0x01, //!< fw version (7:4=Major, 3:0=Minor)
#ifdef I2C_REGS_COMPAT #ifdef I2C_REGS_COMPAT
REG_ID_SYS_CFG = 0x02, // config REG_ID_CFG = 0x02, // config
REG_ID_INT = 0x03, // interrupt status REG_ID_INT = 0x03, // interrupt status
REG_ID_KEY = 0x04, // key status REG_ID_KEY = 0x04, // key status
REG_ID_BKL = 0x05, // backlight steps (0-9) REG_ID_BKL = 0x05, // backlight steps (0-9)
REG_ID_DEB = 0x06, // debounce cfg REG_ID_DEB = 0x06, // debounce cfg
REG_ID_FRQ = 0x07, // poll freq cfg REG_ID_FRQ = 0x07, // poll freq cfg
REG_ID_PWR_CTRL = 0x08, // Power control (0: idle, 1: pico reset, 2: system reset, 3: reserved, 4: sleep, 5: full-shutdown) REG_ID_RST = 0x08, // STM32 full reset
REG_ID_FIF = 0x09, // fifo REG_ID_FIF = 0x09, // fifo
REG_ID_BK2 = 0x0A, // keyboard backlight (0-9) REG_ID_BK2 = 0x0A, // keyboard backlight (0-9)
REG_ID_BAT = 0x0B, // battery REG_ID_BAT = 0x0B, // battery
REG_ID_C64_MTX = 0x0C,// read c64 matrix REG_ID_C64_MTX = 0x0C,// read c64 matrix
REG_ID_C64_JS = 0x0D, // joystick io bits REG_ID_C64_JS = 0x0D, // joystick io bits
REG_ID_INT_CFG = 0x0E, // IRQ config REG_ID_RST_PICO = 0x0E, // Pico reset
REG_ID_RTC_CFG = 0x0F, // RTC general config REG_ID_SHTDW = 0x0F, // self-shutdown
REG_ID_RTC_DATE = 0x10, // RTC date REG_ID_INT_CFG = 0x10, // IRQ config
REG_ID_RTC_TIME = 0x11, // RTC time
REG_ID_RTC_ALARM_DATE = 0x12, // RTC alarm date
REG_ID_RTC_ALARM_TIME = 0x13, // RTC alarm time
#else #else
// TODO: REG_ID_CFG_0 - 32b (RW) REG_ID_CFG = 0x02, //!< config
REG_ID_SYS_CFG = 0x02, //!< config REG_ID_INT_CFG = 0x03, //!< IRQ config
REG_ID_INT_CFG = 0x03, //!< IRQ config REG_ID_INT = 0x04, //!< interrupt status
REG_ID_PWR_CTRL = 0x04, //!< Power control (0: idle, 1: pico reset, 2: system reset, 3: reserved, 4: sleep, 5: full-shutdown) REG_ID_BKL = 0x05, //!< backlight steps (0-9)
REG_ID_RTC_CFG = 0x05, //!< RTC general config REG_ID_BK2 = 0x06, //!< keyboard backlight (0-9)
REG_ID_DEB = 0x07, //!< debounce cfg (time in ms)
REG_ID_FRQ = 0x08, //!< poll freq cfg (time in ms)
// TODO: REG_ID_CFG_1 - 32b (RW) REG_ID_KEY = 0x10, //!< key status
REG_ID_DEB = 0x06, //!< debounce cfg (time in ms) REG_ID_FIF = 0x11, //!< fifo
REG_ID_FRQ = 0x07, //!< poll freq cfg (time in ms) REG_ID_C64_MTX = 0x12, //!< read c64 matrix
REG_ID_BKL = 0x08, //!< backlight steps (0-9) REG_ID_C64_JS = 0x13, //!< joystick io bits
REG_ID_BK2 = 0x09, //!< keyboard backlight (0-9)
// TODO: REG_ID_RTC_DATE - 32b (RW) REG_ID_RST = 0x20, //!< STM32 full reset
REG_ID_RTC_DATE = 0x0A, //!< RTC date REG_ID_RST_PICO = 0x21, //!< Pico reset
// TODO: REG_ID_RTC_TIME - 32b (RW) REG_ID_SHTDW = 0x22, //!< self-shutdown
REG_ID_RTC_TIME = 0x0B, //!< RTC time
// TODO: REG_ID_RTC_ALARM_DATE - 32b (RW)
REG_ID_RTC_ALARM_DATE = 0x0C, //!< RTC alarm date
// TODO: REG_ID_RTC_ALARM_TIME - 32b (RW)
REG_ID_RTC_ALARM_TIME = 0x0D, //!< RTC alarm time
// TODO: REG_ID_INT - 32b (RO) REG_ID_BAT = 0x30, //!< battery
REG_ID_INT = 0x10, //!< interrupt flags status
// TODO: REG_ID_KBD - 32b (RO)
REG_ID_KEY = 0x14, //!< key status - 8b
REG_ID_C64_JS = 0x15, //!< joystick io bits - 8b
REG_ID_FIF = 0x16, //!< fifo - 16b
// TODO: REG_ID_BAT - 32b (RO)
REG_ID_BAT = 0x18, //!< battery percentage - 16b
//REG_ID_BAT_RAW //!< battery voltage value in mV - 16b
// TODO: REG_ID_C64_MTX_0 - 32b (RO)
REG_ID_C64_MTX = 0x1A, //!< read c64 matrix
// TODO: REG_ID_C64_MTX_1 - 32b (RO)
// TODO: REG_ID_C64_MTX_2 - 32b (RO)
#endif #endif
REG_ID_LAST REG_ID_LAST,
}; };
#define REGS_GLOBAL_ENTRY()
typedef struct {
const uint8_t addr;
uint8_t* value[];
} REGS_GLOBAL_ENTRY;
#define CFG_OVERFLOW_ON (1 << 0) //When a FIFO overflow happens, should the new entry still be pushed, overwriting the oldest one. If 0 then new entry is lost. #define CFG_OVERFLOW_ON (1 << 0) //When a FIFO overflow happens, should the new entry still be pushed, overwriting the oldest one. If 0 then new entry is lost.
#define CFG_REPORT_MODS (1 << 6) // Should Alt, Sym and Shifts be reported as well #define CFG_REPORT_MODS (1 << 6) // Should Alt, Sym and Shifts be reported as well
#define CFG_USE_MODS (1 << 7) // Should Alt, Sym and Shifts modify the keys reported #define CFG_USE_MODS (1 << 7) // Should Alt, Sym and Shifts modify the keys reported
@ -90,12 +61,6 @@ typedef struct {
#define KEY_NUMLOCK (1 << 6) #define KEY_NUMLOCK (1 << 6)
#define KEY_COUNT_MASK 0x1F //0x1F == 31 #define KEY_COUNT_MASK 0x1F //0x1F == 31
#define RTC_CFG_RUN_ALARM (1 << 0) // b0: Set the RTC alarm active.
#define RTC_CFG_REARM (1 << 1) // b1: If set, the RTC alarm will rearm for the next day trigger (if RTC_CFG_DATE_ALARM is set, repeat every day after the target date is reached)
#define RTC_CFG_DATE_ALARM (1 << 2) // b2: If set, check when alarm trig for the precise date, otherwise return to normal behavior (or sleep if wake-up)
#define RTC_CFG_PBTN_ALARM_IGNORE (1 << 3) // b3: If unset, override the power button shutdown behavior to keep the STM32 "alive" for the RTC to operate.
//#define RTC_CFG_SLEEP_MODE (1 << 4) // 0 = normal sleep (pico is shutdown, STM32 enter in low power state ~1.2mA); 1 = deep sleep (pico is shutdown, STM32 enter a stop state ~24uA)
uint8_t reg_get_value(enum reg_id reg); uint8_t reg_get_value(enum reg_id reg);
uint8_t* reg_raw_access(void); uint8_t* reg_raw_access(void);

View File

@ -1,15 +0,0 @@
#include "stm32f1xx_hal.h"
#ifndef RTC_H_
#define RTC_H_
void i2cs_fill_buffer_RTC_date(uint8_t* const buff, const volatile RTC_DateTypeDef* const date_s);
void i2cs_fill_buffer_RTC_time(uint8_t* const buff, const volatile RTC_TimeTypeDef* const time_s);
void i2cs_RTC_date_from_buffer(volatile RTC_DateTypeDef* const date_s, const uint8_t* const buff);
void i2cs_RTC_time_from_buffer(volatile RTC_TimeTypeDef* const time_s, const uint8_t* const buff);
uint32_t rtc_run_alarm(void);
uint32_t rtc_stop_alarm(void);
#endif /* RTC_H_ */

View File

@ -57,7 +57,7 @@
/*#define HAL_HCD_MODULE_ENABLED */ /*#define HAL_HCD_MODULE_ENABLED */
/*#define HAL_PWR_MODULE_ENABLED */ /*#define HAL_PWR_MODULE_ENABLED */
/*#define HAL_RCC_MODULE_ENABLED */ /*#define HAL_RCC_MODULE_ENABLED */
#define HAL_RTC_MODULE_ENABLED /*#define HAL_RTC_MODULE_ENABLED */
/*#define HAL_SD_MODULE_ENABLED */ /*#define HAL_SD_MODULE_ENABLED */
/*#define HAL_MMC_MODULE_ENABLED */ /*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_SDRAM_MODULE_ENABLED */ /*#define HAL_SDRAM_MODULE_ENABLED */

View File

@ -65,7 +65,6 @@ void USART1_IRQHandler(void);
#ifdef UART_PICO_INTERFACE #ifdef UART_PICO_INTERFACE
void USART3_IRQHandler(void); void USART3_IRQHandler(void);
#endif #endif
void RTC_Alarm_IRQHandler(void);
/* USER CODE BEGIN EFP */ /* USER CODE BEGIN EFP */
/* USER CODE END EFP */ /* USER CODE END EFP */

View File

@ -2,6 +2,6 @@
#define VERSION_H_ #define VERSION_H_
#define VERSION_MAJOR (0) #define VERSION_MAJOR (0)
#define VERSION_MINOR (6) #define VERSION_MINOR (3)
#endif /* VERSION_H_ */ #endif /* VERSION_H_ */

View File

@ -173,14 +173,14 @@ uint8_t AXP2101_isBatRemoveIrq(void) {
return 0; return 0;
} }
uint8_t AXP2101_isPkeyShortPressIrq(void) { uint8_t AXP2101_isPekeyShortPressIrq(void) {
uint8_t mask = XPOWERS_AXP2101_PKEY_SHORT_IRQ >> 8; uint8_t mask = XPOWERS_AXP2101_PKEY_SHORT_IRQ >> 8;
if (intRegister[1] & mask) if (intRegister[1] & mask)
return ((statusRegister[1] & mask) == mask); return ((statusRegister[1] & mask) == mask);
return 0; return 0;
} }
uint8_t AXP2101_isPkeyLongPressIrq(void) { uint8_t AXP2101_isPekeyLongPressIrq(void) {
uint8_t mask = XPOWERS_AXP2101_PKEY_LONG_IRQ >> 8; uint8_t mask = XPOWERS_AXP2101_PKEY_LONG_IRQ >> 8;
if (intRegister[1] & mask) if (intRegister[1] & mask)
return ((statusRegister[1] & mask) == mask); return ((statusRegister[1] & mask) == mask);

View File

@ -18,14 +18,11 @@
*/ */
#include "hal_interface.h" #include "hal_interface.h"
#include "stm32f1xx_hal_flash_ex.h"
I2C_HandleTypeDef hi2c1; I2C_HandleTypeDef hi2c1;
I2C_HandleTypeDef hi2c2; I2C_HandleTypeDef hi2c2;
RTC_HandleTypeDef hrtc;
TIM_HandleTypeDef htim1; TIM_HandleTypeDef htim1;
TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3; TIM_HandleTypeDef htim3;
@ -37,10 +34,6 @@ UART_HandleTypeDef huart1;
UART_HandleTypeDef huart3; UART_HandleTypeDef huart3;
#endif #endif
volatile uint8_t rtc_reg_xor_events = 0;
volatile RTC_TimeTypeDef_u rtc_alarm_time = {.raw = 0x00000000};
volatile RTC_DateTypeDef_u rtc_alarm_date = {.raw = 0x00010101};
static void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); static void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
@ -130,6 +123,7 @@ static void MX_I2C2_Init(void) {
* @retval None * @retval None
*/ */
static void MX_IWDG_Init(void) { static void MX_IWDG_Init(void) {
#ifndef DEBUG
LL_IWDG_Enable(IWDG); LL_IWDG_Enable(IWDG);
LL_IWDG_EnableWriteAccess(IWDG); LL_IWDG_EnableWriteAccess(IWDG);
LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_32); LL_IWDG_SetPrescaler(IWDG, LL_IWDG_PRESCALER_32);
@ -137,6 +131,7 @@ static void MX_IWDG_Init(void) {
while (LL_IWDG_IsReady(IWDG) != 1) {} while (LL_IWDG_IsReady(IWDG) != 1) {}
LL_IWDG_ReloadCounter(IWDG); LL_IWDG_ReloadCounter(IWDG);
#endif
} }
/** /**
@ -145,47 +140,28 @@ static void MX_IWDG_Init(void) {
* @retval None * @retval None
*/ */
static void MX_RTC_Init(void) { static void MX_RTC_Init(void) {
RTC_TimeTypeDef sTime = {0}; LL_RTC_InitTypeDef RTC_InitStruct = {0};
RTC_DateTypeDef DateToUpdate = {0}; LL_RTC_TimeTypeDef RTC_TimeStruct = {0};
LL_PWR_EnableBkUpAccess();
/* Enable BKP CLK enable for backup registers */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_BKP);
/* Peripheral clock enable */
LL_RCC_EnableRTC();
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
Error_Handler();
/** Initialize RTC and set the Time and Date /** Initialize RTC and set the Time and Date
*/ */
sTime.Hours = 0x0; RTC_InitStruct.AsynchPrescaler = 0xFFFFFFFFU;
sTime.Minutes = 0x0; LL_RTC_Init(RTC, &RTC_InitStruct);
sTime.Seconds = 0x0; LL_RTC_SetAsynchPrescaler(RTC, 0xFFFFFFFFU);
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) /** Initialize RTC and set the Time and Date
Error_Handler(); */
RTC_TimeStruct.Hours = 0;
DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY; RTC_TimeStruct.Minutes = 0;
DateToUpdate.Month = RTC_MONTH_JANUARY; RTC_TimeStruct.Seconds = 0;
DateToUpdate.Date = 0x1; LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BCD, &RTC_TimeStruct);
DateToUpdate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK)
Error_Handler();
}
/**
* @brief RTC fake initialization Function, used when RTC is already alive (after a wake-up reset)
* @param None
* @retval None
*/
static void MX_RTC_Init2(void) {
hrtc.Instance = RTC;
hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
hrtc.Lock = HAL_UNLOCKED;
HAL_RTC_MspInit(&hrtc);
hrtc.State = HAL_RTC_STATE_READY;
} }
/** /**
@ -379,7 +355,7 @@ static void MX_GPIO_Init(void) {
/**/ /**/
GPIO_InitStruct.Pin = SYS_LED_Pin; GPIO_InitStruct.Pin = SYS_LED_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
LL_GPIO_Init(SYS_LED_GPIO_Port, &GPIO_InitStruct); LL_GPIO_Init(SYS_LED_GPIO_Port, &GPIO_InitStruct);
@ -553,41 +529,6 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c) {
} }
} }
/**
* @brief RTC MSP Initialization
* This function configures the hardware resources used in this example
* @param hrtc: RTC handle pointer
* @retval None
*/
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) {
if (hrtc->Instance == RTC) {
HAL_PWR_EnableBkUpAccess();
/* Enable BKP CLK enable for backup registers */
__HAL_RCC_BKP_CLK_ENABLE();
/* Peripheral clock enable */
__HAL_RCC_RTC_ENABLE();
/* RTC interrupt Init */
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
}
}
/**
* @brief RTC MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hrtc: RTC handle pointer
* @retval None
*/
void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc) {
if (hrtc->Instance == RTC) {
/* Peripheral clock disable */
__HAL_RCC_RTC_DISABLE();
/* RTC interrupt DeInit */
HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn);
}
}
/** /**
* @brief TIM_Base MSP Initialization * @brief TIM_Base MSP Initialization
* This function configures the hardware resources used in this example * This function configures the hardware resources used in this example
@ -799,9 +740,7 @@ void assert_failed(uint8_t *file, uint32_t line)
void flash_one_time(uint32_t ts, uint8_t restore_status) { void flash_one_time(uint32_t ts, uint8_t restore_status) {
for (size_t i = 0; i < ts; i++) { for (size_t i = 0; i < ts; i++) {
//#ifndef DEBUG LL_IWDG_ReloadCounter(IWDG);
// LL_IWDG_ReloadCounter(IWDG);
//#endif
LL_GPIO_ResetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin); LL_GPIO_ResetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin);
HAL_Delay(400); HAL_Delay(400);
LL_GPIO_SetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin); LL_GPIO_SetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin);
@ -820,7 +759,6 @@ void flash_one_time(uint32_t ts, uint8_t restore_status) {
*/ */
HAL_StatusTypeDef HAL_Interface_init(void) { HAL_StatusTypeDef HAL_Interface_init(void) {
HAL_StatusTypeDef result = HAL_OK; HAL_StatusTypeDef result = HAL_OK;
FLASH_OBProgramInitTypeDef flash_s;
result |= HAL_Init(); result |= HAL_Init();
if (result != HAL_OK) if (result != HAL_OK)
@ -828,42 +766,16 @@ HAL_StatusTypeDef HAL_Interface_init(void) {
SystemClock_Config(); SystemClock_Config();
// Control wake-up state
//if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST))
//__HAL_RCC_CLEAR_RESET_FLAGS();
// Use SRAM backup registers to check if we have soft-reset
HAL_PWR_EnableBkUpAccess();
MX_GPIO_Init(); MX_GPIO_Init();
MX_I2C1_Init(); MX_I2C1_Init();
MX_I2C2_Init(); MX_I2C2_Init();
if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) != 0) MX_RTC_Init();
MX_RTC_Init2();
else
MX_RTC_Init();
MX_USART1_UART_Init(); MX_USART1_UART_Init();
MX_USART3_UART_Init(); MX_USART3_UART_Init();
//#ifndef DEBUG MX_IWDG_Init();
// MX_IWDG_Init();
//#endif
MX_TIM1_Init(); MX_TIM1_Init();
MX_TIM3_Init(); MX_TIM3_Init();
MX_TIM2_Init(); MX_TIM2_Init();
// Check options registers values
HAL_FLASHEx_OBGetConfig(&flash_s);
//if ((flash_s.USERConfig & (OB_STOP_NO_RST | OB_STDBY_NO_RST)) != 0) {
if ((flash_s.USERConfig & (OB_STOP_NO_RST | OB_STDBY_NO_RST)) == 0) {
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
//flash_s.USERConfig &= (uint8_t)~(OB_STOP_NO_RST | OB_STDBY_NO_RST); // Enable reset when sleep
flash_s.USERConfig |= (uint8_t)(OB_STOP_NO_RST | OB_STDBY_NO_RST); // Disable reset when sleep
HAL_FLASHEx_OBProgram(&flash_s);
HAL_FLASH_OB_Launch(); // Reset system
// We should never reach this point
for ( ;; ) {}
}
return result; return result;
} }

View File

@ -1,221 +0,0 @@
#include "i2cs.h"
#include "hal_interface.h"
#include "backlight.h"
#include "fifo.h"
#include "rtc.h"
#include "regs.h"
extern I2C_HandleTypeDef hi2c1;
extern I2C_HandleTypeDef hi2c2;
extern RTC_HandleTypeDef hrtc;
static uint8_t i2cs_r_buff[5];
static volatile uint8_t i2cs_r_idx = 0;
static uint8_t i2cs_w_buff[10];
static volatile uint8_t i2cs_w_idx = 0;
static volatile uint8_t i2cs_w_len = 0;
enum i2cs_state i2cs_state = I2CS_STATE_IDLE;
uint32_t i2cs_rearm_counter = 0;
extern void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) {
if (hi2c == &hi2c1) {
// I2C slave addr match error detection
if (AddrMatchCode != 0x3E) // 0x1F << 1
return;
if (TransferDirection == I2C_DIRECTION_TRANSMIT) {
if (i2cs_state == I2CS_STATE_IDLE) {
i2cs_state = I2CS_STATE_REG_REQUEST;
i2cs_r_idx = 0;
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, i2cs_r_buff, 1, I2C_FIRST_FRAME); // This write the first received byte to i2cs_r_buff[0]
i2cs_rearm_counter = uptime_ms();
}
}
if (TransferDirection == I2C_DIRECTION_RECEIVE) {
if (i2cs_state == I2CS_STATE_REG_REQUEST) {
const uint8_t is_write = (uint8_t)(i2cs_r_buff[0] & (1 << 7));
const uint8_t reg = (uint8_t)(i2cs_r_buff[0] & ~(1 << 7));
i2cs_w_buff[0] = reg;
i2cs_w_len = 2;
if (reg == REG_ID_BKL) { // We wait an another byte for these registers
if (is_write)
lcd_backlight_update(i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_BKL);
} else if (reg == REG_ID_BK2) {
if (is_write)
kbd_backlight_update(i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_BK2);
} else if (reg == REG_ID_SYS_CFG) {
if (is_write)
reg_set_value(REG_ID_SYS_CFG, i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_SYS_CFG);
} else if (reg == REG_ID_INT_CFG) {
if (is_write)
reg_set_value(REG_ID_INT_CFG, i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_INT_CFG);
} else if (reg == REG_ID_DEB) {
if (is_write) {
keyboard_set_hold_period(*((uint16_t*)&i2cs_r_buff[1]));
reg_set_value(REG_ID_DEB, 0); // Trig async flag for EEPROM saving
}
*((uint16_t*)&i2cs_w_buff[1]) = keyboard_get_hold_period();
i2cs_w_len = 3;
} else if (reg == REG_ID_FRQ) {
if (is_write)
reg_set_value(REG_ID_FRQ, i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_FRQ);
} else if (reg == REG_ID_FIF) {
struct fifo_item item = {0};
fifo_dequeue(&item);
i2cs_w_buff[0] = item.state;
i2cs_w_buff[1] = item.key;
} else if (reg == REG_ID_INT) {
if (is_write)
reg_set_value(REG_ID_INT, 0);
i2cs_w_buff[1] = reg_get_value(REG_ID_INT);
LL_GPIO_SetOutputPin(PICO_IRQ_GPIO_Port, PICO_IRQ_Pin); // De-assert the IRQ signal
} else if (reg == REG_ID_VER) {
i2cs_w_buff[1] = reg_get_value(REG_ID_VER);
} else if (reg == REG_ID_TYP) {
i2cs_w_buff[1] = reg_get_value(REG_ID_TYP);
} else if (reg == REG_ID_BAT) {
i2cs_w_buff[1] = reg_get_value(REG_ID_BAT);
} else if (reg == REG_ID_RTC_CFG) {
if (is_write) {
rtc_reg_xor_events |= reg_get_value(REG_ID_RTC_CFG) ^ i2cs_r_buff[1]; // Using a "OR" set style to avoid loosing change before processing it
reg_set_value(REG_ID_RTC_CFG, i2cs_r_buff[1]);
}
i2cs_w_buff[1] = reg_get_value(REG_ID_RTC_CFG);
} else if (reg == REG_ID_RTC_DATE) {
RTC_DateTypeDef date_s = {0};
if (is_write) {
i2cs_RTC_date_from_buffer(&date_s, &i2cs_r_buff[1]);
HAL_RTC_SetDate(&hrtc, &date_s, RTC_FORMAT_BIN);
}
HAL_RTC_GetDate(&hrtc, &date_s, RTC_FORMAT_BIN);
i2cs_fill_buffer_RTC_date(&i2cs_w_buff[1], &date_s);
i2cs_w_len = 5;
} else if (reg == REG_ID_RTC_TIME) {
RTC_TimeTypeDef time_s = {0};
if (is_write) {
i2cs_RTC_time_from_buffer(&time_s, &i2cs_r_buff[1]);
HAL_RTC_SetTime(&hrtc, &time_s, RTC_FORMAT_BIN);
}
HAL_RTC_GetTime(&hrtc, &time_s, RTC_FORMAT_BIN);
i2cs_fill_buffer_RTC_time(&i2cs_w_buff[1], &time_s);
i2cs_w_len = 4;
} else if (reg == REG_ID_RTC_ALARM_DATE) {
if (is_write)
i2cs_RTC_date_from_buffer(&rtc_alarm_date._s, &i2cs_r_buff[1]);
i2cs_fill_buffer_RTC_date(&i2cs_w_buff[1], &rtc_alarm_date._s);
i2cs_w_len = 5;
} else if (reg == REG_ID_RTC_ALARM_TIME) {
if (is_write)
i2cs_RTC_time_from_buffer(&rtc_alarm_time._s, &i2cs_r_buff[1]);
i2cs_fill_buffer_RTC_time(&i2cs_w_buff[1], &rtc_alarm_time._s);
i2cs_w_len = 4;
} else if (reg == REG_ID_KEY) {
i2cs_w_buff[0] = fifo_count();
i2cs_w_buff[0] |= keyboard_get_numlock() ? KEY_NUMLOCK : 0x00;
i2cs_w_buff[0] |= keyboard_get_capslock() ? KEY_CAPSLOCK : 0x00;
} else if (reg == REG_ID_C64_MTX) {
//memcpy(write_buffer + 1, io_matrix, sizeof(io_matrix));
*((uint32_t*)(&i2cs_w_buff[1]) + 0) = *((uint32_t*)(io_matrix) + 0);
*((uint32_t*)(&i2cs_w_buff[1]) + 1) = *((uint32_t*)(io_matrix) + 1);
i2cs_w_buff[9] = io_matrix[8];
i2cs_w_len = 10;
} else if (reg == REG_ID_C64_JS) {
i2cs_w_buff[1] = js_bits;
} else if (reg == REG_ID_PWR_CTRL) {
if (is_write)
reg_set_value(REG_ID_PWR_CTRL, i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_PWR_CTRL);
} else {
i2cs_w_buff[0] = 0;
i2cs_w_buff[1] = 0;
}
i2cs_state = I2CS_STATE_REG_ANSWER;
i2cs_w_idx = 0;
HAL_I2C_Slave_Sequential_Transmit_IT(hi2c, i2cs_w_buff, i2cs_w_len, I2C_FIRST_AND_LAST_FRAME);
i2cs_rearm_counter = uptime_ms();
}
}
}
}
extern void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) {
if (hi2c == &hi2c1) {
i2cs_r_idx++;
if (i2cs_state == I2CS_STATE_REG_REQUEST) {
const uint8_t is_write = (uint8_t)(i2cs_r_buff[0] & (1 << 7));
const uint8_t reg = (uint8_t)(i2cs_r_buff[0] & ~(1 << 7));
uint8_t bytes_needed = 0;
// Check for another mandatories bytes depending on register requested
if (reg == REG_ID_BKL ||
reg == REG_ID_BK2 ||
reg == REG_ID_SYS_CFG ||
reg == REG_ID_INT_CFG ||
reg == REG_ID_FRQ) {
if (is_write)
bytes_needed = 1;
} else if (reg == REG_ID_DEB) {
if (is_write)
bytes_needed = 2;
} else if (reg == REG_ID_RTC_DATE ||
reg == REG_ID_RTC_ALARM_DATE ||
reg == REG_ID_RTC_TIME ||
reg == REG_ID_RTC_ALARM_TIME) {
if (is_write)
bytes_needed = 3;
}
if (bytes_needed > 0)
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, i2cs_r_buff + i2cs_r_idx, bytes_needed, I2C_NEXT_FRAME); // This write the second or more received byte to i2cs_r_buff[1]
}
}
}
extern void HAL_I2C_ListenCpltCallback (I2C_HandleTypeDef *hi2c) {
if (hi2c == &hi2c1) {
if (i2cs_state == I2CS_STATE_REG_ANSWER)
i2cs_state = I2CS_STATE_IDLE;
HAL_I2C_EnableListen_IT(hi2c);
}
}
extern void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) {
if (hi2c == &hi2c1)
if (HAL_I2C_GetError(hi2c) != HAL_I2C_ERROR_AF) {
//Error_Handler();
// Actually this will trigger the watchdog and restart the system... That can ruin the day of the user.
NVIC_SystemReset();
}
}

View File

@ -152,27 +152,27 @@ static void transition_to(struct list_item * const p_item, const enum key_state
switch (p_entry->mod) { switch (p_entry->mod) {
case MOD_ALT: case MOD_ALT:
if (reg_is_bit_set(REG_ID_SYS_CFG, CFG_REPORT_MODS)) if (reg_is_bit_set(REG_ID_CFG, CFG_REPORT_MODS))
chr = KEY_MOD_ALT; chr = KEY_MOD_ALT;
break; break;
case MOD_SHL: case MOD_SHL:
if (reg_is_bit_set(REG_ID_SYS_CFG, CFG_REPORT_MODS)) if (reg_is_bit_set(REG_ID_CFG, CFG_REPORT_MODS))
chr = KEY_MOD_SHL; chr = KEY_MOD_SHL;
break; break;
case MOD_SHR: case MOD_SHR:
if (reg_is_bit_set(REG_ID_SYS_CFG, CFG_REPORT_MODS)) if (reg_is_bit_set(REG_ID_CFG, CFG_REPORT_MODS))
chr = KEY_MOD_SHR; chr = KEY_MOD_SHR;
break; break;
case MOD_SYM: case MOD_SYM:
if (reg_is_bit_set(REG_ID_SYS_CFG, CFG_REPORT_MODS)) if (reg_is_bit_set(REG_ID_CFG, CFG_REPORT_MODS))
chr = KEY_MOD_SYM; chr = KEY_MOD_SYM;
break; break;
case MOD_CTRL: case MOD_CTRL:
if (reg_is_bit_set(REG_ID_SYS_CFG, CFG_REPORT_MODS)) if (reg_is_bit_set(REG_ID_CFG, CFG_REPORT_MODS))
chr = KEY_MOD_CTRL; chr = KEY_MOD_CTRL;
break; break;
@ -182,7 +182,7 @@ static void transition_to(struct list_item * const p_item, const enum key_state
capslock_changed = 1; capslock_changed = 1;
} }
if (reg_is_bit_set(REG_ID_SYS_CFG, CFG_USE_MODS)) { if (reg_is_bit_set(REG_ID_CFG, CFG_USE_MODS)) {
const uint8_t shift = (mods[MOD_SHL] || mods[MOD_SHR]); const uint8_t shift = (mods[MOD_SHL] || mods[MOD_SHR]);
const uint8_t alt = mods[MOD_ALT] | numlock; const uint8_t alt = mods[MOD_ALT] | numlock;
//const uint8_t ctrl = mods[MOD_CTRL]; //const uint8_t ctrl = mods[MOD_CTRL];

View File

@ -11,25 +11,16 @@
* *
* SYS_LED and COL_x are open-drain, output logic is inverted. * SYS_LED and COL_x are open-drain, output logic is inverted.
* *
* Unless requested by the user through REG_ID_PWR_CTRL register or by removing
* the batteries, pressing the power button when running now put the STM32 in
* low-power stop mode and shutdown the PICO board.
* It's the only mean to keep the RTC functional.
* A full shutdown using AXP2101 power-off or by removing the batteries will
* reset the RTC and disable auto wake-up feature.
*
*/ */
#include "hal_interface.h" #include "hal_interface.h"
#include "axp2101.h" #include "axp2101.h"
#include "backlight.h" #include "backlight.h"
#include "batt.h" #include "batt.h"
#include "eeprom.h" #include "eeprom.h"
#include "fifo.h" #include "fifo.h"
#include "keyboard.h" #include "keyboard.h"
#include "i2cs.h"
#include "regs.h" #include "regs.h"
#include "rtc.h"
// Private define ------------------------------------------------------------ // Private define ------------------------------------------------------------
@ -39,7 +30,9 @@
#define DEFAULT_KBD_BL (0) //step-1 (0%) #define DEFAULT_KBD_BL (0) //step-1 (0%)
#define DEFAULT_KBD_FREQ (KEY_POLL_TIME) #define DEFAULT_KBD_FREQ (KEY_POLL_TIME)
#define DEFAULT_KBD_DEB (KEY_HOLD_TIME) #define DEFAULT_KBD_DEB (KEY_HOLD_TIME)
#define DEFAULT_RCT_CFG (0x00)
#define I2CS_REARM_TIMEOUT 500
#define I2CS_W_BUFF_LEN 31+1 // The last one must be only a 0 value, TODO: another cleaner way?
#ifdef DEBUG #ifdef DEBUG
#define DEBUG_UART_MSG(msg) HAL_UART_Transmit(&huart1, (uint8_t*)msg, sizeof(msg)-1, 1000) #define DEBUG_UART_MSG(msg) HAL_UART_Transmit(&huart1, (uint8_t*)msg, sizeof(msg)-1, 1000)
@ -49,14 +42,18 @@
// Private typedef ----------------------------------------------------------- // Private typedef -----------------------------------------------------------
enum i2cs_state {
//I2CS_STATE_HALT,
I2CS_STATE_IDLE,
I2CS_STATE_REG_REQUEST,
I2CS_STATE_REG_ANSWER
};
// Private variables --------------------------------------------------------- // Private variables ---------------------------------------------------------
extern I2C_HandleTypeDef hi2c1; extern I2C_HandleTypeDef hi2c1;
extern I2C_HandleTypeDef hi2c2; extern I2C_HandleTypeDef hi2c2;
extern RTC_HandleTypeDef hrtc;
extern TIM_HandleTypeDef htim1; extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2; extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3; extern TIM_HandleTypeDef htim3;
@ -71,12 +68,18 @@ extern UART_HandleTypeDef huart3;
volatile uint32_t systicks_counter = 0; // 1 MHz systick counter volatile uint32_t systicks_counter = 0; // 1 MHz systick counter
static uint32_t pmu_check_counter = 0; static uint32_t pmu_check_counter = 0;
static uint32_t i2cs_rearm_counter = 0;
static uint8_t i2cs_r_buff[5];
static volatile uint8_t i2cs_r_idx = 0;
static uint8_t i2cs_w_buff[I2CS_W_BUFF_LEN];
static volatile uint8_t i2cs_w_idx = 0;
static volatile uint8_t i2cs_w_len = 0;
static enum i2cs_state i2cs_state = I2CS_STATE_IDLE;
static uint8_t keycb_start = 0; static uint8_t keycb_start = 0;
static uint32_t head_phone_status = 0; // TODO: Combine status registers static uint32_t head_phone_status = 0; // TODO: Combine status registers
volatile uint8_t stop_mode_active = 0;
volatile uint8_t pmu_irq = 0; volatile uint8_t pmu_irq = 0;
static uint32_t pmu_online = 0; static uint32_t pmu_online = 0;
@ -90,8 +93,6 @@ static void sync_bat(void);
static void printPMU(void); static void printPMU(void);
#endif #endif
static void check_pmu_int(void); static void check_pmu_int(void);
static void sys_prepare_sleep(void);
static void sys_wake_sleep(void);
extern void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { extern void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim == &htim2) { if (htim == &htim2) {
@ -99,6 +100,159 @@ extern void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
} }
} }
extern void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) {
if (hi2c == &hi2c1) {
// I2C slave addr match error detection
if (AddrMatchCode != 0x3E) // 0x1F << 1
return;
if (TransferDirection == I2C_DIRECTION_TRANSMIT) {
if (i2cs_state == I2CS_STATE_IDLE) {
i2cs_state = I2CS_STATE_REG_REQUEST;
i2cs_r_idx = 0;
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, i2cs_r_buff, 1, I2C_FIRST_FRAME); // This write the first received byte to i2cs_r_buff[0]
i2cs_rearm_counter = uptime_ms();
}
}
if (TransferDirection == I2C_DIRECTION_RECEIVE) {
if (i2cs_state == I2CS_STATE_REG_REQUEST) {
const uint8_t is_write = (uint8_t)(i2cs_r_buff[0] & (1 << 7));
const uint8_t reg = (uint8_t)(i2cs_r_buff[0] & ~(1 << 7));
i2cs_w_buff[0] = reg;
i2cs_w_len = 2;
if (reg == REG_ID_BKL) { // We wait an another byte for these registers
if (is_write)
lcd_backlight_update(i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_BKL);
} else if (reg == REG_ID_BK2) {
if (is_write)
kbd_backlight_update(i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_BK2);
} else if (reg == REG_ID_CFG) {
if (is_write)
reg_set_value(REG_ID_CFG, i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_CFG);
} else if (reg == REG_ID_INT_CFG) {
if (is_write)
reg_set_value(REG_ID_INT_CFG, i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_INT_CFG);
} else if (reg == REG_ID_DEB) {
if (is_write) {
keyboard_set_hold_period(*((uint16_t*)&i2cs_r_buff[1]));
reg_set_value(REG_ID_DEB, 0); // Trig async flag for EEPROM saving
}
*((uint16_t*)&i2cs_w_buff[1]) = keyboard_get_hold_period();
i2cs_w_len = 3;
} else if (reg == REG_ID_FRQ) {
if (is_write)
reg_set_value(REG_ID_FRQ, i2cs_r_buff[1]);
i2cs_w_buff[1] = reg_get_value(REG_ID_FRQ);
} else if (reg == REG_ID_FIF) {
struct fifo_item item = {0};
fifo_dequeue(&item);
i2cs_w_buff[0] = item.state;
i2cs_w_buff[1] = item.key;
} else if (reg == REG_ID_INT) {
i2cs_w_buff[1] = reg_get_value(REG_ID_INT);
LL_GPIO_SetOutputPin(PICO_IRQ_GPIO_Port, PICO_IRQ_Pin); // De-assert the IRQ signal
} else if (reg == REG_ID_VER) {
i2cs_w_buff[1] = reg_get_value(REG_ID_VER);
} else if (reg == REG_ID_TYP) {
i2cs_w_buff[1] = reg_get_value(REG_ID_TYP);
} else if (reg == REG_ID_BAT) {
i2cs_w_buff[1] = reg_get_value(REG_ID_BAT);
} else if (reg == REG_ID_KEY) {
i2cs_w_buff[0] = fifo_count();
i2cs_w_buff[0] |= keyboard_get_numlock() ? KEY_NUMLOCK : 0x00;
i2cs_w_buff[0] |= keyboard_get_capslock() ? KEY_CAPSLOCK : 0x00;
} else if (reg == REG_ID_C64_MTX) {
//memcpy(write_buffer + 1, io_matrix, sizeof(io_matrix));
*((uint32_t*)(&i2cs_w_buff[1]) + 0) = *((uint32_t*)(io_matrix) + 0);
*((uint32_t*)(&i2cs_w_buff[1]) + 1) = *((uint32_t*)(io_matrix) + 1);
i2cs_w_buff[9] = io_matrix[8];
i2cs_w_len = 10;
} else if (reg == REG_ID_C64_JS) {
i2cs_w_buff[1] = js_bits;
} else if (reg == REG_ID_RST) {
if (is_write)
reg_set_value(REG_ID_RST, 1);
i2cs_w_buff[1] = reg_get_value(REG_ID_RST);
} else if (reg == REG_ID_RST_PICO) {
if (is_write)
reg_set_value(REG_ID_RST_PICO, 1);
i2cs_w_buff[1] = reg_get_value(REG_ID_RST_PICO);
} else if (reg == REG_ID_SHTDW) {
if (is_write) {
reg_set_value(REG_ID_SHTDW, 1);
return; // Ignore answer, everything will be shutdown
}
i2cs_w_buff[1] = 0;
} else {
i2cs_w_buff[0] = 0;
i2cs_w_buff[1] = 0;
}
i2cs_state = I2CS_STATE_REG_ANSWER;
i2cs_w_idx = 0;
HAL_I2C_Slave_Sequential_Transmit_IT(hi2c, i2cs_w_buff, i2cs_w_len, I2C_FIRST_AND_LAST_FRAME);
i2cs_rearm_counter = uptime_ms();
}
}
}
}
extern void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) {
if (hi2c == &hi2c1) {
i2cs_r_idx++;
if (i2cs_state == I2CS_STATE_REG_REQUEST) {
const uint8_t is_write = (uint8_t)(i2cs_r_buff[0] & (1 << 7));
const uint8_t reg = (uint8_t)(i2cs_r_buff[0] & ~(1 << 7));
uint8_t bytes_needed = 0;
// Check for another mandatories bytes depending on register requested
if (reg == REG_ID_BKL ||
reg == REG_ID_BK2 ||
reg == REG_ID_CFG ||
reg == REG_ID_INT_CFG ||
reg == REG_ID_FRQ) {
if (is_write)
bytes_needed = 1;
} else if (reg == REG_ID_DEB) {
if (is_write)
bytes_needed = 2;
}
if (bytes_needed > 0)
HAL_I2C_Slave_Sequential_Receive_IT(hi2c, i2cs_r_buff + i2cs_r_idx, bytes_needed, I2C_NEXT_FRAME); // This write the second or more received byte to i2cs_r_buff[1]
}
}
}
extern void HAL_I2C_ListenCpltCallback (I2C_HandleTypeDef *hi2c) {
if (hi2c == &hi2c1) {
if (i2cs_state == I2CS_STATE_REG_ANSWER)
i2cs_state = I2CS_STATE_IDLE;
HAL_I2C_EnableListen_IT(hi2c);
}
}
extern void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) {
if (hi2c == &hi2c1)
if (HAL_I2C_GetError(hi2c) != HAL_I2C_ERROR_AF)
Error_Handler();
// Actually this will trigger the watchdog and restart the system... That can ruin the day of the user.
}
#ifdef DEBUG #ifdef DEBUG
void uart_rawdata_write(uint32_t c, size_t s, uint8_t swap) { void uart_rawdata_write(uint32_t c, size_t s, uint8_t swap) {
uint8_t r[4]; uint8_t r[4];
@ -127,12 +281,12 @@ int main(void) {
if (result != HAL_OK) if (result != HAL_OK)
Error_Handler(); Error_Handler();
LL_GPIO_ResetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin); // I'm alive!
// Start the systick timer // Start the systick timer
if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK) if (HAL_TIM_Base_Start_IT(&htim2) != HAL_OK)
Error_Handler(); Error_Handler();
LL_GPIO_ResetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin); // I'm alive!
// EEPROM emulation init // EEPROM emulation init
if (EEPROM_Init() != EEPROM_SUCCESS) if (EEPROM_Init() != EEPROM_SUCCESS)
Error_Handler(); Error_Handler();
@ -152,15 +306,6 @@ int main(void) {
#endif #endif
} }
// Check RTC SRAM first run
if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) == 0) {
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0xCA1C);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, ((rtc_alarm_time.raw & 0xFF) << 8) | DEFAULT_RCT_CFG);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, rtc_alarm_time.raw >> 16);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, rtc_alarm_date.raw & 0xFFFF);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, rtc_alarm_date.raw >> 16);
}
// I2C-Pico interface registers // I2C-Pico interface registers
reg_init(); reg_init();
HAL_Delay(10); HAL_Delay(10);
@ -229,7 +374,6 @@ int main(void) {
AXP2101_clearIrqStatus(); AXP2101_clearIrqStatus();
AXP2101_enableIRQ(XPOWERS_AXP2101_BAT_INSERT_IRQ | AXP2101_enableIRQ(XPOWERS_AXP2101_BAT_INSERT_IRQ |
XPOWERS_AXP2101_BAT_REMOVE_IRQ | // BATTERY XPOWERS_AXP2101_BAT_REMOVE_IRQ | // BATTERY
XPOWERS_AXP2101_WARNING_LEVEL1_IRQ |
XPOWERS_AXP2101_VBUS_INSERT_IRQ | XPOWERS_AXP2101_VBUS_INSERT_IRQ |
XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS
XPOWERS_AXP2101_PKEY_SHORT_IRQ | XPOWERS_AXP2101_PKEY_SHORT_IRQ |
@ -259,9 +403,7 @@ int main(void) {
low_bat(); low_bat();
while (1) { while (1) {
//#ifndef DEBUG LL_IWDG_ReloadCounter(IWDG);
// LL_IWDG_ReloadCounter(IWDG);
//#endif
// Re-arm I2CS in case of lost master signal // Re-arm I2CS in case of lost master signal
if (i2cs_state != I2CS_STATE_IDLE && ((uptime_ms() - i2cs_rearm_counter) > I2CS_REARM_TIMEOUT)) if (i2cs_state != I2CS_STATE_IDLE && ((uptime_ms() - i2cs_rearm_counter) > I2CS_REARM_TIMEOUT))
@ -272,89 +414,36 @@ int main(void) {
keyboard_process(); keyboard_process();
hw_check_HP_presence(); hw_check_HP_presence();
// Check RTC new events to process
if (rtc_reg_xor_events != 0) {
if ((rtc_reg_xor_events & RTC_CFG_RUN_ALARM) == RTC_CFG_RUN_ALARM) {
if (reg_get_value(REG_ID_RTC_CFG) & RTC_CFG_RUN_ALARM) {
if (rtc_run_alarm() != HAL_OK)
reg_set_value(REG_ID_RTC_CFG, reg_get_value(REG_ID_RTC_CFG) & (uint8_t)~RTC_CFG_RUN_ALARM);
} else {
if (rtc_stop_alarm() != HAL_OK)
reg_set_value(REG_ID_RTC_CFG, reg_get_value(REG_ID_RTC_CFG) | RTC_CFG_RUN_ALARM);
}
rtc_reg_xor_events &= (uint8_t)~RTC_CFG_RUN_ALARM;
}
}
// Check internal status // Check internal status
switch (reg_get_value(REG_ID_PWR_CTRL)) { if (reg_get_value(REG_ID_SHTDW) == 1) { // Nominal full system shutdown as requested from I2C bus
case 1: reg_set_value(REG_ID_SHTDW, 0);
reg_set_value(REG_ID_PWR_CTRL, 0);
HAL_Delay(200); // Wait for final I2C answer
if (HAL_I2C_DisableListen_IT(&hi2c1) != HAL_OK)
Error_Handler();
LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
HAL_Delay(200); // No need to use keyboard, so a simple delay should suffice
LL_GPIO_SetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
LL_GPIO_SetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
if (HAL_I2C_EnableListen_IT(&hi2c1) != HAL_OK)
Error_Handler();
break;
case 2:
reg_set_value(REG_ID_PWR_CTRL, 0);
HAL_Delay(200); // Wait for final I2C answer
if (HAL_I2C_DisableListen_IT(&hi2c1) != HAL_OK)
Error_Handler();
LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
NVIC_SystemReset();
break;
//case 3:
case 4:
reg_set_value(REG_ID_PWR_CTRL, 0);
LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
AXP2101_setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
stop_mode_active = 1;
break;
case 5:
reg_set_value(REG_ID_PWR_CTRL, 0);
LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
AXP2101_setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
AXP2101_shutdown(); // Full shudown will rip the RTC configuration! Need to be reset at next reboot.
break;
default:
break;
}
if (stop_mode_active == 1) {
/* Prepare peripherals to the low-power mode */
sys_prepare_sleep();
/* Low-power mode entry */
//HAL_WWDG_Disable();
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config();
HAL_ResumeTick();
LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin); LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin); LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
HAL_Delay(500); AXP2101_setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
/* Wake-up peripherals from low-power mode */ AXP2101_shutdown();
sys_wake_sleep(); } else if (reg_get_value(REG_ID_RST) == 1) { // Try to reset only the STM32
reg_set_value(REG_ID_RST, 0);
HAL_Delay(200); // Wait for final I2C answer
if (HAL_I2C_DisableListen_IT(&hi2c1) != HAL_OK)
Error_Handler();
LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
NVIC_SystemReset();
} else if (reg_get_value(REG_ID_RST_PICO) == 1) { // Reset only the Pico
reg_set_value(REG_ID_RST_PICO, 0);
HAL_Delay(200); // Wait for final I2C answer
if (HAL_I2C_DisableListen_IT(&hi2c1) != HAL_OK)
Error_Handler();
LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
HAL_Delay(200); // No need to use keyboard, so a simple delay should suffice
LL_GPIO_SetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
LL_GPIO_SetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
if (HAL_I2C_EnableListen_IT(&hi2c1) != HAL_OK)
Error_Handler();
} }
} }
} }
@ -412,7 +501,7 @@ static void key_cb(char key, enum key_state state) {
int_trig = 1; int_trig = 1;
} }
if (reg_is_bit_set(REG_ID_SYS_CFG, CFG_OVERFLOW_ON)) fifo_enqueue_force(item); if (reg_is_bit_set(REG_ID_CFG, CFG_OVERFLOW_ON)) fifo_enqueue_force(item);
} }
#ifndef UART_PICO_INTERFACE #ifndef UART_PICO_INTERFACE
@ -631,7 +720,7 @@ __STATIC_INLINE void check_pmu_int(void) {
#endif #endif
stop_chg(); stop_chg();
} }
if (AXP2101_isPkeyShortPressIrq()) { if (AXP2101_isPekeyShortPressIrq()) {
#ifdef DEBUG #ifdef DEBUG
DEBUG_UART_MSG("PMU: isPekeyShortPress\n\r"); DEBUG_UART_MSG("PMU: isPekeyShortPress\n\r");
@ -649,15 +738,9 @@ __STATIC_INLINE void check_pmu_int(void) {
printPMU(); printPMU();
#endif #endif
if (stop_mode_active == 1) { // enterPmuSleep(); //TODO: implement sleep mode, RTC, etc.?
stop_mode_active = 0;
LL_GPIO_SetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
LL_GPIO_SetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
} else {
// enterPmuSleep(); //TODO: replace by pico reset if Shift key is pressed
}
} }
if (AXP2101_isPkeyLongPressIrq()) { if (AXP2101_isPekeyLongPressIrq()) {
#ifdef DEBUG #ifdef DEBUG
DEBUG_UART_MSG("PMU: isPekeyLongPress\n\r"); DEBUG_UART_MSG("PMU: isPekeyLongPress\n\r");
#endif #endif
@ -665,16 +748,10 @@ __STATIC_INLINE void check_pmu_int(void) {
//uint8_t data[4] = {1, 2, 3, 4}; //uint8_t data[4] = {1, 2, 3, 4};
//PMU.writeDataBuffer(data, XPOWERS_AXP2101_DATA_BUFFER_SIZE); //PMU.writeDataBuffer(data, XPOWERS_AXP2101_DATA_BUFFER_SIZE);
if (stop_mode_active == 1) { LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
stop_mode_active = 0; LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
LL_GPIO_SetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin); AXP2101_setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
LL_GPIO_SetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin); AXP2101_shutdown();
} else {
LL_GPIO_ResetOutputPin(SP_AMP_EN_GPIO_Port, SP_AMP_EN_Pin);
LL_GPIO_ResetOutputPin(PICO_EN_GPIO_Port, PICO_EN_Pin);
AXP2101_setChargingLedMode(XPOWERS_CHG_LED_CTRL_CHG);
stop_mode_active = 1;
}
} }
/*if (PMU.isPekeyNegativeIrq()) { /*if (PMU.isPekeyNegativeIrq()) {
@ -731,49 +808,3 @@ __STATIC_INLINE void check_pmu_int(void) {
AXP2101_clearIrqStatus(); AXP2101_clearIrqStatus();
} }
} }
__STATIC_INLINE void sys_prepare_sleep(void) {
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
AXP2101_disableIRQ(XPOWERS_AXP2101_ALL_IRQ);
AXP2101_clearIrqStatus();
AXP2101_enableIRQ(XPOWERS_AXP2101_PKEY_SHORT_IRQ |
XPOWERS_AXP2101_PKEY_LONG_IRQ |
XPOWERS_AXP2101_WARNING_LEVEL1_IRQ
);
lcd_backlight_off();
kbd_backlight_off();
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3);
GPIO_InitStruct.Pin = SYS_LED_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
LL_GPIO_Init(SYS_LED_GPIO_Port, &GPIO_InitStruct);
LL_GPIO_SetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin);
}
__STATIC_INLINE void sys_wake_sleep(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = SYS_LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(SYS_LED_GPIO_Port, &GPIO_InitStruct);
LL_GPIO_ResetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin);
LL_GPIO_ResetOutputPin(SYS_LED_GPIO_Port, SYS_LED_Pin);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
HAL_Delay(300);
kbd_backlight_on();
lcd_backlight_on();
AXP2101_enableIRQ(XPOWERS_AXP2101_BAT_INSERT_IRQ |
XPOWERS_AXP2101_BAT_REMOVE_IRQ | // BATTERY
XPOWERS_AXP2101_VBUS_INSERT_IRQ |
XPOWERS_AXP2101_VBUS_REMOVE_IRQ | // VBUS
XPOWERS_AXP2101_PKEY_SHORT_IRQ |
XPOWERS_AXP2101_PKEY_LONG_IRQ | // POWER KEY
XPOWERS_AXP2101_BAT_CHG_DONE_IRQ |
XPOWERS_AXP2101_BAT_CHG_START_IRQ // CHARGE
);
}

View File

@ -1,21 +1,14 @@
#include "regs.h" #include "regs.h"
#include "hal_interface.h" #include "hal_interface.h"
#include "stm32f1xx_hal_rtc_ex.h"
#include "eeprom.h" #include "eeprom.h"
#include "version.h" #include "version.h"
extern RTC_HandleTypeDef hrtc;
static uint8_t regs[REG_ID_LAST] = {0}; static uint8_t regs[REG_ID_LAST] = {0};
static uint8_t regs_unsync[REG_ID_LAST] = {0};
static uint32_t eeprom_refresh_counter; 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) { inline uint8_t reg_get_value(enum reg_id reg) {
if (reg >= REG_ID_LAST) if (reg >= REG_ID_LAST)
return 0; return 0;
@ -32,7 +25,7 @@ inline void reg_set_value(enum reg_id reg, uint8_t value) {
return; return;
regs[reg] = value; regs[reg] = value;
REGS_UNSYNC_SET(reg); regs_unsync[reg] = 1;
eeprom_refresh_counter = uptime_ms(); eeprom_refresh_counter = uptime_ms();
} }
@ -48,30 +41,29 @@ inline void reg_set_bit(enum reg_id reg, uint8_t bit) {
return; return;
regs[reg] |= bit; regs[reg] |= bit;
REGS_UNSYNC_SET(reg); regs_unsync[reg] = 1;
eeprom_refresh_counter = uptime_ms(); eeprom_refresh_counter = uptime_ms();
} }
/* /*
* | Bit | Name | Description | * | Bit | Name | Description |
* | ------ |:----------------:| ------------------------------------------------------------------:| | ------ |:----------------:| ------------------------------------------------------------------:|
* | 7 | CFG_USE_MODS | Should Alt, Sym and the Shift keys modify the keys being reported. | | 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. | | 6 | CFG_REPORT_MODS | Should Alt, Sym and the Shift keys be reported as well. |
* | 5 | CFG_PANIC_INT | Currently not implemented. | | 5 | CFG_PANIC_INT | Currently not implemented. |
* | 4 | CFG_KEY_INT | Should an interrupt be generated when a key is pressed. | | 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. | | 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. | | 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. | | 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,| | 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. |
* | | | overwriting the oldest one. If 0 then new entry is lost. |
*/ */
void reg_init(void) { void reg_init(void) {
uint32_t buff; uint16_t buff;
regs[REG_ID_VER] = (uint8_t)((VERSION_MAJOR << 4) | VERSION_MINOR); // 1.2 => (0x1 << 4) | 0x2 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); EEPROM_ReadVariable(EEPROM_VAR_CFG, (EEPROM_Value*)&buff);
regs[REG_ID_SYS_CFG] = (uint8_t)((buff >> 8) & 0xFF); regs[REG_ID_CFG] = (uint8_t)((buff >> 8) & 0xFF);
regs[REG_ID_INT_CFG] = (uint8_t)(buff & 0xFF); regs[REG_ID_INT_CFG] = (uint8_t)(buff & 0xFF);
EEPROM_ReadVariable(EEPROM_VAR_KBD, (EEPROM_Value*)&buff); EEPROM_ReadVariable(EEPROM_VAR_KBD, (EEPROM_Value*)&buff);
@ -82,17 +74,6 @@ void reg_init(void) {
regs[REG_ID_BKL] = (uint8_t)((buff >> 8) & 0xFF); regs[REG_ID_BKL] = (uint8_t)((buff >> 8) & 0xFF);
regs[REG_ID_BK2] = (uint8_t)(buff & 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_BAT] = 0; //default .no battery ,no charging
regs[REG_ID_TYP] = 0xCA; // That's me :3 regs[REG_ID_TYP] = 0xCA; // That's me :3
@ -105,33 +86,23 @@ uint32_t reg_check_and_save_eeprom(void) {
uint8_t need_save = 0; uint8_t need_save = 0;
for (size_t i = 0; i < REG_ID_LAST; i++) for (size_t i = 0; i < REG_ID_LAST; i++)
if (REGS_UNSYNC_GET(i) == 1) { if (regs_unsync[i] == 1) {
need_save = 1; need_save = 1;
break; break;
} }
if (need_save == 1) { if (need_save == 1) {
if (REGS_UNSYNC_GET(REG_ID_SYS_CFG) == 1) if (regs_unsync[REG_ID_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); result |= EEPROM_WriteVariable(EEPROM_VAR_CFG, (EEPROM_Value)(uint16_t)((regs[REG_ID_CFG] << 8) | regs[REG_ID_INT_CFG]), EEPROM_SIZE16);
if (REGS_UNSYNC_GET(REG_ID_DEB) == 1 || REGS_UNSYNC_GET(REG_ID_FRQ) == 1) if (regs_unsync[REG_ID_DEB] == 1 || regs_unsync[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); 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) if (regs_unsync[REG_ID_BKL] == 1 || regs_unsync[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); 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++) for (size_t i = 0; i < REG_ID_LAST; i++)
REGS_UNSYNC_UNSET(i); regs_unsync[i] = 0;
} }
return result; return result;

View File

@ -1,81 +0,0 @@
#include "rtc.h"
#include "hal_interface.h"
#include "regs.h"
extern RTC_HandleTypeDef hrtc;
extern void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
uint8_t rtc_conf = reg_get_value(REG_ID_RTC_CFG);
RTC_DateTypeDef date_s = {0};
uint8_t date_valid = 1;
if ((rtc_conf & RTC_CFG_DATE_ALARM) == RTC_CFG_DATE_ALARM) {
HAL_RTC_GetDate(hrtc, &date_s, RTC_FORMAT_BIN);
if (date_s.Year != rtc_alarm_date._s.Year ||
date_s.Month != rtc_alarm_date._s.Month ||
date_s.Date != rtc_alarm_date._s.Date)
date_valid = 0;
}
rtc_stop_alarm();
if (date_valid == 1) {
if ((rtc_conf & RTC_CFG_REARM) == RTC_CFG_REARM)
rtc_run_alarm();
} else {
rtc_run_alarm();
}
}
void i2cs_fill_buffer_RTC_date(uint8_t* const date_buff, const volatile RTC_DateTypeDef* const date_s) {
if (date_s == NULL || date_buff == NULL)
return;
date_buff[0] = date_s->Year;
date_buff[1] = date_s->Month;
date_buff[2] = date_s->Date;
date_buff[3] = date_s->WeekDay;
}
void i2cs_fill_buffer_RTC_time(uint8_t* const time_buff, const volatile RTC_TimeTypeDef* const time_s) {
if (time_s == NULL || time_buff == NULL)
return;
time_buff[0] = time_s->Hours;
time_buff[1] = time_s->Minutes;
time_buff[2] = time_s->Seconds;
}
void i2cs_RTC_date_from_buffer(volatile RTC_DateTypeDef* const date_s, const uint8_t* const date_buff) {
if (date_s == NULL || date_buff == NULL)
return;
date_s->Year = date_buff[0] <= 99? date_buff[0] : 99;
date_s->Month = (date_buff[1] > 0 && date_buff[1] <= 12)? date_buff[1] : 12;
date_s->Date = (date_buff[2] > 0 && date_buff[2] <= 99)? date_buff[2] : 99;
//data_s.WeekDay - this element is automatically recomputed
}
void i2cs_RTC_time_from_buffer(volatile RTC_TimeTypeDef* const time_s, const uint8_t* const time_buff) {
if (time_s == NULL || time_buff == NULL)
return;
time_s->Hours = time_buff[0] <= 23 ? time_buff[0] : 23;
time_s->Minutes = time_buff[1] <= 59 ? time_buff[1] : 59;
time_s->Seconds = time_buff[2] <= 59 ? time_buff[2] : 59;
}
inline uint32_t rtc_run_alarm(void) {
RTC_AlarmTypeDef alarm_s;
alarm_s.Alarm = RTC_ALARM_A;
alarm_s.AlarmTime.Hours = rtc_alarm_time._s.Hours;
alarm_s.AlarmTime.Minutes = rtc_alarm_time._s.Minutes;
alarm_s.AlarmTime.Seconds = rtc_alarm_time._s.Seconds;
return (uint32_t)HAL_RTC_SetAlarm_IT(&hrtc, &alarm_s, RTC_FORMAT_BIN);
}
inline uint32_t rtc_stop_alarm(void) {
return (uint32_t)HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
}

View File

@ -16,7 +16,6 @@
extern I2C_HandleTypeDef hi2c1; extern I2C_HandleTypeDef hi2c1;
extern RTC_HandleTypeDef hrtc;
extern TIM_HandleTypeDef htim2; extern TIM_HandleTypeDef htim2;
#ifdef DEBUG #ifdef DEBUG
extern UART_HandleTypeDef huart1; extern UART_HandleTypeDef huart1;
@ -147,10 +146,3 @@ void USART3_IRQHandler(void) {
HAL_UART_IRQHandler(&huart3); HAL_UART_IRQHandler(&huart3);
} }
#endif #endif
/**
* @brief This function handles RTC alarm interrupt through EXTI line 17.
*/
void RTC_Alarm_IRQHandler(void) {
HAL_RTC_AlarmIRQHandler(&hrtc);
}

View File

@ -76,16 +76,17 @@ Mcu.Pin47=VP_IWDG_VS_IWDG
Mcu.Pin48=VP_RTC_VS_RTC_Activate Mcu.Pin48=VP_RTC_VS_RTC_Activate
Mcu.Pin49=VP_RTC_VS_RTC_Calendar Mcu.Pin49=VP_RTC_VS_RTC_Calendar
Mcu.Pin5=PC0 Mcu.Pin5=PC0
Mcu.Pin50=VP_SYS_VS_ND Mcu.Pin50=VP_RTC_No_RTC_Output
Mcu.Pin51=VP_SYS_VS_Systick Mcu.Pin51=VP_SYS_VS_ND
Mcu.Pin52=VP_TIM1_VS_ClockSourceINT Mcu.Pin52=VP_SYS_VS_Systick
Mcu.Pin53=VP_TIM2_VS_ClockSourceINT Mcu.Pin53=VP_TIM1_VS_ClockSourceINT
Mcu.Pin54=VP_TIM3_VS_ClockSourceINT Mcu.Pin54=VP_TIM2_VS_ClockSourceINT
Mcu.Pin55=VP_TIM3_VS_ClockSourceINT
Mcu.Pin6=PC1 Mcu.Pin6=PC1
Mcu.Pin7=PC2 Mcu.Pin7=PC2
Mcu.Pin8=PC3 Mcu.Pin8=PC3
Mcu.Pin9=PA0-WKUP Mcu.Pin9=PA0-WKUP
Mcu.PinsNb=55 Mcu.PinsNb=56
Mcu.ThirdPartyNb=0 Mcu.ThirdPartyNb=0
Mcu.UserConstants= Mcu.UserConstants=
Mcu.UserName=STM32F103R8Tx Mcu.UserName=STM32F103R8Tx
@ -102,7 +103,6 @@ NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.RTC_Alarm_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:1\:0\:true\:false\:true\:false\:true\:false NVIC.SysTick_IRQn=true\:1\:0\:true\:false\:true\:false\:true\:false
NVIC.TIM2_IRQn=true\:1\:0\:true\:false\:true\:true\:true\:true NVIC.TIM2_IRQn=true\:1\:0\:true\:false\:true\:true\:true\:true
@ -413,12 +413,12 @@ ProjectManager.ProjectName=picocalc_BIOS_jcs
ProjectManager.ProjectStructure= ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack= ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400 ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=Makefile ProjectManager.TargetToolchain=STM32CubeIDE
ProjectManager.ToolChainLocation= ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath= ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-LL-false,2-MX_GPIO_Init-GPIO-false-LL-true,3-MX_I2C1_Init-I2C1-false-HAL-true,4-MX_I2C2_Init-I2C2-false-HAL-true,5-MX_RTC_Init-RTC-false-HAL-true,6-MX_USART1_UART_Init-USART1-false-HAL-true,7-MX_USART3_UART_Init-USART3-false-HAL-true,8-MX_IWDG_Init-IWDG-false-LL-true,9-MX_TIM1_Init-TIM1-false-HAL-true,10-MX_TIM3_Init-TIM3-false-HAL-true,11-MX_TIM2_Init-TIM2-false-HAL-true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-LL-false,2-MX_GPIO_Init-GPIO-false-LL-true,3-MX_I2C1_Init-I2C1-false-HAL-true,4-MX_I2C2_Init-I2C2-false-HAL-true,5-MX_RTC_Init-RTC-false-LL-true,6-MX_USART1_UART_Init-USART1-false-HAL-true,7-MX_USART3_UART_Init-USART3-false-HAL-true,8-MX_IWDG_Init-IWDG-false-LL-true,9-MX_TIM1_Init-TIM1-false-HAL-true,10-MX_TIM3_Init-TIM3-false-HAL-true,11-MX_TIM2_Init-TIM2-false-HAL-true
RCC.ADCFreqValue=2000000 RCC.ADCFreqValue=2000000
RCC.AHBCLKDivider=RCC_SYSCLK_DIV2 RCC.AHBCLKDivider=RCC_SYSCLK_DIV2
RCC.AHBFreq_Value=4000000 RCC.AHBFreq_Value=4000000
@ -474,6 +474,8 @@ USART3.IPParameters=VirtualMode
USART3.VirtualMode=VM_ASYNC USART3.VirtualMode=VM_ASYNC
VP_IWDG_VS_IWDG.Mode=IWDG_Activate VP_IWDG_VS_IWDG.Mode=IWDG_Activate
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
VP_RTC_No_RTC_Output.Mode=RTC_OUT_NO
VP_RTC_No_RTC_Output.Signal=RTC_No_RTC_Output
VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar

View File

@ -1,76 +0,0 @@
#PCC Sequence - do not modify
#Wed May 21 14:12:50 CEST 2025
PCC.Battery=16850
PCC.Battery.Capacity=3000.0
PCC.Battery.InParallel=2
PCC.Battery.InSeries=1
PCC.Battery.SelfDischarge=0.08
PCC.Checker=false
PCC.Datasheet=DS5319_Rev17
PCC.Line=STM32F103
PCC.MCU=STM32F103R(8-B)Tx
PCC.PartNumber=STM32F103R8Tx
PCC.Seq0=4
PCC.Seq0.Step0.Average_Current=3.41 mA
PCC.Seq0.Step0.CPU_Frequency=4 MHz
PCC.Seq0.Step0.Category=In DS Table
PCC.Seq0.Step0.DMIPS=5.0
PCC.Seq0.Step0.Duration=0.1 ms
PCC.Seq0.Step0.Frequency=8 MHz
PCC.Seq0.Step0.Memory=FLASH
PCC.Seq0.Step0.Mode=RUN
PCC.Seq0.Step0.Oscillator=HSE
PCC.Seq0.Step0.Peripherals=APB1-Bridge APB2-Bridge GPIOA GPIOB GPIOC GPIOD I2C1 I2C2 PVD/BOR PWR RTC TIM1 TIM2 TIM3 WWDG
PCC.Seq0.Step0.TaMax=104.49
PCC.Seq0.Step0.User's_Consumption=0 mA
PCC.Seq0.Step0.Vcore=No Scale
PCC.Seq0.Step0.Vdd=3.3
PCC.Seq0.Step0.Voltage_Source=Battery
PCC.Seq0.Step1.Average_Current=1.7 mA
PCC.Seq0.Step1.CPU_Frequency=4 MHz
PCC.Seq0.Step1.Category=In DS Table
PCC.Seq0.Step1.DMIPS=5.0
PCC.Seq0.Step1.Duration=1 ms
PCC.Seq0.Step1.Frequency=8 MHz
PCC.Seq0.Step1.Memory=RAM/FLASH
PCC.Seq0.Step1.Mode=SLEEP
PCC.Seq0.Step1.Oscillator=HSE
PCC.Seq0.Step1.Peripherals=APB1-Bridge APB2-Bridge GPIOA GPIOB GPIOC GPIOD I2C1 I2C2 RTC TIM1 TIM2 TIM3 WWDG
PCC.Seq0.Step1.TaMax=104.75
PCC.Seq0.Step1.User's_Consumption=0 mA
PCC.Seq0.Step1.Vcore=No Scale
PCC.Seq0.Step1.Vdd=3.3
PCC.Seq0.Step1.Voltage_Source=Battery
PCC.Seq0.Step2.Average_Current=24 \u00B5A
PCC.Seq0.Step2.CPU_Frequency=0 Hz
PCC.Seq0.Step2.Category=In DS Table
PCC.Seq0.Step2.DMIPS=0.0
PCC.Seq0.Step2.Duration=1 ms
PCC.Seq0.Step2.Frequency=0 Hz
PCC.Seq0.Step2.Memory=n/a
PCC.Seq0.Step2.Mode=STOP
PCC.Seq0.Step2.Oscillator=Regulator_ON
PCC.Seq0.Step2.Peripherals=RTC*
PCC.Seq0.Step2.TaMax=105
PCC.Seq0.Step2.User's_Consumption=0 mA
PCC.Seq0.Step2.Vcore=No Scale
PCC.Seq0.Step2.Vdd=3.3
PCC.Seq0.Step2.Voltage_Source=Battery
PCC.Seq0.Step3.Average_Current=2 \u00B5A
PCC.Seq0.Step3.CPU_Frequency=0 Hz
PCC.Seq0.Step3.Category=In DS Table
PCC.Seq0.Step3.DMIPS=0.0
PCC.Seq0.Step3.Duration=1 ms
PCC.Seq0.Step3.Frequency=0 Hz
PCC.Seq0.Step3.Memory=n/a
PCC.Seq0.Step3.Mode=STANDBY
PCC.Seq0.Step3.Oscillator=ALL CLOCKS OFF
PCC.Seq0.Step3.Peripherals=RTC*
PCC.Seq0.Step3.TaMax=105
PCC.Seq0.Step3.User's_Consumption=0 mA
PCC.Seq0.Step3.Vcore=No Scale
PCC.Seq0.Step3.Vdd=3.3
PCC.Seq0.Step3.Voltage_Source=Battery
PCC.Series=STM32F1
PCC.Temperature=25
PCC.Vdd=3.3

View File

@ -2,9 +2,8 @@
# Generic Makefile (based on gcc) # Generic Makefile (based on gcc)
# #
# ChangeLog : # ChangeLog :
# 2025-05-09 - Added I2C_REGS_COMPAT option
# 2025-04-25 - Tuned for PicoCalc firmware project # 2025-04-25 - Tuned for PicoCalc firmware project
# 2017-02-10 - Several enhancements + project update mode # 2017-02-10 - Several enhancements + project update mode
# 2015-07-22 - first version # 2015-07-22 - first version
# ------------------------------------------------ # ------------------------------------------------
@ -35,9 +34,9 @@ BUILD_DIR = build
# source # source
###################################### ######################################
# C sources # C sources
C_SOURCES = \ C_SOURCES = \
Core/Src/main.c \ Core/Src/main.c \
Core/Src/stm32f1xx_it.c \ Core/Src/stm32f1xx_it.c \
Core/Src/hal_interface.c \ Core/Src/hal_interface.c \
Core/Src/axp2101.c \ Core/Src/axp2101.c \
Core/Src/backlight.c \ Core/Src/backlight.c \
@ -45,33 +44,31 @@ Core/Src/batt.c \
Core/Src/eeprom.c \ Core/Src/eeprom.c \
Core/Src/fifo.c \ Core/Src/fifo.c \
Core/Src/keyboard.c \ Core/Src/keyboard.c \
Core/Src/regs.c \ Core/Src/regs.c \
Core/Src/rtc.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_gpio.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_i2c.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rcc.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_utils.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_exti.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rcc_ex.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_dma.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_cortex.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_flash_ex.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_ll_rtc.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_rtc_ex.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c \ Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c \
Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_uart.c \
Core/Src/system_stm32f1xx.c Core/Src/system_stm32f1xx.c
# ASM sources # ASM sources
ASM_SOURCES = \ ASM_SOURCES = \
startup_stm32f103xb.s startup_stm32f103xb.s
# ASM sources # ASM sources
@ -118,9 +115,9 @@ MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
AS_DEFS = AS_DEFS =
# C defines # C defines
C_DEFS = \ C_DEFS = \
-DUSE_FULL_LL_DRIVER \ -DUSE_FULL_LL_DRIVER \
-DUSE_HAL_DRIVER \ -DUSE_HAL_DRIVER \
-DSTM32F103xB -DSTM32F103xB
ifeq ($(DEBUG), 1) ifeq ($(DEBUG), 1)
@ -136,11 +133,11 @@ endif
AS_INCLUDES = AS_INCLUDES =
# C includes # C includes
C_INCLUDES = \ C_INCLUDES = \
-ICore/Inc \ -ICore/Inc \
-IDrivers/STM32F1xx_HAL_Driver/Inc \ -IDrivers/STM32F1xx_HAL_Driver/Inc \
-IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \ -IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \
-IDrivers/CMSIS_Device_ST_STM32F1xx/Include \ -IDrivers/CMSIS_Device_ST_STM32F1xx/Include \
-IDrivers/CMSIS/Include -IDrivers/CMSIS/Include
@ -155,7 +152,6 @@ endif
# Generate dependency information # Generate dependency information
CFLAGS_ASM := $(CFLAGS)
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
@ -179,7 +175,6 @@ all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET
####################################### #######################################
# list of objects # list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o))) OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
OBJECTS_ASM = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.s)))
vpath %.c $(sort $(dir $(C_SOURCES))) vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects # list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o))) OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
@ -190,15 +185,12 @@ vpath %.S $(sort $(dir $(ASMM_SOURCES)))
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@ $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.s: %.c Makefile | $(BUILD_DIR)
$(CC) $(CFLAGS_ASM) -fverbose-asm -S $< -o $@
$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR) $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@ $(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR) $(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@ $(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) $(OBJECTS_ASM) Makefile $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
$(CC) $(OBJECTS) $(LDFLAGS) -o $@ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@ $(SZ) $@
@ -222,4 +214,4 @@ clean:
####################################### #######################################
-include $(wildcard $(BUILD_DIR)/*.d) -include $(wildcard $(BUILD_DIR)/*.d)
# *** EOF *** # *** EOF ***

View File

@ -9,12 +9,11 @@ The main differences with the original firmware are the followings:
- drastic reduction in the STM32's electricity consumption when running (~3.5 mA), - drastic reduction in the STM32's electricity consumption when running (~3.5 mA),
- clean up (by removing stm32duino dependencies, use STM32HAL instead, maybe I'll switch to libopencm3 someday...) to reduce binary size (~25 KB) and allow more features to be implemented, - clean up (by removing stm32duino dependencies, use STM32HAL instead, maybe I'll switch to libopencm3 someday...) to reduce binary size (~25 KB) and allow more features to be implemented,
- added configuration saving solution (using internal flash, including backlight option), - added configuration saving solution (using internal flash, including backlight option),
- new I2C registers memory allocation and structure (keeping compatible access to REG_ID_TYP and REG_ID_VER registers to check how to handle comm from pico board side)(WIP), - new I2C registers and structure (keeping compatible access to REG_ID_TYP and REG_ID_VER registers to check how to handle comm from pico board side),
- interrupt event output to pico board can be configured during runtime (for keyboard event or RTC alarm), - interrupt event output to pico board can be configured during runtime (for keyboard event or RTC alarm),
- rewriten or added some debug UART interface message (only when compiled in DEBUG release type), - rewriten or added some debug UART interface message,
- internal RTC access through dedicated I2C registers, - internal RTC access through dedicated I2C registers (WIP),
- auto wake-up using RTC (WIP), - lighten AXP2101 PMIC driver.
- lighten AXP2101 PMIC driver (based on X-PowersLib).
## Compile ## Compile
This source code can be compiled using ARM gcc toolchain (using v13) in path and using make program. This source code can be compiled using ARM gcc toolchain (using v13) in path and using make program.
@ -24,18 +23,9 @@ But this makes them incompatible with official firmware. (More details to come a
If you plan using pico official firmware (PicoMite, etc.), you should set I2C_REGS_COMPAT = 1 in the Makefile. If you plan using pico official firmware (PicoMite, etc.), you should set I2C_REGS_COMPAT = 1 in the Makefile.
## TODO
- Registers memory structure/allocation rewrite
- Auto wake-up
- IRQ to Pico management (register exist but does nothing)
- Add a Pico test program for registers/features implemented
- add few wiki page to detail the I2C protocol, added features, etc.
## Important notes ## Important notes
The current implementation of this firmware is subject to change until the v1 release. The current implementation of this firmware is subject to change until the v1 release.
Some features can be unstable or buggy and are marked as pre-release. A test program will be developped soon to provide some regression testing.
The permanent settings (EEPROM) save can be broken between 0.x version, it is recommanded to make a full flash erase before updating, as The permanent settings (EEPROM) save can be broken between 0.x version, it is recommanded to make a full flash erase before updating, as
EEPROM configuration survives update. EEPROM configuration survives update.