Skip to content

Instantly share code, notes, and snippets.

@charleskeepax
Created November 22, 2010 11:33
Show Gist options
  • Save charleskeepax/709848 to your computer and use it in GitHub Desktop.
Save charleskeepax/709848 to your computer and use it in GitHub Desktop.
Blackfin Deep Sleep with RTC Stopwatch Wakeup
// ISTAT Register Bit Definitions
#define RTC_INT_CLEAR 0x807F
#define RTC_WRITE_COMPLETE 0x8000
// PREN Register Bit Definitions
#define RTC_PRESCALER_ENABLE 0x0001
void Init_RTC(void)
{
// Ensure clock is running at 1Hz by setting the prescalar
*pRTC_ISTAT = RTC_WRITE_COMPLETE; // Clear write complete
*pRTC_PREN = RTC_PRESCALER_ENABLE;
// Wait for write to complete
while (!(*pRTC_ISTAT&RTC_WRITE_COMPLETE)) {};
// Perform setup of the RTC
*pRTC_ISTAT = RTC_WRITE_COMPLETE; // Clear write complete
*pRTC_STAT = 0; // Reset counter
*pRTC_SWCNT = 0; // Make sure stopwatch is off
*pRTC_ICTL = 0; // Deactivate all interrupt events
// Wait for write to complete
while (!(*pRTC_ISTAT&RTC_WRITE_COMPLETE)) {};
}
// PLL Register Bit Definitions
#define PLL_PWDN 0x0020
#define PLL_BYPASS 0x0100
// IWR Register Bit Definitions
#define IWR_PLLWAKEUP 0x0001
#define IWR_RTCWAKEUP 0x0080
void Deep_Sleep(void) {
unsigned int iReg;
// Disable interrupts
iReg = cli();
// Program to wakeup only on an RTC event
*pSIC_IWR = IWR_RTCWAKEUP;
// Activate Deep Sleep, i.e. power down all internal clocks
*pPLL_CTL = *pPLL_CTL|PLL_PWDN;
// Idle processor to perform PLL programming
idle();
// Only wake from idle for PLL event
*pSIC_IWR = IWR_PLLWAKEUP;
// Reactivate the PLL to return to normal clock speed
*pPLL_CTL = *pPLL_CTL&(~PLL_BYPASS);
// Idle processor to perform PLL programming
idle();
// Enable interrupts
sti(iReg);
}
// RTC_ICTL Register Bit Definitions
#define RTC_STOPWATCH_IE 0x0001
#define RTC_ALARM_IE 0x0002
#define RTC_ONEHZTICK_IE 0x0004
// Setup the RTC
Init_RTC();
// Lets wait 5 seconds before we do anything
while (*pRTC_STAT < 5) {};
// Program stopwatch with 5 second countdown and enable the interrupt
*pRTC_ISTAT = RTC_INT_CLEAR; // Clear pending interrupt flags
*pRTC_SWCNT = 5;
*pRTC_ICTL = RTC_STOPWATCH_IE;
while (!(*pRTC_ISTAT & RTC_WRITE_COMPLETE)) {};
// Enter Deep Sleep Mode
Deep_Sleep();
// Program alarm for 15 seconds from boot and enable the interrupt
*pRTC_ISTAT = RTC_INT_CLEAR; // Clear pending interrupt flags
*pRTC_ALARM = 15;
*pRTC_ICTL = RTC_ALARM_IE;
while (!(*pRTC_ISTAT & RTC_WRITE_COMPLETE)) {};
// Enable the 1Hz interrupt
*pRTC_ISTAT = RTC_INT_CLEAR; // Clear pending interrupt flags
*pRTC_ICTL = RTC_ONEHZTICK_IE;
while (!(*pRTC_ISTAT & RTC_WRITE_COMPLETE)) {};
// Clear 1Hz flag
*pRTC_ISTAT = RTC_INT_CLEAR; // Clear pending interrupt flags
@charleskeepax
Copy link
Author

If you found your way here you might want to check out the article on my blog that goes with this code:
http://www.charles-keepax.co.uk/blog/BlackfinDeepSleep.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment