Skip to content

Instantly share code, notes, and snippets.

@jotux
Created July 27, 2014 03:27
Show Gist options
  • Save jotux/2f7d51acf920e22f0dcf to your computer and use it in GitHub Desktop.
Save jotux/2f7d51acf920e22f0dcf to your computer and use it in GitHub Desktop.
fram_hibernate.c
#include <msp430.h>
#include <stdint.h>
#include <stddef.h>
#include "hw.h"
#include "hardware_init.h"
#define RAM_LOC 0x1C00
#define RAM_SIZE 0x800
#define SFR_LOC 0x0200
#define SFR_SIZE 0x013F
#pragma DATA_SECTION(f_from,".fram_data")
volatile uint8_t* f_from;
#pragma DATA_SECTION(f_to,".fram_data")
volatile uint8_t* f_to;
#pragma DATA_SECTION(f_mem_cnt,".fram_data")
volatile size_t f_mem_cnt;
#pragma DATA_SECTION(f_asleep,".fram_data")
volatile uint8_t f_asleep;
#pragma DATA_SECTION(f_ram_backup,".fram_data")
volatile uint8_t f_ram_backup[RAM_SIZE];
#pragma DATA_SECTION(f_sfr_backup,".fram_data")
volatile uint8_t f_sfr_backup[SFR_SIZE];
void Delay(uint32_t time)
{
uint32_t i = 0;
for(i = 0;i < time;i++)
{
__delay_cycles(1000);
}
}
uint8_t led_cnt = 0;
void LedFlash(void)
{
while (led_cnt++ < 5)
{
uint8_t j = 0;
for (j = 0;j < led_cnt;j++)
{
IO_SET(LED1,GPIO_HIGH);
Delay(250);
IO_SET(LED1,GPIO_LOW);
Delay(250);
}
IO_SET(LED1,GPIO_LOW);
Delay(1000);
for (j = 0;j < led_cnt;j++)
{
IO_SET(LED2,GPIO_HIGH);
Delay(250);
IO_SET(LED2,GPIO_LOW);
Delay(250);
}
IO_SET(LED2,GPIO_LOW);
Delay(1000);
}
led_cnt = 0;
}
void Hibernate(void)
{
// save sram
memcpy((uint32_t*)f_ram_backup,(uint32_t*)RAM_LOC,RAM_SIZE);
// save sfr
memcpy((uint32_t*)f_sfr_backup,(uint32_t*)SFR_LOC,SFR_SIZE);
f_asleep = 1;
}
void Restore(void)
{
f_asleep = 0;
// restore sram
f_to = (uint8_t*)RAM_LOC;
f_from = (uint8_t*)f_ram_backup;
f_mem_cnt = RAM_SIZE;
while(--f_mem_cnt != 0)
{
*f_to++ = *f_from++;
}
// restore SFR
f_to = (uint8_t*)SFR_LOC;
f_from = (uint8_t*)f_sfr_backup;
f_mem_cnt = SFR_SIZE;
while(--f_mem_cnt != 0)
{
*f_to++ = *f_from++;
}
}
#pragma vector=PORT4_VECTOR
__interrupt void Sw1Interrupt(void)
{
IO_INT_FLAG(SW1,GPIO_INT_CLEAR);
Hibernate();
while(1);
}
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
PM5CTL0 &= ~LOCKLPM5;
IO_DIRECTION(SW1,GPIO_INPUT);
IO_PULL(SW1,GPIO_PULL_UP);
IO_INT_EDGE(SW1,GPIO_FALLING_EDGE);
IO_INT_FLAG(SW1,GPIO_INT_CLEAR);
IO_INT_EN(SW1,GPIO_ENABLE);
IO_DIRECTION(SW2,GPIO_INPUT);
IO_DIRECTION(LED1,GPIO_OUTPUT);
IO_SET(LED1,GPIO_LOW);
IO_DIRECTION(LED2,GPIO_OUTPUT);
IO_SET(LED2,GPIO_LOW);
_enable_interrupts();
if (f_asleep == 1)
{
Restore();
}
while(1)
{
LedFlash();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment