main.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. ** This file is part of fsusb_picdem
  3. **
  4. ** fsusb_picdem is free software; you can redistribute it and/or
  5. ** modify it under the terms of the GNU General Public License as
  6. ** published by the Free Software Foundation; either version 2 of the
  7. ** License, or (at your option) any later version.
  8. **
  9. ** fsusb_picdem is distributed in the hope that it will be useful, but
  10. ** WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ** General Public License for more details.
  13. **
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with fsusb_picdem; if not, write to the Free Software
  16. ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. ** 02110-1301, USA
  18. */
  19. #include "memimg.h"
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include "fsusb.h"
  23. #include <string.h>
  24. picdem_handle *usbdev;
  25. typedef int scan_callback_t(int,int,mi_byte_t*,char*);
  26. int program_flash(int addr, int len, mi_byte_t *data, char *mask)
  27. {
  28. if(len != 64) {
  29. printf("*** Tried to program flash not 64 bytes at a time!\n");
  30. printf("*** Is flash size divisible by 64?\n");
  31. return -1;
  32. }
  33. // printf("writing program block at %.8x\n", addr);
  34. rjl_write_block(usbdev, addr, data);
  35. return 0;
  36. }
  37. int program_config(int addr, int len, mi_byte_t *data, char *mask)
  38. {
  39. int i;
  40. printf("writing size-%i config block at %.8x:\n", len, (addr/64)*64);
  41. for(i=0;i<64;i++) {
  42. printf("%.2x", data[i]);
  43. }
  44. printf("\n");
  45. rjl_write_config_block(usbdev, addr, len, data);
  46. return 0;
  47. }
  48. int verify_flash(int addr, int len, mi_byte_t *data, char *mask)
  49. {
  50. int mb;
  51. int i;
  52. bl_packet bp;
  53. int bad=0;
  54. // printf("verifying %i bytes at %.8x\n", len, addr);
  55. /*
  56. printf("data is ");
  57. for(i=0;i<len;i++) {
  58. printf("%.2x", data[i]);
  59. }
  60. printf("\nmask is ");
  61. for(i=0;i<len;i++) {
  62. printf("%.2x", (mask[i])?0xff:0x00);
  63. }
  64. printf("\n");
  65. */
  66. for(mb=0;mb<64 && mb<len;mb+=32) {
  67. // printf("doing rjl_request_flash(usbdev, %.8x, %i, %.8x);\n",
  68. // addr+mb, (len-mb>=32)?32:len-mb, &bp);
  69. rjl_request_flash(usbdev, addr+mb, (len-mb>=32)?32:len-mb, &bp);
  70. for(i=0;i<32 && mb+i<len;i++) {
  71. if(mask[mb+i] && data[mb+i] != bp.data[i]) {
  72. bad=1;
  73. // printf("mismatch!\n");
  74. printf("mismatch in %i-byte chunk at 0x%.8x:\n",
  75. (len-mb>=32)?32:len-mb, addr+mb);
  76. printf("File: ");
  77. for(i=0;i<32 && mb+i<len;i++) {
  78. if(mask[mb+i]) {
  79. printf("%.2x", data[mb+i]);
  80. } else {
  81. printf("##");
  82. }
  83. }
  84. printf("\nDevice:");
  85. for(i=0;i<32 && mb+i<len;i++) {
  86. printf("%.2x", bp.data[i]);
  87. }
  88. printf("\n");
  89. }
  90. }
  91. }
  92. return bad;
  93. }
  94. int scanpatch(mi_patch *p, scan_callback_t sc)
  95. {
  96. int b,i,active;
  97. int retval=0;
  98. int callback_ret;
  99. for(b=0;b<=p->top - p->base;b+=64) {
  100. active=0;
  101. for(i=0;i<64 && b+i <= p->top - p->base;i++) {
  102. if(p->mask[i+b]) {
  103. active=1;
  104. }
  105. }
  106. if(active) {
  107. if((callback_ret=sc(b+p->base, (b+63+p->base > p->top)?p->top-p->base-b+1:64,
  108. p->contents+b, p->mask+b))) {
  109. retval=callback_ret;
  110. // printf("*** Something bad happened!\n");
  111. }
  112. // printf("active %s block at %.8lx\n", ttt, b+p->base);
  113. }
  114. }
  115. return retval;
  116. }
  117. void show_usage(void)
  118. {
  119. printf("fsusb: Software for \"PICDEM Full Speed USB\" demo board\n");
  120. printf("fsusb <file> program board with <file> and verify\n");
  121. printf("fsusb --program <file> program board with <file> and verify\n");
  122. printf("fsusb --verify <file> verify board against <file>\n");
  123. printf("fsusb --read <file> read board, saving result in <file>\n");
  124. }
  125. int verify_file(char *file)
  126. {
  127. mi_image *img;
  128. int retval=0;
  129. usbdev=rjl_fsusb_open();
  130. img=mi_load_hexfile(file);
  131. if(scanpatch(img->program, verify_flash)) {
  132. printf("Program memory contains errors!\n");
  133. } else {
  134. printf("Program memory validated\n");
  135. retval=1;
  136. }
  137. // don't bother checking config memory, it's write-protected anyway
  138. // scanpatch(img->id, verify_flash);
  139. // scanpatch(img->config, verify_flash);
  140. // scanpatch(img->devid, verify_flash);
  141. return retval;
  142. }
  143. int program_file(char *file)
  144. {
  145. mi_image *img;
  146. int retval=0;
  147. usbdev=rjl_fsusb_open();
  148. img=mi_load_hexfile(file);
  149. if(scanpatch(img->program, program_flash)) {
  150. printf("Writing program memory unsuccessful\n");
  151. retval=1;
  152. } else {
  153. printf("Writing program memory successful\n");
  154. }
  155. // don't bother with config memory, it's write-protected
  156. // scanpatch(img->id, program_config);
  157. // scanpatch(img->config, program_config);
  158. // devid is read-only, don't program it
  159. // scanpatch(img->devid, program_config);
  160. if(scanpatch(img->program, verify_flash)) {
  161. printf("Program memory contains errors!\n");
  162. retval=1;
  163. } else {
  164. printf("Program memory validated\n");
  165. }
  166. // don't bother checking config memory, it's write-protected anyway
  167. // scanpatch(img->id, verify_flash);
  168. // scanpatch(img->config, verify_flash);
  169. // scanpatch(img->devid, verify_flash);
  170. return retval;
  171. }
  172. int write_range(int base, int top, FILE *f)
  173. {
  174. bl_packet bp;
  175. int addr;
  176. int i;
  177. unsigned char checksum;
  178. int doit;
  179. fprintf(f, ":02000004%.2X%.2X%.2X\n",
  180. (base >> 16) & 0xff,
  181. (base >> 24) & 0xff,
  182. (unsigned char)
  183. (-((char)((2+4+((base >> 16) & 0xff)+((base >> 24) & 0xff))%256))));
  184. for(addr=base;addr<=top;addr+=16) {
  185. rjl_request_flash(usbdev, addr,
  186. (top-addr+1>=16)?16:top-addr+1, &bp);
  187. doit=0;
  188. for(i=0;i<16 && i+addr < top;i++) {
  189. if(bp.data[i] != 0xff) {
  190. doit=1;
  191. }
  192. }
  193. if(doit==0) { // This section is all 0xff, i.e. unprogrammed
  194. continue;
  195. }
  196. // :
  197. fprintf(f, ":");
  198. checksum=0;
  199. // ll
  200. checksum += (top-addr+1>=16)?16:top-addr+1;
  201. fprintf(f, "%.2X", (top-addr+1>=16)?16:top-addr+1);
  202. // aaaa
  203. checksum += (addr & 0xffff) / 256;
  204. fprintf(f, "%.2X", (addr & 0xffff) / 256);
  205. checksum += (addr & 0xffff) % 256;
  206. fprintf(f, "%.2X", (addr & 0xffff) % 256);
  207. // tt
  208. fprintf(f, "00");
  209. // dd...
  210. for(i=0;i<16 && i+addr<=top;i++) {
  211. checksum += bp.data[i];
  212. fprintf(f, "%.2X", bp.data[i]);
  213. }
  214. // cc
  215. fprintf(f, "%.2X\n", (unsigned char)(-((char)checksum)));
  216. }
  217. return 0;
  218. }
  219. int read_to_file(char *file)
  220. {
  221. usbdev=rjl_fsusb_open();
  222. FILE *f;
  223. f=fopen(file, "w");
  224. if(f == NULL) {
  225. return -1;
  226. }
  227. write_range(MI_PROGRAM_BASE, MI_PROGRAM_TOP, f);
  228. write_range(MI_ID_BASE, MI_ID_TOP, f);
  229. write_range(MI_CONFIG_BASE, MI_CONFIG_TOP, f);
  230. write_range(MI_DEVID_BASE, MI_DEVID_TOP, f);
  231. fprintf(f, ":00000001FF\n");
  232. printf("Finished reading\n");
  233. return 0;
  234. }
  235. int main(int argc, char *argv[])
  236. {
  237. if(argc < 2 || argc > 3) {
  238. show_usage();
  239. exit(1);
  240. }
  241. if(argc == 3) {
  242. if(!strcmp(argv[1], "--verify")) {
  243. exit(verify_file(argv[2]));
  244. }
  245. if(!strcmp(argv[1], "--program")) {
  246. exit(program_file(argv[2]));
  247. }
  248. if(!strcmp(argv[1], "--read")) {
  249. exit(read_to_file(argv[2]));
  250. }
  251. printf("Unknown option %s\n", argv[1]);
  252. show_usage();
  253. exit(1);
  254. }
  255. if(argc == 2) {
  256. exit(program_file(argv[1]));
  257. }
  258. return 1;
  259. }