]> git.zerfleddert.de Git - rsbs2/blame_incremental - bmc/chassis.c
use tristate on outputs. Tested with a PC connected and everything works :-)
[rsbs2] / bmc / chassis.c
... / ...
CommitLineData
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <stdio.h>
4
5#include "config.h"
6#include "chassis.h"
7
8#ifdef __AVR_ATmega16__
9#define CHASSISPORT B
10#define POWER_PIN 0
11#define RESET_PIN 1
12#define ACTIVE_LOW
13#else
14#error "Please add chassis power/reset-PIN information for this chip"
15#endif
16
17#define __CPORT(port) PORT##port
18#define _CPORT(port) __CPORT(port)
19#define CPORT _CPORT(CHASSISPORT)
20
21#define __CDDR(port) DDR##port
22#define _CDDR(port) __CDDR(port)
23#define CDDR _CDDR(CHASSISPORT)
24
25static volatile int power_cnt = 0;
26static volatile int reset_cnt = 0;
27static volatile int power_cycle = 0;
28
29static void chassis_set_pins(uint8_t pins, uint8_t state);
30
31void chassis_init()
32{
33 chassis_set_pins((1<<POWER_PIN) | (1<<RESET_PIN), 0);
34
35 /* About 1ms */
36 OCR0 = ((F_CPU/64)/1000) - 1;
37
38 TCCR0 = ((1<<WGM01) | (1<<CS01) | (1<<CS00)); /* CTC, Prescaler 64 */
39 TIMSK |= (1<<OCIE0);
40
41}
42
43/* gracefully transition between tri-state and active */
44static void chassis_set_pins(uint8_t pins, uint8_t state)
45{
46 if(state) {
47 /* active */
48#ifndef ACTIVE_LOW
49 /* Pull UPs for a short moment... */
50 CPORT |= pins;
51#endif
52 CDDR |= pins;
53#ifdef ACTIVE_LOW
54 CPORT &= ~pins;
55#endif
56 } else {
57#ifdef ACTIVE_LOW
58 CPORT &= ~pins; /* NoOp... */
59#endif
60 CDDR &= ~pins;
61#ifndef ACTIVE_LOW
62 CPORT &= ~pins;
63#endif
64 }
65}
66
67static void chassis_power(int msec)
68{
69 uint8_t old_SREG = SREG;
70
71 chassis_set_pins((1<<POWER_PIN), 1);
72
73 cli();
74 if (!power_cnt)
75 power_cnt = msec;
76 SREG = old_SREG;
77}
78
79static void chassis_reset(int msec)
80{
81 uint8_t old_SREG = SREG;
82
83 chassis_set_pins((1<<RESET_PIN), 1);
84
85 cli();
86 if (!reset_cnt)
87 reset_cnt = msec;
88 SREG = old_SREG;
89}
90
91void chassis_control(unsigned char action)
92{
93 uint8_t old_SREG = SREG;
94
95#ifdef DEBUG
96 printf("Chassis control 0x%02x\n", action);
97#endif
98
99 switch(action) {
100 case CHASSIS_ACTION_POWER_DOWN:
101 chassis_power(POWERDOWN_TIME_MS);
102 break;
103
104 case CHASSIS_ACTION_POWER_UP:
105 chassis_power(POWERUP_TIME_MS);
106 break;
107
108 case CHASSIS_ACTION_HARD_RESET:
109 chassis_reset(RESET_TIME_MS);
110 break;
111
112 case CHASSIS_ACTION_POWER_CYCLE:
113 cli();
114 power_cycle = POWER_CYCLE_PAUSE_MS;
115 SREG = old_SREG;
116 chassis_power(POWERDOWN_TIME_MS);
117
118 default:
119#ifdef DEBUG
120 printf("Unimplemented chassis action 0x%02x\n", action);
121#endif
122 break;
123 }
124}
125
126ISR(TIMER0_COMP_vect)
127{
128 if (power_cnt) {
129 power_cnt--;
130
131 if (!power_cnt)
132 chassis_set_pins((1<<POWER_PIN), 0);
133 } else if (power_cycle) {
134 power_cycle--;
135
136 if (!power_cycle) {
137 chassis_set_pins((1<<POWER_PIN), 1);
138 power_cnt = POWERUP_TIME_MS;
139 }
140 }
141 if (reset_cnt) {
142 reset_cnt--;
143
144 if (!reset_cnt)
145 chassis_set_pins((1<<RESET_PIN), 0);
146 }
147}
Impressum, Datenschutz