Mercurial > public > ostc4
annotate ostc4pack/src/OSTC4pack_V4.cpp @ 244:c20c73b0d034
Merged in janlmulder/ostc4/div-fixes-5 (pull request #15)
Improvement SPI stability/recoverability and cleanup, and trivial bugfixes
author | heinrichsweikamp <bitbucket@heinrichsweikamp.com> |
---|---|
date | Tue, 09 Apr 2019 08:52:44 +0000 |
parents | ad98da7e74f8 |
children | 01f40cb1057e |
rev | line source |
---|---|
49 | 1 #include <iostream> |
2 | |
3 /* run this program using the console pauser or add your own getch, system("pause") or input loop */ | |
4 | |
5 | |
6 | |
7 | |
8 #include <stdlib.h> | |
9 | |
10 /******************************************************************************/ | |
11 /* Start of crcmodel.h */ | |
12 /******************************************************************************/ | |
13 /* */ | |
14 /* Author : Ross Williams (ross@guest.adelaide.edu.au.). */ | |
15 /* Date : 3 June 1993. */ | |
16 /* Status : Public domain. */ | |
17 /* */ | |
18 /* Description : This is the header (.h) file for the reference */ | |
19 /* implementation of the Rocksoft^tm Model CRC Algorithm. For more */ | |
20 /* information on the Rocksoft^tm Model CRC Algorithm, see the document */ | |
21 /* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */ | |
22 /* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */ | |
23 /* "ftp.adelaide.edu.au/pub/rocksoft". */ | |
24 /* */ | |
25 /* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */ | |
26 /* */ | |
27 /******************************************************************************/ | |
28 /* */ | |
29 /* How to Use This Package */ | |
30 /* ----------------------- */ | |
31 /* Step 1: Declare a variable of type cm_t. Declare another variable */ | |
32 /* (p_cm say) of type p_cm_t and initialize it to point to the first */ | |
33 /* variable (e.g. p_cm_t p_cm = &cm_t). */ | |
34 /* */ | |
35 /* Step 2: Assign values to the parameter fields of the structure. */ | |
36 /* If you don't know what to assign, see the document cited earlier. */ | |
37 /* For example: */ | |
38 /* p_cm->cm_width = 16; */ | |
39 /* p_cm->cm_poly = 0x8005L; */ | |
40 /* p_cm->cm_init = 0L; */ | |
41 /* p_cm->cm_refin = TRUE; */ | |
42 /* p_cm->cm_refot = TRUE; */ | |
43 /* p_cm->cm_xorot = 0L; */ | |
44 /* Note: Poly is specified without its top bit (18005 becomes 8005). */ | |
45 /* Note: Width is one bit less than the raw poly width. */ | |
46 /* */ | |
47 /* Step 3: Initialize the instance with a call cm_ini(p_cm); */ | |
48 /* */ | |
49 /* Step 4: Process zero or more message bytes by placing zero or more */ | |
50 /* successive calls to cm_nxt. Example: cm_nxt(p_cm,ch); */ | |
51 /* */ | |
52 /* Step 5: Extract the CRC value at any time by calling crc = cm_crc(p_cm); */ | |
53 /* If the CRC is a 16-bit value, it will be in the bottom 16 bits. */ | |
54 /* */ | |
55 /******************************************************************************/ | |
56 /* */ | |
57 /* Design Notes */ | |
58 /* ------------ */ | |
59 /* PORTABILITY: This package has been coded very conservatively so that */ | |
60 /* it will run on as many machines as possible. For example, all external */ | |
61 /* identifiers have been restricted to 6 characters and all internal ones to */ | |
62 /* 8 characters. The prefix cm (for Crc Model) is used as an attempt to avoid */ | |
63 /* namespace collisions. This package is endian independent. */ | |
64 /* */ | |
65 /* EFFICIENCY: This package (and its interface) is not designed for */ | |
66 /* speed. The purpose of this package is to act as a well-defined reference */ | |
67 /* model for the specification of CRC algorithms. If you want speed, cook up */ | |
68 /* a specific table-driven implementation as described in the document cited */ | |
69 /* above. This package is designed for validation only; if you have found or */ | |
70 /* implemented a CRC algorithm and wish to describe it as a set of parameters */ | |
71 /* to the Rocksoft^tm Model CRC Algorithm, your CRC algorithm implementation */ | |
72 /* should behave identically to this package under those parameters. */ | |
73 /* */ | |
74 /******************************************************************************/ | |
75 | |
76 /* The following #ifndef encloses this entire */ | |
77 /* header file, rendering it indempotent. */ | |
78 #ifndef CM_DONE | |
79 #define CM_DONE | |
80 | |
81 /******************************************************************************/ | |
82 | |
83 /* The following definitions are extracted from my style header file which */ | |
84 /* would be cumbersome to distribute with this package. The DONE_STYLE is the */ | |
85 /* idempotence symbol used in my style header file. */ | |
86 | |
87 #ifndef DONE_STYLE | |
88 | |
89 typedef unsigned long ulong; | |
90 typedef unsigned char * p_ubyte_; | |
91 | |
92 #ifndef TRUE | |
93 #define FALSE 0 | |
94 #define TRUE 1 | |
95 #endif | |
96 | |
97 /* Change to the second definition if you don't have prototypes. */ | |
98 #define P_(A) A | |
99 /* #define P_(A) () */ | |
100 | |
101 /* Uncomment this definition if you don't have void. */ | |
102 /* typedef int void; */ | |
103 | |
104 #endif | |
105 | |
106 /******************************************************************************/ | |
107 | |
108 /* CRC Model Abstract Type */ | |
109 /* ----------------------- */ | |
110 /* The following type stores the context of an executing instance of the */ | |
111 /* model algorithm. Most of the fields are model parameters which must be */ | |
112 /* set before the first initializing call to cm_ini. */ | |
113 typedef struct | |
114 { | |
115 int cm_width; /* Parameter: Width in bits [8,32]. */ | |
116 ulong cm_poly; /* Parameter: The algorithm's polynomial. */ | |
117 ulong cm_init; /* Parameter: Initial register value. */ | |
118 bool cm_refin; /* Parameter: Reflect input bytes? */ | |
119 bool cm_refot; /* Parameter: Reflect output CRC? */ | |
120 ulong cm_xorot; /* Parameter: XOR this to output CRC. */ | |
121 | |
122 ulong cm_reg; /* Context: Context during execution. */ | |
123 } cm_t; | |
124 typedef cm_t *p_cm_t; | |
125 | |
126 /******************************************************************************/ | |
127 | |
128 /* Functions That Implement The Model */ | |
129 /* ---------------------------------- */ | |
130 /* The following functions animate the cm_t abstraction. */ | |
131 | |
132 void cm_ini P_((p_cm_t p_cm)); | |
133 /* Initializes the argument CRC model instance. */ | |
134 /* All parameter fields must be set before calling this. */ | |
135 | |
136 void cm_nxt P_((p_cm_t p_cm,int ch)); | |
137 /* Processes a single message byte [0,255]. */ | |
138 | |
139 void cm_blk P_((p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len)); | |
140 /* Processes a block of message bytes. */ | |
141 | |
142 ulong cm_crc P_((p_cm_t p_cm)); | |
143 /* Returns the CRC value for the message bytes processed so far. */ | |
144 | |
145 /******************************************************************************/ | |
146 | |
147 /* Functions For Table Calculation */ | |
148 /* ------------------------------- */ | |
149 /* The following function can be used to calculate a CRC lookup table. */ | |
150 /* It can also be used at run-time to create or check static tables. */ | |
151 | |
152 ulong cm_tab P_((p_cm_t p_cm,int index)); | |
153 /* Returns the i'th entry for the lookup table for the specified algorithm. */ | |
154 /* The function examines the fields cm_width, cm_poly, cm_refin, and the */ | |
155 /* argument table index in the range [0,255] and returns the table entry in */ | |
156 /* the bottom cm_width bytes of the return value. */ | |
157 | |
158 /******************************************************************************/ | |
159 | |
160 /* End of the header file idempotence #ifndef */ | |
161 #endif | |
162 | |
163 /******************************************************************************/ | |
164 /* End of crcmodel.h */ | |
165 /******************************************************************************/ | |
166 | |
167 | |
168 /******************************************************************************/ | |
169 /* Start of crcmodel.c */ | |
170 /******************************************************************************/ | |
171 /* */ | |
172 /* Author : Ross Williams (ross@guest.adelaide.edu.au.). */ | |
173 /* Date : 3 June 1993. */ | |
174 /* Status : Public domain. */ | |
175 /* */ | |
176 /* Description : This is the implementation (.c) file for the reference */ | |
177 /* implementation of the Rocksoft^tm Model CRC Algorithm. For more */ | |
178 /* information on the Rocksoft^tm Model CRC Algorithm, see the document */ | |
179 /* titled "A Painless Guide to CRC Error Detection Algorithms" by Ross */ | |
180 /* Williams (ross@guest.adelaide.edu.au.). This document is likely to be in */ | |
181 /* "ftp.adelaide.edu.au/pub/rocksoft". */ | |
182 /* */ | |
183 /* Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia. */ | |
184 /* */ | |
185 /******************************************************************************/ | |
186 /* */ | |
187 /* Implementation Notes */ | |
188 /* -------------------- */ | |
189 /* To avoid inconsistencies, the specification of each function is not echoed */ | |
190 /* here. See the header file for a description of these functions. */ | |
191 /* This package is light on checking because I want to keep it short and */ | |
192 /* simple and portable (i.e. it would be too messy to distribute my entire */ | |
193 /* C culture (e.g. assertions package) with this package. */ | |
194 /* */ | |
195 /******************************************************************************/ | |
196 | |
197 #include "crcmodel.h" | |
198 | |
199 /******************************************************************************/ | |
200 | |
201 /* The following definitions make the code more readable. */ | |
202 | |
203 #define BITMASK(X) (1L << (X)) | |
204 #define MASK32 0xFFFFFFFFL | |
205 #define LOCAL static | |
206 | |
207 /******************************************************************************/ | |
208 | |
209 ulong reflect P_((ulong v,int b)) | |
210 { | |
211 int i; | |
212 ulong t = v; | |
213 for (i=0; i<b; i++) | |
214 { | |
215 if (t & 1L) | |
216 v|= BITMASK((b-1)-i); | |
217 else | |
218 v&= ~BITMASK((b-1)-i); | |
219 t>>=1; | |
220 } | |
221 return v; | |
222 } | |
223 | |
224 /******************************************************************************/ | |
225 | |
226 LOCAL ulong widmask (p_cm_t p_cm) | |
227 { | |
228 return (((1L<<(p_cm->cm_width-1))-1L)<<1)|1L; | |
229 } | |
230 | |
231 /******************************************************************************/ | |
232 | |
233 void cm_ini (p_cm_t p_cm) | |
234 { | |
235 p_cm->cm_reg = p_cm->cm_init; | |
236 } | |
237 | |
238 /******************************************************************************/ | |
239 | |
240 void cm_nxt (p_cm_t p_cm,int ch) | |
241 { | |
242 int i; | |
243 ulong uch = (ulong) ch; | |
244 ulong topbit = BITMASK(p_cm->cm_width-1); | |
245 | |
246 if (p_cm->cm_refin) uch = reflect(uch,8); | |
247 p_cm->cm_reg ^= (uch << (p_cm->cm_width-8)); | |
248 for (i=0; i<8; i++) | |
249 { | |
250 if (p_cm->cm_reg & topbit) | |
251 p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly; | |
252 else | |
253 p_cm->cm_reg <<= 1; | |
254 p_cm->cm_reg &= widmask(p_cm); | |
255 } | |
256 } | |
257 | |
258 /******************************************************************************/ | |
259 | |
260 void cm_blk (p_cm_t p_cm,p_ubyte_ blk_adr,ulong blk_len) | |
261 { | |
262 while (blk_len--) cm_nxt(p_cm,*blk_adr++); | |
263 } | |
264 | |
265 /******************************************************************************/ | |
266 | |
267 ulong cm_crc (p_cm_t p_cm) | |
268 { | |
269 if (p_cm->cm_refot) | |
270 return p_cm->cm_xorot ^ reflect(p_cm->cm_reg,p_cm->cm_width); | |
271 else | |
272 return p_cm->cm_xorot ^ p_cm->cm_reg; | |
273 } | |
274 | |
275 /******************************************************************************/ | |
276 | |
277 ulong cm_tab (p_cm_t p_cm,int index) | |
278 { | |
279 int i; | |
280 ulong r; | |
281 ulong topbit = BITMASK(p_cm->cm_width-1); | |
282 ulong inbyte = (ulong) index; | |
283 | |
284 if (p_cm->cm_refin) inbyte = reflect(inbyte,8); | |
285 r = inbyte << (p_cm->cm_width-8); | |
286 for (i=0; i<8; i++) | |
287 if (r & topbit) | |
288 r = (r << 1) ^ p_cm->cm_poly; | |
289 else | |
290 r<<=1; | |
291 if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width); | |
292 return r & widmask(p_cm); | |
293 } | |
294 | |
295 /******************************************************************************/ | |
296 /* End of crcmodel.c */ | |
297 /******************************************************************************/ | |
298 | |
299 #define uint32_t unsigned int | |
300 #define uint8_t unsigned char | |
301 | |
302 uint32_t CRC_CalcBlockCRC(uint32_t *buffer, uint32_t words) | |
303 { | |
304 cm_t crc_model; | |
305 uint32_t word_to_do; | |
306 uint8_t byte_to_do; | |
307 int i; | |
308 | |
309 // Values for the STM32F generator. | |
310 | |
311 crc_model.cm_width = 32; // 32-bit CRC | |
312 crc_model.cm_poly = 0x04C11DB7; // CRC-32 polynomial | |
313 crc_model.cm_init = 0xFFFFFFFF; // CRC initialized to 1's | |
314 crc_model.cm_refin = FALSE; // CRC calculated MSB first | |
315 crc_model.cm_refot = FALSE; // Final result is not bit-reversed | |
316 crc_model.cm_xorot = 0x00000000; // Final result XOR'ed with this | |
317 | |
318 cm_ini(&crc_model); | |
319 | |
320 while (words--) | |
321 { | |
322 // The STM32F10x hardware does 32-bit words at a time!!! | |
323 | |
324 word_to_do = *buffer++; | |
325 | |
326 // Do all bytes in the 32-bit word. | |
327 | |
328 for (i = 0; i < sizeof(word_to_do); i++) | |
329 { | |
330 // We calculate a *byte* at a time. If the CRC is MSB first we | |
331 // do the next MS byte and vica-versa. | |
332 | |
333 if (crc_model.cm_refin == FALSE) | |
334 { | |
335 // MSB first. Do the next MS byte. | |
336 | |
337 byte_to_do = (uint8_t) ((word_to_do & 0xFF000000) >> 24); | |
338 word_to_do <<= 8; | |
339 } | |
340 else | |
341 { | |
342 // LSB first. Do the next LS byte. | |
343 | |
344 byte_to_do = (uint8_t) (word_to_do & 0x000000FF); | |
345 word_to_do >>= 8; | |
346 } | |
347 | |
348 cm_nxt(&crc_model, byte_to_do); | |
349 } | |
350 } | |
351 | |
352 // Return the final result. | |
353 | |
354 return (cm_crc(&crc_model)); | |
355 } | |
356 | |
357 | |
358 unsigned checksum(void *buffer, size_t len, unsigned int seed) | |
359 { | |
360 unsigned char *buf = (unsigned char *)buffer; | |
361 size_t i; | |
362 | |
363 for (i = 0; i < len; ++i) | |
364 seed += (unsigned int)(*buf++); | |
365 return seed; | |
366 } | |
367 | |
368 unsigned int crc32c_checksum(unsigned char* message, int length) { | |
369 int i, j; | |
370 unsigned int byte, crc, mask; | |
371 static unsigned int table[256] = {0}; | |
372 | |
373 /* Set up the table, if necessary. */ | |
374 | |
375 if (table[1] == 0) { | |
376 for (byte = 0; byte <= 255; byte++) { | |
377 crc = byte; | |
378 for (j = 7; j >= 0; j--) { // Do eight times. | |
379 mask = -(crc & 1); | |
380 crc = (crc >> 1) ^ (0xEDB88320 & mask); | |
381 } | |
382 table[byte] = crc; | |
383 } | |
384 } | |
385 | |
386 /* Through with table setup, now calculate the CRC. */ | |
387 i = 0; | |
388 crc = 0xFFFFFFFF; | |
389 while (length--) { | |
390 byte = message[i]; | |
391 crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF]; | |
392 i = i + 1; | |
393 } | |
394 return ~crc; | |
395 } | |
396 | |
397 | |
398 | |
399 | |
400 | |
401 | |
402 /******************************************************************************/ | |
403 | |
404 /* MAIN */ | |
405 /* ----------------------- */ | |
406 /* */ | |
407 | |
408 | |
409 #include <stdio.h> | |
410 #include <string.h> | |
411 int main(int argc, char** argv) { | |
412 | |
413 | |
162
ad98da7e74f8
OSTC4pack_V4: do not hard code output filename for fonts
Jan Mulder <jlmulder@xs4all.nl>
parents:
49
diff
changeset
|
414 if (argc != 3) { |
ad98da7e74f8
OSTC4pack_V4: do not hard code output filename for fonts
Jan Mulder <jlmulder@xs4all.nl>
parents:
49
diff
changeset
|
415 fprintf(stderr, "Usage: OSTC4pack_V4 <type> <bin file>\n"); |
ad98da7e74f8
OSTC4pack_V4: do not hard code output filename for fonts
Jan Mulder <jlmulder@xs4all.nl>
parents:
49
diff
changeset
|
416 return(-1); |
ad98da7e74f8
OSTC4pack_V4: do not hard code output filename for fonts
Jan Mulder <jlmulder@xs4all.nl>
parents:
49
diff
changeset
|
417 } |
ad98da7e74f8
OSTC4pack_V4: do not hard code output filename for fonts
Jan Mulder <jlmulder@xs4all.nl>
parents:
49
diff
changeset
|
418 |
49 | 419 FILE *fp, * fpout; |
420 size_t len; | |
421 unsigned char buf[1050000]; | |
422 char *file = argv[2]; | |
423 int type = atoi(argv[1]); | |
424 unsigned int pruefsumme; | |
425 | |
426 //write File with length and cheksum | |
427 char filename[500], filenameout[510] ; | |
428 sprintf(filename,"%s",file); | |
429 int filelength = strlen(filename); | |
430 filename[filelength -4] = 0; | |
431 | |
432 if (NULL == (fp = fopen(file, "rb"))) | |
433 { | |
434 printf("Unable to open %s for reading\n", file); | |
435 return -1; | |
436 } | |
437 len = fread(buf, sizeof(char), sizeof(buf), fp); | |
438 printf("%d bytes read (hex: %#x )\n", len,len); | |
439 // unsigned int checksum = crc32c_checksum(buf, len); | |
440 unsigned int checksum = CRC_CalcBlockCRC((uint32_t *)buf, (uint32_t)(len/4)); | |
441 printf("The checksum of %s is %#x\n", file, checksum); | |
442 | |
443 fclose(fp); | |
444 if(type == 0) | |
445 sprintf(filenameout,"%s_upload.bin",filename); | |
446 else | |
447 if(type == 2) | |
162
ad98da7e74f8
OSTC4pack_V4: do not hard code output filename for fonts
Jan Mulder <jlmulder@xs4all.nl>
parents:
49
diff
changeset
|
448 sprintf(filenameout,"%s_upload.bin",filename); |
49 | 449 else |
450 sprintf(filenameout,"%s_upload.bin",filename); | |
451 | |
452 unsigned char buf2[4]; | |
453 | |
454 buf2[0] = 0xFF & (len >> 24);; | |
455 buf2[1] = 0xFF & (len >> 16);; | |
456 buf2[2] = 0xFF & (len >> 8); | |
457 buf2[3] = 0xFF & len; | |
458 fpout = fopen(filenameout, "wb"); | |
459 fwrite(buf2,sizeof(char),4,fp); | |
460 | |
461 | |
462 unsigned char buf3offset[4]; | |
463 unsigned char bufVersion[4]; | |
464 if(type == 2) | |
465 { | |
466 buf3offset[0] = 0x10; | |
467 buf3offset[1] = 0x00; | |
468 buf3offset[2] = 0x03; | |
469 buf3offset[3] = 0x20; | |
470 bufVersion[0] = buf[0x00]; | |
471 bufVersion[1] = buf[0x01]; | |
472 bufVersion[2] = buf[0x02]; | |
473 bufVersion[3] = buf[0x03]; | |
474 } | |
475 else | |
476 if(type == 0) | |
477 { | |
478 buf3offset[0] = 0xFE; | |
479 buf3offset[1] = 'R'; | |
480 buf3offset[2] = 'T'; | |
481 buf3offset[3] = 'E'; | |
482 bufVersion[0] = buf[0x5000]; | |
483 bufVersion[1] = buf[0x5001]; | |
484 bufVersion[2] = buf[0x5002]; | |
485 bufVersion[3] = buf[0x5003]; | |
486 } | |
487 else | |
488 { | |
489 buf3offset[0] = 0xFF; | |
490 buf3offset[1] = 0; | |
491 buf3offset[2] = 'H'; | |
492 buf3offset[3] = 'W'; | |
493 bufVersion[0] = buf[0x10000]; | |
494 bufVersion[1] = buf[0x10001]; | |
495 bufVersion[2] = buf[0x10002]; | |
496 bufVersion[3] = buf[0x10003]; | |
497 } | |
498 | |
499 fwrite(buf3offset,sizeof(char),4,fp); | |
500 | |
501 pruefsumme = len + (256*256*256*buf3offset[0]) + (256*256*buf3offset[1]) + (256*buf3offset[2]) + buf3offset[3]; | |
502 fwrite(&pruefsumme,sizeof(char),4,fp); | |
503 | |
504 fwrite(bufVersion,sizeof(char),4,fp); | |
505 | |
506 for(int i = 0;i <len;i++) | |
507 { | |
508 if(fwrite(&buf[i],1,1,fpout) != 1) | |
509 printf("error writing\n"); | |
510 } | |
511 | |
512 | |
513 buf2[0] = 0xFF & (checksum >> 24);// & 0xFF000000; | |
514 buf2[1] = 0xFF & (checksum >> 16); | |
515 buf2[2] = 0xFF & (checksum >> 8); | |
516 buf2[3] = 0xFF & checksum; | |
517 | |
518 fwrite(buf2,sizeof(char),4,fp); | |
519 | |
520 } |