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 */
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
 
493 arune 48
#define THISRELAYID         NODE_ID     /* application software should not depend on the id of the physical node
49
                                            but for now lets do it like this */
50
 
486 arune 51
#define APP_TYPE    CAN_APPTYPES_RELAY
52
#define APP_VERSION 0x0001
53
 
351 eqlazer 54
/*-------------------------------------------------------------------------
55
 * Global variables
56
 * -----------------------------------------------------------------------*/
483 arune 57
uint8_t relayStatus, failsafe_flag = 0;
360 eqlazer 58
uint32_t boardTemperature = 0;
351 eqlazer 59
 
483 arune 60
volatile Can_Message_t rxMsg; // Message storage
61
volatile uint8_t rxMsgFull;   // Synchronization flag
354 eqlazer 62
 
483 arune 63
 
351 eqlazer 64
/*----------------------------------------------------------------------------
65
 * Functions
66
 * -------------------------------------------------------------------------*/
67
uint8_t relayOff();
68
uint8_t relayOn();
69
void relayFailsafe();
360 eqlazer 70
void sendStatus();
351 eqlazer 71
 
360 eqlazer 72
void can_receive(Can_Message_t *msg)
73
{ // CAN callback function
483 arune 74
    if (!rxMsgFull) {
75
        memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
76
        rxMsgFull = 1;
351 eqlazer 77
    }
78
}
79
 
80
/*----------------------------------------------------------------------------
81
 * Interrupt routines // FIXME ordna och testa tryckknappar/rotary encoder
82
 * -------------------------------------------------------------------------*/
83
#if TWO_BUTTON_MODE
84
ISR( PCINT2_vect )
85
{
86
 
87
}
88
#endif
89
 
90
/*-----------------------------------------------------------------------------
91
 * Main Program
92
 *---------------------------------------------------------------------------*/
93
int main(void) {
94
 
391 eqlazer 95
    uint32_t timeStamp = Timebase_CurrentTime(), temp = timeStamp;
351 eqlazer 96
 
360 eqlazer 97
    adcTemperatureInit();
351 eqlazer 98
 
99
    // Set up callback for CAN messages
391 eqlazer 100
    BIOS_CanCallback = &can_receive;
351 eqlazer 101
 
102
    sei();
391 eqlazer 103
 
104
    Timebase_Init();
351 eqlazer 105
 
486 arune 106
    Can_Message_t txMsg;
107
    txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
108
    txMsg.DataLength = 4;
109
    txMsg.RemoteFlag = 0;
110
    txMsg.ExtendedFlag = 1;
111
    txMsg.Data.words[0] = APP_TYPE;
112
    txMsg.Data.words[1] = APP_VERSION;
113
    BIOS_CanSend(&txMsg);
114
 
351 eqlazer 115
    // Turn relay off
116
    relayStatus = relayOff();
117
 
118
    // Main loop
119
    while (1) {
120
 
391 eqlazer 121
        temp = Timebase_CurrentTime();
354 eqlazer 122
        if( temp - timeStamp >= STATUS_SEND_PERIOD ){
123
            timeStamp = temp;
483 arune 124
            // Send relay status to CAN
360 eqlazer 125
            sendStatus();
351 eqlazer 126
        }
483 arune 127
 
128
        if (rxMsgFull) {
129
            uint8_t acttype;
493 arune 130
            uint16_t relayid;
483 arune 131
 
132
            if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){
133
                // Actuator package
493 arune 134
                acttype =(uint8_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
135
                relayid = (uint16_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
483 arune 136
 
493 arune 137
                if ((acttype == ACT_TYPE_RELAY) && (relayid == THISRELAYID)) {
483 arune 138
                    // This is a message for this relay
139
                    if (rxMsg.Data.bytes[0] == RELAY_CMD_RESET) {
140
                        // Return to normal operation
141
                        failsafe_flag = 0;
142
                    }
143
 
144
                    if (!failsafe_flag) {
145
                        if (rxMsg.Data.bytes[0] == RELAY_CMD_ON ){
146
                            // Turn relay on
147
                            relayStatus = relayOn();
148
 
149
                        } else if (rxMsg.Data.bytes[0] == RELAY_CMD_OFF ){
150
                            // Turn relay off
151
                            relayStatus = relayOff();
152
 
153
                        } else if (rxMsg.Data.bytes[0] == RELAY_CMD_TOGGLE ){
154
                                // Toggle relay
155
                                if(relayStatus == RELAY_OFF){
156
                                    relayStatus = relayOn();
157
                                }else{
158
                                    relayStatus = relayOff();
159
                                }
160
 
161
                        }else if(rxMsg.Data.bytes[0] == RELAY_CMD_STATUS ){
162
                            // Send relay status to CAN
163
                            sendStatus();
164
                        }
165
                    }
166
                }
167
            }
168
            rxMsgFull = 0; //  
169
 
170
        }
171
 
351 eqlazer 172
    }
173
    return 0;
174
}
175
 
176
uint8_t relayOff()
177
{
178
    // Turn off relay
179
    PORTC &= ~(1<<PC1);
360 eqlazer 180
    DDRC |= (1<<DDC1);
351 eqlazer 181
 
182
    return RELAY_OFF;
183
}
184
 
185
uint8_t relayOn()
186
{
187
    // Turn on relay
360 eqlazer 188
    DDRC &= ~(1<<DDC1);
351 eqlazer 189
    PORTC |= (1<<PC1);
190
 
191
    return RELAY_ON;
192
}
193
 
194
void relayFailsafe()
195
{
360 eqlazer 196
    uint32_t failsafe_timeStamp, temp;
351 eqlazer 197
    relayStatus = relayOff();
352 eqlazer 198
    failsafe_flag = 1;
351 eqlazer 199
 
200
    while(1){
201
 
352 eqlazer 202
        if( !failsafe_flag ){
351 eqlazer 203
            // Return from failsafe mode
204
            return;
205
        }
360 eqlazer 206
// TODO skicka med period
207
        sendStatus( );
208
    }
209
}
351 eqlazer 210
 
360 eqlazer 211
void sendStatus()
212
{
213
    uint32_t temperature;
214
    Can_Message_t statusMsg;
215
    statusMsg.RemoteFlag = 0;
216
    statusMsg.ExtendedFlag = 1;
217
    statusMsg.DataLength = 4;
493 arune 218
    statusMsg.Id = ( CAN_SNS<<CAN_SHIFT_CLASS )|( SNS_TYPE_RELAY_STATUS<<CAN_SHIFT_ACT_TYPE )|( NODE_ID<<CAN_SHIFT_SNS_SID );
483 arune 219
 
360 eqlazer 220
    temperature = getTC1047temperature();
221
    if( (int32_t)temperature >= FAILSAFE_TRESHOLD && !failsafe_flag ){
222
        // Goto failsafe mode
223
        relayFailsafe();
224
    }else{
225
        // Transmitt node status
226
        statusMsg.Data.bytes[0] = temperature & 0x00FF;
227
        statusMsg.Data.bytes[1] = (temperature & 0xFF00)>>8;
228
        statusMsg.Data.bytes[2] = relayStatus;
229
        statusMsg.Data.bytes[3] = failsafe_flag;
351 eqlazer 230
 
391 eqlazer 231
        BIOS_CanSend( &statusMsg );
351 eqlazer 232
    }
233
}