]> git.zerfleddert.de Git - rsbs2/blame - bmc/chassis.c
implement powercycle via IPMI
[rsbs2] / bmc / chassis.c
CommitLineData
da7751cb 1#include <avr/io.h>
93402c2c 2#include <avr/interrupt.h>
da7751cb
MG
3#include <stdio.h>
4
ae50f4d4 5#include "config.h"
da7751cb
MG
6#include "chassis.h"
7
19d56e39
MG
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
93402c2c
MG
25static volatile int power_cnt = 0;
26static volatile int reset_cnt = 0;
ae50f4d4 27static volatile int power_cycle = 0;
93402c2c 28
19d56e39
MG
29static void chassis_set_pins(uint8_t pins, uint8_t state);
30
da7751cb
MG
31void chassis_init()
32{
19d56e39
MG
33 chassis_set_pins((1<<POWER_PIN) | (1<<RESET_PIN), 0);
34 CDDR |= ((1<<POWER_PIN) | (1<<RESET_PIN));
93402c2c
MG
35
36 /* About 1ms */
70947537 37 OCR0 = ((F_CPU/64)/1000) - 1;
93402c2c 38
70947537 39 TCCR0 = ((1<<WGM01) | (1<<CS01) | (1<<CS00)); /* CTC, Prescaler 64 */
93402c2c
MG
40 TIMSK |= (1<<OCIE0);
41
19d56e39
MG
42}
43
44static void chassis_set_pins(uint8_t pins, uint8_t state)
45{
46#ifdef ACTIVE_LOW
47 state = !state;
48#endif
49
50 if(state) {
51 CPORT |= pins;
52 } else {
53 CPORT &= ~pins;
54 }
55}
56
57static void chassis_power(int msec)
58{
93402c2c 59 uint8_t old_SREG = SREG;
19d56e39
MG
60
61 chassis_set_pins((1<<POWER_PIN), 1);
62
93402c2c
MG
63 cli();
64 if (!power_cnt)
65 power_cnt = msec;
66 SREG = old_SREG;
19d56e39
MG
67}
68
69static void chassis_reset(int msec)
70{
93402c2c 71 uint8_t old_SREG = SREG;
19d56e39
MG
72
73 chassis_set_pins((1<<RESET_PIN), 1);
74
93402c2c
MG
75 cli();
76 if (!reset_cnt)
77 reset_cnt = msec;
78 SREG = old_SREG;
da7751cb
MG
79}
80
81void chassis_control(unsigned char action)
82{
ae50f4d4
MG
83 uint8_t old_SREG = SREG;
84
da7751cb
MG
85#ifdef DEBUG
86 printf("Chassis control 0x%02x\n", action);
87#endif
88
89 switch(action) {
90 case CHASSIS_ACTION_POWER_DOWN:
ae50f4d4 91 chassis_power(POWERDOWN_TIME_MS);
da7751cb
MG
92 break;
93
94 case CHASSIS_ACTION_POWER_UP:
ae50f4d4 95 chassis_power(POWERUP_TIME_MS);
da7751cb
MG
96 break;
97
98 case CHASSIS_ACTION_HARD_RESET:
ae50f4d4 99 chassis_reset(RESET_TIME_MS);
da7751cb
MG
100 break;
101
ae50f4d4
MG
102 case CHASSIS_ACTION_POWER_CYCLE:
103 cli();
104 power_cycle = POWER_CYCLE_PAUSE_MS;
105 SREG = old_SREG;
106 chassis_power(POWERDOWN_TIME_MS);
107
da7751cb 108 default:
f9d5c6e0 109#ifdef DEBUG
da7751cb 110 printf("Unimplemented chassis action 0x%02x\n", action);
f9d5c6e0 111#endif
da7751cb
MG
112 break;
113 }
114}
93402c2c
MG
115
116ISR(TIMER0_COMP_vect)
117{
118 if (power_cnt) {
119 power_cnt--;
120
121 if (!power_cnt)
122 chassis_set_pins((1<<POWER_PIN), 0);
ae50f4d4
MG
123 } else if (power_cycle) {
124 power_cycle--;
125
126 if (!power_cycle) {
127 chassis_set_pins((1<<POWER_PIN), 1);
128 power_cnt = POWERUP_TIME_MS;
129 }
93402c2c
MG
130 }
131 if (reset_cnt) {
132 reset_cnt--;
133
134 if (!reset_cnt)
135 chassis_set_pins((1<<RESET_PIN), 0);
136 }
137}
Impressum, Datenschutz