diff --git a/Core/Inc/hal_interface.h b/Core/Inc/hal_interface.h index bcddd2f..54e5d02 100644 --- a/Core/Inc/hal_interface.h +++ b/Core/Inc/hal_interface.h @@ -27,9 +27,7 @@ #include "stm32f1xx_ll_utils.h" #include "stm32f1xx_ll_pwr.h" #include "stm32f1xx_ll_dma.h" -#include "stm32f1xx_ll_rtc.h" #include "stm32f1xx_ll_gpio.h" -#include "stm32f1xx_ll_tim.h" #ifndef HAL_INTERFACE_H_ diff --git a/Core/Inc/regs.h b/Core/Inc/regs.h index b400fd3..efa6b0f 100644 --- a/Core/Inc/regs.h +++ b/Core/Inc/regs.h @@ -23,27 +23,38 @@ enum reg_id { REG_ID_RST_PICO = 0x0E, // Pico reset REG_ID_SHTDW = 0x0F, // self-shutdown REG_ID_INT_CFG = 0x10, // IRQ config + REG_ID_RTC_CFG = 0x11, // RTC general config + REG_ID_RTC_DATE = 0x12, // RTC date + REG_ID_RTC_TIME = 0x13, // RTC time + REG_ID_RTC_ALARM_DATE = 0x14, // RTC alarm date + REG_ID_RTC_ALARM_TIME = 0x15, // RTC alarm time #else - REG_ID_CFG = 0x02, //!< config - REG_ID_INT_CFG = 0x03, //!< IRQ config - REG_ID_INT = 0x04, //!< interrupt status - REG_ID_BKL = 0x05, //!< backlight steps (0-9) - 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) + REG_ID_CFG = 0x02, //!< config + REG_ID_INT_CFG = 0x03, //!< IRQ config + REG_ID_INT = 0x04, //!< interrupt status + REG_ID_BKL = 0x05, //!< backlight steps (0-9) + 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) - REG_ID_KEY = 0x10, //!< key status - REG_ID_FIF = 0x11, //!< fifo - REG_ID_C64_MTX = 0x12, //!< read c64 matrix - REG_ID_C64_JS = 0x13, //!< joystick io bits + REG_ID_RTC_CFG = 0x0A, //!< RTC general config + REG_ID_RTC_DATE = 0x0B, //!< RTC date + REG_ID_RTC_TIME = 0x0C, //!< RTC time + REG_ID_RTC_ALARM_DATE = 0x0D, //!< RTC alarm date + REG_ID_RTC_ALARM_TIME = 0x0E, //!< RTC alarm time - REG_ID_RST = 0x20, //!< STM32 full reset - REG_ID_RST_PICO = 0x21, //!< Pico reset - REG_ID_SHTDW = 0x22, //!< self-shutdown + REG_ID_KEY = 0x10, //!< key status + REG_ID_FIF = 0x11, //!< fifo + REG_ID_C64_MTX = 0x12, //!< read c64 matrix + REG_ID_C64_JS = 0x13, //!< joystick io bits - REG_ID_BAT = 0x30, //!< battery + REG_ID_RST = 0x20, //!< STM32 full reset + REG_ID_RST_PICO = 0x21, //!< Pico reset + REG_ID_SHTDW = 0x22, //!< self-shutdown + + REG_ID_BAT = 0x30, //!< battery #endif - REG_ID_LAST, + REG_ID_LAST }; #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. diff --git a/Core/Inc/stm32f1xx_hal_conf.h b/Core/Inc/stm32f1xx_hal_conf.h index fe77540..f7b0a5d 100644 --- a/Core/Inc/stm32f1xx_hal_conf.h +++ b/Core/Inc/stm32f1xx_hal_conf.h @@ -57,7 +57,7 @@ /*#define HAL_HCD_MODULE_ENABLED */ /*#define HAL_PWR_MODULE_ENABLED */ /*#define HAL_RCC_MODULE_ENABLED */ -/*#define HAL_RTC_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED /*#define HAL_SD_MODULE_ENABLED */ /*#define HAL_MMC_MODULE_ENABLED */ /*#define HAL_SDRAM_MODULE_ENABLED */ diff --git a/Core/Inc/stm32f1xx_it.h b/Core/Inc/stm32f1xx_it.h index 254de69..5c58f9f 100644 --- a/Core/Inc/stm32f1xx_it.h +++ b/Core/Inc/stm32f1xx_it.h @@ -65,6 +65,7 @@ void USART1_IRQHandler(void); #ifdef UART_PICO_INTERFACE void USART3_IRQHandler(void); #endif +void RTC_Alarm_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/Core/Src/hal_interface.c b/Core/Src/hal_interface.c index 0801d6f..2e4d66a 100644 --- a/Core/Src/hal_interface.c +++ b/Core/Src/hal_interface.c @@ -23,6 +23,8 @@ I2C_HandleTypeDef hi2c1; I2C_HandleTypeDef hi2c2; +RTC_HandleTypeDef hrtc; + TIM_HandleTypeDef htim1; TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim3; @@ -140,28 +142,33 @@ static void MX_IWDG_Init(void) { * @retval None */ static void MX_RTC_Init(void) { - LL_RTC_InitTypeDef RTC_InitStruct = {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(); + RTC_TimeTypeDef sTime = {0}; + RTC_DateTypeDef DateToUpdate = {0}; + /** Initialize RTC Only + */ + hrtc.Instance = RTC; + hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND; + hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM; + if (HAL_RTC_Init(&hrtc) != HAL_OK) + Error_Handler(); /** Initialize RTC and set the Time and Date */ - RTC_InitStruct.AsynchPrescaler = 0xFFFFFFFFU; - LL_RTC_Init(RTC, &RTC_InitStruct); - LL_RTC_SetAsynchPrescaler(RTC, 0xFFFFFFFFU); + sTime.Hours = 0x0; + sTime.Minutes = 0x0; + sTime.Seconds = 0x0; - /** Initialize RTC and set the Time and Date - */ - RTC_TimeStruct.Hours = 0; - RTC_TimeStruct.Minutes = 0; - RTC_TimeStruct.Seconds = 0; - LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BCD, &RTC_TimeStruct); + if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) + Error_Handler(); + + DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY; + DateToUpdate.Month = RTC_MONTH_JANUARY; + DateToUpdate.Date = 0x1; + DateToUpdate.Year = 0x0; + + if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK) + Error_Handler(); } /** @@ -529,6 +536,41 @@ 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 * This function configures the hardware resources used in this example diff --git a/Core/Src/main.c b/Core/Src/main.c index 7b06ed5..74945a5 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -54,6 +54,8 @@ enum i2cs_state { extern I2C_HandleTypeDef hi2c1; extern I2C_HandleTypeDef hi2c2; +extern RTC_HandleTypeDef hrtc; + extern TIM_HandleTypeDef htim1; extern TIM_HandleTypeDef htim2; extern TIM_HandleTypeDef htim3; @@ -93,6 +95,10 @@ static void sync_bat(void); static void printPMU(void); #endif static void check_pmu_int(void); +static void i2cs_fill_buffer_RTC_date(uint8_t* date_buff); +static void i2cs_fill_buffer_RTC_time(uint8_t* time_buff); +static void i2cs_RTC_date_from_buffer(uint8_t* date_buff); +static void i2cs_RTC_time_from_buffer(uint8_t* time_buff); extern void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim2) { @@ -166,6 +172,16 @@ extern void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirect 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_DATE) { + if (is_write) + i2cs_RTC_date_from_buffer(&i2cs_r_buff[1]); + i2cs_fill_buffer_RTC_date(&i2cs_w_buff[1]); + i2cs_w_len = 5; + } else if (reg == REG_ID_RTC_TIME) { + if (is_write) + i2cs_RTC_time_from_buffer(&i2cs_r_buff[1]); + i2cs_fill_buffer_RTC_time(&i2cs_w_buff[1]); + 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; @@ -229,6 +245,10 @@ extern void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) { } else if (reg == REG_ID_DEB) { if (is_write) bytes_needed = 2; + } else if (reg == REG_ID_RTC_TIME || + reg == REG_ID_RTC_DATE) { + if (is_write) + bytes_needed = 4; } if (bytes_needed > 0) @@ -808,3 +828,45 @@ __STATIC_INLINE void check_pmu_int(void) { AXP2101_clearIrqStatus(); } } + +__STATIC_INLINE void i2cs_fill_buffer_RTC_date(uint8_t* date_buff) { + RTC_DateTypeDef data_s = {0}; + + HAL_RTC_GetDate(&hrtc, &data_s, RTC_FORMAT_BCD); + + date_buff[0] = data_s.Year; + date_buff[1] = data_s.Month; + date_buff[2] = data_s.Date; + date_buff[3] = data_s.WeekDay; +} + +__STATIC_INLINE void i2cs_fill_buffer_RTC_time(uint8_t* time_buff) { + RTC_TimeTypeDef time_s = {0}; + + HAL_RTC_GetTime(&hrtc, &time_s, RTC_FORMAT_BCD); + + time_buff[0] = time_s.Hours; + time_buff[1] = time_s.Minutes; + time_buff[2] = time_s.Seconds; +} + +__STATIC_INLINE void i2cs_RTC_date_from_buffer(uint8_t* date_buff) { + RTC_DateTypeDef data_s = {0}; + + data_s.Year = date_buff[0] <= 99? date_buff[0] : 99; + data_s.Month = (date_buff[1] > 0 && date_buff[1] <= 12)? date_buff[1] : 12; + data_s.Date = (date_buff[2] > 0 && date_buff[2] <= 99)? date_buff[2] : 99; + //data_s.WeekDay - this element is automatically recomputed + + HAL_RTC_SetDate(&hrtc, &data_s, RTC_FORMAT_BIN); +} + +__STATIC_INLINE void i2cs_RTC_time_from_buffer(uint8_t* time_buff) { + RTC_TimeTypeDef time_s = {0}; + + 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; + + HAL_RTC_SetTime(&hrtc, &time_s, RTC_FORMAT_BIN); +} diff --git a/Core/Src/stm32f1xx_it.c b/Core/Src/stm32f1xx_it.c index 276b493..8902de9 100644 --- a/Core/Src/stm32f1xx_it.c +++ b/Core/Src/stm32f1xx_it.c @@ -16,6 +16,7 @@ extern I2C_HandleTypeDef hi2c1; +extern RTC_HandleTypeDef hrtc; extern TIM_HandleTypeDef htim2; #ifdef DEBUG extern UART_HandleTypeDef huart1; @@ -146,3 +147,10 @@ void USART3_IRQHandler(void) { HAL_UART_IRQHandler(&huart3); } #endif + +/** + * @brief This function handles RTC alarm interrupt through EXTI line 17. + */ +void RTC_Alarm_IRQHandler(void) { + HAL_RTC_AlarmIRQHandler(&hrtc); +} diff --git a/CubeMX/picocalc_BIOS_jcs.ioc b/CubeMX/picocalc_BIOS_jcs.ioc index c7099cd..d646c9b 100644 --- a/CubeMX/picocalc_BIOS_jcs.ioc +++ b/CubeMX/picocalc_BIOS_jcs.ioc @@ -76,17 +76,16 @@ Mcu.Pin47=VP_IWDG_VS_IWDG Mcu.Pin48=VP_RTC_VS_RTC_Activate Mcu.Pin49=VP_RTC_VS_RTC_Calendar Mcu.Pin5=PC0 -Mcu.Pin50=VP_RTC_No_RTC_Output -Mcu.Pin51=VP_SYS_VS_ND -Mcu.Pin52=VP_SYS_VS_Systick -Mcu.Pin53=VP_TIM1_VS_ClockSourceINT -Mcu.Pin54=VP_TIM2_VS_ClockSourceINT -Mcu.Pin55=VP_TIM3_VS_ClockSourceINT +Mcu.Pin50=VP_SYS_VS_ND +Mcu.Pin51=VP_SYS_VS_Systick +Mcu.Pin52=VP_TIM1_VS_ClockSourceINT +Mcu.Pin53=VP_TIM2_VS_ClockSourceINT +Mcu.Pin54=VP_TIM3_VS_ClockSourceINT Mcu.Pin6=PC1 Mcu.Pin7=PC2 Mcu.Pin8=PC3 Mcu.Pin9=PA0-WKUP -Mcu.PinsNb=56 +Mcu.PinsNb=55 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F103R8Tx @@ -103,6 +102,7 @@ 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.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false 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.SysTick_IRQn=true\:1\:0\:true\:false\:true\:false\:true\:false NVIC.TIM2_IRQn=true\:1\:0\:true\:false\:true\:true\:true\:true @@ -413,12 +413,12 @@ ProjectManager.ProjectName=picocalc_BIOS_jcs ProjectManager.ProjectStructure= ProjectManager.RegisterCallBack= ProjectManager.StackSize=0x400 -ProjectManager.TargetToolchain=STM32CubeIDE +ProjectManager.TargetToolchain=Makefile ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= -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-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 +ProjectManager.UnderRoot=false +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 RCC.ADCFreqValue=2000000 RCC.AHBCLKDivider=RCC_SYSCLK_DIV2 RCC.AHBFreq_Value=4000000 @@ -474,8 +474,6 @@ USART3.IPParameters=VirtualMode USART3.VirtualMode=VM_ASYNC VP_IWDG_VS_IWDG.Mode=IWDG_Activate 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.Signal=RTC_VS_RTC_Activate VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar