#include <string.h>
#if ! (BSP430_PLATFORM_BUTTON0 - 0)
#error No button available on this platform
#endif
typedef struct sCommand {
char cmd;
const char * description;
} sCommand;
const sCommand commands[] = {
#define CMD_MODE_ACTIVE 'a'
{ CMD_MODE_ACTIVE, "Remain in active mode while idle" },
#define CMD_MODE_LPM0 '0'
{ CMD_MODE_LPM0, "Set mode to enter LPM0" },
#define CMD_MODE_LPM1 '1'
{ CMD_MODE_LPM1, "Set mode to enter LPM1" },
#define CMD_MODE_LPM2 '2'
{ CMD_MODE_LPM2, "Set mode to enter LPM2" },
#define CMD_MODE_LPM3 '3'
{ CMD_MODE_LPM3, "Set mode to enter LPM3" },
#define CMD_MODE_LPM4 '4'
{ CMD_MODE_LPM4, "Set mode to enter LPM4" },
#ifdef BSP430_PMM_ENTER_LPMXp5_NI
#define CMD_MODE_LPM3p5 '5'
{ CMD_MODE_LPM3p5, "Set mode to enter LPM3.5" },
#define CMD_MODE_LPM4p5 '6'
{ CMD_MODE_LPM4p5, "Set mode to enter LPM4.5" },
#endif
#define CMD_HOLD_SERIAL 's'
{ CMD_HOLD_SERIAL, "Toggle whether serial is placed on hold during LPM" },
#define CMD_HOLD_CLOCK 'u'
{ CMD_HOLD_CLOCK, "Toggle whether uptime clock is placed on hold during LPM" },
#define CMD_HELP '?'
{ CMD_HELP, "Display help" },
#define CMD_STATE '='
{ CMD_STATE, "Display system state (clock speeds, etc.)" },
#define CMD_SLEEP '$'
{ CMD_SLEEP, "Enter sleep mode" },
#if (BSP430_PMM_SUPPORTS_COREV - 0)
#define CMD_COREV_INCR '>'
{ CMD_COREV_INCR, "Increment core voltage" },
#define CMD_COREV_DECR '<'
{ CMD_COREV_DECR, "Decrement core voltage" },
#endif
};
typedef struct sState {
unsigned int lpm_bits;
const char * lpm_description;
int hold_serial;
int hold_clock;
} sState;
volatile int button;
static int
void * context,
int idx)
{
(void)cb;
(void)context;
(void)idx;
++button;
}
};
char rx_buffer[16];
char * volatile rx_head;
char * volatile rx_tail;
static int
consume_rx_ni ()
{
int rc;
if (rx_head == rx_tail) {
return -1;
}
rc = *rx_tail++;
if (rx_tail > (rx_buffer + sizeof(rx_buffer) / sizeof(*rx_buffer))) {
rx_tail = rx_buffer;
}
return rc;
}
static int
consume_rx ()
{
int rc;
rc = consume_rx_ni();
return rc;
}
static int
void * context)
{
if (rx_head > (rx_buffer + sizeof(rx_buffer) / sizeof(*rx_buffer))) {
rx_head = rx_buffer;
}
if (rx_head == rx_tail) {
(void)consume_rx_ni;
}
}
};
void main ()
{
int b0pin;
sState state;
#if (BSP430_MODULE_SYS - 0)
unsigned long reset_causes = 0;
unsigned int reset_flags = 0;
#endif
#if (BSP430_MODULE_SYS - 0)
{
unsigned int sysrstiv;
reset_causes |= 1UL << (sysrstiv / 2);
}
#ifdef BSP430_PMM_ENTER_LPMXp5_NI
PMMCTL0_H = PMMPW_H;
PM5CTL0 = 0;
PMMCTL0_H = 0;
}
#endif
}
#endif
#if APP_CONFIGURE_PORTS_FOR_LPM
#endif
cprintf(
"\napplpm " __DATE__
" " __TIME__
"\n");
#if (BSP430_MODULE_SYS - 0)
cprintf(
"System reset bitmask %lx; causes:\n", reset_causes);
{
int bit = 0;
while (bit < (8 * sizeof(reset_causes))) {
if (reset_causes & (1UL << bit)) {
}
++bit;
}
}
}
}
}
}
#endif
#if (BSP430_PORT_SUPPORTS_REN - 0)
#endif
rx_head = rx_tail = rx_buffer;
*rx_head++ = CMD_MODE_ACTIVE;
*rx_head++ = CMD_STATE;
memset(&state, 0, sizeof(state));
#if 1 && (BSP430_PMM_SUPPORTS_SVSM - 0)
#endif
while (1) {
int enter_sleep = 0;
unsigned long int sleep_utt;
unsigned long int wake_utt;
do {
int c;
while (0 <= ((c = consume_rx()))) {
const sCommand * cmdp = commands;
const sCommand * const commands_end = commands + sizeof(commands) / sizeof(*commands);
while ((cmdp < commands_end) && (cmdp->cmd != c)) {
++cmdp;
}
if (cmdp->cmd == c) {
cputs(cmdp->description);
switch (cmdp->cmd) {
case CMD_MODE_ACTIVE:
state.lpm_bits = 0;
state.lpm_description = "Active";
break;
case CMD_MODE_LPM0:
state.lpm_description = "LPM0";
break;
case CMD_MODE_LPM1:
state.lpm_description = "LPM1";
break;
case CMD_MODE_LPM2:
state.lpm_description = "LPM2";
break;
case CMD_MODE_LPM3:
state.lpm_description = "LPM3";
break;
case CMD_MODE_LPM4:
state.lpm_description = "LPM4";
break;
#ifdef BSP430_PMM_ENTER_LPMXp5_NI
case CMD_MODE_LPM3p5:
state.lpm_description = "LPM3.5";
break;
case CMD_MODE_LPM4p5:
state.lpm_description = "LPM4.5";
break;
#endif
case CMD_HELP: {
cmdp = commands;
while (cmdp < commands_end) {
cprintf(
"\t%c : %s\n", cmdp->cmd, cmdp->description);
++cmdp;
}
break;
}
case CMD_STATE:
cprintf(
"Selected idle state: %s\n", state.lpm_description);
cprintf(
"Clocks will %s\n", state.hold_clock ?
"freeze" :
"run");
cprintf(
"Serial will %s\n", state.hold_serial ?
"be held" :
"be active");
#if (BSP430_PMM_SUPPORTS_COREV - 0)
cprintf(
"Core voltage level %d, SVSMHCTL %04x SVSMLCTL %04x\n",
#endif
#ifdef BSP430_PMM_ENTER_LPMXp5_NI
#else
cprintf(
"LPM X.5 is NOT supported\n");
#endif
break;
case CMD_HOLD_SERIAL:
state.hold_serial = ! state.hold_serial;
break;
case CMD_HOLD_CLOCK:
state.hold_clock = ! state.hold_clock;
break;
case CMD_SLEEP:
enter_sleep = 1;
break;
#if (BSP430_PMM_SUPPORTS_COREV - 0)
case CMD_COREV_INCR:
case CMD_COREV_DECR: {
int delta = 0;
int rc = 0;
do {
if ((cmdp->cmd == CMD_COREV_INCR) && (level < PMMCOREV_3)) {
delta = 1;
}
if ((cmdp->cmd == CMD_COREV_DECR) && (level >
PMMCOREV_0)) {
delta = -1;
}
if (0 != delta) {
}
} while (0);
if (0 == delta) {
cprintf(
"Core voltage at limit\n");
} else {
cprintf(
"Core voltage adjusted %d to %d rv %d\n", delta, PMMCTL0 & PMMCOREV_3, rc);
}
cprintf(
"PMM: CTL0 %04x CTL1 %04x\n", PMMCTL0, PMMCTL1);
break;
}
#endif
}
} else {
cprintf(
"Unrecognized command: %c\n", c);
}
}
} while (! enter_sleep);
cprintf(
"Entering idle mode at %lu: %s\n", sleep_utt, state.lpm_description);
cprintf(
"NOTE: Will use LPMx.5: press button to exit\n");
}
if (state.hold_clock) {
}
if (state.hold_serial) {
cprintf(
"Disabling serial; press button to wake\n\n");
}
} else {
}
if (0 == state.lpm_bits) {
button = 0;
while ((rx_head == rx_tail) && (! button)) {
}
} else {
#ifdef BSP430_PMM_ENTER_LPMXp5_NI
}
#endif
}
if (state.hold_serial) {
}
if (state.hold_clock) {
}
cprintf(
"Left idle mode at %lu: %lu asleep\n", wake_utt, wake_utt - sleep_utt);
}
}