void writeMemory(int addr, int n, int tick) { struct timespec tspec; tspec.tv_sec=0; tspec.tv_nsec=1000000; /* wait at least 1 ms (datasheet specifies 11 bit times) */ if (verbose>2) flsprintf(stdout,"Write memory address %04X size %04X\n",addr,n); unsigned char* p = &image[ addr ]; sendByte(0x49); // Monitor mode WRITE command sendByte(addr >> 8); sendByte(addr & 0xFF); sendByte(*(p++)); if (verbose>3) flsprintf(stdout,"Command delay\n"); nanosleep(&tspec,0); int tc=1; while (n>1) { sendByte(0x19); // Monitor mode IWRITE command sendByte(*(p++)); if (verbose>3) flsprintf(stdout,"Command delay\n"); nanosleep(&tspec,0); n -= 1; if (tick) { tc++; if ((tc & tickP1)==0) flsprintf(stdout,"."); //if ((tc & tickP2)==0) // flsprintf(stdout,"\n"); } } }
void readMemory(int addr, int n,int tick) { if (verbose>2) flsprintf(stdout,"Read memory address %04X size %04X\n",addr,n); unsigned char* p = &image[ addr ]; sendByte(0x4A); // Monitor mode READ command sendByte(addr >> 8); sendByte(addr & 0xFF); *(p++) = getByte(); n--; int tc=0; while (n>0) { sendByte(0x1A); // Monitor mode IREAD command int b1 = getByte(); int b2 = getByte(); *(p++) = b1; n--; if (n > 0) *(p++) = b2; n--; if (tick) { tc++; if ((tc & tickP1)==0) flsprintf(stdout,"."); //if ((tc & tickP2)==0) // flsprintf(stdout,"\n"); } } }
int callMonitor(int mon, int ctrlbyt, int accu, int faddr, int laddr) { int SP; image[ CTRLBYT ] = ctrlbyt; // CTRLBYT BIT 6 = 1 = > mass erase image[ CPUSPD ] = CPUSPEED; // CPUSPD = 16 MHz ext clock = > 4 MHz Fbus speed = > 8 if (verbose>3) flsprintf(stdout,"CPUSPEED=%02X\n",CPUSPEED); image[ LADDR ] = laddr>>8; image[ LADDR+1 ] = laddr&0xFF; writeMemory(MONDATA, 4, 0); if (WORKRAM>0xFF) { flsprintf(stderr,"Work RAM must be on zero page\n"); abort(); } if (lastMon!=mon) { // construct small HC908 code fragment to call the monitor function and return results int i = WORKRAM; image[ i++ ] = 0xCD; // JSR mon ; calls the monitor routine image[ i++ ] = mon>>8; image[ i++ ] = mon&0xFF; image[ i++ ] = 0x83; // SWI ; return to monitor if (WORKRAM>=WORKTOP) { // leave some stack space for monitor routines flsprintf(stderr,"Not enough WORKRAM on target\n"); abort(); } writeMemory(WORKRAM , i-WORKRAM , 0); lastMon=mon; }
void dumpMemory(int addr, int n) { unsigned char* p = &image[ addr ]; int i; for (i = 0; i<n; ++i) { if ((i&0xF) == 0) flsprintf(stdout,"%04X ", addr+i); flsprintf(stdout,"%02X ", *(p++) & 0xFF); if ((i&0xF) == 7) flsprintf(stdout," "); if ((i&0xF) == 15) flsprintf(stdout,"\n"); } if ((i&0xF) != 0) flsprintf(stdout,"\n"); }
void putByte(int byte) { int n; if (verbose>3) flsprintf(stdout,"TX: 0x%02X\n", byte); WriteFile(port_handle, &byte, 1, (LPDWORD)((void *)&n), NULL); if (n != 1) comErr("Serial port failed to send a byte, write returned %d\n", n); }
void putByte(int byte) { char buf = byte; if (verbose>3) flsprintf(stdout,"TX: 0x%02X\n", byte); int n = write(com, &buf, 1); if (n != 1) comErr("Serial port failed to send a byte, write returned %d\n", n); }
int p16a_load_config (void) { if (verbose>2) flsprintf(stdout,"Load config\n"); putByte(0x04); putByte(0x00); getByte(); return 0; }
int p16a_rst_pointer (void) { if (verbose>2) flsprintf(stdout,"Resetting PC\n"); putByte(0x03); //operation number putByte(0x00); //number of bytes remaining getByte(); //return result - no check for its value return 0; }
int p18b_mass_erase (void) { if (verbose>2) flsprintf(stdout,"Mass erase\n"); putByte(0x23); putByte(0x00); getByte(); return 0; }
int prog_exit_progmode (void) { if (verbose>2) flsprintf(stdout,"Exiting programming mode\n"); putByte(0x02); putByte(0x00); getByte(); return 0; }
int p16a_inc_pointer (unsigned char num) { if (verbose>2) flsprintf(stdout,"Inc pointer %d\n",num); putByte(0x05); putByte(0x01); putByte(num); getByte(); return 0; }
// This reads away break 'character' from the serial line void flushBreak() { int i; for (i=0; i<2; ++i) { char buf; int n = read(com, &buf, 1); if (verbose>3) flsprintf(stdout,n<1?"FL: nothing\n":"FL: 0x%02X\n", buf & 0xFF); } }
int getByte() { unsigned char buf[2]; int n; ReadFile(port_handle, buf, 1, (LPDWORD)((void *)&n), NULL); if (verbose>3) flsprintf(stdout,n<1?"RX: fail\n":"RX: 0x%02X\n", buf[0] & 0xFF); if (n == 1) return buf[0] & 0xFF; comErr("Serial port failed to receive a byte, read returned %d\n", n); return -1; // never reached }
int getByte() { char buf; int n = read(com, &buf, 1); if (verbose>3) flsprintf(stdout,n<1?"RX: fail\n":"RX: 0x%02X\n", buf & 0xFF); if (n == 1) return buf & 0xFF; comErr("Serial port failed to receive a byte, read returned %d\n", n); return -1; // never reached }
void dumpMemorySrec(int addr, int size) { unsigned char* p = &image[ addr ]; while (size>0) { int n = size>16 ? 16 : size; int bc=2+n+1; flsprintf(stdout,"S1%02X%04X",bc,addr); int s=(addr >> 8) + (addr & 0xFF) + bc; int i; for (i=0; i<n; ++i) { int bty=*p & 0xFF; s += bty; flsprintf(stdout,"%02X",bty); ++p; ++addr; } size -= n; flsprintf(stdout,"%02X\n",~s & 0xFF); } }
int p18d_mass_erase_part (unsigned long data) { if (verbose>2) flsprintf(stdout,"Mass erase part of 0x%6.6x\n",data); putByte(0x30); putByte(0x03); putByte((data>>16)&0xFF); putByte((data>>8)&0xFF); putByte((data>>0)&0xFF); getByte(); return 0; }
int p16a_read_page (unsigned char * data, unsigned char num) { unsigned char i; if (verbose>2) flsprintf(stdout,"Reading page of %d bytes\n", num); putByte(0x06); putByte(0x01); putByte(num/2); getByte(); for (i=0; i<num; i++) *data++ = getByte(); return 0; }
int prog_enter_progmode (void) { if (verbose>2) flsprintf(stdout,"Entering programming mode\n"); if (chip_family==CF_P16F_A) putByte(0x01); else if (chip_family==CF_P16F_B) putByte(0x01); else if (chip_family==CF_P18F_A) putByte(0x10); else if (chip_family==CF_P18F_B) putByte(0x10); else if (chip_family==CF_P18F_D) putByte(0x10); else if (chip_family==CF_P18F_E) putByte(0x10); putByte(0x00); getByte(); return 0; }
int p16a_get_config (unsigned char n) { unsigned char tdat[20],devid_lo,devid_hi; unsigned int retval; p16a_rst_pointer(); p16a_load_config(); p16a_inc_pointer(n); p16a_read_page(tdat, 4); devid_hi = tdat[(2*0)+1]; devid_lo = tdat[(2*0)+0]; retval = (((unsigned int)(devid_lo))<<0) + (((unsigned int)(devid_hi))<<8); if (verbose>2) flsprintf(stdout,"Getting config +%d - lo:%2.2x,hi:%2.2x = %4.4x\n",n,devid_lo,devid_hi,retval); return retval; }
int p18d_write_cfg (unsigned char data1, unsigned char data2, int address) { if (verbose>2) flsprintf(stdout,"Writing cfg 0x%2.2x 0x%2.2x at 0x%6.6x\n", data1, data2, address); putByte(0x32); putByte(6); putByte(0); putByte((address>>16)&0xFF); putByte((address>>8)&0xFF); putByte((address>>0)&0xFF); putByte(data1); putByte(data2); getByte(); return 0; }
int p16a_get_devid (void) { unsigned char tdat[20],devid_lo,devid_hi; unsigned int retval; p16a_rst_pointer(); p16a_load_config(); p16a_inc_pointer(6); p16a_read_page(tdat, 4); devid_hi = tdat[(2*0)+1]; devid_lo = tdat[(2*0)+0]; if (verbose>2) flsprintf(stdout,"Getting devid - lo:%2.2x,hi:%2.2x\n",devid_lo,devid_hi); retval = (((unsigned int)(devid_lo))<<0) + (((unsigned int)(devid_hi))<<8); retval = retval & devid_mask; return retval; }
void connectTarget() { int j; if (connected) return; flsprintf(stdout, "Security code: "); for (j = 0; j<8; ++j) { sendByte(scode[j]); flsprintf(stdout, "."); } flsprintf(stdout, " "); flushBreak(); readMemory(RAM, 1 , 0); connected=1; if ((image[ RAM ] & 0x40) == 0) flsprintf(stdout,"failed\n"); else flsprintf(stdout,"passed\n"); // in case FLBPR is RAM based we clear it first by just writing it image[FLBPR]=0xFF; writeMemory(FLBPR,1,0); }
void initSerialPort() { com = open(COM, O_RDWR | O_NOCTTY | O_NDELAY); if (com <0) comErr("Failed to open serial port\n"); fcntl(com, F_SETFL, 0); struct termios opts; tcgetattr(com, &opts); opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); opts.c_cflag |= (CLOCAL | CREAD); opts.c_cflag &= ~PARENB; opts.c_cflag |= CSTOPB; // two stop bits opts.c_cflag &= ~CSIZE; opts.c_cflag |= CS8; opts.c_oflag &= ~OPOST; opts.c_iflag &= ~INPCK; opts.c_iflag &= ~(IXON | IXOFF | IXANY); opts.c_cc[ VMIN ] = 0; opts.c_cc[ VTIME ] = 10;//0.1 sec cfsetispeed(&opts, baudRate); cfsetospeed(&opts, baudRate); setHandshake(); if (tcsetattr(com, TCSANOW, &opts) != 0) { perror(COM); abort(); } tcflush(com,TCIOFLUSH); // just in case some crap is the buffers if (!terminalMode) { char buf = -2; while (read(com, &buf, 1)>0) { if (verbose) flsprintf(stderr,"Unexpected data from serial port: %02X\n",buf & 0xFF); } } }
int prog_get_device_id (void) { unsigned char mem_str[10]; unsigned int devid; if (verbose>2) flsprintf(stdout,"getting ID for family %d\n",chip_family); if ((chip_family==CF_P16F_A)|(chip_family==CF_P16F_B) ) return p16a_get_devid(); else if ((chip_family==CF_P18F_A)|(chip_family==CF_P18F_B)|(chip_family==CF_P18F_D)|(chip_family==CF_P18F_E)) { p18a_read_page((unsigned char *)&mem_str, 0x3FFFFE, 2); devid = (((unsigned int)(mem_str[1]))<<8) + (((unsigned int)(mem_str[0]))<<0); devid = devid & devid_mask; return devid; } return 0; }
int p16a_program_page (unsigned int ptr, unsigned char num, unsigned char slow) { // unsigned char i; if (verbose>2) flsprintf(stdout,"Programming page of %d bytes at 0x%4.4x\n", num,ptr); putByte(0x08); putByte(num+2); putByte(num); putByte(slow); /* for (i=0;i<num;i++) putByte(file_image[ptr+i]); */ putBytes(&file_image[ptr],num); getByte(); return 0; }
int p18e_mass_erase (void) { if (verbose>2) flsprintf(stdout,"Mass erase\n"); p18d_mass_erase_part(0x800104); p18d_mass_erase_part(0x800204); p18d_mass_erase_part(0x800404); p18d_mass_erase_part(0x800804); p18d_mass_erase_part(0x801004); p18d_mass_erase_part(0x802004); p18d_mass_erase_part(0x804004); p18d_mass_erase_part(0x808004); p18d_mass_erase_part(0x800004); p18d_mass_erase_part(0x800005); p18d_mass_erase_part(0x800002); return 0; }
int p18a_read_page (unsigned char * data, int address, unsigned char num) { unsigned char i; if (verbose>2) flsprintf(stdout,"Reading page of %d bytes at 0x%6.6x\n", num, address); putByte(0x11); putByte(0x04); putByte(num/2); putByte((address>>16)&0xFF); putByte((address>>8)&0xFF); putByte((address>>0)&0xFF); getByte(); for (i=0; i<num; i++) { *data++ = getByte(); } return 0; }
int runFrom(int PC, int A, int CC, int HX) { int SP=readSP(); if (verbose>2) flsprintf(stdout,"Execute code PC=%04X A=%02X CC=%02X H:X=%04X SP=%04X\n",PC,A,CC,HX,SP); image[ SP + 1 ] = HX >> 8; image[ SP + 2 ] = CC; image[ SP + 3 ] = A; image[ SP + 4 ] = HX & 0xFF; image[ SP + 5 ] = PC >> 8; image[ SP + 6 ] = PC & 0xFF; writeMemory(SP + 1 , 6 , 0); sendByte(0x28); // Monitor mode RUN command //struct timespec tspec; //tspec.tv_sec=0; //tspec.tv_nsec=5000000; /* wait at least 1 ms (datasheet specifies 11 bit times) */ //nanosleep(&tspec,0); return SP; }
int readSP() { if (verbose>2) flsprintf(stdout,"Read Stack Pointer\n"); sendByte(0x0C); // Monitor mode READSP command return (((getByte() << 8) | (getByte() & 0xFF)) - 1) & 0xFFFF; }
void printHelp() { flsprintf(stdout,"pp programmer\n"); exit(0); }