Files
GbTModuleEV/Core/Src/soft_rtc.c

198 lines
5.3 KiB
C
Executable File

/*
* rtc.c
*
* Created on: Jul 22, 2024
* Author: colorbass
*/
#include <soft_rtc.h>
#include <stdint.h>
#include <time.h>
uint8_t tmp_time[4];
uint32_t tmp_time32;
extern RTC_HandleTypeDef hrtc;
static HAL_StatusTypeDef RTC1_WriteTimeCounter(RTC_HandleTypeDef *hrtc, uint32_t TimeCounter);
static uint32_t RTC1_ReadTimeCounter(RTC_HandleTypeDef *hrtc);
static HAL_StatusTypeDef RTC1_ExitInitMode(RTC_HandleTypeDef *hrtc);
static HAL_StatusTypeDef RTC1_EnterInitMode(RTC_HandleTypeDef *hrtc);
uint32_t get_Current_Time(){
return RTC1_ReadTimeCounter(&hrtc);
}
void set_Time(uint32_t unix_time){
RTC1_WriteTimeCounter(&hrtc, unix_time);
}
uint8_t to_bcd(int value) {
return ((value / 10) << 4) | (value % 10);
}
void unix_to_bcd(uint32_t unix_time, uint8_t *time) {
struct tm *tm_info;
time_t raw_time = (time_t)unix_time;
tm_info = gmtime(&raw_time);
time[0] = to_bcd(tm_info->tm_sec);
time[1] = to_bcd(tm_info->tm_min);
time[2] = to_bcd(tm_info->tm_hour);
time[3] = to_bcd(tm_info->tm_mday);
time[4] = to_bcd(tm_info->tm_mon + 1); // tm_mon is 0-11
time[5] = to_bcd((tm_info->tm_year + 1900) % 100); // Year in 2 digits
time[6] = to_bcd((tm_info->tm_year + 1900) / 100); // Century in 2 digits
}
void writeTimeReg(uint8_t reg_number, uint8_t value){
tmp_time[reg_number] = value;
if(reg_number == 3) set_Time((tmp_time[0])+(tmp_time[1]<<8)+(tmp_time[2]<<16)+(tmp_time[3]<<24));
};
uint8_t getTimeReg(uint8_t reg_number){
if(reg_number == 0){
tmp_time32 = get_Current_Time();
return tmp_time32 & 0xFF;
}else if(reg_number == 1){
return (tmp_time32>>8) & 0xFF;
}else if(reg_number == 2){
return (tmp_time32>>16) & 0xFF;
}else if(reg_number == 3){
return (tmp_time32>>24) & 0xFF;
}else{
return 0x00;
}
};
//int main() {
// uint32_t unix_time = 1672531199; // Example Unix timestamp
// uint8_t time[8];
//
// unix_to_bcd(unix_time, time);
//
// // Print the BCD values for verification
// for (int i = 0; i < 8; i++) {
// printf("time[%d]: %02X\n", i, time[i]);
// }
//
// return 0;
//}
/**
* @brief Read the time counter available in RTC_CNT registers.
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval Time counter
*/
static uint32_t RTC1_ReadTimeCounter(RTC_HandleTypeDef *hrtc)
{
uint16_t high1 = 0U, high2 = 0U, low = 0U;
uint32_t timecounter = 0U;
high1 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
low = READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT);
high2 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
if (high1 != high2)
{
/* In this case the counter roll over during reading of CNTL and CNTH registers,
read again CNTL register then return the counter value */
timecounter = (((uint32_t) high2 << 16U) | READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT));
}
else
{
/* No counter roll over during reading of CNTL and CNTH registers, counter
value is equal to first value of CNTL and CNTH */
timecounter = (((uint32_t) high1 << 16U) | low);
}
return timecounter;
}
/**
* @brief Write the time counter in RTC_CNT registers.
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @param TimeCounter: Counter to write in RTC_CNT registers
* @retval HAL status
*/
static HAL_StatusTypeDef RTC1_WriteTimeCounter(RTC_HandleTypeDef *hrtc, uint32_t TimeCounter)
{
HAL_StatusTypeDef status = HAL_OK;
/* Set Initialization mode */
if (RTC1_EnterInitMode(hrtc) != HAL_OK)
{
status = HAL_ERROR;
}
else
{
/* Set RTC COUNTER MSB word */
WRITE_REG(hrtc->Instance->CNTH, (TimeCounter >> 16U));
/* Set RTC COUNTER LSB word */
WRITE_REG(hrtc->Instance->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
/* Wait for synchro */
if (RTC1_ExitInitMode(hrtc) != HAL_OK)
{
status = HAL_ERROR;
}
}
return status;
}
/**
* @brief Enters the RTC Initialization mode.
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval HAL status
*/
static HAL_StatusTypeDef RTC1_EnterInitMode(RTC_HandleTypeDef *hrtc)
{
uint32_t tickstart = 0U;
tickstart = HAL_GetTick();
/* Wait till RTC is in INIT state and if Time out is reached exit */
while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
{
if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
return HAL_OK;
}
/**
* @brief Exit the RTC Initialization mode.
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
* the configuration information for RTC.
* @retval HAL status
*/
static HAL_StatusTypeDef RTC1_ExitInitMode(RTC_HandleTypeDef *hrtc)
{
uint32_t tickstart = 0U;
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
tickstart = HAL_GetTick();
/* Wait till RTC is in INIT state and if Time out is reached exit */
while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
{
if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
return HAL_OK;
}