IMX6ULL bare metal-1-RTC timer

Publisher:EnchantedMagicLatest update time:2024-07-03 Source: elecfans Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1 Introducing RTC timer

The RTC timer is called the real time clock. There are many timers inside the CPU, such as the watchdog WDT, PWM timer, high-precision timer Timer, etc., which only run when "started" or "powered on", and stop when the power is off. Of course, if the clock cannot track time continuously, it must be set manually. Then there is no way to automatically count the time after shutting down. The essence of a timer is a counter, which can count up or down. RTC has a power supply that is separate from the host, such as a button battery (backup battery). Even if the host power is turned off, it maintains the counting and timing function. This is why the time on our mobile phones can remain accurate after turning off. For example, the old Nokia mobile phones in the past will not be accurate if the battery is removed, because the RTC power supply is cut off and it cannot count. The counter of the RTC timer will be cleared to 0, and the current time needs to be set manually. RTC generally uses a button battery to power the external crystal oscillator and circuit. !

2 RTC Timer Principle

Taking the RTC timer of the IMX6U chip as an example, there is also an RTC module inside the I.MX6U, but it is not called "RTC", but "SNVS". The RTC module structure diagram is as follows:


SNVS is divided into two sub-modules: SNVS_HP and SNVS_LP, namely the high power domain (SNVS_HP) and the low power domain (SNVS_LP). The power sources of these two domains are as follows:

SNVS_LP: A dedicated always-powered-on power domain that can be powered by both the system main power supply and the backup power supply.
SNVS_HP: System (chip) power supply.

After the system main power is cut off, SNVS_HP will also be powered off, but with the support of the backup power supply, SNVS_LP will not be powered off, and SNVS_LP is isolated from the chip reset, so the values ​​of the registers related to SNVS_LP will be kept, that is, the low power domain is not affected by the system power supply. The meanings of the serial numbers in the above figure are as follows: ①, VDD_HIGH_IN is the main power supply of the system (chip), this power supply will be supplied to SNVS_HP and SNVS_LP at the same time. ②, VDD_SNVS_IN is the power supply powered by the button battery, this power supply will only be supplied to SNVS_LP, ensuring that SNVS_LP will continue to run after the system main power supply VDD_HIGH_IN is powered off. ③, SNVS_HP part. ④, SNVS_LP part, this part has an SRTC, this is the RTC to be used. SRTC requires a 32.768KHz clock from the outside world. The 32.768KHz crystal oscillator on the I.MX6U-ALPHA core board provides this clock.


3 RTC Timer Registers

SNVS_SRTCMR[14:0] represents the high 15 bits of the SRTC counter SNVS_SRTCLR[31:15] represents the low 17 bits of the SRTC counter Note: The starting point is 0:0:00 on January 1, 1970, and the total number of seconds that have passed can be added to get the current time point. SNVS_HPCOMR[31], NPSWA_EN bit, non-privileged software access control bit, if non-privileged software wants to access SNVS, this bit must be 1. SNVS_LPCR[0], SRTC_ENV bit, enables the STC counter.

4 RTC bare metal source code display

The NXP official SDK package is written for I.MX6ULL, so the registers in the structure SNVS_Type in the file MCIMX6Y2.h are incomplete. We need to add the registers required for the experiment in this chapter and modify SNVS_Type to be as follows:


/*!

* @addtogroup SNVS_Peripheral_Access_Layer SNVS Peripheral Access Layer

* @{

*/


/** SNVS - Register Layout Typedef */

/* zuozhongkai 2018/12/13 */

typedef struct {

__IO uint32_t HPLR; /**< SNVS_HP Lock register, offset: 0x0 */

__IO uint32_t HPCOMR; /**< SNVS_HP Command register, offset: 0x4 */

__IO uint32_t HPCR; /**< SNVS_HP Control register, offset: 0x8 */

__IO uint32_t HPSICR; /**< SNVS_HP Control register, offset: 0x8 */

__IO uint32_t HPSVCR;

__IO uint32_t HPSR;

__IO uint32_t HPSVSR;

__IO uint32_t HPHACIVR;

__IO uint32_t HPHACR;

__IO uint32_t HPRTCMR;

__IO uint32_t HPRTCLR;

__IO uint32_t HPTAMR;

__IO uint32_t HPTALR;

__IO uint32_t LPLR;

__IO uint32_t LPCR;

__IO uint32_t LPMKCR;

__IO uint32_t LPSVCR;

__IO uint32_t LPTGFCR;

__IO uint32_t LPTDCR;

__IO uint32_t LPSR;

__IO uint32_t LPSRTCMR;

__IO uint32_t LPSRTCLR;

__IO uint32_t LPTAR;

__IO uint32_t LPSMCMR;

__IO uint32_t LPSMCLR;

}SNVS_Type;



bsp_rtc.h




#ifndef _BSP_RTC_H

#define _BSP_RTC_H

/****************************************************** ****************

Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.

File name: bsp_rtc.c

Author : Zuo Zhongkai

Version: V1.0

Description: RTC driver header file.

Others: None

Forum : www.wtmembed.com

Log: First version V1.0 2019/1/3 Created by Zuo Zhongkai

*************************************************** *************/

#include "imx6ul.h"


/* Related macro definitions */

#define SECONDS_IN_A_DAY (86400) /* 86400 seconds in a day */

#define SECONDS_IN_A_HOUR (3600) /* 3600 seconds in an hour */

#define SECONDS_IN_A_MINUTE (60) /* 60 seconds in a minute */

#define DAYS_IN_A_YEAR (365) /* 365 days in a year */

#define YEAR_RANGE_START (1970) /* Start year 1970 */

#define YEAR_RANGE_END (2099) /* End year 2099 */


/* Date and time structure*/

struct rtc_datetime

{

unsigned short year; /* Range: 1970 ~ 2099 */

unsigned char month; /* Range: 1 ~ 12 */

unsigned char day; /* Range: 1 ~ 31 (different months, different days).*/

unsigned char hour; /* Range: 0 ~ 23 */

unsigned char minute; /* Range: 0 ~ 59 */

unsigned char second; /* Range: 0 ~ 59 */

};


/* Function declaration */

void rtc_init(void);

void rtc_enable(void);

void rtc_disable(void);

unsigned int rtc_coverdate_to_seconds(struct rtc_datetime *datetime);

unsigned int rtc_getseconds(void);

void rtc_setdatetime(struct rtc_datetime *datetime);

void rtc_getdatetime(struct rtc_datetime *datetime);

#endif





bsp_rtc.c




/****************************************************** ****************

Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.

File name: bsp_rtc.c

Author : Zuo Zhongkai

Version: V1.0

Description: RTC driver file.

Others: None

Forum : www.wtmembed.com

Log: First version V1.0 2019/1/3 Created by Zuo Zhongkai

*************************************************** *************/

#include "bsp_rtc.h"

#include "stdio.h"


/*

* Description: Initialize RTC

*/

void rtc_init(void)

{

/*

* Set the HPCOMR register

* bit[31] 1: Allow access to the SNVS register, must be set to 1

* bit[8] 1: This bit is set to 1. You need to sign the NDA agreement to see the detailed description of this bit.

* It is OK not to set it to 1

*/

SNVS->HPCOMR |= (1 << 31) | (1 << 8);


#if 0

struct rtc_datetime rtcdate;


rtcdate.year = 2018U;

rtcdate.month = 12U;

rtcdate.day = 13U;

rtcdate.hour = 14U;

rtcdate.minute = 52;

rtcdate.second = 0;

rtc_setDatetime(&rtcdate); //Initialize time and date

#endif


rtc_enable(); //Enable RTC


}


/*

* Description: Enable RTC

*/

void rtc_enable(void)

{

/*

* Set LPCR register bit 0 to 1 to enable RTC

*/

SNVS->LPCR |= 1 << 0;

while(!(SNVS->LPCR & 0X01));//Wait for enabling to complete


}


/*

* Description: Turn off RTC

*/

void rtc_disable(void)

{

/*

* Set LPCR register bit0 to 0 to turn off RTC

*/

SNVS->LPCR &= ~(1 << 0);

while(SNVS->LPCR & 0X01); //Wait for shutdown to complete

}


/*

* @description: Determines whether the specified year is a leap year. The leap year conditions are as follows:

* @param - year: the year to be judged

* @return: 1 is a leap year, 0 is not a leap year

*/

unsigned char rtc_isleapyear(unsigned short year)

{

unsigned char value=0;


if(year % 400 == 0)

value = 1;

else

{

if((year % 4 == 0) && (year % 100 != 0))

value = 1;

else

value = 0;

}

return value;

}


/*

* @description: Convert time to seconds

* @param - datetime: The date and time to convert.

* @return: the converted seconds

*/

unsigned int rtc_coverdate_to_seconds(struct rtc_datetime *datetime)

{

unsigned short i = 0;

unsigned int seconds = 0;

unsigned int days = 0;

unsigned short monthdays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U};


for(i = 1970; i < datetime->year; i++)

{

days += DAYS_IN_A_YEAR; /* Ordinary year, 365 days per year*/

if(rtc_isleapyear(i)) days += 1;/* add one more day in leap year */

}


days += monthdays[datetime->month];

if(rtc_isleapyear(i) && (datetime->month >= 3)) days += 1;/* If it is a leap year and the current month is greater than or equal to March, add one day*/


days += datetime->day - 1;

seconds = days * SECONDS_IN_A_DAY +

datetime->hour * SECONDS_IN_A_HOUR +

datetime->minute * SECONDS_IN_A_MINUTE +

datetime->second;

return seconds;

}


/*

* @description: Set time and date

* @param - datetime: the date and time to set

* @return : None

*/

void rtc_setdatetime(struct rtc_datetime *datetime)

{

unsigned int seconds = 0;

unsigned int tmp = SNVS->LPCR;


rtc_disable(); /* Be sure to turn off RTC before setting registers HPRTCMR and HPRTCLR */


/* Convert the time to seconds first */

seconds = rtc_coverdate_to_seconds(datetime);


SNVS->LPSRTCMR = (unsigned int)(seconds >> 17); /* Set the upper 16 bits */

SNVS->LPSRTCLR = (unsigned int)(seconds << 15); /* Set ground 16 bits */


/* If the RTC was turned on before, you need to turn it on again after setting the RTC time */

[1] [2]
Reference address:IMX6ULL bare metal-1-RTC timer

Previous article:IMX6ULL bare metal -2-PWM timer
Next article:s3c2440 bare metal - resistive touch screen - 7 - touch screen calibration test and optimization

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号