📄 pmp_rtc_driver.c
字号:
#ifdef EVB_SN_V10
// 如果是在开发板上, 还需要将日期时间设置到 RTC 中
tmp_time.Hour = pTimeAttr->tm_hour;
tmp_time.Minute = pTimeAttr->tm_min;
tmp_time.Second = pTimeAttr->tm_sec;
tmp_date.Year = pTimeAttr->tm_year;
tmp_date.Month = pTimeAttr->tm_mon;
tmp_date.Day = pTimeAttr->tm_mday;
tmp_date.Week = WeekDay;
SPMP_RTC_SetDataFormat( DATA_FORMAT_HEX );
// 将数据设定到RTC 中去
SPMP_RTC_SetY_M_D_W( &tmp_date );
SPMP_RTC_SetH_M_S( &tmp_time );
#endif
return APP_DRV_OK;
}
/************************************************************************/
/* 获取 RTC 的时间信息
input: pTimt_t [in] 时间信息的指针
output: 0 成功, 非0值失败
func:
获取 时分秒信息
note:
使用文件系统的时间
根据设定的数据格式,进行数据的输出
*/
/************************************************************************/
UINT16 SPMP_RTC_GetH_M_S( Time_Attr_t * pTime_t, UINT16 DataFormat )
{
// 判断输入参数是否合法
if (NULL == pTime_t) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 获得当前的时间值
tmrNowTimeGet( pTime_t );
// 判断是否需要进行数据格式的转换
if ( DATA_FORMAT_BCD == DataFormat )
{
pTime_t ->tm_hour = ValueHEX_2_BCD( pTime_t ->tm_hour );
pTime_t ->tm_min = ValueHEX_2_BCD( pTime_t ->tm_min );
pTime_t ->tm_sec = ValueHEX_2_BCD( pTime_t ->tm_sec );
}
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 获取 年月日 星期
input:
pDate_t [in] 日期的指针
output:
0 成功, 非0值失败
func:
获取日期信息
note:
使用文件系统的时间,防止有2套时间存在
根据设定的数据格式,进行数据的输出
*/
/************************************************************************/
UINT16 SPMP_RTC_GetY_M_D_W( Time_Attr_t * pTime_t, UINT16 *pWeek, UINT16 DataFormat )
{
struct RTCdate_t tmp_date;
// 判断输入参数是否合法
if ( (NULL == pTime_t ) || ( NULL == pWeek) )
{
ERROR_REPORT;
return APP_DRV_ERR;
}
*pWeek = 0x00;
#ifndef EVB_SN_V10
tmrNowTimeGet( pTime_t ); // 首先获得 FS time
// 如果输出的数据是 BCD 格式,进行数据格式的转换
if ( DATA_FORMAT_BCD == DataFormat )
{
pTime_t ->tm_year = ValueHEX_2_BCD( pTime_t ->tm_year );
pTime_t ->tm_mon = ValueHEX_2_BCD( pTime_t ->tm_mon );
pTime_t ->tm_mday = ValueHEX_2_BCD( pTime_t ->tm_mday );
}
#else
SPMP_RTC_SetDataFormat( DataFormat );
// 获取 RTC 的日期值
SPMP_RTC_GetNowY_M_D_W( &tmp_date );
*pWeek = tmp_date.Week;
pTime_t ->tm_year = tmp_date.Year ;
pTime_t ->tm_mon = tmp_date.Month ;
pTime_t ->tm_mday = tmp_date.Day ;
#endif
return APP_DRV_OK; // 返回成功
}
/************************************************************************/
/* 初始化CPU与RTC相连接的I/O 的功能和状态,将
input:
void
output:
void
func:
初始化 HOST_GPIO2 HOST_GPIO3
note:
*/
/************************************************************************/
void SPMP_RTC_InterfaceInitial( void )
{
UINT8 i;
// disable HOST interafce
host_interface_disable();
// initial I2C SCL
// disable pull
set_register(REG_HGPIO_PULL_ENABLE, I2C_SCL_BIT, 0);
// disable input
set_register(REG_HGPIO_INPUT_ENABLE, I2C_SCL_BIT, 0);
// enable output
set_register(REG_HGPIO_OUTPUT_ENABLE, I2C_SCL_BIT, 1);
// output high
set_register(REG_HGPIO_OUTPUT_VALUE, I2C_SCL_BIT, 1);
// initial I2C SDA
// disable pull
set_register(REG_HGPIO_PULL_ENABLE, I2C_SDA_BIT, 0);
// disbale input
set_register(REG_HGPIO_INPUT_ENABLE, I2C_SDA_BIT, 0);
// enable output
set_register(REG_HGPIO_OUTPUT_ENABLE, I2C_SDA_BIT,1);
// output high
set_register(REG_HGPIO_OUTPUT_VALUE, I2C_SDA_BIT, 1);
// 读取控制寄存器信息
read_RTC_addr(RTC_ADDR_CTL2, 0x01, &i);
if ( !(i& (HOUR_12_24_BIT)) )
{
// 将RTC 小时模式设置为 24小时制式
i |= HOUR_12_24_BIT;
write_RTC_addr( RTC_ADDR_CTL2, 0x01, &i );
}
// disable 32K output
SPMP_RTC_Set32KOut( 0x00 );
return;
}
/************************************************************************/
/* 设定输出的数据的格式
input:
DataFormat [in] 数据的格式
DATA_FORMAT_BCD
DATA_FORMAT_HEX
output:
0 成功, 非0值失败
func:
设置数据的格式
note:
默认采用 BCD 的模式
*/
/************************************************************************/
static UINT16 SPMP_RTC_SetDataFormat( UINT16 DataFormat )
{
rtc_data_format = DATA_FORMAT_BCD;
// 判断输入的参数是否合法, 非法直接返回
if ( DataFormat > DATA_FORMAT_HEX ) {
return APP_DRV_ERR;
}
rtc_data_format = DataFormat;
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 获取 RTC 的日期信息
input:
pDate_t [in] 日期的指针
output:
0 成功, 非0值失败
func:
获取日期信息
note:
根据设定的数据格式,进行数据的输出
*/
/************************************************************************/
static UINT16 SPMP_RTC_GetNowY_M_D_W( struct RTCdate_t *pDate_t )
{
UINT8 buf[0x04];
// 判断输入参数是否合法
if (NULL == pDate_t) {
ERROR_OUTPUT(("get date err!\r\n"));
return APP_DRV_ERR;
}
// 读RTC 的日期信息
read_RTC_addr(RTC_ADDR_WEEK, 0x04, buf);
// 如果数据格式是 HEX, 需要进行数据的转换
if (DATA_FORMAT_HEX == get_data_format() )
{
// 将输入的BCD 数据转换为 HEX
bcd_2_hex( buf, buf, sizeof(buf));
}
pDate_t ->Week = (UINT16) buf[0];
pDate_t ->Day = (UINT16) buf[1];
pDate_t ->Month = (UINT16) buf[2];
if (DATA_FORMAT_HEX == get_data_format() ) {
pDate_t ->Year = buf[3] + BASE_YEAR_HEX;
}
else{
pDate_t ->Year = (UINT16)BASE_YEAR_BCD | buf[3];
}
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 设定时间
input:
pTime_t [in] 时间的指针
output:
0 成功, 非0值失败
func:
进行时间的设定
note:
根据设定的数据格式,进行数据的输出
*/
/************************************************************************/
static UINT16 SPMP_RTC_SetH_M_S( struct RTCtime_t *pTime_t )
{
UINT8 buf[0x10];
// 判断输入参数是否合法
if (NULL == pTime_t) {
ERROR_OUTPUT(("set time err1!\r\n"));
return APP_DRV_ERR;
}
// 按照 RTC 中存放的位置进行
buf[0] = (UINT8) pTime_t ->Second;
buf[1] = (UINT8) pTime_t ->Minute;
buf[2] = (UINT8) pTime_t ->Hour;
// 如果是HEX 模式, 需要进行格式转换
if ( DATA_FORMAT_HEX == get_data_format() )
{
hex_2_bcd(buf, buf, 0x03);
}
// 判断输入的时间值是否合法
if ( (buf[0] >0x59)
|| (buf[1]>0x59)
|| (buf[2] >0x23) )
{
ERROR_REPORT;
return APP_DRV_ERR;
}
// 将检查后的数据写入到RTC中
write_RTC_addr( RTC_ADDR_SECOND, 0x03, buf );
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 设置 年月日星期
input:
pDate_t [in] 日期的时间指针
output:
0 成功, 非0值失败
func:
进行日期星期的设置
*/
/************************************************************************/
static UINT16 SPMP_RTC_SetY_M_D_W( struct RTCdate_t *pDate_t )
{
UINT8 buf[0x10];
// 判断输入参数是否合法
if (NULL == pDate_t) {
ERROR_OUTPUT(("set date err1!\r\n"));
return APP_DRV_ERR;
}
buf[0] = (UINT8) pDate_t ->Week;
buf[1] = (UINT8) pDate_t ->Day;
buf[2] = (UINT8) pDate_t ->Month;
// 如果是HEX 模式, 需要进行格式转换
if ( DATA_FORMAT_HEX == get_data_format() )
{
buf[3] = (UINT8) (pDate_t->Year - BASE_YEAR_HEX);
}
else
{
buf[3] = (UINT8) (pDate_t->Year & 0xff);
}
// 如果是HEX 模式, 需要进行格式转换
if ( DATA_FORMAT_HEX == get_data_format() )
{
hex_2_bcd(buf, buf, 0x04);
}
// 判断输入的时间值是否合法
if ( (buf[0] >0x07) || (buf[1]>0x31)
|| (buf[2] >0x12) || (buf[2] >0x99))
{
ERROR_REPORT;
return APP_DRV_ERR;
}
// 将检查后的数据写入到RTC中
write_RTC_addr( RTC_ADDR_WEEK, 0x04, buf );
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 输入一个RTC的内部地址, 数据长度,源数据的指针, 进行数据的写入动作
input:
rtc_internal_add [in] RTC 模块的内部地址
len [in] 需要读取的数据的字节总数
pbuf [in] 指针 存放读到的数据
output:
0 成功, 非0值失败
func:
制定RTC的内部地址和长度,进行数据的读取
*/
/************************************************************************/
static UINT16 write_RTC_addr(UINT8 rtc_internal_add, UINT8 len, UINT8 *pbuf)
{
UINT8 i;
// 判断输入参数是否正常
if ((rtc_internal_add > RTC_INTERNAL_ADDR_MAX)
|| !len
|| (NULL == pbuf))
{
ERROR_OUTPUT(("wr rtc err!\r\n"));
return APP_DRV_ERR;
}
// Start
i2c_start();
// Send RTC address
send_rtc_addr(I2C_RTC_ADDR, FLAG_WRITE_DATA);
// send start addr and transmission mode
i = rtc_internal_add;
i <<= 0x04; // address high 4 bit
i |= RTC_WRITE_MODE_0; // 0th mode of transmission
i2c_byte_send( i );
// 进行数据的写入过程
for(i=0x00; i<len; i++)
{
i2c_byte_send(pbuf[i]);
}
// Stop
i2c_stop();
return APP_DRV_OK;
}
/************************************************************************/
/* 输入一个RTC的内部地址, 和想要读取的数据的长度,
将数据保存到数据的地址指针保存的地方
input:
rtc_internal_add [in] RTC 模块的内部地址
len [in] 需要读取的数据的字节总数
pbuf [out] 指针 存放读到的数据
output:
0 成功, 非0值失败
func:
制定RTC的内部地址和长度,进行数据的读取
*/
/************************************************************************/
static UINT16 read_RTC_addr(UINT8 rtc_internal_add, UINT8 len, UINT8 *pbuf)
{
UINT8 i,ack;
UINT8 *ptemp;
// 判断输入参数是否正常
if ((rtc_internal_add > RTC_INTERNAL_ADDR_MAX)
|| !len
|| (NULL == pbuf))
{
ERROR_OUTPUT(("rd rtc err!\r\n"));
return APP_DRV_ERR;
}
// Start
i2c_start();
// Send RTC address
send_rtc_addr(I2C_RTC_ADDR, FLAG_WRITE_DATA );
// send start addr and transmission mode
i = rtc_internal_add;
i <<= 0x04; // address high 4 bit
i |= RTC_READ_MODE_4; // 4th mode of transmission
i2c_byte_send( i );
ptemp = pbuf;
// read data
for(i=0x00; i<len; i++)
{
i2c_byte_receive(ptemp+i); // read one byte data
ack = LOW_LEVEL;
if (i == (len -1))
{
ack = HIGH_LEVEL;
}
i2c_read_ack(ack);
}
// i2c stop
i2c_stop();
// return OK!
return APP_DRV_OK;
}
/************************************************************************/
/* 发送 RTC 的设备地址
input:
RTCAddr [in] RTC的设备地址
RWFlag [in] 数据的读写标志
0 表示进行数据的写入动作
1 表示进行数据的读出动作
output:
void
func:
*/
/************************************************************************/
static void send_rtc_addr(UINT8 Addr, UINT8 Flag)
{
UINT8 data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -