/* * rtc.c * * Created on: Jul 22, 2024 * Author: colorbass */ #include #include #include 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++) { // log_printf(LOG_INFO, "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; }