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