Subversion Repositories HomeAutomation

Rev

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