Subversion Repositories HomeAutomation

Rev

Rev 483 | Rev 493 | Go to most recent revision | Details | Compare with Previous | 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 */
483 arune 26
#include <config.h>
351 eqlazer 27
#include <bios.h>
391 eqlazer 28
#include <drivers/timer/timebase.h>
483 arune 29
//#include <funcdefs.h>
351 eqlazer 30
 
31
/* defines */
360 eqlazer 32
#define RELAY_OFF			0x01
33
#define RELAY_ON			0x02
34
#define FAILSAFE_MODE		0x0F
391 eqlazer 35
#define FAILSAFE_TRESHOLD	0xFF  /* Degrees when nodeRelay goes into failsafe mode */
351 eqlazer 36
 
360 eqlazer 37
#define RELAY_CMD_ON		0x01
38
#define RELAY_CMD_OFF		0x02
39
#define RELAY_CMD_TOGGLE	0x03
40
#define RELAY_CMD_STATUS	0x04
41
#define RELAY_CMD_RESET		0x05
42
#define STATUS_SEND_PERIOD	10000UL /* milliseconds */
43
#define FAILSAFE_SEND_PERIOD	10000UL /* milliseconds */
351 eqlazer 44
#define BOUNCE_TIME			10 /* milliseconds */
45
#define BUTTON1				1
46
#define BUTTON2				2
47
 
486 arune 48
#define APP_TYPE    CAN_APPTYPES_RELAY
49
#define APP_VERSION 0x0001
50
 
351 eqlazer 51
/*-------------------------------------------------------------------------
52
 * Global variables
53
 * -----------------------------------------------------------------------*/
483 arune 54
uint8_t relayStatus, failsafe_flag = 0;
360 eqlazer 55
uint32_t boardTemperature = 0;
351 eqlazer 56
 
483 arune 57
volatile Can_Message_t rxMsg; // Message storage
58
volatile uint8_t rxMsgFull;   // Synchronization flag
354 eqlazer 59
 
483 arune 60
 
351 eqlazer 61
/*----------------------------------------------------------------------------
62
 * Functions
63
 * -------------------------------------------------------------------------*/
64
uint8_t relayOff();
65
uint8_t relayOn();
66
void relayFailsafe();
360 eqlazer 67
void sendStatus();
351 eqlazer 68
 
360 eqlazer 69
void can_receive(Can_Message_t *msg)
70
{ // CAN callback function
483 arune 71
	if (!rxMsgFull) {
72
		memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
73
		rxMsgFull = 1;
351 eqlazer 74
	}
75
}
76
 
77
/*----------------------------------------------------------------------------
78
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
79
 * -------------------------------------------------------------------------*/
80
#if TWO_BUTTON_MODE
81
ISR( PCINT2_vect )
82
{
83
 
84
}
85
#endif
86
 
87
/*-----------------------------------------------------------------------------
88
 * Main Program
89
 *---------------------------------------------------------------------------*/
90
int main(void) {
91
 
391 eqlazer 92
	uint32_t timeStamp = Timebase_CurrentTime(), temp = timeStamp;
351 eqlazer 93
 
360 eqlazer 94
	adcTemperatureInit();
351 eqlazer 95
 
96
	// Set up callback for CAN messages
391 eqlazer 97
	BIOS_CanCallback = &can_receive;
351 eqlazer 98
 
99
	sei();
391 eqlazer 100
 
101
	Timebase_Init();
351 eqlazer 102
 
486 arune 103
	Can_Message_t txMsg;
104
	txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
105
	txMsg.DataLength = 4;
106
	txMsg.RemoteFlag = 0;
107
	txMsg.ExtendedFlag = 1;
108
	txMsg.Data.words[0] = APP_TYPE;
109
	txMsg.Data.words[1] = APP_VERSION;
110
	BIOS_CanSend(&txMsg);
111
 
351 eqlazer 112
	// Turn relay off
113
	relayStatus = relayOff();
114
 
115
	// Main loop
116
	while (1) {
117
 
391 eqlazer 118
		temp = Timebase_CurrentTime();
354 eqlazer 119
		if( temp - timeStamp >= STATUS_SEND_PERIOD ){
120
			timeStamp = temp;
483 arune 121
			// Send relay status to CAN
360 eqlazer 122
			sendStatus();
351 eqlazer 123
		}
483 arune 124
 
125
		if (rxMsgFull) {
126
			uint8_t acttype;
127
			uint16_t servoid;
128
 
129
			if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
130
				// Actuator package
131
				acttype =(uint8_t)((rxMsg.Id & CAN_MASK_ACT_FUNCC) >> CAN_SHIFT_ACT_FUNCC);
132
				servoid = (uint16_t)((rxMsg.Id & CAN_MASK_ACT_NID) >> CAN_SHIFT_ACT_NID);
133
 
134
				if ((acttype == ACT_FUNCC_RELAY) && (servoid == NODE_ID)) {
135
					// This is a message for this relay
136
					if (rxMsg.Data.bytes[0] == RELAY_CMD_RESET) {
137
						// Return to normal operation
138
						failsafe_flag = 0;
139
					}
140
 
141
					if (!failsafe_flag) {
142
						if (rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
143
							// Turn relay on
144
							relayStatus = relayOn();
145
 
146
						} else if (rxMsg.Data.bytes[0] == RELAY_CMD_OFF ){
147
							// Turn relay off
148
							relayStatus = relayOff();
149
 
150
						} else if (rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
151
								// Toggle relay
152
								if(relayStatus == RELAY_OFF){
153
									relayStatus = relayOn();
154
								}else{
155
									relayStatus = relayOff();
156
								}
157
 
158
						}else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS ){
159
							// Send relay status to CAN
160
							sendStatus();
161
						}
162
					}
163
				}
164
			}
165
    		rxMsgFull = 0; //  
166
 
167
		}
168
 
351 eqlazer 169
	}
170
	return 0;
171
}
172
 
173
uint8_t relayOff()
174
{
175
	// Turn off relay
176
	PORTC &= ~(1<<PC1);
360 eqlazer 177
	DDRC |= (1<<DDC1);
351 eqlazer 178
 
179
	return RELAY_OFF;
180
}
181
 
182
uint8_t relayOn()
183
{
184
	// Turn on relay
360 eqlazer 185
	DDRC &= ~(1<<DDC1);
351 eqlazer 186
	PORTC |= (1<<PC1);
187
 
188
	return RELAY_ON;
189
}
190
 
191
void relayFailsafe()
192
{
360 eqlazer 193
	uint32_t failsafe_timeStamp, temp;
351 eqlazer 194
	relayStatus = relayOff();
352 eqlazer 195
	failsafe_flag = 1;
351 eqlazer 196
 
197
	while(1){
198
 
352 eqlazer 199
		if( !failsafe_flag ){
351 eqlazer 200
			// Return from failsafe mode
201
			return;
202
		}
360 eqlazer 203
// TODO skicka med period
204
		sendStatus( );
205
	}
206
}
351 eqlazer 207
 
360 eqlazer 208
void sendStatus()
209
{
210
	uint32_t temperature;
211
	Can_Message_t statusMsg;
212
	statusMsg.RemoteFlag = 0;
213
	statusMsg.ExtendedFlag = 1;
214
	statusMsg.DataLength = 4;
483 arune 215
	statusMsg.Id = ( CAN_SNS<<CAN_SHIFT_CLASS )|( SNS_FUNCC_RELAY_STATUS<<CAN_SHIFT_ACT_FUNCC )|( NODE_ID<<CAN_SHIFT_SNS_SID );
216
 
360 eqlazer 217
	temperature = getTC1047temperature();
218
	if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
219
		// Goto failsafe mode
220
		relayFailsafe();
221
	}else{
222
		// Transmitt node status
223
		statusMsg.Data.bytes[0] = temperature & 0x00FF;
224
		statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
225
		statusMsg.Data.bytes[2] = relayStatus;
226
		statusMsg.Data.bytes[3] = failsafe_flag;
351 eqlazer 227
 
391 eqlazer 228
		BIOS_CanSend( &statusMsg );
351 eqlazer 229
	}
230
}