forked from achamaikin/CCSModuleSW30Web
198 lines
5.3 KiB
C
Executable File
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++) {
|
|
// 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;
|
|
}
|
|
|