Rev 270 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 270 | Rev 758 | ||
|---|---|---|---|
| 1 | #include "DownloadState.h" |
1 | #include "DownloadState.h" |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | 4 | ||
| 5 | static HexFile * hf; |
5 | static HexFile * hf; |
| 6 | //static CSerial * serial; |
6 | //static CSerial * serial; |
| 7 | static SerialConnection * serial; |
7 | static SerialConnection * serial; |
| 8 | 8 | ||
| 9 | static HANDLE hRunMutex; // "Keep Running" mutex |
9 | static HANDLE hRunMutex; // "Keep Running" mutex |
| 10 | 10 | ||
| 11 | void downloadState(void *pMyID); |
11 | void downloadState(void *pMyID); |
| 12 | 12 | ||
| 13 | typedef enum { SEND_START, WAIT_ACK, SEND_PGM_DATA, WAIT_OWN_PACKET, WAIT_PGM_ACK, RESEND_ADDR, WAIT_DONE, SEND_DONE, DONE, WAIT_ADDR_ACK,DEBUG_STATE1,DEBUG_STATE2 } dState; |
13 | typedef enum { SEND_START, WAIT_ACK, SEND_PGM_DATA, WAIT_OWN_PACKET, WAIT_PGM_ACK, RESEND_ADDR, WAIT_DONE, SEND_DONE, DONE, WAIT_ADDR_ACK,DEBUG_STATE1,DEBUG_STATE2 } dState; |
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | void downloadState(void *pMyID) |
16 | void downloadState(void *pMyID) |
| 17 | { |
17 | { |
| 18 | long lLastError = 0; |
18 | long lLastError = 0; |
| 19 | 19 | ||
| 20 | dState pgs = SEND_START; |
20 | dState pgs = SEND_START; |
| 21 | DWORD t = 0; |
21 | DWORD t = 0; |
| 22 | CanProtoMessage * outCm = (CanProtoMessage *)malloc(sizeof(CanProtoMessage)); |
22 | CanProtoMessage * outCm = (CanProtoMessage *)malloc(sizeof(CanProtoMessage)); |
| 23 | CanProtoMessage * cm = (CanProtoMessage *)malloc(sizeof(CanProtoMessage)); |
23 | CanProtoMessage * cm = (CanProtoMessage *)malloc(sizeof(CanProtoMessage)); |
| 24 | unsigned char data[8]; |
24 | unsigned char data[8]; |
| 25 | unsigned char byteSent = 0; |
25 | unsigned char byteSent = 0; |
| 26 | unsigned long currentAddress = 0; |
26 | unsigned long currentAddress = 0; |
| 27 | unsigned char bytesToWrite[PACKET_LENGTH]; |
27 | unsigned char bytesToWrite[PACKET_LENGTH]; |
| 28 | 28 | ||
| 29 | while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT ) |
29 | while ( WaitForSingleObject( hRunMutex, 75L ) == WAIT_TIMEOUT ) |
| 30 | { |
30 | { |
| 31 | 31 | ||
| 32 | bool hasMessage = serial->getMessage(cm); |
32 | bool hasMessage = serial->getMessage(cm); |
| 33 | if (hasMessage) |
33 | if (hasMessage) |
| 34 | { |
34 | { |
| 35 | unsigned char *dtmp = cm->getData(); |
35 | unsigned char *dtmp = cm->getData(); |
| 36 | for(int i=0;i<8;i++) data[i]=dtmp[i]; |
36 | for(int i=0;i<8;i++) data[i]=dtmp[i]; |
| 37 | printf("[%ld] Has message\n",GetTickCount()); |
37 | printf("[%ld] Has message\n",GetTickCount()); |
| 38 | } |
38 | } |
| 39 | 39 | ||
| 40 | switch(pgs) |
40 | switch(pgs) |
| 41 | { |
41 | { |
| 42 | case SEND_START: |
42 | case SEND_START: |
| 43 | // Send boot start packet to target. |
43 | // Send boot start packet to target. |
| 44 | // and wait for ack. |
44 | // and wait for ack. |
| 45 | currentAddress = hf->getAddrLower(); |
45 | currentAddress = hf->getAddrLower(); |
| 46 | data[RID_INDEX] = TARGET_ID; |
46 | data[RID_INDEX] = TARGET_ID; |
| 47 | data[ADDRU_INDEX] = (unsigned char)((currentAddress & 0xFF0000) >> 16); |
47 | data[ADDRU_INDEX] = (unsigned char)((currentAddress & 0xFF0000) >> 16); |
| 48 | data[ADDRH_INDEX] = (unsigned char)((currentAddress & 0xFF00) >> 8); |
48 | data[ADDRH_INDEX] = (unsigned char)((currentAddress & 0xFF00) >> 8); |
| 49 | data[ADDRL_INDEX] = (unsigned char)(currentAddress & 0xFF); |
49 | data[ADDRL_INDEX] = (unsigned char)(currentAddress & 0xFF); |
| 50 | outCm = &CanProtoMessage::CanProtoMessage(FUNCT_BOOTLOADER, FUNCC_BOOT_INIT, MY_NID, MY_ID, 8, data); |
50 | outCm = &CanProtoMessage::CanProtoMessage(FUNCT_BOOTLOADER, FUNCC_BOOT_INIT, MY_NID, MY_ID, 8, data); |
| 51 | outCm->getBytes(bytesToWrite); |
51 | outCm->getBytes(bytesToWrite); |
| 52 | serial->write(bytesToWrite,PACKET_LENGTH); |
52 | serial->write(bytesToWrite,PACKET_LENGTH); |
| 53 | t = GetTickCount(); |
53 | t = GetTickCount(); |
| 54 | pgs = WAIT_ACK; |
54 | pgs = WAIT_ACK; |
| 55 | break; |
55 | break; |
| 56 | 56 | ||
| 57 | 57 | ||
| 58 | case WAIT_ACK: |
58 | case WAIT_ACK: |
| 59 | 59 | ||
| 60 | // Check for timeout, resend start packet in that case.. |
60 | // Check for timeout, resend start packet in that case.. |
| 61 | if ((GetTickCount() - t) > TIMEOUT_MS) |
61 | if ((GetTickCount() - t) > TIMEOUT_MS) |
| 62 | { |
62 | { |
| 63 | pgs = SEND_START; |
63 | pgs = SEND_START; |
| 64 | } |
64 | } |
| 65 | 65 | ||
| 66 | // If received ack. |
66 | // If received ack. |
| 67 | if (hasMessage && cm->getFunct() == FUNCT_BOOTLOADER && cm->getFuncc() == FUNCC_BOOT_ACK && cm->getNid() == MY_NID && cm->getSid() == TARGET_ID) |
67 | if (hasMessage && cm->getFunct() == FUNCT_BOOTLOADER && cm->getFuncc() == FUNCC_BOOT_ACK && cm->getNid() == MY_NID && cm->getSid() == TARGET_ID) |
| 68 | { |
68 | { |
| 69 | // If no error |
69 | // If no error |
| 70 | if (data[ERR_INDEX] == ERR_NO_ERROR) |
70 | if (data[ERR_INDEX] == ERR_NO_ERROR) |
| 71 | { |
71 | { |
| 72 | // Start sending program data.. |
72 | // Start sending program data.. |
| 73 | byteSent = 0; |
73 | byteSent = 0; |
| 74 | pgs = SEND_PGM_DATA; |
74 | pgs = SEND_PGM_DATA; |
| 75 | } |
75 | } |
| 76 | else |
76 | else |
| 77 | { |
77 | { |
| 78 | // else resend start.. |
78 | // else resend start.. |
| 79 | pgs = SEND_START; |
79 | pgs = SEND_START; |
| 80 | } |
80 | } |
| 81 | } |
81 | } |
| 82 | break; |
82 | break; |
| 83 | 83 | ||
| 84 | case SEND_PGM_DATA: |
84 | case SEND_PGM_DATA: |
| 85 | // Send program data. |
85 | // Send program data. |
| 86 | for (int i = 0; i < 8; i++) |
86 | for (int i = 0; i < 8; i++) |
| 87 | { |
87 | { |
| 88 | // Populate data. |
88 | // Populate data. |
| 89 | data[i] = hf->getByte(currentAddress + i + byteSent); |
89 | data[i] = hf->getByte(currentAddress + i + byteSent); |
| 90 | } |
90 | } |
| 91 | outCm = &CanProtoMessage::CanProtoMessage(FUNCT_BOOTLOADER, (unsigned int)((unsigned int)((unsigned int)(floor(((double)byteSent/8.0)))<<2) + (FUNCC_BOOT_PGM)), MY_NID, MY_ID, 8, data); |
91 | outCm = &CanProtoMessage::CanProtoMessage(FUNCT_BOOTLOADER, (unsigned int)((unsigned int)((unsigned int)(floor(((double)byteSent/8.0)))<<2) + (FUNCC_BOOT_PGM)), MY_NID, MY_ID, 8, data); |
| 92 | outCm->getBytes(bytesToWrite); |
92 | outCm->getBytes(bytesToWrite); |
| 93 | serial->write(bytesToWrite,PACKET_LENGTH); |
93 | serial->write(bytesToWrite,PACKET_LENGTH); |
| 94 | t = GetTickCount(); |
94 | t = GetTickCount(); |
| 95 | pgs = WAIT_OWN_PACKET; |
95 | pgs = WAIT_OWN_PACKET; |
| 96 | break; |
96 | break; |
| 97 | 97 | ||
| 98 | case WAIT_OWN_PACKET: |
98 | case WAIT_OWN_PACKET: |
| 99 | // Wait reciving own packet, if timeout, resend last. |
99 | // Wait reciving own packet, if timeout, resend last. |
| 100 | if ((GetTickCount() - t) > TIMEOUT_MS) |
100 | if ((GetTickCount() - t) > TIMEOUT_MS) |
| 101 | { |
101 | { |
| 102 | //pgs = dState.SEND_PGM_DATA; |
102 | //pgs = dState.SEND_PGM_DATA; |
| 103 | pgs = RESEND_ADDR; |
103 | pgs = RESEND_ADDR; |
| 104 | } |
104 | } |
| 105 | 105 | ||
| 106 | // If received own packet.. |
106 | // If received own packet.. |
| 107 | if (hasMessage && outCm->equals(cm)) |
107 | if (hasMessage && outCm->equals(cm)) |
| 108 | { |
108 | { |
| 109 | 109 | ||
| 110 | byteSent += 8; |
110 | byteSent += 8; |
| 111 | 111 | ||
| 112 | // Check if 64 bytes sent or not.. |
112 | // Check if 64 bytes sent or not.. |
| 113 | if (byteSent == 64) |
113 | if (byteSent == 64) |
| 114 | { |
114 | { |
| 115 | // Yes, wait for ack. |
115 | // Yes, wait for ack. |
| 116 | t = GetTickCount(); |
116 | t = GetTickCount(); |
| 117 | pgs = WAIT_PGM_ACK; |
117 | pgs = WAIT_PGM_ACK; |
| 118 | } |
118 | } |
| 119 | else |
119 | else |
| 120 | { |
120 | { |
| 121 | // No, send more. |
121 | // No, send more. |
| 122 | pgs = SEND_PGM_DATA; |
122 | pgs = SEND_PGM_DATA; |
| 123 | } |
123 | } |
| 124 | 124 | ||
| 125 | } |
125 | } |
| 126 | break; |
126 | break; |
| 127 | 127 | ||
| 128 | 128 | ||
| 129 | case WAIT_PGM_ACK: |
129 | case WAIT_PGM_ACK: |
| 130 | // Wait for pgm ack. |
130 | // Wait for pgm ack. |
| 131 | if ((GetTickCount() - t) > 2*TIMEOUT_MS) |
131 | if ((GetTickCount() - t) > 2*TIMEOUT_MS) |
| 132 | { |
132 | { |
| 133 | // Woops, error. Resend address and start over. |
133 | // Woops, error. Resend address and start over. |
| 134 | pgs = RESEND_ADDR; |
134 | pgs = RESEND_ADDR; |
| 135 | } |
135 | } |
| 136 | 136 | ||
| 137 | // If received ack. |
137 | // If received ack. |
| 138 | if (hasMessage && cm->getFunct() == FUNCT_BOOTLOADER && cm->getFuncc() == FUNCC_BOOT_ACK && cm->getNid() == MY_NID && cm->getSid() == TARGET_ID) |
138 | if (hasMessage && cm->getFunct() == FUNCT_BOOTLOADER && cm->getFuncc() == FUNCC_BOOT_ACK && cm->getNid() == MY_NID && cm->getSid() == TARGET_ID) |
| 139 | { |
139 | { |
| 140 | // If no error |
140 | // If no error |
| 141 | if (data[ERR_INDEX] == ERR_NO_ERROR) |
141 | if (data[ERR_INDEX] == ERR_NO_ERROR) |
| 142 | { |
142 | { |
| 143 | currentAddress += 64; |
143 | currentAddress += 64; |
| 144 | // Check if end. |
144 | // Check if end. |
| 145 | if (currentAddress > hf->getAddrUpper()) |
145 | if (currentAddress > hf->getAddrUpper()) |
| 146 | { |
146 | { |
| 147 | // Yes, we are done, send done. |
147 | // Yes, we are done, send done. |
| 148 | pgs = SEND_DONE; |
148 | pgs = SEND_DONE; |
| 149 | } |
149 | } |
| 150 | else |
150 | else |
| 151 | { |
151 | { |
| 152 | // More to write. |
152 | // More to write. |
| 153 | byteSent = 0; |
153 | byteSent = 0; |
| 154 | pgs = SEND_PGM_DATA; |
154 | pgs = SEND_PGM_DATA; |
| 155 | } |
155 | } |
| 156 | } |
156 | } |
| 157 | else |
157 | else |
| 158 | { |
158 | { |
| 159 | // else resend start.. |
159 | // else resend start.. |
| 160 | pgs = RESEND_ADDR; |
160 | pgs = RESEND_ADDR; |
| 161 | } |
161 | } |
| 162 | } |
162 | } |
| 163 | break; |
163 | break; |
| 164 | 164 | ||
| 165 | 165 | ||
| 166 | case SEND_DONE: |
166 | case SEND_DONE: |
| 167 | // Send done |
167 | // Send done |
| 168 | outCm = &CanProtoMessage::CanProtoMessage(FUNCT_BOOTLOADER, FUNCC_BOOT_DONE, MY_NID, MY_ID, 8, data); |
168 | outCm = &CanProtoMessage::CanProtoMessage(FUNCT_BOOTLOADER, FUNCC_BOOT_DONE, MY_NID, MY_ID, 8, data); |
| 169 | outCm->getBytes(bytesToWrite); |
169 | outCm->getBytes(bytesToWrite); |
| 170 | serial->write(bytesToWrite,PACKET_LENGTH); |
170 | serial->write(bytesToWrite,PACKET_LENGTH); |
| 171 | t = GetTickCount(); |
171 | t = GetTickCount(); |
| 172 | pgs = WAIT_DONE; |
172 | pgs = WAIT_DONE; |
| 173 | break; |
173 | break; |
| 174 | 174 | ||
| 175 | case RESEND_ADDR: |
175 | case RESEND_ADDR: |
| 176 | // Resend addr. |
176 | // Resend addr. |
| 177 | data[RID_INDEX] = TARGET_ID; |
177 | data[RID_INDEX] = TARGET_ID; |
| 178 | data[ADDRU_INDEX] = (byte)((currentAddress & 0xFF0000) >> 16); |
178 | data[ADDRU_INDEX] = (byte)((currentAddress & 0xFF0000) >> 16); |
| 179 | data[ADDRH_INDEX] = (byte)((currentAddress & 0xFF00) >> 8); |
179 | data[ADDRH_INDEX] = (byte)((currentAddress & 0xFF00) >> 8); |
| 180 | data[ADDRL_INDEX] = (byte)(currentAddress & 0xFF); |
180 | data[ADDRL_INDEX] = (byte)(currentAddress & 0xFF); |
| 181 | outCm = &CanProtoMessage::CanProtoMessage(FUNCT_BOOTLOADER, FUNCC_BOOT_ADDR, MY_NID, MY_ID, 8, data); |
181 | outCm = &CanProtoMessage::CanProtoMessage(FUNCT_BOOTLOADER, FUNCC_BOOT_ADDR, MY_NID, MY_ID, 8, data); |
| 182 | outCm->getBytes(bytesToWrite); |
182 | outCm->getBytes(bytesToWrite); |
| 183 | serial->write(bytesToWrite,PACKET_LENGTH); |
183 | serial->write(bytesToWrite,PACKET_LENGTH); |
| 184 | t = GetTickCount(); |
184 | t = GetTickCount(); |
| 185 | pgs = WAIT_ADDR_ACK; |
185 | pgs = WAIT_ADDR_ACK; |
| 186 | break; |
186 | break; |
| 187 | 187 | ||
| 188 | 188 | ||
| 189 | case WAIT_ADDR_ACK: |
189 | case WAIT_ADDR_ACK: |
| 190 | // Check for timeout, resend addr packet in that case.. |
190 | // Check for timeout, resend addr packet in that case.. |
| 191 | if ((GetTickCount() - t) > TIMEOUT_MS) |
191 | if ((GetTickCount() - t) > TIMEOUT_MS) |
| 192 | { |
192 | { |
| 193 | pgs = RESEND_ADDR; |
193 | pgs = RESEND_ADDR; |
| 194 | } |
194 | } |
| 195 | 195 | ||
| 196 | // If received ack. |
196 | // If received ack. |
| 197 | if (hasMessage && cm->getFunct() == FUNCT_BOOTLOADER && cm->getFuncc() == FUNCC_BOOT_ACK && cm->getNid() == MY_NID && cm->getSid() == TARGET_ID) |
197 | if (hasMessage && cm->getFunct() == FUNCT_BOOTLOADER && cm->getFuncc() == FUNCC_BOOT_ACK && cm->getNid() == MY_NID && cm->getSid() == TARGET_ID) |
| 198 | { |
198 | { |
| 199 | // If no error |
199 | // If no error |
| 200 | if (data[ERR_INDEX] == ERR_NO_ERROR) |
200 | if (data[ERR_INDEX] == ERR_NO_ERROR) |
| 201 | { |
201 | { |
| 202 | // Start sending program data.. |
202 | // Start sending program data.. |
| 203 | byteSent = 0; |
203 | byteSent = 0; |
| 204 | pgs = SEND_PGM_DATA; |
204 | pgs = SEND_PGM_DATA; |
| 205 | } |
205 | } |
| 206 | else |
206 | else |
| 207 | { |
207 | { |
| 208 | // else resend addr.. |
208 | // else resend addr.. |
| 209 | pgs = RESEND_ADDR; |
209 | pgs = RESEND_ADDR; |
| 210 | } |
210 | } |
| 211 | } |
211 | } |
| 212 | break; |
212 | break; |
| 213 | 213 | ||
| 214 | case WAIT_DONE: |
214 | case WAIT_DONE: |
| 215 | // Check for timeout, resend done packet in that case.. |
215 | // Check for timeout, resend done packet in that case.. |
| 216 | if ((GetTickCount() - t) > TIMEOUT_MS) |
216 | if ((GetTickCount() - t) > TIMEOUT_MS) |
| 217 | { |
217 | { |
| 218 | pgs = SEND_DONE; |
218 | pgs = SEND_DONE; |
| 219 | } |
219 | } |
| 220 | 220 | ||
| 221 | // If received ack. |
221 | // If received ack. |
| 222 | if (hasMessage && cm->getFunct() == FUNCT_BOOTLOADER && cm->getFuncc() == FUNCC_BOOT_ACK && cm->getNid() == MY_NID && cm->getSid() == TARGET_ID) |
222 | if (hasMessage && cm->getFunct() == FUNCT_BOOTLOADER && cm->getFuncc() == FUNCC_BOOT_ACK && cm->getNid() == MY_NID && cm->getSid() == TARGET_ID) |
| 223 | { |
223 | { |
| 224 | // If no error |
224 | // If no error |
| 225 | if (data[ERR_INDEX] == ERR_NO_ERROR) |
225 | if (data[ERR_INDEX] == ERR_NO_ERROR) |
| 226 | { |
226 | { |
| 227 | // Start sending program data.. |
227 | // Start sending program data.. |
| 228 | byteSent = 0; |
228 | byteSent = 0; |
| 229 | pgs = DONE; |
229 | pgs = DONE; |
| 230 | } |
230 | } |
| 231 | else |
231 | else |
| 232 | { |
232 | { |
| 233 | // else resend addr.. |
233 | // else resend addr.. |
| 234 | pgs = RESEND_ADDR; |
234 | pgs = RESEND_ADDR; |
| 235 | } |
235 | } |
| 236 | } |
236 | } |
| 237 | break; |
237 | break; |
| 238 | 238 | ||
| 239 | case DONE: |
239 | case DONE: |
| 240 | downloadStop(); |
240 | downloadStop(); |
| 241 | printf("DONE!\n"); |
241 | printf("DONE!\n"); |
| 242 | break; |
242 | break; |
| 243 | } |
243 | } |
| 244 | } |
244 | } |
| 245 | 245 | ||
| 246 | return; |
246 | return; |
| 247 | } |
247 | } |
| 248 | 248 | ||
| 249 | 249 | ||
| 250 | void downloadStart(SerialConnection * ser,HexFile *hex) |
250 | void downloadStart(SerialConnection * ser,HexFile *hex) |
| 251 | { |
251 | { |
| 252 | hf = hex; |
252 | hf = hex; |
| 253 | serial = ser; |
253 | serial = ser; |
| 254 | hRunMutex = CreateMutex( NULL, TRUE, NULL ); // Set |
254 | hRunMutex = CreateMutex( NULL, TRUE, NULL ); // Set |
| 255 | _beginthread( downloadState, 0, 0 ); |
255 | _beginthread( downloadState, 0, 0 ); |
| 256 | 256 | ||
| 257 | } |
257 | } |
| 258 | 258 | ||
| 259 | void downloadStop( void ) |
259 | void downloadStop( void ) |
| 260 | { |
260 | { |
| 261 | ReleaseMutex( hRunMutex ); |
261 | ReleaseMutex( hRunMutex ); |
| 262 | CloseHandle( hRunMutex ); |
262 | CloseHandle( hRunMutex ); |
| 263 | } |
263 | } |
| 264 | 264 | ||
| 265 | 265 | ||