/* ** This file is part of fsusb_picdem ** ** fsusb_picdem is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as ** published by the Free Software Foundation; either version 2 of the ** License, or (at your option) any later version. ** ** fsusb_picdem is distributed in the hope that it will be useful, but ** WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with fsusb_picdem; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ** 02110-1301, USA */ #include "memimg.h" #include #include #include "fsusb.h" #include picdem_handle *usbdev; typedef int scan_callback_t(int,int,mi_byte_t*,char*); int program_flash(int addr, int len, mi_byte_t *data, char *mask) { if(len != 64) { printf("*** Tried to program flash not 64 bytes at a time!\n"); printf("*** Is flash size divisible by 64?\n"); return -1; } // printf("writing program block at %.8x\n", addr); rjl_write_block(usbdev, addr, data); return 0; } int program_config(int addr, int len, mi_byte_t *data, char *mask) { int i; printf("writing size-%i config block at %.8x:\n", len, (addr/64)*64); for(i=0;i<64;i++) { printf("%.2x", data[i]); } printf("\n"); rjl_write_config_block(usbdev, addr, len, data); return 0; } int verify_flash(int addr, int len, mi_byte_t *data, char *mask) { int mb; int i; bl_packet bp; int bad=0; // printf("verifying %i bytes at %.8x\n", len, addr); /* printf("data is "); for(i=0;i=32)?32:len-mb, &bp); rjl_request_flash(usbdev, addr+mb, (len-mb>=32)?32:len-mb, &bp); for(i=0;i<32 && mb+i=32)?32:len-mb, addr+mb); printf("File: "); for(i=0;i<32 && mb+itop - p->base;b+=64) { active=0; for(i=0;i<64 && b+i <= p->top - p->base;i++) { if(p->mask[i+b]) { active=1; } } if(active) { if((callback_ret=sc(b+p->base, (b+63+p->base > p->top)?p->top-p->base-b+1:64, p->contents+b, p->mask+b))) { retval=callback_ret; // printf("*** Something bad happened!\n"); } // printf("active %s block at %.8lx\n", ttt, b+p->base); } } return retval; } void show_usage(void) { printf("fsusb: Software for \"PICDEM Full Speed USB\" demo board\n"); printf("fsusb program board with and verify\n"); printf("fsusb --program program board with and verify\n"); printf("fsusb --verify verify board against \n"); printf("fsusb --read read board, saving result in \n"); } int verify_file(char *file) { mi_image *img; int retval=0; usbdev=rjl_fsusb_open(); img=mi_load_hexfile(file); if(scanpatch(img->program, verify_flash)) { printf("Program memory contains errors!\n"); } else { printf("Program memory validated\n"); retval=1; } // don't bother checking config memory, it's write-protected anyway // scanpatch(img->id, verify_flash); // scanpatch(img->config, verify_flash); // scanpatch(img->devid, verify_flash); return retval; } int program_file(char *file) { mi_image *img; int retval=0; usbdev=rjl_fsusb_open(); img=mi_load_hexfile(file); if(scanpatch(img->program, program_flash)) { printf("Writing program memory unsuccessful\n"); retval=1; } else { printf("Writing program memory successful\n"); } // don't bother with config memory, it's write-protected // scanpatch(img->id, program_config); // scanpatch(img->config, program_config); // devid is read-only, don't program it // scanpatch(img->devid, program_config); if(scanpatch(img->program, verify_flash)) { printf("Program memory contains errors!\n"); retval=1; } else { printf("Program memory validated\n"); } // don't bother checking config memory, it's write-protected anyway // scanpatch(img->id, verify_flash); // scanpatch(img->config, verify_flash); // scanpatch(img->devid, verify_flash); return retval; } int write_range(int base, int top, FILE *f) { bl_packet bp; int addr; int i; unsigned char checksum; int doit; fprintf(f, ":02000004%.2X%.2X%.2X\n", (base >> 16) & 0xff, (base >> 24) & 0xff, (unsigned char) (-((char)((2+4+((base >> 16) & 0xff)+((base >> 24) & 0xff))%256)))); for(addr=base;addr<=top;addr+=16) { rjl_request_flash(usbdev, addr, (top-addr+1>=16)?16:top-addr+1, &bp); doit=0; for(i=0;i<16 && i+addr < top;i++) { if(bp.data[i] != 0xff) { doit=1; } } if(doit==0) { // This section is all 0xff, i.e. unprogrammed continue; } // : fprintf(f, ":"); checksum=0; // ll checksum += (top-addr+1>=16)?16:top-addr+1; fprintf(f, "%.2X", (top-addr+1>=16)?16:top-addr+1); // aaaa checksum += (addr & 0xffff) / 256; fprintf(f, "%.2X", (addr & 0xffff) / 256); checksum += (addr & 0xffff) % 256; fprintf(f, "%.2X", (addr & 0xffff) % 256); // tt fprintf(f, "00"); // dd... for(i=0;i<16 && i+addr<=top;i++) { checksum += bp.data[i]; fprintf(f, "%.2X", bp.data[i]); } // cc fprintf(f, "%.2X\n", (unsigned char)(-((char)checksum))); } return 0; } int read_to_file(char *file) { usbdev=rjl_fsusb_open(); FILE *f; f=fopen(file, "w"); if(f == NULL) { return -1; } write_range(MI_PROGRAM_BASE, MI_PROGRAM_TOP, f); write_range(MI_ID_BASE, MI_ID_TOP, f); write_range(MI_CONFIG_BASE, MI_CONFIG_TOP, f); write_range(MI_DEVID_BASE, MI_DEVID_TOP, f); fprintf(f, ":00000001FF\n"); printf("Finished reading\n"); return 0; } int main(int argc, char *argv[]) { if(argc < 2 || argc > 3) { show_usage(); exit(1); } if(argc == 3) { if(!strcmp(argv[1], "--verify")) { exit(verify_file(argv[2])); } if(!strcmp(argv[1], "--program")) { exit(program_file(argv[2])); } if(!strcmp(argv[1], "--read")) { exit(read_to_file(argv[2])); } printf("Unknown option %s\n", argv[1]); show_usage(); exit(1); } if(argc == 2) { exit(program_file(argv[1])); } return 1; }