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 |
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 (( |
77 | if (((msg->Id & CAN_MASK_NMT_TYPE)>>CAN_SHIFT_NMT_TYPE) == CAN_NMT_RESET && msg->DataLength == 4 && |
| 71 | - | ||
| 72 |
|
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 = |
130 | tx_msg.DataLength = 8; |
| 125 | tx_msg.Data. |
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 |
|
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 |
|
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 = |
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); |