//hibernate example.
int
main(void)
{
unsigned long ulIdx;
unsigned long ulStatus = 0;
unsigned long ulHibernateCount = 0;
tContext sContext;
tRectangle sRect;
//
// The FPU should be enabled because some compilers will use floating-
// point registers, even for non-floating-point code. If the FPU is not
// enabled this will cause a fault. This also ensures that floating-
// point operations could be added to this application and would work
// correctly and use the hardware floating-point unit. Finally, lazy
// stacking is enabled for interrupt handlers. This allows floating-
// point instructions to be used within interrupt handlers, but at the
// expense of extra stack usage.
//
FPUEnable();
FPULazyStackingEnable();
//
// Set the clocking to run directly from the crystal.
// 设置时钟运行直接从晶体
ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
// 设置时钟运行在50MHZ
//ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
// SYSCTL_OSC_MAIN);
//
// Initialize the UART.
// 初始化UART
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
UARTStdioInit(0);
//
// Initialize the OLED display
// 初始化OLED显示屏
CFAL96x64x16Init();
//
// Initialize the graphics context.
// 初始化图形环境
GrContextInit(&sContext, &g_sCFAL96x64x16);
//
// Fill the top 24 rows of the screen with blue to create the banner.
// 填充蓝色屏幕的上方24行创建的标题
sRect.sXMin = 0;
sRect.sYMin = 0;
sRect.sXMax = GrContextDpyWidthGet(&sContext) - 1;
sRect.sYMax = 9;
GrContextForegroundSet(&sContext, ClrDarkBlue);
GrRectFill(&sContext, &sRect);
//
// Change foreground for white text.
// 更改为白色文本的前景
GrContextForegroundSet(&sContext, ClrWhite);
//
// Put the application name in the middle of the banner.
// 把应用程序的名称放到标题的中间
GrContextFontSet(&sContext, g_pFontFixed6x8);
GrStringDrawCentered(&sContext, "hibernate", -1,
GrContextDpyWidthGet(&sContext) / 2, 4, 0);
//
// Initialize the buttons driver
// 初始化按钮驱动程序
ButtonsInit();
//
// Set up systick to generate interrupts at 100 Hz.
//设置SysTick 100HZ 产生中断,
ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100);
ROM_SysTickIntEnable();
ROM_SysTickEnable();
//
// Enable the Hibernation module.
// 使能休眠模块
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
//
// Print wake cause message on display.
// 在显示屏上打印唤醒原因消息
GrStringDrawCentered(&sContext, "Wake due to:", -1,
GrContextDpyWidthGet(&sContext) / 2, ROW(2) + 4,
true);
//
// Check to see if Hibernation module is already active, which could mean
// that the processor is waking from a hibernation.
// 请检查如果休眠模块已经被激活,这可能意味着,处理器从休眠中醒来
if(HibernateIsActive())
{
//
// Read the status bits to see what caused the wake.
// 读取状态位,看看有什么引起唤醒
ulStatus = HibernateIntStatus(0);
HibernateIntClear(ulStatus);
//
// Wake was due to the push button.
// 由于按钮唤醒
if(ulStatus & HIBERNATE_INT_PIN_WAKE)
{
GrStringDrawCentered(&sContext, "BUTTON", -1,
GrContextDpyWidthGet(&sContext) / 2,
ROW(3) + 4, true);
}
//
// Wake was due to RTC match
// 由于RTC的匹配唤醒
else if(ulStatus & HIBERNATE_INT_RTC_MATCH_0)
{
GrStringDrawCentered(&sContext, "TIMEOUT", -1,
GrContextDpyWidthGet(&sContext) / 2,
ROW(3) + 4, true);
}
//
// Wake is due to neither button nor RTC, so it must have been a hard
// reset.
// 由于既不是按钮也不是RTC唤醒,所以它必须被硬复位
else
{
GrStringDrawCentered(&sContext, "RESET", -1,
GrContextDpyWidthGet(&sContext) / 2,
ROW(3) + 4, true);
}
//
// If the wake is due to button or RTC, then read the first location
// from the battery backed memory, as the hibernation count
// 如果唤醒是由于按钮或RTC,然后从电池备份的存储器读取第一的位置,作为休眠计数
if(ulStatus & (HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATCH_0))
{
HibernateDataGet(&ulHibernateCount, 1);
}
}
//
// Enable the Hibernation module. This should always be called, even if
// the module was already enabled, because this function also initializes
// some timing parameters.
// 启用休眠模块。这应始终被调用,即使已经启用的模块,因为这个函数还初始化一些时序参数
HibernateEnableExpClk(ROM_SysCtlClockGet());
//
// If the wake was not due to button or RTC match, then it was a reset.
// 如果不是因为按钮或RTC匹配唤醒,那么它是一个复位
if(!(ulStatus & (HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATCH_0)))
{
//
// Configure the module clock source.
// 配置模块的时钟源
HibernateClockSelect(HIBERNATE_CLOCK_SEL_DIV128);
//
// Finish the wake cause message.
// 完成唤醒导致消息
GrStringDrawCentered(&sContext, "RESET", -1,
GrContextDpyWidthGet(&sContext) / 2,
ROW(3) + 4, true);
//
// Wait a couple of seconds in case we need to break in with the
// debugger.
// 等待几秒钟的情况下,我们需要分开调试
SysTickWait(3 * 100);
//
// Allow time for the crystal to power up. This line is separated from
// the above to make it clear this is still needed, even if the above
// delay is removed.
// 上电晶体允许时间 。这条线是从上面的分开,要清楚这仍然需要被删除,即使上述延迟
SysTickWait(15);
}
//
// Print the count of times that hibernate has occurred.
// 打印,休眠已发生的次数计数
usnprintf(cBuf, sizeof(cBuf), "Hib count=%4u", ulHibernateCount);
GrStringDrawCentered(&sContext, cBuf, -1,
GrContextDpyWidthGet(&sContext) / 2,
ROW(1) + 4, true);
//
// Wait for user to release the button.
// 等待用户释放按钮
while(bSelectPressed)
{
}
//
// If hibernation count is very large, it may be that there was already
// a value in the hibernate memory, so reset the count.
// 如果休眠数是非常大的的,它可能已经有一个休眠内存中的值,所以复位计数
ulHibernateCount = (ulHibernateCount > 10000) ? 0 : ulHibernateCount;
//
// Increment the hibernation count, and store it in the battery backed
// memory.
// 增加休眠计数,并储存在电池供电的存储器
ulHibernateCount++;
HibernateDataSet(&ulHibernateCount, 1);
//
// Clear and enable the RTC and set the match registers to 5 seconds in the
// future. Set both to same, though they could be set differently, the
// first to match will cause a wake.
// 清除和使能RTC并且将设置匹配寄存器为5秒。设置都相同,但他们有可能设置不同,第一个匹配将导致唤醒
HibernateRTCSet(0);
HibernateRTCEnable();
HibernateRTCMatch0Set(5);
//
// Set wake condition on pin or RTC match. Board will wake when 5 seconds
// elapses, or when the button is pressed.
// 设置管脚唤醒条件或RTC匹配。每过去5秒过后将会唤醒,或当按下按钮
HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC);