loadcommon.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. #define STAGEBASE 568
  2. #if 0
  3. static PROGMEM prog_uint32_t crc_table[16] = {
  4. 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
  5. 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
  6. 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
  7. 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
  8. };
  9. unsigned long crc_update(unsigned long crc, byte data)
  10. {
  11. uint_farptr_t tab = GET_FAR_ADDRESS(crc_table);
  12. byte tbl_idx;
  13. tbl_idx = crc ^ data;
  14. crc = pgm_read_dword_far(tab + 4 * (tbl_idx & 0x0f)) ^ (crc >> 4);
  15. tbl_idx = crc ^ (data >> 4);
  16. crc = pgm_read_dword_far(tab + 4 * (tbl_idx & 0x0f)) ^ (crc >> 4);
  17. return crc;
  18. }
  19. #else
  20. static uint32_t crc_table[16] = {
  21. 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
  22. 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
  23. 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
  24. 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
  25. };
  26. unsigned long crc_update(unsigned long crc, byte data)
  27. {
  28. byte tbl_idx;
  29. tbl_idx = crc ^ data;
  30. crc = crc_table[tbl_idx & 0x0f] ^ (crc >> 4);
  31. tbl_idx = crc ^ (data >> 4);
  32. crc = crc_table[tbl_idx & 0x0f] ^ (crc >> 4);
  33. return crc;
  34. }
  35. #endif
  36. class GDflashbits {
  37. public:
  38. void begin(prog_uchar *s) {
  39. src = s;
  40. mask = 0x01;
  41. }
  42. byte get1(void) {
  43. byte r = (pgm_read_byte_near(src) & mask) != 0;
  44. mask <<= 1;
  45. if (!mask) {
  46. mask = 1;
  47. src++;
  48. }
  49. return r;
  50. }
  51. unsigned short getn(byte n) {
  52. unsigned short r = 0;
  53. while (n--) {
  54. r <<= 1;
  55. r |= get1();
  56. }
  57. return r;
  58. }
  59. private:
  60. prog_uchar *src;
  61. byte mask;
  62. };
  63. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  64. // far ptr version
  65. class GDflashbitsF {
  66. public:
  67. void begin(uint_farptr_t s) {
  68. src = s;
  69. mask = 8;
  70. m = pgm_read_byte_far(src++);
  71. }
  72. byte get1(void) {
  73. byte r = (m & 1);
  74. m >>= 1;
  75. if (--mask == 0) {
  76. mask = 8;
  77. m = pgm_read_byte_far(src++);
  78. }
  79. return r;
  80. }
  81. unsigned short getn(byte n) {
  82. unsigned short r = 0;
  83. while (n--) {
  84. r <<= 1;
  85. r |= get1();
  86. }
  87. return r;
  88. }
  89. private:
  90. uint_farptr_t src;
  91. byte m, mask;
  92. };
  93. #endif
  94. static byte history[264], hp;
  95. int page, offset;
  96. #define FLOCAL 2
  97. #define SEL_local() digitalWrite(FLOCAL, LOW)
  98. #define UNSEL_local() digitalWrite(FLOCAL, HIGH)
  99. #define spix(n) SPI.transfer(n)
  100. static void spipage(int n)
  101. {
  102. spix(n >> 7);
  103. spix(n << 1);
  104. spix(0);
  105. }
  106. static byte status()
  107. {
  108. SEL_local();
  109. spix(0xd7); // read SPI flash status
  110. byte status = spix(0);
  111. UNSEL_local();
  112. return status;
  113. }
  114. static void UNSEL_local_wait()
  115. {
  116. UNSEL_local();
  117. while ((status() & 0x80) == 0)
  118. ;
  119. }
  120. static void pgcmd(byte cmd, int page)
  121. {
  122. SEL_local();
  123. spix(cmd);
  124. spipage(page);
  125. }
  126. static void supply(byte b)
  127. {
  128. history[hp++] = b;
  129. if (offset == 0) {
  130. if ((page & 7) == 0) {
  131. pgcmd(0x50, page);
  132. UNSEL_local_wait();
  133. }
  134. pgcmd(0x84, page);
  135. }
  136. spix(b);
  137. if (++offset == 264) {
  138. UNSEL_local();
  139. pgcmd(0x88, page++);
  140. UNSEL_local_wait();
  141. offset = 0;
  142. }
  143. }
  144. #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  145. static GDflashbitsF GDFB;
  146. static void GD_uncompress(uint_farptr_t src)
  147. #else
  148. static GDflashbits GDFB;
  149. static void GD_uncompress(PROGMEM prog_uchar *src)
  150. #endif
  151. {
  152. GDFB.begin(src);
  153. byte b_off = GDFB.getn(4);
  154. byte b_len = GDFB.getn(4);
  155. byte minlen = GDFB.getn(2);
  156. unsigned short items = GDFB.getn(16);
  157. hp = 0;
  158. offset = 0;
  159. while (items--) {
  160. if (GDFB.get1() == 0) {
  161. supply(GDFB.getn(8));
  162. } else {
  163. int offset = -GDFB.getn(b_off) - 1;
  164. int l = GDFB.getn(b_len) + minlen;
  165. while (l--) {
  166. supply(history[0xff & (hp + offset)]);
  167. }
  168. }
  169. }
  170. }
  171. static unsigned long flash_crc(int page, int n)
  172. {
  173. SEL_local();
  174. SPI.transfer(0x03);
  175. spipage(page);
  176. unsigned long crc = ~0;
  177. unsigned long len = 264L * n;
  178. while (len--) {
  179. byte b = spix(0);
  180. crc = crc_update(crc, b);
  181. }
  182. crc = ~crc;
  183. UNSEL_local();
  184. return crc;
  185. }
  186. static unsigned long flash_sum(int page, int n)
  187. {
  188. SEL_local();
  189. SPI.transfer(0x03);
  190. spipage(page);
  191. unsigned long sum = 0;
  192. unsigned long len = 264L * n;
  193. while (len--) {
  194. byte b = spix(0);
  195. sum = sum + b;
  196. }
  197. UNSEL_local();
  198. return sum;
  199. }
  200. #ifdef P0OFF
  201. static byte ready(byte part, int sb = STAGEBASE)
  202. {
  203. switch (part) {
  204. case 0: return flash_crc(sb + P0OFF, P0SIZE) == P0CRC;
  205. case 1: return flash_crc(sb + P1OFF, P1SIZE) == P1CRC;
  206. case 2: return flash_crc(sb + P2OFF, P2SIZE) == P2CRC;
  207. case 3: return flash_crc(sb + P3OFF, P3SIZE) == P3CRC;
  208. case 4: return flash_crc(P4OFF, P4SIZE) == P4CRC;
  209. }
  210. return 0;
  211. }
  212. static int atxy(int x, int y)
  213. {
  214. return (y << 6) + x;
  215. }
  216. static void common_show_status()
  217. {
  218. for (byte i = 0; i < 5; i++) {
  219. byte y = 10 + 2 * i;
  220. GD.putstr(0, y, "part ");
  221. GD.wr(atxy(6, y), '0' + i);
  222. GD.putstr(25, y, ready(i) ? "OK" : "--");
  223. }
  224. }
  225. static int ready0123(int sb)
  226. {
  227. return ready(0, sb) && ready(1, sb) && ready(2, sb) && ready(3, sb);
  228. }
  229. #endif
  230. static void common_setup(byte part)
  231. {
  232. GD.begin();
  233. GD.wr(IOMODE, 'F');
  234. pinMode(2, OUTPUT);
  235. digitalWrite(2, HIGH);
  236. GD.ascii();
  237. #ifdef REVISION
  238. // avoid sprintf because it bloats executable
  239. GD.putstr(0, 0, "Flash loader");
  240. char revmsg[] = "Firmware X.X";
  241. revmsg[9] = '0' + (REVISION >> 4);
  242. revmsg[11] = '0' + (REVISION & 0xf);
  243. GD.putstr(0, 2, revmsg);
  244. char partmsg[] = "part X";
  245. partmsg[5] = '0' + part;
  246. GD.putstr(0, 4, partmsg);
  247. GD.putstr(0, 8, "loading");
  248. GD.putstr(8, 8, partmsg);
  249. common_show_status();
  250. #endif
  251. }