Subversion Repositories HomeAutomation

Rev

Rev 585 | Rev 771 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 585 Rev 769
Line 1... Line 1...
1
/*
1
/*
2
 * $Id: bios.c 585 2007-08-06 17:44:46Z arune $
2
 * $Id: bios.c 769 2008-04-28 20:34:34Z arune $
3
 */
3
 */
4
 
4
 
5
#include <inttypes.h>
5
#include <inttypes.h>
6
#include <avr/io.h>
6
#include <avr/io.h>
7
#include <avr/interrupt.h>
7
#include <avr/interrupt.h>
Line 13... Line 13...
13
#include <vectors.h> // Must be included after sfr_defs.h but before any ISR()
13
#include <vectors.h> // Must be included after sfr_defs.h but before any ISR()
14
#include <drivers/can/can.h>
14
#include <drivers/can/can.h>
15
#include <flash.h>
15
#include <flash.h>
16
#include <bios_export.h>
16
#include <bios_export.h>
17
#include CAN_DRIVER_H
17
#include CAN_DRIVER_H
-
 
18
 
-
 
19
#if !defined( NODE_HW_ID )
-
 
20
#error No NODE_HW_ID in bios.inc, set NODE_HW_ID=<GENERATE_HW> and Ill generate it for you
-
 
21
#endif
18
 
22
 
19
#if defined(__AVR_ATmega8__)
23
#if defined(__AVR_ATmega8__)
20
#define IVSEL_REG GICR
24
#define IVSEL_REG GICR
21
#elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
25
#elif defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
22
#define IVSEL_REG MCUCR
26
#define IVSEL_REG MCUCR
Line 25... Line 29...
25
#endif
29
#endif
26
 
30
 
27
#if defined(AUTOSTART)
31
#if defined(AUTOSTART)
28
#if AUTOSTART == 0 
32
#if AUTOSTART == 0 
29
#error Please choose a higher AUTOSTART value in bios.inc, the nod will cease to work, and you can only reflash node with ISP
33
#error Please choose a higher AUTOSTART value in bios.inc, the nod will cease to work, and you can only reflash node with ISP
30
#endif
34
#endif
31
#if AUTOSTART == 1
35
#if AUTOSTART == 1
32
#error Please choose a higher AUTOSTART value in bios.inc, there might be problems with updating software on node
36
#error Please choose a higher AUTOSTART value in bios.inc, there might be problems with updating software on node
33
#endif
37
#endif
34
#endif
38
#endif
35
 
39
 
36
//---------------------------------------------------------------------------
40
//---------------------------------------------------------------------------
37
// Private declarations
41
// Private declarations
38
 
42
 
39
volatile uint8_t bios_msg_full;
43
volatile uint8_t bios_msg_full;
40
Can_Message_t* bios_msg_ptr; // only a pointer to main-local structure to save .bss space
44
Can_Message_t* bios_msg_ptr; // only a pointer to main-local structure to save .bss space
41
extern void __bios_start; // Start of BIOS area in flash, from ld-script.
45
extern void __bios_start; // Start of BIOS area in flash, from ld-script.
-
 
46
 
-
 
47
prog_uint32_t hwid = NODE_HW_ID;
42
 
48
 
43
#if defined(AUTOSTART)
49
#if defined(AUTOSTART)
44
uint8_t autostart_cnt;
50
uint8_t autostart_cnt;
45
#endif
51
#endif
46
 
52
 
47
#define BIOS_APP    1
53
#define BIOS_APP        1
48
#define BIOS_NOAPP  2
54
#define BIOS_NOAPP      2
49
#define BIOS_PGM    3
55
#define BIOS_PGM        3
-
 
56
#define BIOS_END_PGM    4
50
 
57
 
51
//---------------------------------------------------------------------------
58
//---------------------------------------------------------------------------
52
// Private functions
59
// Private functions
53
 
60
 
54
void Can_Process(Can_Message_t* msg) {
61
void Can_Process(Can_Message_t* msg) {
Line 62... Line 69...
62
            // or the master node is not up, the node will be reset.
69
            // or the master node is not up, the node will be reset.
63
            wdt_reset();
70
            wdt_reset();
64
            //TODO: Don't care about time right now... Figure out what to do with it. 
71
            //TODO: Don't care about time right now... Figure out what to do with it. 
65
#if defined(AUTOSTART)
72
#if defined(AUTOSTART)
66
            autostart_cnt++;
73
            autostart_cnt++;
67
#endif
74
#endif
68
        }
75
        }
69
       
76
       
70
        if ((msg->Id & CAN_MASK_NMT_RID)>>CAN_SHIFT_NMT_RID == NODE_ID) {
77
        if (((msg->Id & CAN_MASK_NMT_TYPE)>>CAN_SHIFT_NMT_TYPE) == CAN_NMT_RESET && msg->DataLength == 4 &&
71
 
-
 
72
            if ((msg->Id & CAN_MASK_NMT_TYPE)>>CAN_SHIFT_NMT_TYPE == CAN_NMT_RESET) {
78
                msg->Data.bytes[0] == (hwid&0xff) && msg->Data.bytes[1] == ((hwid>>8)&0xff) &&
-
 
79
                msg->Data.bytes[2] == ((hwid>>16)&0xff) && msg->Data.bytes[3] == ((hwid>>24)&0xff) ) {
73
                BIOS_Reset();
80
            BIOS_Reset();
74
            }
81
        }
75
            // Copy message to bios buffer if bios is done with the previous message.
82
        // Copy message to bios buffer if bios is done with the previous message.
76
            // This is also a check to see if bios is still running. When app is
83
        // This is also a check to see if bios is still running. When app is
77
            // started, bios_msg_full is never reset to 0 so the check fails and all
84
        // started, bios_msg_full is never reset to 0 so the check fails and all
78
            // NMT communication except reset is ignored. 
85
        // NMT communication except reset is ignored. 
79
            if (!(bios_msg_full)) {
86
        if (!(bios_msg_full)) {
80
                memcpy(bios_msg_ptr, msg, sizeof(Can_Message_t));
87
            memcpy(bios_msg_ptr, msg, sizeof(Can_Message_t));
81
                bios_msg_full = 1;
88
            bios_msg_full = 1;
82
            }
-
 
83
        }      
89
        }
84
    } else if (BIOS_CanCallback) {
90
    } else if (BIOS_CanCallback) {
85
        //printf("Calling app callback.\n");
91
        //printf("Calling app callback.\n");
86
        BIOS_CanCallback(msg);
92
        BIOS_CanCallback(msg);
87
    }
93
    }
Line 119... Line 125...
119
    if (Can_Init() != CAN_OK) BIOS_Reset();
125
    if (Can_Init() != CAN_OK) BIOS_Reset();
120
   
126
   
121
    tx_msg.RemoteFlag = 0;
127
    tx_msg.RemoteFlag = 0;
122
    tx_msg.ExtendedFlag = 1;
128
    tx_msg.ExtendedFlag = 1;
123
    tx_msg.Id = CAN_ID_NMT_BIOS_START;
129
    tx_msg.Id = CAN_ID_NMT_BIOS_START;
124
    tx_msg.DataLength = 3;
130
    tx_msg.DataLength = 8;
125
    tx_msg.Data.words[0] = BIOS_VERSION;
131
    tx_msg.Data.bytes[0] = BIOS_VERSION&0xff;
-
 
132
    tx_msg.Data.bytes[1] = (BIOS_VERSION>>8)&0xff;
-
 
133
    tx_msg.Data.bytes[4] = hwid&0xff;
-
 
134
    tx_msg.Data.bytes[5] = (hwid>>8)&0xff;
-
 
135
    tx_msg.Data.bytes[6] = (hwid>>16)&0xff;
-
 
136
    tx_msg.Data.bytes[7] = (hwid>>24)&0xff;
126
 
137
 
127
    if (pgm_read_word(0) == 0xffff) {
138
    if (pgm_read_word(0) == 0xffff) {
128
        // No application in flash
139
        // No application in flash
129
        // Send CAN_NMT_BIOS_START(BIOS_VERSION, 0)
140
        // Send CAN_NMT_BIOS_START(BIOS_VERSION, 0)
130
        tx_msg.Data.bytes[2] = 0;
141
        tx_msg.Data.bytes[2] = 0;
Line 153... Line 164...
153
       
164
       
154
        nmt_type = (bios_msg.Id & CAN_MASK_NMT_TYPE)>>CAN_SHIFT_NMT_TYPE;
165
        nmt_type = (bios_msg.Id & CAN_MASK_NMT_TYPE)>>CAN_SHIFT_NMT_TYPE;
155
       
166
       
156
        switch (bios_state) {
167
        switch (bios_state) {
157
        case BIOS_APP:
168
        case BIOS_APP:
158
            if (nmt_type == CAN_NMT_START_APP) {
169
            //if (nmt_type == CAN_NMT_START_APP) {
-
 
170
            if (nmt_type == CAN_NMT_START_APP && bios_msg.DataLength == 4 &&
-
 
171
                    bios_msg.Data.bytes[0] == (hwid&0xff) && bios_msg.Data.bytes[1] == ((hwid>>8)&0xff) &&
-
 
172
                    bios_msg.Data.bytes[2] == ((hwid>>16)&0xff) && bios_msg.Data.bytes[3] == ((hwid>>24)&0xff) ) {
159
                app_reset(); // Will never return
173
                app_reset(); // Will never return
160
            }
174
            }
161
            // Fall through
175
            // Fall through
162
        case BIOS_NOAPP:
176
        case BIOS_NOAPP:
163
            if (nmt_type == CAN_NMT_PGM_START) {
177
            //if (nmt_type == CAN_NMT_PGM_START) {
-
 
178
            if (nmt_type == CAN_NMT_PGM_START && bios_msg.DataLength == 8 &&
-
 
179
                    bios_msg.Data.bytes[4] == (hwid&0xff) && bios_msg.Data.bytes[5] == ((hwid>>8)&0xff) &&
-
 
180
                    bios_msg.Data.bytes[6] == ((hwid>>16)&0xff) && bios_msg.Data.bytes[7] == ((hwid>>24)&0xff) ) {
164
                // Set base address
181
                // Set base address
165
                base_addr = bios_msg.Data.words[0];
182
                base_addr = bios_msg.Data.words[0];
166
                flash_init(pagebuf);
183
                flash_init(pagebuf);
167
                //send CAN_NMT_PGM_ACK(offset)
184
                //send CAN_NMT_PGM_ACK(offset)
168
                tx_msg.Id = CAN_ID_NMT_PGM_ACK;
185
                tx_msg.Id = CAN_ID_NMT_PGM_ACK;
169
                tx_msg.Data.words[0] = base_addr;
186
                tx_msg.Data.words[0] = base_addr;
170
                send_msg = 1;
187
                send_msg = 1;
171
                bios_state = BIOS_PGM;
188
                bios_state = BIOS_PGM;
172
            }
-
 
173
            if (nmt_type == CAN_NMT_PGM_COPY) {
-
 
174
                // For BIOS updating over CAN. Upload bios to application area,
-
 
175
                // send this message with correct parameters to copy data from
-
 
176
                // application to bios area and pray it will come alive again.
-
 
177
                flash_copy_data(bios_msg.Data.words[0],
-
 
178
                                bios_msg.Data.words[1],
-
 
179
                                bios_msg.Data.words[2]);
-
 
180
                // flash_copy_data will never return.
-
 
181
            }
189
            }
182
            break;
190
            break;
183
        case BIOS_PGM:
191
        case BIOS_PGM:
184
            // Default to send CAN_NMT_PGM_ACK(offset)
192
            // Default to send CAN_NMT_PGM_ACK(offset)
185
            tx_msg.Id = CAN_ID_NMT_PGM_ACK;
193
            tx_msg.Id = CAN_ID_NMT_PGM_ACK;
Line 225... Line 233...
225
                    crc = _crc16_update(crc, pgm_read_byte(loc));
233
                    crc = _crc16_update(crc, pgm_read_byte(loc));
226
                }
234
                }
227
               
235
               
228
                tx_msg.Data.words[0] = crc;
236
                tx_msg.Data.words[0] = crc;
229
                send_msg = 1;
237
                send_msg = 1;
230
                bios_state = BIOS_NOAPP;
238
                bios_state = BIOS_END_PGM;
-
 
239
            }
-
 
240
            break;
-
 
241
        case BIOS_END_PGM:
-
 
242
            if (nmt_type == CAN_NMT_PGM_COPY) {
-
 
243
                // For BIOS updating over CAN. Upload bios to application area,
-
 
244
                // send this message with correct parameters to copy data from
-
 
245
                // application to bios area and pray it will come alive again.
-
 
246
                flash_copy_data(bios_msg.Data.words[0],
-
 
247
                                bios_msg.Data.words[1],
-
 
248
                                bios_msg.Data.words[2]);
-
 
249
                // flash_copy_data will never return.
231
            }
250
            }
232
        }
251
        }
233
       
252
       
234
        if (send_msg) {
253
        if (send_msg) {
235
            while (Can_Send(&tx_msg) != CAN_OK);
254
            while (Can_Send(&tx_msg) != CAN_OK);