Subversion Repositories HomeAutomation

Rev

Go to most recent revision | Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
351 eqlazer 1
/**
2
 * CAN Relay.
3
 *
4
 *
5
 * @date    2006-12-17
6
 * @author  Erik Larsson
7
 *
8
 *   ADC=Vin*1024/Vref
9
 *   Vout=( 10 mV/C )( Temperature C ) + 500 mV
10
 *
11
 *  Transmitts: DATA: <temperature low byte> <temperature high byte> <relay status> <failsafe mode>
12
 *
13
 *
14
 */
15
 
16
#define TWO_BUTTON_MODE 0 /* If using two (or just one but nothing more) auxiliary buttons */
17
 
18
/*-----------------------------------------------------------------------------
19
 * Includes
20
 *---------------------------------------------------------------------------*/
21
/* system files */
22
#include <avr/io.h>
23
#include <avr/interrupt.h>
24
#include <stdio.h>
25
/* lib files */
26
#include <bios.h>
27
#include <tc1047.h>
28
#include <funcdefs.h>
29
 
30
/* defines */
31
#define GROUP_ID		0x01
32
 
33
#define RELAY_OFF			0x01
34
#define RELAY_ON			0x02
35
#define FAILSAFE_MODE		0x0F
36
#define FAILSAFE_TRESHOLD	60  /* Degrees when nodeRelay goes into failsafe mode */
37
 
38
#define RELAY_CMD_ON		0x01
39
#define RELAY_CMD_OFF		0x02
40
#define RELAY_CMD_TOGGLE	0x03
41
#define RELAY_CMD_STATUS	0x04
42
#define RELAY_CMD_RESET		0x05
43
#define STATUS_SEND_PERIOD	10000 /* milliseconds */
44
#define FAILSAFE_SEND_PERIOD	10000 /* milliseconds */
45
#define BOUNCE_TIME			10 /* milliseconds */
46
#define BUTTON1				1
47
#define BUTTON2				2
48
 
49
/*-------------------------------------------------------------------------
50
 * Global variables
51
 * -----------------------------------------------------------------------*/
52
#if TWO_BUTTON_MODE
53
Can_Message_t txMsg_Button;
54
#endif
55
 
56
uint8_t relayStatus, failsafe_flag;
57
uint32_t boardTemperature = 0;
58
Can_Message_t txMsg;
59
 
60
/*----------------------------------------------------------------------------
61
 * Functions
62
 * -------------------------------------------------------------------------*/
63
uint8_t relayOff();
64
uint8_t relayOn();
65
void relayFailsafe();
66
 
67
void can_receive(Can_Message_t *msg){
68
	uint32_t act;
69
	uint8_t m, act_type, group, node;
70
 
71
	if( ((msg->Id & CLASS_MASK)>>CLASS_MASK_BITS) == CLASS_ACT){
72
 
73
		act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
74
		act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
75
		group = (act & ACT_GROUP_MASK) >> ACT_GROUP_BITS;
76
		node = (act & ACT_NODE_MASK) >> ACT_NODE_BITS;
77
 
78
		if( act_type == ACT_TYPE_RELAY && (group == GROUP_ID || node == NODE_ID) ){
79
			if(msg->Data.bytes[0] == RELAY_CMD_ON){
80
				// Turn relay on
81
				relayStatus = relayOn();
82
 
83
			}else if(msg->Data.bytes[0] == RELAY_CMD_OFF){
84
				// Turn relay off
85
				relayStatus = relayOff();
86
 
87
			}else if(msg->Data.bytes[0] == RELAY_CMD_TOGGLE ){
88
					// Toggle relay
89
					if(relayStatus == RELAY_OFF){
90
						relayStatus = relayOn();
91
					}else{
92
						relayStatus = relayOff();
93
					}
94
 
95
			}else if(msg->Data.bytes[0] == RELAY_CMD_STATUS){
96
				// Send relay status to CAN
97
				boardTemperature = getTC1047temperature();
98
 
99
				if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
100
					// Goto failsafe mode
101
					relayFailsafe();
102
				}else{
103
					// Transmitt node status
104
					txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
105
					txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
106
					txMsg.Data.bytes[2] = relayStatus;
107
					txMsg.DataLength = 3;
108
					bios->can_send( &txMsg );
109
				}
110
			}else if(msg->Data.bytes[0] == RELAY_CMD_RESET){
111
				// Return to normal operation
112
				failsafe_flag = 1;
113
			}
114
		}
115
	}
116
}
117
 
118
/*----------------------------------------------------------------------------
119
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
120
 * -------------------------------------------------------------------------*/
121
#if TWO_BUTTON_MODE
122
ISR( PCINT2_vect )
123
{
124
    /* 
125
     * Auxiliary button pressed and released
126
     * Check time between press and release to eliminate bounces
127
     */
128
    static uint32_t buttonTime[2];
129
 
130
    txMsg_Button.RemoteFlag = 0;
131
    txMsg_Button.ExtendedFlag = 1;
132
 
133
    if( (PIND & (1<<PD6)) == 0){
134
        /* Button pressed */
135
        buttonTime[0] = Timebase_CurrentTime();
136
    }else if( (PIND & (1<<PD6)) == 1){
137
        if( Timebase_PassedTimeMillis( buttonTime[0] ) >= BOUNCE_TIME ){
138
            /* No bounce, send message */
139
            txMsg_Button.Id = BUTTON_ID;
140
            txMsg_Button.DataLength = 1;
141
            txMsg_Button.Data.bytes[0] = BUTTON1;
142
            return;
143
        }else{
144
            /* Just bounces, ignore it */
145
            return;
146
        }
147
    }
148
    if( (PIND & (1<<PD7)) == 0){
149
        /* Button pressed */
150
        buttonTime[1] = Timebase_CurrentTime();
151
    }else if( (PIND & (1<<PD7)) == 1){
152
        if( Timebase_PassedTimeMillis( buttonTime[1] ) >= BOUNCE_TIME ){
153
            /* No bounce, send message */
154
            txMsg_Button.Id = BUTTON_ID;
155
            txMsg_Button.DataLength = 1;
156
            txMsg_Button.Data.bytes[0] = BUTTON2;
157
            return;
158
        }else{
159
            /* Just bounces, ignore it */
160
            return;
161
        }
162
    }
163
}
164
#endif
165
 
166
/*-----------------------------------------------------------------------------
167
 * Main Program
168
 *---------------------------------------------------------------------------*/
169
int main(void) {
170
 
171
	adcTemperatureInit();
172
 
173
#if TWO_BUTTON_MODE
174
#error two button mode not yet tested
175
    /*
176
     * Initialize buttons
177
     * It is possible to use ie. sensors instead
178
     * but then change this
179
     */
180
    // Set as input and enable pull-up
181
    DDRD &= ~( (1<<DDD6)|(1<<DDD7) );
182
    PORTD |= (1<<PD6)|(1<<PD7);
183
 
184
    // Enable IO-pin interrupt
185
    PCICR |= (1<<PCIE1);
186
    // Unmask PD6 and PD7
187
    PCMSK2 |= (1<<PCINT22) | (1<<PCINT23);
188
#endif
189
 
190
	// Control channel for relay
191
	DDRC |= (1<<DDC1);
192
 
193
	// Set up callback for CAN messages
194
	bios->can_callback = &can_receive;
195
 
196
	sei();
197
 
198
	// Turn relay off
199
	relayStatus = relayOff();
200
 
201
	uint32_t timeStamp = 0;
202
 
203
	txMsg.RemoteFlag = 0;
204
	txMsg.ExtendedFlag = 1;
205
	txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_STATUS_RELAY<<TYPE_MASK_BITS )|(NODE_ID);
206
 
207
	// Main loop
208
	while (1) {
209
 
210
		if( bios->timebase_get() - timeStamp >= STATUS_SEND_PERIOD ){
211
			timeStamp = bios->timebase_get();
212
			// Send relay status to CAN
213
 
214
			boardTemperature = getTC1047temperature();
215
 
216
			if( (int32_t)boardTemperature >= FAILSAFE_TRESHOLD ){
217
				relayFailsafe();
218
			}else{
219
				txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
220
				txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
221
				txMsg.Data.bytes[2] = relayStatus;
222
				txMsg.DataLength = 3;
223
				bios->can_send( &txMsg );
224
			}
225
		}
226
	}
227
	return 0;
228
}
229
 
230
uint8_t relayOff()
231
{
232
	// Turn off relay
233
	PORTC &= ~(1<<PC1);
234
 
235
	return RELAY_OFF;
236
}
237
 
238
uint8_t relayOn()
239
{
240
	// Turn on relay
241
	PORTC |= (1<<PC1);
242
 
243
	return RELAY_ON;
244
}
245
 
246
void relayFailsafe()
247
{
248
	uint32_t timeStamp = 0;
249
 
250
	relayStatus = relayOff();
251
	failsafe_flag = 0;
252
 
253
	while(1){
254
 
255
		if( failsafe_flag ){
256
			// Return from failsafe mode
257
			return;
258
		}
259
 
260
		if( bios->timebase_get() - timeStamp >= FAILSAFE_SEND_PERIOD ){
261
			timeStamp = bios->timebase_get();
262
			// Send relay status to CAN
263
			boardTemperature = getTC1047temperature();
264
 
265
			txMsg.Data.bytes[0] = boardTemperature & 0x00FF;
266
			txMsg.Data.bytes[1] = (boardTemperature & 0xFF00)>>8;
267
			txMsg.Data.bytes[2] = relayStatus;
268
			txMsg.Data.bytes[3] = FAILSAFE_MODE;
269
 
270
			bios->can_send( &txMsg );
271
		}
272
	}
273
}
274