From aa38e5c1f48e31213ee349aa5cd6f06c85bda70d Mon Sep 17 00:00:00 2001 From: android <android@lingyun.com> Date: Tue, 25 Jun 2024 21:49:39 +0800 Subject: [PATCH] Add GD32F103RCT6 ADC converter board SDK source code --- mcu_sdk/gd32f103/rk_eFire/System/Src/rtc.c | 642 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 642 insertions(+), 0 deletions(-) diff --git a/mcu_sdk/gd32f103/rk_eFire/System/Src/rtc.c b/mcu_sdk/gd32f103/rk_eFire/System/Src/rtc.c new file mode 100644 index 0000000..0d2c3a3 --- /dev/null +++ b/mcu_sdk/gd32f103/rk_eFire/System/Src/rtc.c @@ -0,0 +1,642 @@ +/** + ****************************************************************************** + * File Name : RTC.c + * Description : This file provides code for the configuration + * of the RTC instances. + ****************************************************************************** + * @attention + * + * <h2><center>© Copyright (c) 2021 STMicroelectronics. + * All rights reserved.</center></h2> + * + * This software component is licensed by ST under Ultimate Liberty license + * SLA0044, the "License"; You may not use this file except in compliance with + * the License. You may obtain a copy of the License at: + * www.st.com/SLA0044 + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "rtc.h" +#include <math.h> +#include "board_common.h" +// MCU Wake Up Time +#define MIN_ALARM_DELAY 3 // in ticks + +// sub-second number of bits +#define N_PREDIV_S 10 + +// Synchronous prediv +#define PREDIV_S ( ( 1 << N_PREDIV_S ) - 1 ) + +// Asynchronous prediv +#define PREDIV_A ( 1 << ( 15 - N_PREDIV_S ) ) - 1 + +// Sub-second mask definition +#define ALARM_SUBSECOND_MASK ( N_PREDIV_S << RTC_ALRMASSR_MASKSS_Pos ) + +// RTC Time base in us +#define USEC_NUMBER 1000000 +#define MSEC_NUMBER ( USEC_NUMBER / 1000 ) + +#define COMMON_FACTOR 3 +#define CONV_NUMER ( MSEC_NUMBER >> COMMON_FACTOR ) +#define CONV_DENOM ( 1 << ( N_PREDIV_S - COMMON_FACTOR ) ) + +/*! + * \brief Days, Hours, Minutes and seconds + */ +#define DAYS_IN_LEAP_YEAR ( ( uint32_t ) 366U ) +#define DAYS_IN_YEAR ( ( uint32_t ) 365U ) +#define SECONDS_IN_1DAY ( ( uint32_t )86400U ) +#define SECONDS_IN_1HOUR ( ( uint32_t ) 3600U ) +#define SECONDS_IN_1MINUTE ( ( uint32_t ) 60U ) +#define MINUTES_IN_1HOUR ( ( uint32_t ) 60U ) +#define HOURS_IN_1DAY ( ( uint32_t ) 24U ) + +/*! + * \brief Correction factors + */ +#define DAYS_IN_MONTH_CORRECTION_NORM ( ( uint32_t )0x99AAA0 ) +#define DAYS_IN_MONTH_CORRECTION_LEAP ( ( uint32_t )0x445550 ) + +/*! + * \brief Calculates ceiling( X / N ) + */ +#define DIVC( X, N ) ( ( ( X ) + ( N ) -1 ) / ( N ) ) + + +/*! + * RTC timer context + */ +typedef struct +{ + uint32_t Time; // Reference time + RTC_TimeTypeDef CalendarTime; // Reference time in calendar format + RTC_DateTypeDef CalendarDate; // Reference date in calendar format +}RtcTimerContext_t; + +/*! + * \brief Compensates MCU wakeup time + */ +//static int16_t McuWakeUpTimeCal = 0; + +/*! + * Number of days in each month on a normal year + */ +static const uint8_t DaysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +/*! + * Number of days in each month on a leap year + */ +static const uint8_t DaysInMonthLeapYear[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + +/*! + * Keep the value of the RTC timer when the RTC alarm is set + * Set with the \ref RtcSetTimerContext function + * Value is kept as a Reference to calculate alarm + */ +static RtcTimerContext_t RtcTimerContext; + +static RTC_AlarmTypeDef RtcAlarm; + +RTC_HandleTypeDef RtcHandle; +static bool RtcInitialized = false; + +static uint64_t RtcGetCalendarValue( RTC_DateTypeDef* date, RTC_TimeTypeDef* time ); + +/* RTC init function */ +void Board_RTCInit(void) +{ + RTC_TimeTypeDef sTime = {0}; + RTC_DateTypeDef DateToUpdate = {0}; + + if( RtcInitialized == false ) + { + + /** Initialize RTC Only + */ + RtcHandle.Instance = RTC; + RtcHandle.Lock = HAL_UNLOCKED; + RtcHandle.Init.AsynchPrediv = RTC_AUTO_1_SECOND; + RtcHandle.Init.OutPut = RTC_OUTPUTSOURCE_ALARM; + if (HAL_RTC_Init(&RtcHandle) != HAL_OK) + { + Error_Handler(); + } + + /** Initialize RTC and set the Time and Date + */ + sTime.Hours = 0x0; + sTime.Minutes = 0x0; + sTime.Seconds = 0x0; + if (HAL_RTC_SetTime(&RtcHandle, &sTime, RTC_FORMAT_BIN) != HAL_OK) + { + Error_Handler(); + } + DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY; + DateToUpdate.Month = RTC_MONTH_JANUARY; + DateToUpdate.Date = 0x1; + DateToUpdate.Year = 0x0; + + if (HAL_RTC_SetDate(&RtcHandle, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK) + { + Error_Handler(); + } + + RtcSetTimerContext( ); + //HAL_RTCEx_SetSecond_IT(&RtcHandle); + + RtcInitialized = true; + } +} + +void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle) +{ + + if(rtcHandle->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspInit 0 */ + + /* USER CODE END RTC_MspInit 0 */ + HAL_PWR_EnableBkUpAccess(); + /* Enable BKP CLK enable for backup registers */ + __HAL_RCC_BKP_CLK_ENABLE(); + /* RTC clock enable */ + __HAL_RCC_RTC_ENABLE(); + + /* RTC interrupt Init */ + HAL_NVIC_SetPriority(RTC_IRQn, 1, 0); + HAL_NVIC_EnableIRQ(RTC_IRQn); + //HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0x0, 0); + //HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn); + + /* USER CODE BEGIN RTC_MspInit 1 */ + + /* USER CODE END RTC_MspInit 1 */ + } +} + +void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle) +{ + + if(rtcHandle->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspDeInit 0 */ + + /* USER CODE END RTC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_RTC_DISABLE(); + + /* RTC interrupt Deinit */ + HAL_NVIC_DisableIRQ(RTC_IRQn); + /* USER CODE END RTC_MspDeInit 1 */ + } +} + +/*! + * \brief RTC IRQ Handler of the RTC Alarm + */ +void HW_RTC_IrqHandler( void ) +{ + RTC_HandleTypeDef* hrtc = &RtcHandle; + + // Enable low power at irq + // LPM_SetStopMode(LPM_RTC_Id , LPM_Enable ); + + // Clear the EXTI's line Flag for RTC Alarm + __HAL_RTC_ALARM_EXTI_CLEAR_FLAG( ); + + // Gets the AlarmA interrupt source enable status + if( __HAL_RTC_ALARM_GET_IT_SOURCE( hrtc, RTC_IT_ALRA ) != RESET ) + { + // Gets the pending status of the AlarmA interrupt + if( __HAL_RTC_ALARM_GET_FLAG( hrtc, RTC_FLAG_ALRAF ) != RESET ) + { + // Clear the AlarmA interrupt pending bit + __HAL_RTC_ALARM_CLEAR_FLAG( hrtc, RTC_FLAG_ALRAF ); + // AlarmA callback + //HAL_RTC_AlarmAEventCallback( hrtc ); + TimerIrqHandler( ); + } + } +} + +/*! + * \brief Sets the RTC timer reference, sets also the RTC_DateStruct and RTC_TimeStruct + * + * \param none + * \retval timerValue In ticks + */ +uint32_t RtcSetTimerContext( void ) +{ + RtcTimerContext.Time = ( uint32_t )RtcGetCalendarValue( &RtcTimerContext.CalendarDate, &RtcTimerContext.CalendarTime ); + return ( uint32_t )RtcTimerContext.Time; +} + +/*! + * \brief Gets the RTC timer reference + * + * \param none + * \retval timerValue In ticks + */ +uint32_t RtcGetTimerContext( void ) +{ + return RtcTimerContext.Time; +} + +/*! + * \brief returns the wake up time in ticks + * + * \retval wake up time in ticks + */ +uint32_t RtcGetMinimumTimeout( void ) +{ + return( MIN_ALARM_DELAY ); +} + +uint32_t RtcGetTimerValue( void ) +{ + RTC_TimeTypeDef time; + RTC_DateTypeDef date; + + uint32_t calendarValue = ( uint32_t )RtcGetCalendarValue( &date, &time ); + + return( calendarValue ); +} + +/*! + * \brief converts time in ms to time in ticks + * + * \param[IN] milliseconds Time in milliseconds + * \retval returns time in timer ticks + */ +uint32_t RtcMs2Tick( uint32_t milliseconds ) +{ + return ( uint32_t )( ( ( ( uint64_t )milliseconds ) * CONV_DENOM ) / CONV_NUMER ); + + //return milliseconds; +} + +/*! + * \brief converts time in ticks to time in ms + * + * \param[IN] time in timer ticks + * \retval returns time in milliseconds + */ +uint32_t RtcTick2Ms( uint32_t tick ) +{ + uint32_t seconds = tick >> N_PREDIV_S; + + tick = tick & PREDIV_S; + return ( ( seconds * 1000 ) + ( ( tick * 1000 ) >> N_PREDIV_S ) ); +} + +/*! + * \brief a delay of delay ms by polling RTC + * + * \param[IN] delay in ms + */ +void RtcDelayMs( uint32_t delay ) +{ + uint64_t delayTicks = 0; + uint64_t refTicks = RtcGetTimerValue( ); + + delayTicks = RtcMs2Tick( delay ); + + // Wait delay ms + while( ( ( RtcGetTimerValue( ) - refTicks ) ) < delayTicks ) + { + __NOP( ); + } +} + +/*! + * \brief Sets the alarm + * + * \note The alarm is set at now (read in this function) + timeout + * + * \param timeout Duration of the Timer ticks + */ +void RtcSetAlarm( uint32_t timeout ) +{ +#if 0 + // We don't go in Low Power mode for timeout below MIN_ALARM_DELAY + if( ( int64_t )( MIN_ALARM_DELAY + McuWakeUpTimeCal ) < ( int64_t )( timeout - RtcGetTimerElapsedTime( ) ) ) + { + LPM_SetStopMode(LPM_RTC_Id , LPM_Enable ); + } + else + { + LPM_SetStopMode(LPM_RTC_Id , LPM_Disable ); + } + + // In case stop mode is required + if( LPM_GetMode() == LPM_StopMode ) + { + timeout = timeout - McuWakeUpTimeCal; + } +#endif + //timeout = timeout - McuWakeUpTimeCal; + //PRINTF("---timeout:%d\r\n", timeout); + + RtcStartAlarm( timeout ); +} + +void RtcStopAlarm( void ) +{ + // Disable the Alarm A interrupt + HAL_RTC_DeactivateAlarm( &RtcHandle, RTC_ALARM_A ); + + // Clear RTC Alarm Flag + __HAL_RTC_ALARM_CLEAR_FLAG( &RtcHandle, RTC_FLAG_ALRAF ); + + // Clear the EXTI's line Flag for RTC Alarm + __HAL_RTC_ALARM_EXTI_CLEAR_FLAG( ); +} + +#if 1 +void RtcStartAlarm( uint32_t timeoutValue ) +{ +#if 1 + //uint16_t rtcAlarmSubSeconds = 0; + uint16_t rtcAlarmSeconds = 0; + uint16_t rtcAlarmMinutes = 0; + uint16_t rtcAlarmHours = 0; + uint16_t rtcAlarmDays = 0; + RTC_TimeTypeDef RTC_TimeStruct = RtcTimerContext.CalendarTime; + RTC_DateTypeDef RTC_DateStruct = RtcTimerContext.CalendarDate; + + RtcStopAlarm( ); + //DBG_GPIO_SET(GPIOB, GPIO_PIN_13); + //PRINTF("timeoutValue:%d\r\n", timeoutValue); + + /*reverse counter */ + //rtcAlarmSubSeconds = PREDIV_S - RTC_TimeStruct.SubSeconds; + //rtcAlarmSubSeconds += ( timeoutValue & PREDIV_S); + + //PRINTF("rtcAlarmSeconds:%d, PREDIV_S:%d\r\n", rtcAlarmSeconds, PREDIV_S); + /* convert timeout to seconds */ + timeoutValue >>= N_PREDIV_S; /* convert timeout in seconds */ + //PRINTF("timeoutValue:%d\r\n", timeoutValue); + if (timeoutValue != 0) + timeoutValue -= 1; + /*convert microsecs to RTC format and add to 'Now' */ + rtcAlarmDays = RTC_DateStruct.Date; + while (timeoutValue >= SECONDS_IN_1DAY) + { + timeoutValue -= SECONDS_IN_1DAY; + rtcAlarmDays++; + } + //PRINTF("timeoutValue:%d\r\n", timeoutValue); + + /* calc hours */ + rtcAlarmHours = RTC_TimeStruct.Hours; + while (timeoutValue >= SECONDS_IN_1HOUR) + { + timeoutValue -= SECONDS_IN_1HOUR; + rtcAlarmHours++; + } + //PRINTF("timeoutValue:%d\r\n", timeoutValue); + + /* calc minutes */ + rtcAlarmMinutes = RTC_TimeStruct.Minutes; + while (timeoutValue >= SECONDS_IN_1MINUTE) + { + timeoutValue -= SECONDS_IN_1MINUTE; + rtcAlarmMinutes++; + } + //PRINTF("timeoutValue:%d\r\n", timeoutValue); + + /* calc seconds */ + rtcAlarmSeconds = RTC_TimeStruct.Seconds + timeoutValue; +//PRINTF("rtcAlarmSeconds:%d, RTC_TimeStruct.Seconds:%d\r\n", rtcAlarmSeconds, RTC_TimeStruct.Seconds); +#if 0 + /***** correct for modulo********/ + while (rtcAlarmSubSeconds >= (PREDIV_S+1)) + { + rtcAlarmSubSeconds -= (PREDIV_S+1); + rtcAlarmSeconds++; + } +#endif + while (rtcAlarmSeconds >= SECONDS_IN_1MINUTE) + { + rtcAlarmSeconds -= SECONDS_IN_1MINUTE; + rtcAlarmMinutes++; + } + + while (rtcAlarmMinutes >= MINUTES_IN_1HOUR) + { + rtcAlarmMinutes -= MINUTES_IN_1HOUR; + rtcAlarmHours++; + } + + while (rtcAlarmHours >= HOURS_IN_1DAY) + { + rtcAlarmHours -= HOURS_IN_1DAY; + rtcAlarmDays++; + } + + if( RTC_DateStruct.Year % 4 == 0 ) + { + if( rtcAlarmDays > DaysInMonthLeapYear[ RTC_DateStruct.Month - 1 ] ) + { + rtcAlarmDays = rtcAlarmDays % DaysInMonthLeapYear[ RTC_DateStruct.Month - 1 ]; + } + } + else + { + if( rtcAlarmDays > DaysInMonth[ RTC_DateStruct.Month - 1 ] ) + { + rtcAlarmDays = rtcAlarmDays % DaysInMonth[ RTC_DateStruct.Month - 1 ]; + } + } + #endif +#if 1 + /* Set RTC_AlarmStructure with calculated values*/ + RtcAlarm.AlarmTime.Seconds = rtcAlarmSeconds; + RtcAlarm.AlarmTime.Minutes = rtcAlarmMinutes; + RtcAlarm.AlarmTime.Hours = rtcAlarmHours; + RtcAlarm.Alarm = RTC_ALARM_A; +//PRINTF("--wqw--rtcAlarmSeconds:%d, rtcAlarmMinutes:%d\r\n", rtcAlarmSeconds, rtcAlarmMinutes); +#else +RtcAlarm.Alarm = RTC_ALARM_A; + +RtcAlarm.AlarmTime.Seconds += 1; +if (RtcAlarm.AlarmTime.Seconds==60) +{ + RtcAlarm.AlarmTime.Minutes += 1; + RtcAlarm.AlarmTime.Seconds = 0; + PRINTF("Minutes:%d\r\n", RtcAlarm.AlarmTime.Minutes); +} + +#endif + /* Set RTC_Alarm */ + HAL_RTC_SetAlarm_IT( &RtcHandle, &RtcAlarm, RTC_FORMAT_BIN); + +#if 0 + /* Debug Printf*/ + DBG( HW_RTC_GetCalendarValue( &RTC_DateStruct, &RTC_TimeStruct ); ); + DBG_PRINTF("it's %d:%d:%d:%d ", RTC_TimeStruct.Hours, RTC_TimeStruct.Minutes, RTC_TimeStruct.Seconds, ((PREDIV_S - RTC_TimeStruct.SubSeconds)*1000)>>N_PREDIV_S); + DBG_PRINTF("WU@ %d:%d:%d:%d\n\r", rtcAlarmHours, rtcAlarmMinutes, rtcAlarmSeconds, (rtcAlarmSubSeconds*1000)>>N_PREDIV_S ); + + DBG_GPIO_RST(GPIOB, GPIO_PIN_13); + #endif +} +#else +void RtcStartAlarm(uint32_t AlarmCounter) +{ + RTC_AlarmTypeDef sAlarm; + uint32_t counter_alarm = 0; + uint32_t counter_time = 0; + RTC_TimeTypeDef stime = {0}; + + RtcStopAlarm( ); + + +// assert_param(AlarmCounter<= 86400); + + HAL_RTC_GetTime(&RtcHandle, &stime, RTC_FORMAT_BCD); + + //sprintf((char*)ShowTime1," GetTime %02d:%02d:%02d",stime.Hours, stime.Minutes, stime.Seconds); + + /* Convert time in seconds */ + counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600) + \ + ((uint32_t)stime.Minutes * 60) + \ + ((uint32_t)stime.Seconds)); + + counter_alarm = counter_time+AlarmCounter; + + sAlarm.Alarm = RTC_ALARM_A; + sAlarm.AlarmTime.Hours = (uint32_t)((counter_alarm / 3600) % 24); + sAlarm.AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600) / 60); + sAlarm.AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600) % 60); + + //sprintf((char*)ShowTime2,"SetAlarm %02d:%02d:%02d", sAlarm.AlarmTime.Hours, sAlarm.AlarmTime.Minutes, sAlarm.AlarmTime.Seconds); + if(HAL_RTC_SetAlarm_IT(&RtcHandle,&sAlarm,RTC_FORMAT_BCD) != HAL_OK) + { + /* Initialization Error */ + Error_Handler(); + } +} +#endif + + +static uint64_t RtcGetCalendarValue( RTC_DateTypeDef* date, RTC_TimeTypeDef* time ) +{ + uint64_t calendarValue = 0; + //uint32_t firstRead; + uint32_t correction; + uint32_t seconds; + + // Make sure it is correct due to asynchronus nature of RTC + //do + //{ + // firstRead = RTC->SSR; + HAL_RTC_GetDate( &RtcHandle, date, RTC_FORMAT_BIN ); + HAL_RTC_GetTime( &RtcHandle, time, RTC_FORMAT_BIN ); + //}while( firstRead != RTC->SSR ); + + // Calculte amount of elapsed days since 01/01/2000 + seconds = DIVC( ( DAYS_IN_YEAR * 3 + DAYS_IN_LEAP_YEAR ) * date->Year , 4 ); + + correction = ( ( date->Year % 4 ) == 0 ) ? DAYS_IN_MONTH_CORRECTION_LEAP : DAYS_IN_MONTH_CORRECTION_NORM; + + seconds += ( DIVC( ( date->Month-1 ) * ( 30 + 31 ), 2 ) - ( ( ( correction >> ( ( date->Month - 1 ) * 2 ) ) & 0x03 ) ) ); + + seconds += ( date->Date -1 ); + + // Convert from days to seconds + seconds *= SECONDS_IN_1DAY; + + seconds += ( ( uint32_t )time->Seconds + + ( ( uint32_t )time->Minutes * SECONDS_IN_1MINUTE ) + + ( ( uint32_t )time->Hours * SECONDS_IN_1HOUR ) ) ; + + calendarValue = ( ( ( uint64_t )seconds ) << N_PREDIV_S ); + + return( calendarValue ); +} + +uint32_t RtcGetCalendarTime( uint16_t *milliseconds ) +{ + RTC_TimeTypeDef time ; + RTC_DateTypeDef date; + uint32_t ticks; + + uint64_t calendarValue = RtcGetCalendarValue( &date, &time ); + + uint32_t seconds = ( uint32_t )( calendarValue >> N_PREDIV_S ); + + ticks = ( uint32_t )calendarValue & PREDIV_S; + + *milliseconds = RtcTick2Ms( ticks ); + + return seconds; +} + + +uint32_t RtcGetTimerElapsedTime( void ) +{ + RTC_TimeTypeDef time; + RTC_DateTypeDef date; + + uint32_t calendarValue = ( uint32_t )RtcGetCalendarValue( &date, &time ); + + return( ( uint32_t )( calendarValue - RtcTimerContext.Time ) ); +} + +void RtcBkupWrite( uint32_t data0, uint32_t data1 ) +{ + HAL_RTCEx_BKUPWrite( &RtcHandle, RTC_BKP_DR1, data0 ); + HAL_RTCEx_BKUPWrite( &RtcHandle, RTC_BKP_DR2, data1 ); +} + +void RtcBkupRead( uint32_t *data0, uint32_t *data1 ) +{ + *data0 = HAL_RTCEx_BKUPRead( &RtcHandle, RTC_BKP_DR1 ); + *data1 = HAL_RTCEx_BKUPRead( &RtcHandle, RTC_BKP_DR2 ); +} + +void RtcProcess( void ) +{ + // Not used on this platform. +} + +TimerTime_t RtcTempCompensation( TimerTime_t period, float temperature ) +{ + float k = RTC_TEMP_COEFFICIENT; + float kDev = RTC_TEMP_DEV_COEFFICIENT; + float t = RTC_TEMP_TURNOVER; + float tDev = RTC_TEMP_DEV_TURNOVER; + float interim = 0.0; + float ppm = 0.0; + + if( k < 0.0 ) + { + ppm = ( k - kDev ); + } + else + { + ppm = ( k + kDev ); + } + interim = ( temperature - ( t - tDev ) ); + ppm *= interim * interim; + + // Calculate the drift in time + interim = ( ( float ) period * ppm ) / 1e6; + // Calculate the resulting time period + interim += period; + interim = floor( interim ); + + if( interim < 0.0 ) + { + interim = ( float )period; + } + + // Calculate the resulting period + return ( TimerTime_t ) interim; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -- Gitblit v1.9.1