?? pmp_rtc_driver.c
字號:
#ifdef EVB_SN_V10
// 如果是在開發(fā)板上, 還需要將日期時間設(shè)置到 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 );
// 將數(shù)據(jù)設(shè)定到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:
使用文件系統(tǒng)的時間
根據(jù)設(shè)定的數(shù)據(jù)格式,進行數(shù)據(jù)的輸出
*/
/************************************************************************/
UINT16 SPMP_RTC_GetH_M_S( Time_Attr_t * pTime_t, UINT16 DataFormat )
{
// 判斷輸入?yún)?shù)是否合法
if (NULL == pTime_t) {
ERROR_REPORT;
return APP_DRV_ERR;
}
// 獲得當前的時間值
tmrNowTimeGet( pTime_t );
// 判斷是否需要進行數(shù)據(jù)格式的轉(zhuǎn)換
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:
使用文件系統(tǒng)的時間,防止有2套時間存在
根據(jù)設(shè)定的數(shù)據(jù)格式,進行數(shù)據(jù)的輸出
*/
/************************************************************************/
UINT16 SPMP_RTC_GetY_M_D_W( Time_Attr_t * pTime_t, UINT16 *pWeek, UINT16 DataFormat )
{
struct RTCdate_t tmp_date;
// 判斷輸入?yún)?shù)是否合法
if ( (NULL == pTime_t ) || ( NULL == pWeek) )
{
ERROR_REPORT;
return APP_DRV_ERR;
}
*pWeek = 0x00;
#ifndef EVB_SN_V10
tmrNowTimeGet( pTime_t ); // 首先獲得 FS time
// 如果輸出的數(shù)據(jù)是 BCD 格式,進行數(shù)據(jù)格式的轉(zhuǎn)換
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 的功能和狀態(tài),將
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 小時模式設(shè)置為 24小時制式
i |= HOUR_12_24_BIT;
write_RTC_addr( RTC_ADDR_CTL2, 0x01, &i );
}
// disable 32K output
SPMP_RTC_Set32KOut( 0x00 );
return;
}
/************************************************************************/
/* 設(shè)定輸出的數(shù)據(jù)的格式
input:
DataFormat [in] 數(shù)據(jù)的格式
DATA_FORMAT_BCD
DATA_FORMAT_HEX
output:
0 成功, 非0值失敗
func:
設(shè)置數(shù)據(jù)的格式
note:
默認采用 BCD 的模式
*/
/************************************************************************/
static UINT16 SPMP_RTC_SetDataFormat( UINT16 DataFormat )
{
rtc_data_format = DATA_FORMAT_BCD;
// 判斷輸入的參數(shù)是否合法, 非法直接返回
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:
根據(jù)設(shè)定的數(shù)據(jù)格式,進行數(shù)據(jù)的輸出
*/
/************************************************************************/
static UINT16 SPMP_RTC_GetNowY_M_D_W( struct RTCdate_t *pDate_t )
{
UINT8 buf[0x04];
// 判斷輸入?yún)?shù)是否合法
if (NULL == pDate_t) {
ERROR_OUTPUT(("get date err!\r\n"));
return APP_DRV_ERR;
}
// 讀RTC 的日期信息
read_RTC_addr(RTC_ADDR_WEEK, 0x04, buf);
// 如果數(shù)據(jù)格式是 HEX, 需要進行數(shù)據(jù)的轉(zhuǎn)換
if (DATA_FORMAT_HEX == get_data_format() )
{
// 將輸入的BCD 數(shù)據(jù)轉(zhuǎn)換為 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;
}
/************************************************************************/
/* 設(shè)定時間
input:
pTime_t [in] 時間的指針
output:
0 成功, 非0值失敗
func:
進行時間的設(shè)定
note:
根據(jù)設(shè)定的數(shù)據(jù)格式,進行數(shù)據(jù)的輸出
*/
/************************************************************************/
static UINT16 SPMP_RTC_SetH_M_S( struct RTCtime_t *pTime_t )
{
UINT8 buf[0x10];
// 判斷輸入?yún)?shù)是否合法
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 模式, 需要進行格式轉(zhuǎn)換
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;
}
// 將檢查后的數(shù)據(jù)寫入到RTC中
write_RTC_addr( RTC_ADDR_SECOND, 0x03, buf );
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 設(shè)置 年月日星期
input:
pDate_t [in] 日期的時間指針
output:
0 成功, 非0值失敗
func:
進行日期星期的設(shè)置
*/
/************************************************************************/
static UINT16 SPMP_RTC_SetY_M_D_W( struct RTCdate_t *pDate_t )
{
UINT8 buf[0x10];
// 判斷輸入?yún)?shù)是否合法
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 模式, 需要進行格式轉(zhuǎn)換
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 模式, 需要進行格式轉(zhuǎn)換
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;
}
// 將檢查后的數(shù)據(jù)寫入到RTC中
write_RTC_addr( RTC_ADDR_WEEK, 0x04, buf );
// 返回成功
return APP_DRV_OK;
}
/************************************************************************/
/* 輸入一個RTC的內(nèi)部地址, 數(shù)據(jù)長度,源數(shù)據(jù)的指針, 進行數(shù)據(jù)的寫入動作
input:
rtc_internal_add [in] RTC 模塊的內(nèi)部地址
len [in] 需要讀取的數(shù)據(jù)的字節(jié)總數(shù)
pbuf [in] 指針 存放讀到的數(shù)據(jù)
output:
0 成功, 非0值失敗
func:
制定RTC的內(nèi)部地址和長度,進行數(shù)據(jù)的讀取
*/
/************************************************************************/
static UINT16 write_RTC_addr(UINT8 rtc_internal_add, UINT8 len, UINT8 *pbuf)
{
UINT8 i;
// 判斷輸入?yún)?shù)是否正常
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 );
// 進行數(shù)據(jù)的寫入過程
for(i=0x00; i<len; i++)
{
i2c_byte_send(pbuf[i]);
}
// Stop
i2c_stop();
return APP_DRV_OK;
}
/************************************************************************/
/* 輸入一個RTC的內(nèi)部地址, 和想要讀取的數(shù)據(jù)的長度,
將數(shù)據(jù)保存到數(shù)據(jù)的地址指針保存的地方
input:
rtc_internal_add [in] RTC 模塊的內(nèi)部地址
len [in] 需要讀取的數(shù)據(jù)的字節(jié)總數(shù)
pbuf [out] 指針 存放讀到的數(shù)據(jù)
output:
0 成功, 非0值失敗
func:
制定RTC的內(nèi)部地址和長度,進行數(shù)據(jù)的讀取
*/
/************************************************************************/
static UINT16 read_RTC_addr(UINT8 rtc_internal_add, UINT8 len, UINT8 *pbuf)
{
UINT8 i,ack;
UINT8 *ptemp;
// 判斷輸入?yún)?shù)是否正常
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;
}
/************************************************************************/
/* 發(fā)送 RTC 的設(shè)備地址
input:
RTCAddr [in] RTC的設(shè)備地址
RWFlag [in] 數(shù)據(jù)的讀寫標志
0 表示進行數(shù)據(jù)的寫入動作
1 表示進行數(shù)據(jù)的讀出動作
output:
void
func:
*/
/************************************************************************/
static void send_rtc_addr(UINT8 Addr, UINT8 Flag)
{
UINT8 data;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -