2018-11-09 03:36 AM
On last version normal rtc init code was so:
/* RTC init function */
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
RTC_AlarmTypeDef sAlarm;
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/**Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 0;
hrtc.Init.SynchPrediv = 0x7FFF;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
/**Initialize RTC and set the Time and Date
*/
sTime.Hours = 0;
sTime.Minutes = 0;
sTime.Seconds = 0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/* USER CODE BEGIN RTC_Init 3 */
/* USER CODE END RTC_Init 3 */
sDate.WeekDay = RTC_WEEKDAY_SUNDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 1;
sDate.Year = 17;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/* USER CODE BEGIN RTC_Init 4 */
/* USER CODE END RTC_Init 4 */
/**Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 0;
sAlarm.AlarmTime.SubSeconds = 0;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 1;
sAlarm.Alarm = RTC_ALARM_A;
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/* USER CODE BEGIN RTC_Init 5 */
/* USER CODE END RTC_Init 5 */
/**Enable the WakeUp
*/
if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 1, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/* USER CODE BEGIN RTC_Init 6 */
/* USER CODE END RTC_Init 6 */
}
And I can insert code with simple control for RTC state:
/* USER CODE BEGIN RTC_Init 2 */
if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
/* USER CODE END RTC_Init 2 */
And so one.
But in new version of libraries no any user code for this purpose:
/* RTC init function */
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/**Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 0;
hrtc.Init.SynchPrediv = 0x7FFF;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initialize RTC and set the Time and Date
*/
sTime.Hours = 0;
sTime.Minutes = 0;
sTime.Seconds = 0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sDate.WeekDay = RTC_WEEKDAY_SUNDAY;
sDate.Month = RTC_MONTH_JANUARY;
sDate.Date = 1;
sDate.Year = 17;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
Only Use Code 0 and User code 1. But I can't stopped writing date and time. It's needed User code 2 and 4.
Of course I can write this code by myself, but after next code updating by STMCube I will lost all my changes.
2018-11-09 10:46 AM
So it was intended.
I advise the second time: use CMSIS.
#define swRCC_BDCR_LSEDRV(write) (((write) & 0x00000003U) << 3)
#define srRCC_BDCR_LSEDRV (((RCC->BDCR) >> 3) & 0x00000003U)
#define srRCC_BDCR_LSERDY (((RCC->BDCR) >> 1) & 0x00000001U)
static const struct
{
const uint32_t No_clock;
const uint32_t LSE;
const uint32_t LSI;
const uint32_t HSE;
const uint32_t FFFF;
}sRCC_BDCR_RTCSEL = {0x00000000U,0x00000100U,0x00000200U,0x00000300U,0x00000300U};
/*
RCC->BDCR = swRCC_BDCR_LSEDRV(write) /// Power LSE oscillator's drive capability. 0-3
|sRCC_BDCR_RTCSEL.x /// RTC clock source selection
|RCC_BDCR_LSEON /// 1: External low-speed oscillator LSE enable
|RCC_BDCR_LSEBYP /// 1: Bypassing the LSE generator
|RCC_BDCR_RTCEN /// RTC clock enable
|RCC_BDCR_BDRST /// Backup domain software reset
srRCC_BDCR_LSEDRV /// Reading power LSE oscillator's drive capability.
/// only reading
srRCC_BDCR_LSERDY /// 1: Stable operation of the LSE
*/
if((RCC->BDCR & ( RCC_BDCR_LSERDY | sRCC_BDCR_RTCSEL.LSE | RCC_BDCR_RTCEN ))
^ ( RCC_BDCR_LSERDY | sRCC_BDCR_RTCSEL.LSE | RCC_BDCR_RTCEN ))
{ /// Сбой ча�?ового кварца, коммутатора кварца, ча�?ового модул�?
RCC->BDCR = RCC_BDCR_BDRST; /// ре�?ет модул�?
RCC->BDCR &= ~RCC_BDCR_BDRST;
RCC->AHB1LPENR |= RCC_AHB1LPENR_BKPSRAMLPEN;
PWR->CSR1 |= PWR_CSR1_BRE; /// вкл LP �?таб на BKPSRAM
while(!(PWR->CSR1 & PWR_CSR1_BRR));
RCC->BDCR |= RCC_BDCR_RTCEN /// вкл ча�?ового модул�?
|RCC_BDCR_LSEON /// включаем внешний кварц
|swRCC_BDCR_LSEDRV(3); /// Power LSE oscillator's drive capability. 0-3
RCC->CSR |= RCC_CSR_LSION; /// включаем внутренний генератор 32Кгц
for(tmp = 0x40024000; tmp < 0x40024FFC ; tmp +=4) // обнуление BKPSRAM
{ *(__IO uint32_t*) tmp = 0x0; delay(10);}
tmp = 33554432;
do { tmp--; }
while ( (srRCC_BDCR_LSERDY == 0) && ( tmp != 0) );
if ( tmp != 0) RCC->BDCR |= sRCC_BDCR_RTCSEL.LSE;
else RCC->BDCR |= sRCC_BDCR_RTCSEL.LSI;
/// обновление даты и времени: год , ме�?�?ц , день , день_недели , ча�? , минуты , �?екунды
/// year, month, day, day_of_the_week, hour, minutes, seconds);
PWR->CR1 |= PWR_CR1_DBP;
RTC->WPR = 0xCA;
delay(1000);
RTC->WPR = 0x53;
delay(1000);
RTC->ISR |= RTC_ISR_INIT;
while(!(RTC->ISR & RTC_ISR_INITF));
RTC->CR |= RTC_CR_BYPSHAD; /// чтение/запи�?ь без кеша
RTC->PRER = 0x007F00FF; //0x007f00ff;
delay(100);
RTC->TR = ((__TIME__[0]-'0') << 20) // hour 10
| ((__TIME__[1]-'0') << 16) // hour 1
| ((__TIME__[3]-'0') << 12) // minutes 10
| ((__TIME__[4]-'0') << 8) // minutes 1
| ((__TIME__[6]-'0') << 4) // seconds 10
| (__TIME__[7]-'0'); // seconds 1
RTC->DR = ((__DATE__[9]-'0') << 20) // year 10
| ((__DATE__[10]-'0') << 16) // year 1
| ((__TIMESTAMP__[2]=='e'?2:__TIMESTAMP__[2]=='d'?3 \
:__TIMESTAMP__[2]=='u'?4:__TIMESTAMP__[2]=='i'?5 \
:__TIMESTAMP__[2]=='t'?6:__TIMESTAMP__[0]=='M'?1:7) << 13) // Week day
| ((((__DATE__[2]=='n'?(__DATE__[1]=='a'?0:5):__DATE__[2]=='b'?1 \
:__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4 \
:__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8 \
:__DATE__[2] =='t'?9:__DATE__[2]=='v'?10:11)+1)/10) << 12) // Month 10
| ((((__DATE__[2]=='n'?(__DATE__[1]=='a'?0:5):__DATE__[2]=='b'?1 \
:__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4 \
:__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8 \
:__DATE__[2] =='t'?9:__DATE__[2]=='v'?10:11)+1)%10) << 8) // Month 1
| ((__DATE__[4]==' ' ? 0 : __DATE__[4]-'0') << 4) // day 10
| (__DATE__[5]-'0'); // day 1
delay(100);
RTC->ISR &= (~RTC_ISR_INIT); // закрываем до�?туп на запи�?ь реги�?трам ча�?ов реального времени
RTC->WPR =0xEE;
delay(1000);
}else;
2018-11-09 01:12 PM
Good variant.
But I must using Hall Libraries for fully compatible with all code.
2019-01-21 08:35 AM
In new version all is OK.
Thank :)