#include <avr/interrupt.h>
#include <stdio.h>
+#include "config.h"
#include "chassis.h"
#ifdef __AVR_ATmega16__
static volatile int power_cnt = 0;
static volatile int reset_cnt = 0;
+static volatile int power_cycle = 0;
static void chassis_set_pins(uint8_t pins, uint8_t state);
void chassis_init()
{
chassis_set_pins((1<<POWER_PIN) | (1<<RESET_PIN), 0);
- CDDR |= ((1<<POWER_PIN) | (1<<RESET_PIN));
/* About 1ms */
- OCR0 = ((F_CPU/256)/1000)-1;
+ OCR0 = ((F_CPU/64)/1000) - 1;
- TCCR0 = ((1<<WGM01) | (1<<CS02)); /* CTC, Prescaler 256 */
+ TCCR0 = ((1<<WGM01) | (1<<CS01) | (1<<CS00)); /* CTC, Prescaler 64 */
TIMSK |= (1<<OCIE0);
}
+/* gracefully transition between tri-state and active */
static void chassis_set_pins(uint8_t pins, uint8_t state)
{
-#ifdef ACTIVE_LOW
- state = !state;
-#endif
-
if(state) {
+ /* active */
+#ifndef ACTIVE_LOW
+ /* Pull UPs for a short moment... */
CPORT |= pins;
+#endif
+ CDDR |= pins;
+#ifdef ACTIVE_LOW
+ CPORT &= ~pins;
+#endif
} else {
+#ifdef ACTIVE_LOW
+ CPORT &= ~pins; /* NoOp... */
+#endif
+ CDDR &= ~pins;
+#ifndef ACTIVE_LOW
CPORT &= ~pins;
+#endif
}
}
void chassis_control(unsigned char action)
{
+ uint8_t old_SREG = SREG;
+
#ifdef DEBUG
printf("Chassis control 0x%02x\n", action);
#endif
switch(action) {
case CHASSIS_ACTION_POWER_DOWN:
- chassis_power(5000);
+ chassis_power(POWERDOWN_TIME_MS);
break;
case CHASSIS_ACTION_POWER_UP:
- chassis_power(500);
+ chassis_power(POWERUP_TIME_MS);
break;
case CHASSIS_ACTION_HARD_RESET:
- chassis_reset(500);
+ chassis_reset(RESET_TIME_MS);
break;
+ case CHASSIS_ACTION_POWER_CYCLE:
+ cli();
+ power_cycle = POWER_CYCLE_PAUSE_MS;
+ SREG = old_SREG;
+ chassis_power(POWERDOWN_TIME_MS);
+
default:
#ifdef DEBUG
printf("Unimplemented chassis action 0x%02x\n", action);
if (!power_cnt)
chassis_set_pins((1<<POWER_PIN), 0);
+ } else if (power_cycle) {
+ power_cycle--;
+
+ if (!power_cycle) {
+ chassis_set_pins((1<<POWER_PIN), 1);
+ power_cnt = POWERUP_TIME_MS;
+ }
}
if (reset_cnt) {
reset_cnt--;