⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmic_rtc.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
字号:
//------------------------------------------------------------------------------
//
//  Copyright (C) 2005, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//
//  File:  pmic_rtc.cpp
//
//  This file contains the PMIC rtc SDK interface that is used by applications
//  and other drivers to access registers of the MC13783 RTC.
//
//-----------------------------------------------------------------------------

#include <windows.h>
#include "mxarm11_macros.h"
#include "pmic_ioctl.h"
#include "regs.h"
#include "regs_regulator.h"
#include "pmic_rtc.h"
#include "pmic_basic_types.h"
#include "pmic_lla.h"
//-----------------------------------------------------------------------------
// External Functions

//-----------------------------------------------------------------------------
// External Variables

//-----------------------------------------------------------------------------
// Defines

//-----------------------------------------------------------------------------
// Types

//-----------------------------------------------------------------------------
// Global Variables
extern HANDLE hPMI;

#ifdef DEBUG

// Debug zone bit positions
#define ZONEID_ERROR            0
#define ZONEID_WARN             1
#define ZONEID_INIT             2
#define ZONEID_FUNC             3
#define ZONEID_INFO             4

// Debug zone masks
#define ZONEMASK_ERROR      (1 << ZONEID_ERROR)
#define ZONEMASK_WARN           (1 << ZONEID_WARN)
#define ZONEMASK_INIT           (1 << ZONEID_INIT)
#define ZONEMASK_FUNC       (1 << ZONEID_FUNC)
#define ZONEMASK_INFO           (1 << ZONEID_INFO)

// Debug zone args to DEBUGMSG
#define ZONE_ERROR              DEBUGZONE(ZONEID_ERROR)
#define ZONE_WARN               DEBUGZONE(ZONEID_WARN)
#define ZONE_INIT               DEBUGZONE(ZONEID_INIT)
#define ZONE_FUNC               DEBUGZONE(ZONEID_FUNC)
#define ZONE_INFO               DEBUGZONE(ZONEID_INFO)

extern DBGPARAM dpCurSettings;
// Named event for interrupt registration
static TCHAR *gEventNamePri = TEXT("EVENT_RTC");
static TCHAR *gRTCEventName;
#endif  // DEBUG
//------------------------------------------------------------------------------
// Global Variables
//These macro define some default information of RTC
#define ORIGINYEAR       1980                  // the begin year
#define MAXYEAR          (ORIGINYEAR + 100)    // the maxium year
#define JAN1WEEK         2                     // Jan 1 1980 is a Tuesday
#define GetDayOfWeek(X) (((X-1)+JAN1WEEK)%7)

#define TYPE_TIME		0
#define TYPE_ALRM		1

static const UINT8 monthtable[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static const UINT8 monthtable_leap[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static HANDLE hIntrEventtodaPmic;
static HANDLE hPmicTODalarmThread;
//static BOOL bTODalarmTerminate;
static BOOL PmicTodAlarmThreadProc(LPVOID lpParam);
SYSTEMTIME default_time = {2003,1,3,1,0,0,0,0};  //Jan 1, 2003, Wednesday
//-----------------------------------------------------------------------------
// Local Variables

//-----------------------------------------------------------------------------
// Local Functions
static int IsLeapYear(int Year)
{
    int Leap;

    Leap = 0;
    if ((Year % 4) == 0) {
        Leap = 1;
        if ((Year % 100) == 0) {
            Leap = (Year%400) ? 0 : 1;
        }
    }

    return (Leap);
}


// Calculate the total number of days in lpTime, since Jan 1, ORIGINYEAR
int CalculateDays(SYSTEMTIME* lpTime)
{
	UINT8 *month_tab;
	int days, year, month;
	int i;

	days = lpTime->wDay;
	month = lpTime->wMonth;
	year = lpTime->wYear;

	// Calculate number of days spent so far from beginning of this year
	month_tab = (UINT8 *)(IsLeapYear(year) ? monthtable_leap : monthtable);

	for (i = 0; i < month - 1; i++) 
	{
		days += month_tab[i];
	}

	// calculate the number of days in the previous years
	for (i = ORIGINYEAR; i < year; i++)
	{
		days += (IsLeapYear(i) ? 366 : 365);
	}

	return days;
}

// Calculate the number of seconds in lpTime since the beginning of the day
int CalculateSeconds(SYSTEMTIME* lpTime)
{
	return (lpTime->wHour * 60 * 60 + lpTime->wMinute * 60 
					+ lpTime->wSecond);
}

// split total days since Jan 1, ORIGINYEAR into year, month and day
PMIC_STATUS ConvertDays(int days, SYSTEMTIME* lpTime)
{
	int dayofweek, month, year;
	UINT8 *month_tab;

	//Calculate current day of the week
	dayofweek = GetDayOfWeek(days);

	year = ORIGINYEAR;

	while (days > 365)
	{
		if (IsLeapYear(year))
		{
			if (days > 366)
			{
				days -= 366;
				year += 1;
			}
		}
		else
		{
			days -= 365;
			year += 1;
		}
	}


    // Determine whether it is a leap year
	month_tab = (UINT8 *)((IsLeapYear(year))? monthtable_leap : monthtable);

    for (month=0; month<12; month++)
    {
        if (days <= month_tab[month])
            break;
        days -= month_tab[month];
    }
    
	month += 1;
    
	lpTime->wDay = days;
    lpTime->wDayOfWeek = dayofweek;
    lpTime->wMonth = month;
    lpTime->wYear = year;

	return PMIC_SUCCESS;
}

// convert time of day in seconds to hour, minute and seconds
PMIC_STATUS ConvertSeconds(int seconds, SYSTEMTIME* lpTime)
{
	int minutes = 0, hours = 0;

	if(seconds < 86400)
	{
		if (seconds >= 60)
		{
			minutes = (int) seconds / 60;
			seconds -= (minutes * 60);
			if (minutes >= 60)
			{
				hours = (int) minutes / 60;
				minutes -= (hours * 60);
			}
		}
	}
	else 
	{
		ERRORMSG(TRUE, (_T("TOD in sec is wrong(seconds > 86399) %d"), seconds));
		return PMIC_ERROR;
	}

	lpTime->wHour = hours;
	lpTime->wMinute = minutes;
	lpTime->wSecond = seconds;

	return PMIC_SUCCESS;
}

// set the given time & day into the register pair indicated by type
PMIC_STATUS SetTime(int type, SYSTEMTIME* lpTime)
{
    PMIC_PARAM_LLA_WRITE_REG param;
	int days, seconds;

	// calculate time of day in seconds 
	seconds = CalculateSeconds(lpTime);
	if(seconds > 86399)
		return PMIC_ERROR;

	//Set Reg TimeOftheDay TOD -> Hours, Min , Sec : a 17 bit time of day (TOD)

    param.addr = (type == TYPE_TIME) ? MC13783_RTC_TM_ADDR : MC13783_RTC_ALM_ADDR;
    param.data = seconds;
	param.mask = 0xFFFFFFFF;
			 
	if(!DeviceIoControl(hPMI, PMIC_IOCTL_LLA_WRITE_REG, &param,
			sizeof(param), NULL, 0, NULL, NULL))
		return PMIC_ERROR;

	// Calculate days.
	days = CalculateDays(lpTime);

	//Set Reg Day -> years, months ,  days :the 15 bit DAY counter
    param.addr = (type == TYPE_TIME) ? MC13783_RTC_DAY_ADDR : MC13783_RTC_DAY_ALM_ADDR;
    param.data = days;
	    
	if(!DeviceIoControl(hPMI, PMIC_IOCTL_LLA_WRITE_REG, &param,
			sizeof(param), NULL, 0, NULL, NULL))
		return PMIC_ERROR;	
	
	return PMIC_SUCCESS;
}

// get the time and day from the register pair indicated by type
PMIC_STATUS GetTime(int type, SYSTEMTIME* lpTime)
{
	UINT32 seconds, days;
	UINT32 addr;

	addr = (type == TYPE_TIME) ? MC13783_RTC_TM_ADDR : MC13783_RTC_ALM_ADDR;

	if (!DeviceIoControl(hPMI, PMIC_IOCTL_LLA_READ_REG, &addr, sizeof(addr),
			&seconds, sizeof(seconds), NULL, NULL))
		return PMIC_ERROR;
    
	addr = (type == TYPE_TIME) ? MC13783_RTC_DAY_ADDR : MC13783_RTC_DAY_ALM_ADDR;

	if (!DeviceIoControl(hPMI, PMIC_IOCTL_LLA_READ_REG, &addr, sizeof(addr),
			&days, sizeof(days), NULL, NULL))
		return PMIC_ERROR;

	//convert seconds to hours , minutes and seconds of the day
	if (ConvertSeconds(seconds, lpTime) != PMIC_SUCCESS)
		return PMIC_ERROR;

	// convert days to year, month and day
	if (ConvertDays(days, lpTime) != PMIC_SUCCESS)
		return PMIC_ERROR;

	return PMIC_SUCCESS;	
}


//------------------------------------------------------------------------------
//
// Function: pmicRTCSetSystemTime
//
// This function sets the current system time and date.
//
// Parameters:
//      Pointer to a SYSTEMTIME structure that contains the current system date and time. 
//
// Returns:
//      PMIC_STATUS.
//
//------------------------------------------------------------------------------
PMIC_STATUS pmicRTCSetSystemTime(SYSTEMTIME* lpSystemTime)
{
	return SetTime(TYPE_TIME, lpSystemTime);
}

//------------------------------------------------------------------------------
//
// Function: pmicRTCGetSystemTime
//
// This function retrieves the current system time and date.
//
// Parameters:
//      lpSystemTime
//		Pointer to a SYSTEMTIME structure to receive the current system date 
// Returns:
//      PMIC_STATUS.
//
//------------------------------------------------------------------------------
PMIC_STATUS pmicRTCGetSystemTime(SYSTEMTIME* lpSystemTime)
{
	return GetTime(TYPE_TIME, lpSystemTime);	
}

//------------------------------------------------------------------------------
//
// Function: pmicRTCSetAlarmTime
//
// This function sets the alarm time and date
//
// Parameters:
//      lpAlarmTime 
//	 	Pointer to a SYSTEMTIME structure that contains thealarm date and time. 
//
// Returns:
//      PMIC_STATUS.
//
//------------------------------------------------------------------------------
PMIC_STATUS pmicRTCSetAlarmTime(SYSTEMTIME* lpAlarmTime)
{
	return SetTime(TYPE_ALRM, lpAlarmTime);
}

//------------------------------------------------------------------------------
//
// Function: pmicRTCGetAlarmTime
//
// This function retrieves the alarm time and date
//
// Parameters:
//      llpAlarmTime 
//		 Pointer to a SYSTEMTIME structure to receive the alarm date and time. 
//
// Returns:
//      PMIC_STATUS.
//
//------------------------------------------------------------------------------
PMIC_STATUS pmicRTCGetAlarmTime(SYSTEMTIME* lpAlarmTime)
{
	return GetTime(TYPE_ALRM, lpAlarmTime);	
}

//------------------------------------------------------------------------------
//
// Function: pmicRTCRegisterAlarmCallback
//
// This function registers alarm callback function.
//
// Parameters:
//      alarmCB
//		Alarm callback function. 
//
// Returns:
//      PMIC_STATUS.
//
//------------------------------------------------------------------------------
PMIC_STATUS pmicRTCRegisterAlarmCallback(RTC_ALARM_CB alarmCB)
{
	PMIC_STATUS status=PMIC_ERROR;
    // create event for PMIC interrupt signaling
    //      pEventAttributes = NULL (must be NULL)
    //      bManualReset = FALSE => resets automatically to nonsignaled
    //                              state after waiting thread released
    //      bInitialState = FALSE => initial state is non-signaled
    //      lpName = EVENT_RTC_PRI => object created with a name


    hIntrEventtodaPmic = CreateEvent(NULL, FALSE, FALSE, TEXT("EVENT_RTC_PRI"));

    // check if CreateEvent failed
    if (hIntrEventtodaPmic == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s(): CreateEvent failed!\r\n"),
            __WFUNCTION__));
	return status;
    }
	

 // Register for PMIC ADC done interrupts.
    if (PmicInterruptRegister(PMIC_MC13783_INT_TODAI, TEXT("EVENT_RTC_PRI"))
        != PMIC_SUCCESS)
    {
        ERRORMSG(1, (_T("Pmic TODAlarm RtcInterruptRegister failed\r\n")));
        return status;
    }

	// Make sure RTC interrupt is unmasked
    if (PmicInterruptEnable(PMIC_MC13783_INT_TODAI) != PMIC_SUCCESS)
    {
        ERRORMSG(TRUE, (_T("PmicRTCInit:  PmicInterruptEnable failed\r\n")));
        goto cleanUp;
    }
 
  
    bTODalarmTerminate = FALSE;

    hPmicTODalarmThread = CreateThread(NULL, 0,
                                  (LPTHREAD_START_ROUTINE)PmicTodAlarmThreadProc,
                                  (LPVOID)alarmCB, 0, NULL);
    if (!hPmicTODalarmThread)
    {
		DEBUGMSG(ZONE_ERROR,(TEXT("PmicIsrThreadStart: CreateThread failed\r\n")));
		PmicInterruptDeregister(PMIC_MC13783_INT_TODAI);
		goto cleanUp;	
    }

    status = PMIC_SUCCESS;

cleanUp:
    if (status != PMIC_SUCCESS)PmicInterruptDeregister(PMIC_MC13783_INT_TODAI);

	 return status;
}


//------------------------------------------------------------------------------
//
// Function: pmicRTCCancelAlarm
//
// This function cancels the alarm time and date setting.
//
// Parameters:
//      None 
//
// Returns:
//      PMIC_STATUS.
//
//------------------------------------------------------------------------------
PMIC_STATUS pmicRTCCancelAlarm()
{

    PmicInterruptDeregister(PMIC_MC13783_INT_TODAI);
    bTODalarmTerminate = TRUE; 
    CloseHandle(hPmicTODalarmThread);
	
	 return PMIC_SUCCESS;
}

//------------------------------------------------------------------------------
//
// Function: PmicIsrThreadProc
//
// ISR Thread Process that launches IST loop.
//
// Parameters:
//      None.
//
// Returns:
//      TRUE if success, FALSE if failure.
//
//------------------------------------------------------------------------------
static BOOL
PmicTodAlarmThreadProc(LPVOID lpParam)
{
   RTC_ALARM_CB p =  (RTC_ALARM_CB) lpParam;

   SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

    while(!bTODalarmTerminate)
    {
        if (WaitForSingleObject(hIntrEventtodaPmic, INFINITE) == WAIT_OBJECT_0)
		p();
    }

    ExitThread(TRUE);

    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -