Rev 248 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 248 | Rev 250 | ||
|---|---|---|---|
| Line 6... | Line 6... | ||
| 6 | #include <avr/wdt.h> |
6 | #include <avr/wdt.h> |
| 7 | #include <avr/pgmspace.h> |
7 | #include <avr/pgmspace.h> |
| 8 | #include <stdio.h> |
8 | #include <stdio.h> |
| 9 | #include "flash.h" |
9 | #include "flash.h" |
| 10 | #include "vectors.h" // Must be included after sfr_defs.h but before any ISR() |
10 | #include "vectors.h" // Must be included after sfr_defs.h but before any ISR() |
| 11 | #include " |
11 | #include "mcp2515/mcp2515.h" |
| 12 | - | ||
| 13 | #define FUNCTmask 0x1E000000 |
- | |
| 14 | #define FUNCTshift 25 |
- | |
| 15 | #define FUNCCmask 0x01FF8000 |
- | |
| 16 | #define FUNCCshift 15 |
- | |
| 17 | #define NIDmask 0x00007E00 |
- | |
| 18 | #define NIDshift 9 |
- | |
| 19 | #define SIDmask 0x000001FF |
- | |
| 20 | #define SIDshift 0 |
- | |
| 21 | - | ||
| 22 | #define FUNCTbios 0x00 |
- | |
| 23 | - | ||
| 24 | #define FUNCCstartprg 0x81 |
- | |
| 25 | #define FUNCCprgdata 0x82 |
- | |
| 26 | #define FUNCCstopprg 0x83 |
- | |
| 27 | - | ||
| 28 | #define PRG_STATE_IDLE 0 |
- | |
| 29 | #define PRG_STATE_PROGRAMMING 1 |
- | |
| 30 | - | ||
| 31 | 12 | ||
| 32 | //--------------------------------------------------------------------------- |
13 | //--------------------------------------------------------------------------- |
| 33 | // Globals |
14 | // Globals |
| 34 | 15 | ||
| 35 | volatile long gMilliSecTick; |
16 | volatile long gMilliSecTick; |
| 36 | 17 | ||
| 37 | //--------------------------------------------------------------------------- |
18 | //--------------------------------------------------------------------------- |
| 38 | // Function definitions for the exported interface |
19 | // Function definitions for the exported interface |
| 39 | 20 | ||
| 40 | void reset(void) { |
21 | void reset(void) { |
| 41 | //Just loop and let the watchdog reset |
22 | //Just loop and let the watchdog reset |
| 42 | cli(); |
23 | cli(); |
| 43 | while(1); |
24 | while(1); |
| 44 | } |
25 | } |
| 45 | 26 | ||
| 46 | void bios_putchar(char c) { |
27 | void bios_putchar(char c) { |
| 47 | UART_PUTCHAR(c); |
28 | UART_PUTCHAR(c); |
| 48 | } |
29 | } |
| 49 | 30 | ||
| 50 | char bios_getchar(void) { |
31 | char bios_getchar(void) { |
| 51 | char c; |
32 | char c; |
| 52 | UART_GETCHAR(c) |
33 | UART_GETCHAR(c) |
| 53 | return c; |
34 | return c; |
| 54 | } |
35 | } |
| 55 | 36 | ||
| 56 | long timebase_get(void) { |
37 | long timebase_get(void) { |
| 57 | uint8_t sreg; |
38 | uint8_t sreg; |
| 58 | long res; |
39 | long res; |
| 59 | 40 | ||
| Line 65... | Line 46... | ||
| 65 | 46 | ||
| 66 | SREG=sreg; |
47 | SREG=sreg; |
| 67 | 48 | ||
| 68 | return res; |
49 | return res; |
| 69 | } |
50 | } |
| - | 51 | ||
| - | 52 | // TODO: Insert can driver's Can_Send directly in bios interface. |
|
| - | 53 | Can_Return_t can_send(Can_Message_t* msg) { |
|
| - | 54 | return CAN_FAIL; |
|
| - | 55 | } |
|
| - | 56 | ||
| - | 57 | //Can_Return_t can_receive(Can_Message_t *msg) { |
|
| - | 58 | // return CAN_FAIL; |
|
| - | 59 | //} |
|
| 70 | 60 | ||
| 71 | //--------------------------------------------------------------------------- |
61 | //--------------------------------------------------------------------------- |
| 72 | // Function definitions for the private functions |
62 | // Function definitions for the private functions |
| 73 | 63 | ||
| 74 | static int console_getchar(FILE *stream) { |
64 | static int console_getchar(FILE *stream) { |
| Line 85... | Line 75... | ||
| 85 | 75 | ||
| 86 | 76 | ||
| 87 | //--------------------------------------------------------------------------- |
77 | //--------------------------------------------------------------------------- |
| 88 | // Interrupt Service Routines |
78 | // Interrupt Service Routines |
| 89 | // Read app_vectors.h! |
79 | // Read app_vectors.h! |
| 90 | 80 | ||
| 91 | ISR(TIMEBASE_VECTOR) { |
81 | ISR(TIMEBASE_VECTOR) { |
| 92 | TIMEBASE_COUNTER -= TIMEBASE_RELOAD; |
82 | TIMEBASE_COUNTER -= TIMEBASE_RELOAD; |
| 93 | gMilliSecTick++; |
83 | gMilliSecTick++; |
| 94 | wdt_reset(); |
84 | wdt_reset(); |
| - | 85 | } |
|
| - | 86 | ||
| - | 87 | void Can_Process(Can_Message_t* msg) { |
|
| - | 88 | if (msg->ExtendedFlag && ((msg->Id & CAN_FUNCT_MASK) == CAN_MSG_TYPE_BIOS)) { |
|
| - | 89 | printf("BIOS received msg!\n"); |
|
| - | 90 | } else if (bios->can_callback) { |
|
| - | 91 | printf("Calling app callback.\n"); |
|
| - | 92 | bios->can_callback(msg); |
|
| - | 93 | } else { |
|
| - | 94 | printf("BIOS received application msg but no handler installed!\n"); |
|
| - | 95 | } |
|
| 95 | } |
96 | } |
| 96 | 97 | ||
| 97 | int main() { |
98 | int main() { |
| 98 | void (*app_reset)(void) = 0; |
99 | void (*app_reset)(void) = 0; |
| 99 | 100 | ||
| Line 114... | Line 115... | ||
| 114 | IVSEL_REG = _BV(IVSEL); |
115 | IVSEL_REG = _BV(IVSEL); |
| 115 | sei(); |
116 | sei(); |
| 116 | 117 | ||
| 117 | printf("AVR BIOS\n"); |
118 | printf("AVR BIOS\n"); |
| 118 | 119 | ||
| - | 120 | if (pgm_read_word(0) != 0xffff) { |
|
| - | 121 | printf("Starting application.\n"); |
|
| - | 122 | app_reset(); |
|
| - | 123 | } |
|
| - | 124 | ||
| - | 125 | printf("No application found.\n"); |
|
| 119 | 126 | ||
| - | 127 | printf("\n------------------------------------------------------------\n"); |
|
| - | 128 | printf( " CAN Test: Periodic Transmission\n"); |
|
| - | 129 | printf( "------------------------------------------------------------\n"); |
|
| - | 130 | ||
| 120 | printf("CanInit..."); |
131 | printf("CanInit...\n"); |
| 121 | if (Can_Init() != CAN_OK) { |
132 | if (Can_Init() != CAN_OK) { |
| 122 | printf("FAILED!\n"); |
133 | printf("FAILED!\n"); |
| 123 | } |
134 | } |
| 124 | else { |
135 | else { |
| 125 | printf("OK!\n"); |
136 | printf("OK!\n"); |
| 126 | } |
137 | } |
| 127 | 138 | ||
| 128 | uint32_t timeStamp = 0; |
139 | uint32_t timeStamp = 0; |
| 129 | 140 | ||
| 130 | Can_Message_t txMsg; |
141 | Can_Message_t txMsg; |
| 131 | Can_Message_t rxMsg; |
- | |
| 132 | //The databytes are just what happens to be in the memory. They are never set. |
142 | //The databytes are just what happens to be in the memory. They are never set. |
| 133 | txMsg.RemoteFlag = 0; |
143 | txMsg.RemoteFlag = 0; |
| 134 | txMsg.ExtendedFlag = 1; |
144 | txMsg.ExtendedFlag = 1; |
| 135 | - | ||
| - | 145 | #define NODENUMBER 2 |
|
| - | 146 | #if NODENUMBER == 1 |
|
| 136 | txMsg.Id = |
147 | txMsg.Id = 16; |
| 137 | txMsg.DataLength = 2; |
148 | txMsg.DataLength = 2; |
| 138 | - | ||
| - | 149 | #elif NODENUMBER == 2 |
|
| 139 |
|
150 | txMsg.Id = 32; |
| 140 |
|
151 | txMsg.DataLength = 5; |
| - | 152 | #else |
|
| 141 |
|
153 | # error NODENUMBER not set! |
| - | 154 | #endif |
|
| 142 | 155 | ||
| 143 | uint8_t i; |
- | |
| 144 | /* main loop */ |
156 | /* main loop */ |
| 145 | while (1) { |
157 | while (1) { |
| 146 | /* service the CAN routines */ |
- | |
| 147 | Can_Service(); |
- | |
| 148 | 158 | ||
| 149 | /* send CAN message and check for CAN errors once every second */ |
159 | /* send CAN message and check for CAN errors once every second */ |
| 150 | if ((timebase_get() - timeStamp) >= |
160 | if ((timebase_get() - timeStamp) >= 1000) { |
| 151 | timeStamp = timebase_get(); |
161 | timeStamp = timebase_get(); |
| 152 | - | ||
| 153 | /* send txMsg */ |
162 | /* send txMsg */ |
| 154 |
|
163 | txMsg.Id++; |
| 155 | Can_Send(&txMsg); |
164 | Can_Send(&txMsg); |
| 156 | - | ||
| 157 | if (prg_state==PRG_STATE_IDLE) { |
- | |
| 158 | if (pgm_read_word(0) != 0xffff) { |
- | |
| 159 | printf("Starting application.\n"); |
- | |
| 160 | app_reset(); |
- | |
| 161 | } |
- | |
| 162 | printf("No application found.\n"); |
- | |
| 163 | } |
- | |
| 164 | } |
- | |
| 165 | - | ||
| 166 | /* check if any messages have been received */ |
- | |
| 167 | while (Can_Receive(&rxMsg) == CAN_OK) { |
- | |
| 168 | printf("BIOS Received: ID=%lx, DLC=%u, EXT=%u, RTR=%u, ", rxMsg.Id, (uint16_t)(rxMsg.DataLength), (uint16_t)(rxMsg.ExtendedFlag), (uint16_t)(rxMsg.RemoteFlag)); |
- | |
| 169 | printf("data={ "); |
- | |
| 170 | for (i=0; i<rxMsg.DataLength; i++) { |
- | |
| 171 | printf("%x ", rxMsg.Data.bytes[i]); |
- | |
| 172 | } |
- | |
| 173 | printf("}\n"); |
- | |
| 174 | - | ||
| 175 | if ((rxMsg.Id & FUNCTmask) == ((uint32_t)FUNCTbios<<FUNCTshift)) { |
- | |
| 176 | //printf("Got 'bios package'\n"); |
- | |
| 177 | //om mottagen data är bois-data (detta borde redan filtrerats i can_receive?) |
- | |
| 178 | if ((prg_state==PRG_STATE_IDLE) && ((rxMsg.Id & FUNCCmask) == ((uint32_t)FUNCCstartprg<<FUNCCshift)) && (rxMsg.DataLength == 6)) { |
- | |
| 179 | //om mottagen data har funktionskoden starta programmering |
- | |
| 180 | - | ||
| 181 | //ska kolla om nod-id i IDENT stämmer med nodens id |
- | |
| 182 | //om ok: |
- | |
| 183 | prg_state=PRG_STATE_PROGRAMMING; |
- | |
| 184 | address = rxMsg.Data.bytes[2]; |
- | |
| 185 | address |= rxMsg.Data.bytes[3]; |
- | |
| 186 | printf("Got 'start programming' at address %x\n", address); |
- | |
| 187 | } else if (prg_state==PRG_STATE_PROGRAMMING) { |
- | |
| 188 | if ((rxMsg.Id & FUNCCmask) == ((uint32_t)FUNCCprgdata<<FUNCCshift)) { |
- | |
| 189 | //om mottagen data har funktionskoden programdata |
- | |
| 190 | uint16_t tmpaddress = rxMsg.Data.bytes[0] + (rxMsg.Data.bytes[1] << 8); |
- | |
| 191 | if (tmpaddress >= lastoffset) { |
- | |
| 192 | tmpaddress += address; |
- | |
| 193 | printf("Got 'programdatapacket' at offset %x\n", tmpaddress); |
- | |
| 194 | for (i=2; i<rxMsg.DataLength; i+=2) { |
- | |
| 195 | flash_write_word(tmpaddress, rxMsg.Data.bytes[i] + (rxMsg.Data.bytes[i+1] << 8)); |
- | |
| 196 | tmpaddress+=2; |
- | |
| 197 | } |
- | |
| 198 | printf("Setting lastoffset to %x\n", tmpaddress); |
- | |
| 199 | lastoffset = tmpaddress; |
- | |
| 200 | } |
- | |
| 201 | } else if ((rxMsg.Id & FUNCCmask) == ((uint32_t)FUNCCstopprg<<FUNCCshift)) { |
- | |
| 202 | flash_flush_buffer(); |
- | |
| 203 | prg_state=PRG_STATE_IDLE; |
- | |
| 204 | lastoffset=0x0; |
- | |
| 205 | //beräkna crc på all programdata mellan address och address+lastoffset |
- | |
| 206 | printf("Got 'end programming'\n"); |
- | |
| 207 | } |
- | |
| 208 | } |
- | |
| 209 | } |
- | |
| 210 | - | ||
| 211 | //if (rxMsg.Id % 20 == 19) reset(); |
- | |
| 212 | } |
165 | } |
| 213 | } |
166 | } |
| 214 | 167 | ||
| 215 | return 0; |
168 | return 0; |
| 216 | } |
169 | } |