From ef864d5d315e7422213db19b13c211aa65524f03 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Sun, 4 Aug 2024 14:34:02 +0200 Subject: [PATCH 01/15] Started on dsPIC33CK support --- src/devices/dspic33ck.cpp | 1057 +++++++++++++++++++++++++++++++++++++ src/devices/dspic33ck.h | 83 +++ 2 files changed, 1140 insertions(+) create mode 100644 src/devices/dspic33ck.cpp create mode 100644 src/devices/dspic33ck.h diff --git a/src/devices/dspic33ck.cpp b/src/devices/dspic33ck.cpp new file mode 100644 index 0000000..060d6af --- /dev/null +++ b/src/devices/dspic33ck.cpp @@ -0,0 +1,1057 @@ +/* + * Raspberry Pi PIC Programmer using GPIO connector + * https://github.com/WallaceIT/picberry + * Copyright 2014 Francesco Valla + * Copyright 2024 Gitle Mikkelsen + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#include +#include +#include +#include + +#include "dspic33ck.h" + +/* delays (in microseconds; nanoseconds are rounded to 1us) */ +#define DELAY_P1 1 // 200ns +#define DELAY_P1A 1 // 80ns +#define DELAY_P1B 1 // 80ns +#define DELAY_P2 1 // 15ns +#define DELAY_P3 1 // 15ns +#define DELAY_P4 1 // 40ns +#define DELAY_P4A 1 // 40ns +#define DELAY_P5 1 // 20ns +#define DELAY_P6 1 // 100ns +#define DELAY_P7 50000 // 50ms +#define DELAY_P8 12 // 12us +#define DELAY_P9A 10 // 10us +#define DELAY_P9B 15 // 15us - 23us max! +#define DELAY_P10 1 // 400ns +#define DELAY_P11 100000 // 20ms max, guess 10ms +#define DELAY_P12 100000 // 20ms max, guess 10ms +#define DELAY_P13 10 // 20us max, guess 10us +#define DELAY_P14 1 // 1us MAX! +#define DELAY_P15 1 // 10ns +#define DELAY_P16 0 // 0s +#define DELAY_P17 1 // 100ns +#define DELAY_P18 1000 // 1ms +#define DELAY_P19 1 // 25ns +#define DELAY_P20 25000 // 25ms +#define DELAY_P21 1 // 1us - 500us MAX! + +#define ENTER_PROGRAM_KEY 0x4D434851 + +#define reset_pc() send_cmd(0x040200) +#define send_nop() send_cmd(0x000000) + +static unsigned int counter=0; +static uint16_t nvmcon; + +/* Send a 24-bit command to the PIC (LSB first) through a SIX instruction */ +void dspic33ck::send_cmd(uint32_t cmd) +{ + uint8_t i; + + GPIO_CLR(pic_data); + + /* send the SIX = 0x0000 instruction */ + for (i = 0; i < 4; i++) { + GPIO_SET(pic_clk); + delay_us(DELAY_P1B); + GPIO_CLR(pic_clk); + delay_us(DELAY_P1A); + } + + delay_us(DELAY_P4); + + /* send the 24-bit command */ + for (i = 0; i < 24; i++) { + if ( (cmd >> i) & 0x00000001 ) + GPIO_SET(pic_data); + else + GPIO_CLR(pic_data); + delay_us(DELAY_P1A); + GPIO_SET(pic_clk); + delay_us(DELAY_P1B); + GPIO_CLR(pic_clk); + } + + delay_us(DELAY_P4A); + +} + +/* Read 16-bit data word from the PIC (LSB first) through a REGOUT inst */ +uint16_t dspic33ck::read_data(void) +{ + uint8_t i; + uint16_t data = 0; + + GPIO_CLR(pic_data); + GPIO_CLR(pic_clk); + + /* send the REGOUT=0x0001 instruction */ + for (i = 0; i < 4; i++) { + if ( (0x0001 >> i) & 0x001 ) + GPIO_SET(pic_data); + else + GPIO_CLR(pic_data); + delay_us(DELAY_P1A); + GPIO_SET(pic_clk); + delay_us(DELAY_P1B); + GPIO_CLR(pic_clk); + } + + delay_us(DELAY_P4); + + /* idle for 8 clock cycles, waiting for the data to be ready */ + for (i = 0; i < 8; i++) { + GPIO_SET(pic_clk); + delay_us(DELAY_P1B); + GPIO_CLR(pic_clk); + delay_us(DELAY_P1A); + } + + delay_us(DELAY_P5); + + GPIO_IN(pic_data); + + /* read a 16-bit data word */ + for (i = 0; i < 16; i++) { + GPIO_SET(pic_clk); + delay_us(DELAY_P1B); + data |= ( GPIO_LEV(pic_data) & 0x00000001 ) << i; + GPIO_CLR(pic_clk); + delay_us(DELAY_P1A); + } + + delay_us(DELAY_P4A); + GPIO_OUT(pic_data); + return data; +} + +/* enter program mode */ +void dspic33ck::enter_program_mode(void) +{ + int i; + + GPIO_IN(pic_mclr); + GPIO_OUT(pic_mclr); + + GPIO_CLR(pic_clk); + + GPIO_CLR(pic_mclr); /* remove VDD from MCLR pin */ + delay_us(DELAY_P6); + GPIO_SET(pic_mclr); /* apply VDD to MCLR pin */ + delay_us(DELAY_P21); + GPIO_CLR(pic_mclr); /* remove VDD from MCLR pin */ + delay_us(DELAY_P18); + + /* Shift in the "enter program mode" key sequence (MSB first) */ + for (i = 31; i > -1; i--) { + if ( (ENTER_PROGRAM_KEY >> i) & 0x01 ) + GPIO_SET(pic_data); + else + GPIO_CLR(pic_data); + delay_us(DELAY_P1A); + GPIO_SET(pic_clk); + delay_us(DELAY_P1B); + GPIO_CLR(pic_clk); + + } + GPIO_CLR(pic_data); + delay_us(DELAY_P19); + GPIO_SET(pic_mclr); + if(subfamily == SF_DSPIC33E) + delay_us(DELAY_P7_DSPIC33E); + else if(subfamily == SF_PIC24FJ) + delay_us(DELAY_P7_PIC24FJ); + + /* idle for 5 clock cycles */ + for (i = 0; i < 5; i++) { + GPIO_SET(pic_clk); + delay_us(DELAY_P1B); + GPIO_CLR(pic_clk); + delay_us(DELAY_P1A); + } + +} + +/* exit program mode */ +void dspic33ck::exit_program_mode(void) +{ + GPIO_CLR(pic_clk); + GPIO_CLR(pic_data); + delay_us(DELAY_P16); + GPIO_CLR(pic_mclr); /* remove VDD from MCLR pin */ + delay_us(DELAY_P17); /* wait (at least) P17 */ + GPIO_SET(pic_mclr); + GPIO_IN(pic_mclr); +} + +/* read the device ID and revision; returns only the id */ +bool dspic33ck::read_device_id(void) +{ + // TODO + + bool found = 0; + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + send_cmd(0x200FF0); + send_cmd(0x8802A0); + send_cmd(0x200006); + send_cmd(0x20F887); + send_nop(); + + send_cmd(0xBA0BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + device_id = read_data(); + + send_cmd(0xBA0BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + device_rev = read_data(); + + reset_pc(); + send_nop(); + + for (unsigned short i=0;i < sizeof(piclist)/sizeof(piclist[0]);i++){ + + if (piclist[i].device_id == device_id){ + + strcpy(name, piclist[i].name); + mem.code_memory_size = piclist[i].code_memory_size; + mem.program_memory_size = 0x0F80018; + mem.location = (uint16_t*) calloc(mem.program_memory_size,sizeof(uint16_t)); + mem.filled = (bool*) calloc(mem.program_memory_size,sizeof(bool)); + found = 1; + break; + } + } + + return found; + +} + +/* Check if the device is blank */ +uint8_t dspic33ck::blank_check(void) +{ + // TODO + + uint32_t addr; + unsigned short i; + uint16_t data[8], raw_data[6]; + uint8_t ret = 0; + + if(!flags.debug) cerr << "[ 0%]"; + + counter=0; + + /* exit reset vector */ + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + /* Output data to W0:W5; repeat until all desired code memory is read. */ + for(addr=0; addr < mem.code_memory_size; addr=addr+8) { + + if((addr & 0x0000FFFF) == 0){ + send_cmd(0x200000 | ((addr & 0x00FF0000) >> 12) ); // MOV #, W0 + send_cmd(0x8802A0); // MOV W0, TBLPAG + send_cmd(0x200006 | ((addr & 0x0000FFFF) << 4) ); // MOV #, W6 + } + + /* Fetch the next four memory locations and put them to W0:W5 */ + send_cmd(0xEB0380); // CLR W7 + send_nop(); + send_cmd(0xBA1B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBD6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA1BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA1B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBD6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA0BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + + /* read six data words (16 bits each) */ + for(i=0; i<6; i++){ + send_cmd(0x887C40 + i); + send_nop(); + raw_data[i] = read_data(); + send_nop(); + } + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + /* store data correctly */ + data[0] = raw_data[0]; + data[1] = raw_data[1] & 0x00FF; + data[3] = (raw_data[1] & 0xFF00) >> 8; + data[2] = raw_data[2]; + data[4] = raw_data[3]; + data[5] = raw_data[4] & 0x00FF; + data[7] = (raw_data[4] & 0xFF00) >> 8; + data[6] = raw_data[5]; + + if(counter != addr*100/mem.code_memory_size){ + counter = addr*100/mem.code_memory_size; + fprintf(stderr, "\b\b\b\b\b[%2d%%]", counter); + } + + for(i=0; i<8; i++){ + if(flags.debug) + fprintf(stderr, "\n addr = 0x%06X data = 0x%04X", + (addr+i), data[i]); + if ((i%2 == 0 && data[i] != 0xFFFF) || (i%2 == 1 && data[i] != 0x00FF)) { + if(!flags.debug) cerr << "\b\b\b\b\b"; + ret = 1; + addr = mem.code_memory_size + 10; + break; + } + } + } + + if(addr <= (mem.code_memory_size + 8)){ + if(!flags.debug) cerr << "\b\b\b\b\b"; + ret = 0; + }; + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + return ret; +} + +/* Bulk erase the chip */ +void dspic33ck::bulk_erase(void) +{ + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + send_cmd(0x2400EA); + send_cmd(0x88468A); + send_nop(); + send_nop(); + + send_cmd(0x200551); + send_cmd(0x8846B1); + send_cmd(0x200AA1); + send_cmd(0x8846B1); + send_cmd(0xA8F1A1); + send_nop(); + send_nop(); + send_nop(); + + delay_us(DELAY_P11); + + /* wait while the erase operation completes */ + do{ + send_cmd(0x804680); + send_nop(); + send_cmd(0x887E60); + send_nop(); + nvmcon = read_data(); + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + } while((nvmcon & 0x8000) == 0x8000); + + if(flags.client) fprintf(stdout, "@FIN"); +} + +/* Read PIC memory and write the contents to a .hex file */ +void dspic33ck::read(char *outfile, uint32_t start, uint32_t count) +{ + uint32_t addr, startaddr, stopaddr; + uint16_t data[8], raw_data[6]; + int i=0; + + startaddr = start; + stopaddr = mem.code_memory_size; + if(count != 0 && count < stopaddr){ + stopaddr = startaddr + count; + fprintf(stderr, "Read only %d memory locations, from %06X to %06X\n", + count, startaddr, stopaddr); + } + + if(!flags.debug) cerr << "[ 0%]"; + if(flags.client) fprintf(stdout, "@000"); + counter=0; + + /* exit reset vector */ + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + /* Output data to W0:W5; repeat until all desired code memory is read. */ + for(addr=startaddr; addr < stopaddr; addr=addr+8) { + + if((addr & 0x0000FFFF) == 0 || startaddr != 0){ + send_cmd(0x200000 | ((addr & 0x00FF0000) >> 12) ); // MOV #, W0 + send_cmd(0x8802A0); // MOV W0, TBLPAG + send_cmd(0x200006 | ((addr & 0x0000FFFF) << 4) ); // MOV #, W6 + startaddr = 0; + } + + /* Fetch the next four memory locations and put them to W0:W5 */ + send_cmd(0xEB0380); // CLR W7 + send_nop(); + send_cmd(0xBA1B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBD6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA1BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA1B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBD6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA0BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + + /* read six data words (16 bits each) */ + for(i=0; i<6; i++){ + send_cmd(0x887C40 + i); + send_nop(); + raw_data[i] = read_data(); + send_nop(); + } + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + /* store data correctly */ + data[0] = raw_data[0]; + data[1] = raw_data[1] & 0x00FF; + data[3] = (raw_data[1] & 0xFF00) >> 8; + data[2] = raw_data[2]; + data[4] = raw_data[3]; + data[5] = raw_data[4] & 0x00FF; + data[7] = (raw_data[4] & 0xFF00) >> 8; + data[6] = raw_data[5]; + + for(i=0; i<8; i++){ + if (flags.debug) + fprintf(stderr, "\n addr = 0x%06X data = 0x%04X", + (addr+i), data[i]); + + if (i%2 == 0 && data[i] != 0xFFFF) { + mem.location[addr+i] = data[i]; + mem.filled[addr+i] = 1; + } + + if (i%2 == 1 && data[i] != 0x00FF) { + mem.location[addr+i] = data[i]; + mem.filled[addr+i] = 1; + } + } + + if(counter != addr*100/stopaddr){ + counter = addr*100/stopaddr; + if(flags.client) + fprintf(stdout,"@%03d", counter); + if(!flags.debug) + fprintf(stderr,"\b\b\b\b\b[%2d%%]", counter); + } + + /* TODO: checksum */ + } + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + send_cmd(0x200F80); + send_cmd(0x8802A0); + send_cmd(0x200046); + send_cmd(0x20F887); + send_nop(); + + addr = 0x00F80004; + + for(i=0; i<8; i++){ + send_cmd(0xBA0BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + data[0] = read_data(); + if (data[0] != 0xFFFF) { + mem.location[addr+2*i] = data[0]; + mem.filled[addr+2*i] = 1; + } + } + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + if(!flags.debug) cerr << "\b\b\b\b\b"; + if(flags.client) fprintf(stdout, "@FIN"); + write_inhx(&mem, outfile); +} + +/* Write contents of the .hex file to the PIC */ +void dspic33ck::write(char *infile) +{ + uint16_t i,j,p; + uint16_t k; + bool skip; + uint32_t data[8],raw_data[6]; + uint32_t addr = 0; + + unsigned int filled_locations=1; + + const char *regname[] = {"FSEC","FBSLIM","FSIGN","FOSCSEL","FOSC","FWDT","FPOR","FICD","FDMTIVTL","FDMTIVTH","FDMTCNTL","FDMTCNTH","FDMT","FDEVOPT","FALTREG"}; + + filled_locations = read_inhx(infile, &mem); + if(!filled_locations) return; + + bulk_erase(); + + /* Exit reset vector */ + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + /* WRITE CODE MEMORY */ + if(!flags.debug) cerr << "[ 0%]"; + if(flags.client) fprintf(stdout, "@000"); + counter=0; + + for (addr = 0; addr < mem.code_memory_size; ){ + + skip = 1; + + for(k=0; k<256; k+=2) + if(mem.filled[addr+k]) skip = 0; + + if(skip){ + addr=addr+256; + continue; + } + + send_cmd(0x200FAC); + send_cmd(0x8802AC); + + for(j=0;j<4;j++){ + if (mem.filled[addr+j]) data[j] = mem.location[addr+j]; + else data[j] = 0xFFFF; + if (flags.debug) + fprintf(stderr,"\n Writing 0x%04X to address 0x%06X ", data[j], addr+j ); + } + + send_cmd(0x200000 | (data[0] << 4)); // MOV #, W0 + send_cmd(0x200001 | (0x00FFFF & ((data[3] << 8) | (data[1] & 0x00FF))) <<4);// MOV #, W1 + send_cmd(0x200002 | (data[2] << 4)); // MOV #, W2 + + /* set W6+W7 and load latches */ + send_cmd(0xEB0300); + send_nop(); + send_cmd(0xEB0380); + send_nop(); + send_cmd(0xBB0BB6); + send_nop(); + send_nop(); + send_cmd(0xBBDBB6); + send_nop(); + send_nop(); + send_cmd(0xBBEBB6); + send_nop(); + send_nop(); + send_cmd(0xBB0B96); + send_nop(); + send_nop(); + + /* Set the NVMADRU/NVMADR register-pair to point to the correct row */ + send_cmd(0x200003 | ((addr & 0x0000FFFF) << 4)); + send_cmd(0x200004 | ((addr & 0x00FF0000) >> 12)); + send_cmd(0x884693); + send_cmd(0x8846A4); + + /* Set the NVMCON to program two instruction words */ + send_cmd(0x24001A); + send_nop(); + send_cmd(0x88468A); + send_nop(); + send_nop(); + + /* Initiate the write cycle */ + send_cmd(0x200551); + send_cmd(0x8846B1); + send_cmd(0x200AA1); + send_cmd(0x8846B1); + send_cmd(0xA8F1A1); + send_nop(); + send_nop(); + send_nop(); + + delay_us(DELAY_P13); + + // Wait until finished + do{ + send_nop(); + send_cmd(0x804680); + send_nop(); + send_cmd(0x887E60); + send_nop(); + nvmcon = read_data(); + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + } while((nvmcon & 0x8000) == 0x8000); + + if(counter != addr*100/filled_locations){ + if(flags.client) + fprintf(stdout,"@%03d", (addr*100/(filled_locations+0x100))); + if(!flags.debug) + fprintf(stderr,"\b\b\b\b\b[%2d%%]", addr*100/(filled_locations+0x100)); + counter = addr*100/filled_locations; + } + + addr += 4; + }; + + if(!flags.debug) cerr << "\b\b\b\b\b\b"; + if(flags.client) fprintf(stdout, "@100"); + + delay_us(100000); + + /* WRITE CONFIGURATION REGISTERS */ + if(flags.debug) + cerr << endl << "Writing Configuration registers..." << endl; + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + send_cmd(0x200FAC); + send_cmd(0x8802AC); + + addr = 0x00005F00; // +4? + if (subfamily == SF_DSPIC33CK64) + addr = 0x0000AF00; + + for(i=0; i<15; i+=2, addr+=4){ + + if (i == 1) + addr += 12; // jump to 0x10 offset after first register + + if(mem.filled[addr]){ + + send_cmd(0x200000 | ((0x0000FFFF & mem.location[addr]) << 4)); + send_cmd(0x200001 | ((0x0000FFFF & mem.location[addr+1]) << 4)); + send_cmd(0x200002 | ((0x0000FFFF & mem.location[addr+2]) << 4)); + send_cmd(0x200003 | ((0x0000FFFF & mem.location[addr+3]) << 4)); + + /* set W3 and load latches */ + send_cmd(0xEB0300); + send_nop(); + send_cmd(0xBB0B00); + send_nop(); + send_nop(); + send_cmd(0xBB9B01); + send_nop(); + send_nop(); + send_cmd(0xBB0B02); + send_nop(); + send_nop(); + send_cmd(0xBB9B03); + send_nop(); + send_nop(); + + /* Set the NVMADRU/NVMADR register-pair to point to the correct row */ + send_cmd(0x200004 | ((addr & 0x0000FFFF) << 4)); + send_cmd(0x200005 | ((addr & 0x00FF0000) >> 12)); + send_cmd(0x884694); + send_cmd(0x8846A5); + + /* Set the NVMCON register to program one Configuration register */ + send_cmd(0x24001A); + send_nop(); + send_cmd(0x88468A); + send_nop(); + send_nop(); + + /* Initiate the write cycle */ + send_cmd(0x200551); + send_cmd(0x8846B1); + send_cmd(0x200AA1); + send_cmd(0x8846B1); + send_cmd(0xA8F1A1); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + + delay_us(DELAY_P20); + + // Wait until finished + do{ + send_nop(); + send_cmd(0x804680); + send_nop(); + send_cmd(0x887E60); + send_nop(); + nvmcon = read_data(); + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + } while((nvmcon & 0x8000) == 0x8000); + + if(flags.debug) + fprintf(stderr,"\n - %s set to 0x%01x", + regname[i], mem.location[addr]); + } + else if(flags.debug) + fprintf(stderr,"\n - %s left unchanged", regname[i]); + + } + + if(flags.debug) cerr << endl; + + delay_us(100000); + + /* VERIFY CODE MEMORY */ + // todo + if(!flags.noverify){ + if(!flags.debug) cerr << "[ 0%]"; + if(flags.client) fprintf(stdout, "@000"); + counter = 0; + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + for(addr=0; addr < mem.code_memory_size; addr=addr+8) { + + skip=1; + + for(k=0; k<8; k+=2) + if(mem.filled[addr+k]) + skip = 0; + + if(skip) continue; + + send_cmd(0x200000 | ((addr & 0x00FF0000) >> 12) ); // MOV #, W0 + send_cmd(0x8802A0); // MOV W0, TBLPAG + send_cmd(0x200006 | ((addr & 0x0000FFFF) << 4) ); // MOV #, W6 + + /* Fetch the next four memory locations and put them to W0:W5 */ + send_cmd(0xEB0380); // CLR W7 + send_nop(); + send_cmd(0xBA1B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBD6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA1BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA1B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBADBD6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_cmd(0xBA0BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + + /* read six data words (16 bits each) */ + for(i=0; i<6; i++){ + send_cmd(0x887C40 + i); + send_nop(); + raw_data[i] = read_data(); + send_nop(); + } + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + /* store data correctly */ + data[0] = raw_data[0]; + data[1] = raw_data[1] & 0x00FF; + data[3] = (raw_data[1] & 0xFF00) >> 8; + data[2] = raw_data[2]; + data[4] = raw_data[3]; + data[5] = raw_data[4] & 0x00FF; + data[7] = (raw_data[4] & 0xFF00) >> 8; + data[6] = raw_data[5]; + + for(i=0; i<8; i++){ + if (flags.debug) + fprintf(stderr, "\n addr = 0x%06X data = 0x%04X", (addr+i), data[i]); + + if(mem.filled[addr+i] && data[i] != mem.location[addr+i]){ + fprintf(stderr,"\n\n ERROR at address %06X: written %04X but %04X read!\n\n", + addr+i, mem.location[addr+i], data[i]); + return; + } + + } + + if(counter != addr*100/filled_locations){ + if(flags.client) + fprintf(stdout,"@%03d", (addr*100/(filled_locations+0x100))); + if(!flags.debug) + fprintf(stderr,"\b\b\b\b\b[%2d%%]", addr*100/(filled_locations+0x100)); + counter = addr*100/filled_locations; + } + } + + if(!flags.debug) cerr << "\b\b\b\b\b"; + if(flags.client) fprintf(stdout, "@FIN"); + } + else{ + if(flags.client) fprintf(stdout, "@FIN"); + } + +} + +/* write to screen the configuration registers, without saving them anywhere */ +void dspic33ck::dump_configuration_registers(void) +{ + // todo + const char *regname[] = {"FGS","FOSCSEL","FOSC","FWDT","FPOR", + "FICD","FAS","FUID0"}; + + cerr << endl << "Configuration registers:" << endl << endl; + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + send_cmd(0x200F80); + send_cmd(0x8802A0); + send_cmd(0x200046); + send_cmd(0x20F887); + send_nop(); + + for(unsigned short i=0; i<8; i++){ + send_cmd(0xBA0BB6); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + fprintf(stderr," - %s: 0x%02x\n", regname[i], read_data()); + } + + cerr << endl; + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); +} + diff --git a/src/devices/dspic33ck.h b/src/devices/dspic33ck.h new file mode 100644 index 0000000..af134f3 --- /dev/null +++ b/src/devices/dspic33ck.h @@ -0,0 +1,83 @@ +/* + * Raspberry Pi PIC Programmer using GPIO connector + * https://github.com/WallaceIT/picberry + * Copyright 2014 Francesco Valla + * Copyright 2024 Gitle Mikkelsen + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +#include + +#include "../common.h" +#include "device.h" + +using namespace std; + +#define SF_DSPIC33CK32 0x00 +#define SF_DSPIC33CK64 0x01 + +class dspic33ck : public Pic{ + + public:{ + dspic33ck(uint8_t sf) { + subfamily = sf; + }; + void enter_program_mode(void); + void exit_program_mode(void); + bool setup_pe(void){return true;}; + bool read_device_id(void); + void bulk_erase(void); + void dump_configuration_registers(void); + void read(char *outfile, uint32_t start, uint32_t count); + void write(char *infile); + uint8_t blank_check(void); + + protected: + void send_cmd(uint32_t cmd); + uint16_t read_data(void); + + /* + * DEVICES SECTION + * ID NAME MEMSIZE + */ + pic_device piclist[28] = {{0x1861, "dsPIC33EP256MU806", 0x02ABFF}, + {0x1862, "dsPIC33EP256MU810", 0x02ABFF}, + {0x1863, "dsPIC33EP256MU814", 0x02ABFF}, + {0x1826, "PIC24EP256GU810", 0x02ABFF}, + {0x1827, "PIC24EP256GU814", 0x02ABFF}, + {0x187D, "dsPIC33EP512GP806", 0x02ABFF}, + {0x1879, "dsPIC33EP512MC806", 0x0557FF}, + {0x1872, "dsPIC33EP512MU810", 0x0557FF}, + {0x1873, "dsPIC33EP512MU814", 0x0557FF}, + {0x183D, "PIC24EP512GP806", 0x0557FF}, + {0x1836, "PIC24EP512GU810", 0x0557FF}, + {0x1837, "PIC24EP512GU814", 0x0557FF}, + {0x6000, "PIC24FJ128GA606", 0x015FFF}, + {0x6008, "PIC24FJ256GA606", 0x02AFFF}, + {0x6010, "PIC24FJ512GA606", 0x055FFF}, + {0x6018, "PIC24FJ1024GA606", 0x0ABFFF}, + {0x6001, "PIC24FJ128GA610", 0x015FFF}, + {0x6009, "PIC24FJ256GA610", 0x02AFFF}, + {0x6011, "PIC24FJ512GA610", 0x055FFF}, + {0x6019, "PIC24FJ1024GA610", 0x0ABFFF}, + {0x6004, "PIC24FJ128GB606", 0x015FFF}, + {0x600C, "PIC24FJ256GB606", 0x02AFFF}, + {0x6014, "PIC24FJ512GB606", 0x055FFF}, + {0x601C, "PIC24FJ1024GB606", 0x0ABFFF}, + {0x6005, "PIC24FJ128GB610", 0x015FFF}, + {0x600D, "PIC24FJ256GB610", 0x02AFFF}, + {0x6015, "PIC24FJ512GB610", 0x055FFF}, + {0x601D, "PIC24FJ1024GB610", 0x0ABFFF}}; +}; From c2a696bc746c857c04de45572224fabbc6baa83c Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Mon, 5 Aug 2024 15:59:44 +0200 Subject: [PATCH 02/15] More work on dspic33ck --- README.md | 1 + src/devices/dspic33ck.cpp | 114 +++++++++++++++++++++----------------- src/devices/dspic33ck.h | 39 +++---------- src/picberry.cpp | 2 + 4 files changed, 74 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index c099e5f..eb4796f 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,7 @@ To compile it, just launch `qmake` and then `make` in the *remote_gui* folder. - [PIC12(L)F1822/PIC16(L)F182X Flash Programming Specification](http://ww1.microchip.com/downloads/en/DeviceDoc/41390D.pdf) - [PIC18F2XJXX/4XJXX Family Programming Specification](http://ww1.microchip.com/downloads/en/DeviceDoc/39687e.pdf) - [PIC32 Flash Programming Specification](http://ww1.microchip.com/downloads/en/DeviceDoc/60001145S.pdf) +- [dsPIC33CK64/32 Flash Programming Specification](https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/ProgrammingSpecifications/70005352c.pdf) ## Licensing diff --git a/src/devices/dspic33ck.cpp b/src/devices/dspic33ck.cpp index 060d6af..9cf86d9 100644 --- a/src/devices/dspic33ck.cpp +++ b/src/devices/dspic33ck.cpp @@ -174,10 +174,7 @@ void dspic33ck::enter_program_mode(void) GPIO_CLR(pic_data); delay_us(DELAY_P19); GPIO_SET(pic_mclr); - if(subfamily == SF_DSPIC33E) - delay_us(DELAY_P7_DSPIC33E); - else if(subfamily == SF_PIC24FJ) - delay_us(DELAY_P7_PIC24FJ); + delay_us(DELAY_P7); /* idle for 5 clock cycles */ for (i = 0; i < 5; i++) { @@ -208,6 +205,8 @@ bool dspic33ck::read_device_id(void) bool found = 0; + uint32_t addr = 0xFF0000; + send_nop(); send_nop(); send_nop(); @@ -216,30 +215,28 @@ bool dspic33ck::read_device_id(void) send_nop(); send_nop(); - send_cmd(0x200FF0); + send_cmd(0x200000 | ((addr & 0x00FF0000) >> 12)); // MOV #, W0 + send_cmd(0x20FCC7); send_cmd(0x8802A0); - send_cmd(0x200006); - send_cmd(0x20F887); - send_nop(); + send_cmd(0x200006 | ((addr & 0x0000FFFF) << 4)); // MOV #, W6 - send_cmd(0xBA0BB6); send_nop(); + send_cmd(0xBA8B96); send_nop(); send_nop(); send_nop(); send_nop(); - device_id = read_data(); - - send_cmd(0xBA0BB6); send_nop(); + device_id = read_data(); + send_cmd(0xBA0B96); send_nop(); send_nop(); send_nop(); send_nop(); - device_rev = read_data(); - - reset_pc(); send_nop(); + device_rev = read_data() + + fprintf(stderr, "devid: 0x%02x , devrev: 0x%02x\n", device_id, device_rev); for (unsigned short i=0;i < sizeof(piclist)/sizeof(piclist[0]);i++){ @@ -247,7 +244,16 @@ bool dspic33ck::read_device_id(void) strcpy(name, piclist[i].name); mem.code_memory_size = piclist[i].code_memory_size; - mem.program_memory_size = 0x0F80018; + if (mem.code_memory_size == 0x005EFF) + { + subfamily = SF_DSPIC33CK32; + mem.program_memory_size = 0x005FFF; + } + else + { + subfamily = SF_DSPIC33CK64; + mem.program_memory_size = 0x00AFFF; + } mem.location = (uint16_t*) calloc(mem.program_memory_size,sizeof(uint16_t)); mem.filled = (bool*) calloc(mem.program_memory_size,sizeof(bool)); found = 1; @@ -451,6 +457,7 @@ void dspic33ck::bulk_erase(void) } /* Read PIC memory and write the contents to a .hex file */ +// todo void dspic33ck::read(char *outfile, uint32_t start, uint32_t count) { uint32_t addr, startaddr, stopaddr; @@ -785,11 +792,11 @@ void dspic33ck::write(char *infile) send_cmd(0x200FAC); send_cmd(0x8802AC); - addr = 0x00005F00; // +4? + addr = 0x00005F00; if (subfamily == SF_DSPIC33CK64) addr = 0x0000AF00; - for(i=0; i<15; i+=2, addr+=4){ + for(i=0; i<15; i+=1, addr+=4){ if (i == 1) addr += 12; // jump to 0x10 offset after first register @@ -861,9 +868,11 @@ void dspic33ck::write(char *infile) send_nop(); } while((nvmcon & 0x8000) == 0x8000); - if(flags.debug) - fprintf(stderr,"\n - %s set to 0x%01x", - regname[i], mem.location[addr]); + if (flags.debug) + { + fprintf(stderr, "\n - %s set to 0x%01x, 0x%01x, 0x%01x, 0x%01x", + regname[i], mem.location[addr], mem.location[addr+1], mem.location[addr+2], mem.location[addr+3]); + } } else if(flags.debug) fprintf(stderr,"\n - %s left unchanged", regname[i]); @@ -875,7 +884,6 @@ void dspic33ck::write(char *infile) delay_us(100000); /* VERIFY CODE MEMORY */ - // todo if(!flags.noverify){ if(!flags.debug) cerr << "[ 0%]"; if(flags.client) fprintf(stdout, "@000"); @@ -957,7 +965,7 @@ void dspic33ck::write(char *infile) /* read six data words (16 bits each) */ for(i=0; i<6; i++){ - send_cmd(0x887C40 + i); + send_cmd(0x887E60 + i); send_nop(); raw_data[i] = read_data(); send_nop(); @@ -1014,44 +1022,50 @@ void dspic33ck::write(char *infile) /* write to screen the configuration registers, without saving them anywhere */ void dspic33ck::dump_configuration_registers(void) { - // todo - const char *regname[] = {"FGS","FOSCSEL","FOSC","FWDT","FPOR", - "FICD","FAS","FUID0"}; + const char* regname[] = { "FSEC","FBSLIM","FSIGN","FOSCSEL","FOSC","FWDT","FPOR","FICD","FDMTIVTL","FDMTIVTH","FDMTCNTL","FDMTCNTH","FDMT","FDEVOPT","FALTREG" }; cerr << endl << "Configuration registers:" << endl << endl; - send_nop(); - send_nop(); - send_nop(); - reset_pc(); - send_nop(); - send_nop(); - send_nop(); + uint32_t addr = 0x00005F00; + if (subfamily == SF_DSPIC33CK64) + addr = 0x0000AF00; - send_cmd(0x200F80); - send_cmd(0x8802A0); - send_cmd(0x200046); - send_cmd(0x20F887); - send_nop(); + for (unsigned short i = 0; i < 15; addr += 4, i += 1) { + + if (i == 1) + addr += 12; // jump to offset 0x10 after first config value - for(unsigned short i=0; i<8; i++){ - send_cmd(0xBA0BB6); send_nop(); send_nop(); send_nop(); + reset_pc(); + send_nop(); send_nop(); send_nop(); - fprintf(stderr," - %s: 0x%02x\n", regname[i], read_data()); - } - cerr << endl; + send_cmd(0x200000 | ((addr & 0x00FF0000) >> 12)); // MOV #, W0 + send_cmd(0x20FCC7); + send_cmd(0x8802A0); + send_cmd(0x200006 | ((addr & 0x0000FFFF) << 4)); // MOV #, W6 - send_nop(); - send_nop(); - send_nop(); - reset_pc(); - send_nop(); - send_nop(); - send_nop(); + send_nop(); + send_cmd(0xBA8B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + uint16_t data_1 = read_data(); + send_cmd(0xBA0B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + uint16_t data_2 = read_data() + fprintf(stderr, " - %s: 0x%02x , 0x%02x\n", regname[i], data_1, data_2); + + cerr << endl; + } } diff --git a/src/devices/dspic33ck.h b/src/devices/dspic33ck.h index af134f3..2d08923 100644 --- a/src/devices/dspic33ck.h +++ b/src/devices/dspic33ck.h @@ -30,10 +30,7 @@ using namespace std; class dspic33ck : public Pic{ - public:{ - dspic33ck(uint8_t sf) { - subfamily = sf; - }; + public: void enter_program_mode(void); void exit_program_mode(void); bool setup_pe(void){return true;}; @@ -52,32 +49,10 @@ class dspic33ck : public Pic{ * DEVICES SECTION * ID NAME MEMSIZE */ - pic_device piclist[28] = {{0x1861, "dsPIC33EP256MU806", 0x02ABFF}, - {0x1862, "dsPIC33EP256MU810", 0x02ABFF}, - {0x1863, "dsPIC33EP256MU814", 0x02ABFF}, - {0x1826, "PIC24EP256GU810", 0x02ABFF}, - {0x1827, "PIC24EP256GU814", 0x02ABFF}, - {0x187D, "dsPIC33EP512GP806", 0x02ABFF}, - {0x1879, "dsPIC33EP512MC806", 0x0557FF}, - {0x1872, "dsPIC33EP512MU810", 0x0557FF}, - {0x1873, "dsPIC33EP512MU814", 0x0557FF}, - {0x183D, "PIC24EP512GP806", 0x0557FF}, - {0x1836, "PIC24EP512GU810", 0x0557FF}, - {0x1837, "PIC24EP512GU814", 0x0557FF}, - {0x6000, "PIC24FJ128GA606", 0x015FFF}, - {0x6008, "PIC24FJ256GA606", 0x02AFFF}, - {0x6010, "PIC24FJ512GA606", 0x055FFF}, - {0x6018, "PIC24FJ1024GA606", 0x0ABFFF}, - {0x6001, "PIC24FJ128GA610", 0x015FFF}, - {0x6009, "PIC24FJ256GA610", 0x02AFFF}, - {0x6011, "PIC24FJ512GA610", 0x055FFF}, - {0x6019, "PIC24FJ1024GA610", 0x0ABFFF}, - {0x6004, "PIC24FJ128GB606", 0x015FFF}, - {0x600C, "PIC24FJ256GB606", 0x02AFFF}, - {0x6014, "PIC24FJ512GB606", 0x055FFF}, - {0x601C, "PIC24FJ1024GB606", 0x0ABFFF}, - {0x6005, "PIC24FJ128GB610", 0x015FFF}, - {0x600D, "PIC24FJ256GB610", 0x02AFFF}, - {0x6015, "PIC24FJ512GB610", 0x055FFF}, - {0x601D, "PIC24FJ1024GB610", 0x0ABFFF}}; + pic_device piclist[6] = {{0x8E00, "dsPIC33CK32MP102", 0x005EFF}, + {0x8E01, "dsPIC33CK32MP103", 0x005EFF}, + {0x8E02, "dsPIC33CK32MP105", 0x005EFF}, + {0x8E10, "dsPIC33CK64MP102", 0x00AEFF}, + {0x8E11, "dsPIC33CK64MP103", 0x00AEFF}, + {0x8E12, "dsPIC33CK64MP105", 0x00AEFF}}; }; diff --git a/src/picberry.cpp b/src/picberry.cpp index ba5001c..c888a2e 100644 --- a/src/picberry.cpp +++ b/src/picberry.cpp @@ -278,6 +278,7 @@ int main(int argc, char *argv[]) cerr << "ERROR: PIC family not correctly chosen." << endl; cerr << "Available families:" << endl << "- dspic33e" << endl + << "- dspic33ck" << endl << "- pic24fj" << endl << "- pic24fjxxxga0xx" << endl << "- pic24fjxxxga3xx" << endl @@ -478,6 +479,7 @@ void usage(void) "\n" " dspic33e \n" " dspic33f \n" + " dspic33ck \n" " pic10f322 \n" " pic18fj \n" " pic24fj \n" From 6ef55048469988e0a07bb31b76c893b2c6ae4c97 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Mon, 5 Aug 2024 20:40:27 +0200 Subject: [PATCH 03/15] rk3308 host support --- src/common.h | 2 ++ src/hosts/rk3308.h | 41 +++++++++++++++++++++++++++++++++++++++++ src/picberry.cpp | 8 ++++++++ 3 files changed, 51 insertions(+) create mode 100644 src/hosts/rk3308.h diff --git a/src/common.h b/src/common.h index 5cbfc05..00c556e 100644 --- a/src/common.h +++ b/src/common.h @@ -31,6 +31,8 @@ #include "hosts/rpi4.h" #elif defined(BOARD_AM335X) #include "hosts/am335x.h" +#elif defined(BOARD_RK3308) +#include "hosts/rk3308.h" #endif #include "devices/device.h" diff --git a/src/hosts/rk3308.h b/src/hosts/rk3308.h new file mode 100644 index 0000000..3d2c644 --- /dev/null +++ b/src/hosts/rk3308.h @@ -0,0 +1,41 @@ +/* + * Raspberry Pi PIC Programmer using GPIO connector + * https://github.com/WallaceIT/picberry + * Copyright 2016 Francesco Valla + * Copyright 2024 Gitle Mikkelsen + * + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see . + */ + +// RK3308, used in Rock Pi S, Rock S0 etc. +// NB: Mapped to GPIO2, pin index must be 0 to 31 + +/* GPIO registers address */ +#define GPIO_BASE (0xff240000) /* GPIO controller */ +#define BLOCK_SIZE (0x80) +#define PORTOFFSET 0 + +/* GPIO setup macros. Always use GPIO_IN(x) before using GPIO_OUT(x) */ +#define GPIO_IN(g) *(gpio + 0x04) &= ~(1 << (g & 0xFF)) +#define GPIO_OUT(g) *(gpio + 0x04) |= (1 << (g & 0xFF)) + +#define GPIO_SET(g) *(gpio + 0x00) |= (1 << (g & 0xFF)) +#define GPIO_CLR(g) *(gpio + 0x00) &= ~(1 << (g & 0xFF)) +#define GPIO_LEV(g) ((*(gpio + 0x50) >> (g & 0xFF)) & 1) + +/* default GPIO <-> PIC connections */ +#define DEFAULT_PIC_CLK 16 // PGC - Output +#define DEFAULT_PIC_DATA 10 // PGD - I/O +#define DEFAULT_PIC_MCLR 4 // MCLR - Output diff --git a/src/picberry.cpp b/src/picberry.cpp index c888a2e..b15d763 100644 --- a/src/picberry.cpp +++ b/src/picberry.cpp @@ -42,6 +42,7 @@ #include "common.h" #include "devices/dspic33f.h" #include "devices/dspic33e.h" +#include "devices/dspic33ck.h" #include "devices/pic10f322.h" #include "devices/pic18fj.h" #include "devices/pic24fjxxxga0xx.h" @@ -242,6 +243,8 @@ int main(int argc, char *argv[]) pic = new dspic33e(SF_DSPIC33E); else if(strcmp(family,"pic24fj") == 0) pic = new dspic33e(SF_PIC24FJ); + else if (strcmp(family, "dspic33ck") == 0) + pic = new dspic33ck(); else if(strcmp(family,"pic10f322") == 0) pic = new pic10f322(); else if(strcmp(family,"pic18fj") == 0) @@ -524,6 +527,7 @@ enum srv_families : char{ SRV_FAM_PIC32MX3 = '6', SRV_FAM_PIC32MZ = '7', SRV_FAM_PIC32MK = '8' + SRV_FAM_PIC33CK = '9' }; void server_mode(int port){ @@ -627,6 +631,10 @@ void server_mode(int port){ cerr << "DSPIC33F" << endl; pic = new dspic33f(); break; + case SRV_FAM_DSPIC33CK: + cerr << "DSPIC33CK" << endl; + pic = new dspic33ck(); + break; case SRV_FAM_PIC18FJ: cerr << "PIC18FJ" << endl; pic = new pic18fj(); From 3fa2782f45e1182ae39fedb5a7b7c3c10246afef Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Tue, 6 Aug 2024 13:11:27 +0200 Subject: [PATCH 04/15] Makefile for dsPIC33CK and RK3308 host --- Makefile | 3 +++ src/gpio_test.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/Makefile b/Makefile index 9c47525..32ab12d 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ MKDIR = mkdir -p DEVICES = $(BUILDDIR)/devices/dspic33e.o \ $(BUILDDIR)/devices/dspic33f.o \ + $(BUILDDIR)/devices/dspic33ck.o \ $(BUILDDIR)/devices/pic10f322.o \ $(BUILDDIR)/devices/pic18fj.o \ $(BUILDDIR)/devices/pic24fjxxxga0xx.o \ @@ -28,6 +29,7 @@ raspberrypi: CFLAGS += -DBOARD_RPI raspberrypi2: CFLAGS += -DBOARD_RPI2 raspberrypi4: CFLAGS += -DBOARD_RPI4 am335x: CFLAGS += -DBOARD_AM335X +rk3308: CFLAGS += -DBOARD_RK3308 default: @echo "Please specify a target with 'make raspberrypi', 'make a10' or 'make am335x'." @@ -37,6 +39,7 @@ raspberrypi2: prepare picberry raspberrypi4: prepare picberry a10: prepare picberry am335x: prepare picberry gpio_test +rk3308: prepare picberry gpio_test prepare: $(MKDIR) $(BUILDDIR)/devices diff --git a/src/gpio_test.cpp b/src/gpio_test.cpp index b70efa2..28d4b78 100644 --- a/src/gpio_test.cpp +++ b/src/gpio_test.cpp @@ -90,7 +90,11 @@ int main(int argc, char *argv[]) } cout << "Testing GPIO " << tested_gpio_port << (tested_gpio&0xFF) << endl; +#ifdef OFFSET cout << "BASE ADDRESS " << hex << GPIO_BASE << " + OFFSET " << hex << OFFSET(tested_gpio) << " = FINAL ADDRESS " << hex << GPIO_BASE + OFFSET(tested_gpio) << endl; +#else + cout << "BASE ADDRESS " << hex << GPIO_BASE << endl; +#endif setup_io(); From 78d243e3be91e87f26b793d1f36c233de5e2bb78 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Tue, 6 Aug 2024 13:17:56 +0200 Subject: [PATCH 05/15] compile error fix and readme for rk3308 --- README.md | 3 ++- src/devices/dspic33ck.cpp | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index eb4796f..d1fa1d0 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,10 @@ To build picberry launch `make TARGET`, where _TARGET_ can be one of the followi | ------------- | ------------------------------------------ | | raspberrypi | Raspberry Pi v1 or Zero | | raspberrypi2 | Raspberry Pi v2 or v3 | -| raspberrypi4 | Raspberry Pi 4A or 4B or CM4 +| raspberrypi4 | Raspberry Pi 4A or 4B or CM4 | | am335x | Boards based on TI AM335x (BeagleBone) | | a10 | Boards based on Allwinner A10 (Cubieboard) | +| rk3308 | Rock Pi S, Rock S0 and others | Then launch `sudo make install` to install it to /usr/bin. diff --git a/src/devices/dspic33ck.cpp b/src/devices/dspic33ck.cpp index 9cf86d9..7f79164 100644 --- a/src/devices/dspic33ck.cpp +++ b/src/devices/dspic33ck.cpp @@ -234,7 +234,7 @@ bool dspic33ck::read_device_id(void) send_nop(); send_nop(); send_nop(); - device_rev = read_data() + device_rev = read_data(); fprintf(stderr, "devid: 0x%02x , devrev: 0x%02x\n", device_id, device_rev); @@ -646,8 +646,7 @@ void dspic33ck::read(char *outfile, uint32_t start, uint32_t count) /* Write contents of the .hex file to the PIC */ void dspic33ck::write(char *infile) { - uint16_t i,j,p; - uint16_t k; + uint16_t i,j,k; bool skip; uint32_t data[8],raw_data[6]; uint32_t addr = 0; @@ -1062,7 +1061,7 @@ void dspic33ck::dump_configuration_registers(void) send_nop(); send_nop(); send_nop(); - uint16_t data_2 = read_data() + uint16_t data_2 = read_data(); fprintf(stderr, " - %s: 0x%02x , 0x%02x\n", regname[i], data_1, data_2); cerr << endl; From 67633e57acd651321400cf15b36a584bd103e792 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Tue, 6 Aug 2024 13:21:47 +0200 Subject: [PATCH 06/15] Compilation error --- src/picberry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/picberry.cpp b/src/picberry.cpp index b15d763..ef618f7 100644 --- a/src/picberry.cpp +++ b/src/picberry.cpp @@ -526,8 +526,8 @@ enum srv_families : char{ SRV_FAM_PIC32MX2 = '5', SRV_FAM_PIC32MX3 = '6', SRV_FAM_PIC32MZ = '7', - SRV_FAM_PIC32MK = '8' - SRV_FAM_PIC33CK = '9' + SRV_FAM_PIC32MK = '8', + SRV_FAM_PIC33CK = '9' }; void server_mode(int port){ From 863e6c927e58041504cadd57b52e2286f8e813f9 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Tue, 6 Aug 2024 13:23:04 +0200 Subject: [PATCH 07/15] Another compilation error --- src/picberry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/picberry.cpp b/src/picberry.cpp index ef618f7..7c95bdb 100644 --- a/src/picberry.cpp +++ b/src/picberry.cpp @@ -527,7 +527,7 @@ enum srv_families : char{ SRV_FAM_PIC32MX3 = '6', SRV_FAM_PIC32MZ = '7', SRV_FAM_PIC32MK = '8', - SRV_FAM_PIC33CK = '9' + SRV_FAM_DSPIC33CK = '9' }; void server_mode(int port){ From 646bb49c99583ce5e05ec630f1b9ffaf794acd2c Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Tue, 6 Aug 2024 14:00:47 +0200 Subject: [PATCH 08/15] Fix rk3308 gpio addressing --- src/hosts/rk3308.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hosts/rk3308.h b/src/hosts/rk3308.h index 3d2c644..acfb2b7 100644 --- a/src/hosts/rk3308.h +++ b/src/hosts/rk3308.h @@ -28,12 +28,12 @@ #define PORTOFFSET 0 /* GPIO setup macros. Always use GPIO_IN(x) before using GPIO_OUT(x) */ -#define GPIO_IN(g) *(gpio + 0x04) &= ~(1 << (g & 0xFF)) -#define GPIO_OUT(g) *(gpio + 0x04) |= (1 << (g & 0xFF)) +#define GPIO_IN(g) *(gpio + (0x04 / 4)) &= ~(1 << (g & 0xFF)) +#define GPIO_OUT(g) *(gpio + (0x04 / 4)) |= (1 << (g & 0xFF)) -#define GPIO_SET(g) *(gpio + 0x00) |= (1 << (g & 0xFF)) -#define GPIO_CLR(g) *(gpio + 0x00) &= ~(1 << (g & 0xFF)) -#define GPIO_LEV(g) ((*(gpio + 0x50) >> (g & 0xFF)) & 1) +#define GPIO_SET(g) *(gpio + (0x00 / 4)) |= (1 << (g & 0xFF)) +#define GPIO_CLR(g) *(gpio + (0x00 / 4)) &= ~(1 << (g & 0xFF)) +#define GPIO_LEV(g) ((*(gpio + (0x50 / 4)) >> (g & 0xFF)) & 1) /* default GPIO <-> PIC connections */ #define DEFAULT_PIC_CLK 16 // PGC - Output From 439ca37b53103e218173544f81ba807195e209f7 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Mon, 19 Aug 2024 18:48:58 +0200 Subject: [PATCH 09/15] dsPIC33CKxxMC series, and fix wrong word order on double read --- Makefile | 2 +- README.md | 6 ++++++ src/devices/dspic33ck.cpp | 14 ++++++-------- src/devices/dspic33ck.h | 8 +++++++- src/hosts/rk3308.h | 8 ++++---- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 32ab12d..fd16a11 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ am335x: CFLAGS += -DBOARD_AM335X rk3308: CFLAGS += -DBOARD_RK3308 default: - @echo "Please specify a target with 'make raspberrypi', 'make a10' or 'make am335x'." + @echo "Please specify a target with 'make raspberrypi', 'make a10', 'make am335x', or 'make rk3308'." raspberrypi: prepare picberry raspberrypi2: prepare picberry diff --git a/README.md b/README.md index d1fa1d0..1c322c3 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,12 @@ for BeagleBone Black (AM335x): PGC <-> GPIO60 (P9.12) PGD <-> GPIO49 (P9.23) MCLR <-> GPIO48 (P9.15) + +for Rock Pi S / Rock S0: + + PGC <-> GPIO2_C0 + PGD <-> GPIO2_B2 + MCLR <-> GPIO2_A4 ### Remote GUI diff --git a/src/devices/dspic33ck.cpp b/src/devices/dspic33ck.cpp index 7f79164..5e4e980 100644 --- a/src/devices/dspic33ck.cpp +++ b/src/devices/dspic33ck.cpp @@ -201,8 +201,6 @@ void dspic33ck::exit_program_mode(void) /* read the device ID and revision; returns only the id */ bool dspic33ck::read_device_id(void) { - // TODO - bool found = 0; uint32_t addr = 0xFF0000; @@ -227,16 +225,16 @@ bool dspic33ck::read_device_id(void) send_nop(); send_nop(); send_nop(); - device_id = read_data(); + device_rev = read_data(); send_cmd(0xBA0B96); send_nop(); send_nop(); send_nop(); send_nop(); send_nop(); - device_rev = read_data(); + device_id = read_data(); - fprintf(stderr, "devid: 0x%02x , devrev: 0x%02x\n", device_id, device_rev); + fprintf(stderr, "devid: 0x%04x , devrev: 0x%04x\n", device_id, device_rev); for (unsigned short i=0;i < sizeof(piclist)/sizeof(piclist[0]);i++){ @@ -1054,15 +1052,15 @@ void dspic33ck::dump_configuration_registers(void) send_nop(); send_nop(); send_nop(); - uint16_t data_1 = read_data(); + uint16_t data_2 = read_data(); send_cmd(0xBA0B96); send_nop(); send_nop(); send_nop(); send_nop(); send_nop(); - uint16_t data_2 = read_data(); - fprintf(stderr, " - %s: 0x%02x , 0x%02x\n", regname[i], data_1, data_2); + uint16_t data_1 = read_data(); + fprintf(stderr, " - %s: 0x%04x , 0x%04x\n", regname[i], data_1, data_2); cerr << endl; } diff --git a/src/devices/dspic33ck.h b/src/devices/dspic33ck.h index 2d08923..e4fb096 100644 --- a/src/devices/dspic33ck.h +++ b/src/devices/dspic33ck.h @@ -54,5 +54,11 @@ class dspic33ck : public Pic{ {0x8E02, "dsPIC33CK32MP105", 0x005EFF}, {0x8E10, "dsPIC33CK64MP102", 0x00AEFF}, {0x8E11, "dsPIC33CK64MP103", 0x00AEFF}, - {0x8E12, "dsPIC33CK64MP105", 0x00AEFF}}; + {0x8E12, "dsPIC33CK64MP105", 0x00AEFF}, + {0x9900, "dsPIC33CK32MC102", 0x005EFF}, + {0x9901, "dsPIC33CK32MC103", 0x005EFF}, + {0x9902, "dsPIC33CK32MC105", 0x005EFF}, + {0x9910, "dsPIC33CK64MC102", 0x00AEFF}, + {0x9911, "dsPIC33CK64MC103", 0x00AEFF}, + {0x9912, "dsPIC33CK64MC105", 0x00AEFF} }; }; diff --git a/src/hosts/rk3308.h b/src/hosts/rk3308.h index acfb2b7..a7aa78d 100644 --- a/src/hosts/rk3308.h +++ b/src/hosts/rk3308.h @@ -20,7 +20,7 @@ */ // RK3308, used in Rock Pi S, Rock S0 etc. -// NB: Mapped to GPIO2, pin index must be 0 to 31 +// NB: Mapped to GPIO2, pin index must be 0 to 31. A0 = 0, A7 = 7, B0 = 8, B7 = 15, C0 = 16, etc... /* GPIO registers address */ #define GPIO_BASE (0xff240000) /* GPIO controller */ @@ -36,6 +36,6 @@ #define GPIO_LEV(g) ((*(gpio + (0x50 / 4)) >> (g & 0xFF)) & 1) /* default GPIO <-> PIC connections */ -#define DEFAULT_PIC_CLK 16 // PGC - Output -#define DEFAULT_PIC_DATA 10 // PGD - I/O -#define DEFAULT_PIC_MCLR 4 // MCLR - Output +#define DEFAULT_PIC_CLK 16 // GPIO2_C0 - PGC - Output +#define DEFAULT_PIC_DATA 10 // GPIO2_B2 - PGD - I/O +#define DEFAULT_PIC_MCLR 4 // GPIO2_A4 - MCLR - Output From fcd2a023e05ff6902c810c01aeefd1945b167909 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Mon, 19 Aug 2024 18:50:45 +0200 Subject: [PATCH 10/15] compilation error --- src/devices/dspic33ck.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/dspic33ck.h b/src/devices/dspic33ck.h index e4fb096..53551c8 100644 --- a/src/devices/dspic33ck.h +++ b/src/devices/dspic33ck.h @@ -49,7 +49,7 @@ class dspic33ck : public Pic{ * DEVICES SECTION * ID NAME MEMSIZE */ - pic_device piclist[6] = {{0x8E00, "dsPIC33CK32MP102", 0x005EFF}, + pic_device piclist[12] = {{0x8E00, "dsPIC33CK32MP102", 0x005EFF}, {0x8E01, "dsPIC33CK32MP103", 0x005EFF}, {0x8E02, "dsPIC33CK32MP105", 0x005EFF}, {0x8E10, "dsPIC33CK64MP102", 0x00AEFF}, From 86edbb8834c295ea63f51d4fbc10fd029b23e5b8 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Mon, 19 Aug 2024 19:04:03 +0200 Subject: [PATCH 11/15] config register formatting --- src/devices/dspic33ck.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devices/dspic33ck.cpp b/src/devices/dspic33ck.cpp index 5e4e980..4765302 100644 --- a/src/devices/dspic33ck.cpp +++ b/src/devices/dspic33ck.cpp @@ -1052,15 +1052,15 @@ void dspic33ck::dump_configuration_registers(void) send_nop(); send_nop(); send_nop(); - uint16_t data_2 = read_data(); + uint16_t data_1 = read_data(); send_cmd(0xBA0B96); send_nop(); send_nop(); send_nop(); send_nop(); send_nop(); - uint16_t data_1 = read_data(); - fprintf(stderr, " - %s: 0x%04x , 0x%04x\n", regname[i], data_1, data_2); + uint16_t data_2 = read_data(); + fprintf(stderr, " - %s: 0x%04x%04x\n", regname[i], data_1, data_2); cerr << endl; } From d24f34022a4f0c403125a7ed9777cd1c73c04633 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Mon, 11 Nov 2024 19:57:58 +0100 Subject: [PATCH 12/15] Fix bug on xxMC family. Tested write and verify sequence working --- README.md | 7 +-- src/devices/dspic33ck.cpp | 99 ++++++++++++++++++++++++++++++++++----- src/devices/dspic33ck.h | 4 +- src/inhx.cpp | 2 +- 4 files changed, 93 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1c322c3..41c2e6a 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,16 @@ You should have received a copy of the GNU General Public License along with thi _picberry_ is a PIC programmer using GPIOs that doesn't require additional programming hardware. -It theorically supports dsPIC33E/PIC24E, dsPIC33F/PIC24H, PIC24FJ, PIC18FxxJxx, PIC32MX, PIC32MZ and PIC32MK families, but only some PICs have been tested. +It theorically supports dsPIC33E/PIC24E, dsPIC33F/PIC24H, dsPIC33CK64/32, PIC24FJ, PIC18FxxJxx, PIC32MX, PIC32MZ and PIC32MK families, but only some PICs have been tested. ### Supported hosts Currently _picberry_ has support for the following host boards/processors: -- the [Raspberry Pi](https://www.raspberrypi.org/) -- Allwinner A10-based boards (like the [Cubieboard](http://cubieboard.org/)) +- The [Raspberry Pi](https://www.raspberrypi.org/). +- Allwinner A10-based boards (like the [Cubieboard](http://cubieboard.org/)). - TI AM335x-based boards (like the [Beaglebone Black](https://beagleboard.org/black) or the [AM3359 ICEv2](http://www.ti.com/tool/tmdsice3359)). +- Rock Pi S / S0 (and maybe other boards based on the RK3308). Support for additional boards and processors can be easily added, providing the following macro in a header file inside the _hosts_ folder: diff --git a/src/devices/dspic33ck.cpp b/src/devices/dspic33ck.cpp index 4765302..1438ddd 100644 --- a/src/devices/dspic33ck.cpp +++ b/src/devices/dspic33ck.cpp @@ -244,14 +244,21 @@ bool dspic33ck::read_device_id(void) mem.code_memory_size = piclist[i].code_memory_size; if (mem.code_memory_size == 0x005EFF) { - subfamily = SF_DSPIC33CK32; mem.program_memory_size = 0x005FFF; } else { - subfamily = SF_DSPIC33CK64; mem.program_memory_size = 0x00AFFF; } + if (i <= 5) + { + subfamily = SF_DSPIC33CKxxMP; + } + else + { + subfamily = SF_DSPIC33CKxxMC; + } + mem.location = (uint16_t*) calloc(mem.program_memory_size,sizeof(uint16_t)); mem.filled = (bool*) calloc(mem.program_memory_size,sizeof(bool)); found = 1; @@ -428,7 +435,10 @@ void dspic33ck::bulk_erase(void) send_cmd(0x8846B1); send_cmd(0x200AA1); send_cmd(0x8846B1); - send_cmd(0xA8F1A1); + if (subfamily == SF_DSPIC33CKxxMP) + send_cmd(0xA8F1A1); + else //if (subfamily == SF_DSPIC33CKxxMC) + send_cmd(0xA8E8D1); send_nop(); send_nop(); send_nop(); @@ -437,6 +447,7 @@ void dspic33ck::bulk_erase(void) /* wait while the erase operation completes */ do{ + send_nop(); send_cmd(0x804680); send_nop(); send_cmd(0x887E60); @@ -455,7 +466,7 @@ void dspic33ck::bulk_erase(void) } /* Read PIC memory and write the contents to a .hex file */ -// todo +// TODO void dspic33ck::read(char *outfile, uint32_t start, uint32_t count) { uint32_t addr, startaddr, stopaddr; @@ -547,7 +558,7 @@ void dspic33ck::read(char *outfile, uint32_t start, uint32_t count) /* read six data words (16 bits each) */ for(i=0; i<6; i++){ - send_cmd(0x887C40 + i); + send_cmd(0x887E60 + i); send_nop(); raw_data[i] = read_data(); send_nop(); @@ -598,6 +609,10 @@ void dspic33ck::read(char *outfile, uint32_t start, uint32_t count) /* TODO: checksum */ } + + //addr = 0x00F80004; + + /* send_nop(); send_nop(); send_nop(); @@ -612,9 +627,7 @@ void dspic33ck::read(char *outfile, uint32_t start, uint32_t count) send_cmd(0x20F887); send_nop(); - addr = 0x00F80004; - - for(i=0; i<8; i++){ + for (i = 0; i<8; i++) { send_cmd(0xBA0BB6); send_nop(); send_nop(); @@ -626,6 +639,60 @@ void dspic33ck::read(char *outfile, uint32_t start, uint32_t count) mem.location[addr+2*i] = data[0]; mem.filled[addr+2*i] = 1; } + }*/ + + addr = 0x00005F00; + if (mem.program_memory_size == 0x00AFFF) + addr = 0x0000AF00; + + for (unsigned short i = 0; i < 15; addr += 4, i += 1) { + + if (i == 1) + addr += 12; // jump to offset 0x10 after first config value + + send_nop(); + send_nop(); + send_nop(); + reset_pc(); + send_nop(); + send_nop(); + send_nop(); + + send_cmd(0x200000 | ((addr & 0x00FF0000) >> 12)); // MOV #, W0 + send_cmd(0x20FCC7); + send_cmd(0x8802A0); + send_cmd(0x200006 | ((addr & 0x0000FFFF) << 4)); // MOV #, W6 + + send_nop(); + send_cmd(0xBA8B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + uint16_t data_1 = read_data() | 0xFF00; + + if (data_1 != 0xFFFF) { + mem.location[addr] = data_1; + mem.filled[addr] = 1; + } + + send_cmd(0xBA0B96); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + send_nop(); + uint16_t data_2 = read_data(); + + if (data_2 != 0xFFFF) { + mem.location[addr + 1] = data_2; + mem.filled[addr + 1] = 1; + } + + //fprintf(stderr, " - %s: 0x%04x%04x\n", regname[i], data_1, data_2); + + cerr << endl; } send_nop(); @@ -734,7 +801,10 @@ void dspic33ck::write(char *infile) send_cmd(0x8846B1); send_cmd(0x200AA1); send_cmd(0x8846B1); - send_cmd(0xA8F1A1); + if (subfamily == SF_DSPIC33CKxxMP) + send_cmd(0xA8F1A1); + else //if (subfamily == SF_DSPIC33CKxxMC) + send_cmd(0xA8E8D1); send_nop(); send_nop(); send_nop(); @@ -790,7 +860,7 @@ void dspic33ck::write(char *infile) send_cmd(0x8802AC); addr = 0x00005F00; - if (subfamily == SF_DSPIC33CK64) + if (mem.program_memory_size == 0x00AFFF) addr = 0x0000AF00; for(i=0; i<15; i+=1, addr+=4){ @@ -839,7 +909,10 @@ void dspic33ck::write(char *infile) send_cmd(0x8846B1); send_cmd(0x200AA1); send_cmd(0x8846B1); - send_cmd(0xA8F1A1); + if (subfamily == SF_DSPIC33CKxxMP) + send_cmd(0xA8F1A1); + else //if (subfamily == SF_DSPIC33CKxxMC) + send_cmd(0xA8E8D1); send_nop(); send_nop(); send_nop(); @@ -1024,7 +1097,7 @@ void dspic33ck::dump_configuration_registers(void) cerr << endl << "Configuration registers:" << endl << endl; uint32_t addr = 0x00005F00; - if (subfamily == SF_DSPIC33CK64) + if (mem.program_memory_size == 0x00AFFF) addr = 0x0000AF00; for (unsigned short i = 0; i < 15; addr += 4, i += 1) { @@ -1052,7 +1125,7 @@ void dspic33ck::dump_configuration_registers(void) send_nop(); send_nop(); send_nop(); - uint16_t data_1 = read_data(); + uint16_t data_1 = read_data() | 0xFF00; send_cmd(0xBA0B96); send_nop(); send_nop(); diff --git a/src/devices/dspic33ck.h b/src/devices/dspic33ck.h index 53551c8..4598276 100644 --- a/src/devices/dspic33ck.h +++ b/src/devices/dspic33ck.h @@ -25,8 +25,8 @@ using namespace std; -#define SF_DSPIC33CK32 0x00 -#define SF_DSPIC33CK64 0x01 +#define SF_DSPIC33CKxxMC 0x00 +#define SF_DSPIC33CKxxMP 0x01 class dspic33ck : public Pic{ diff --git a/src/inhx.cpp b/src/inhx.cpp index 22dac14..d99d170 100644 --- a/src/inhx.cpp +++ b/src/inhx.cpp @@ -56,7 +56,7 @@ unsigned int read_inhx(char *infile, memory *mem, uint32_t offset) fp = fopen(infile, "r"); if (fp == NULL) { - cerr << "Error: cannot open source file " << infile << endl; + cerr << "Error: cannot open source file " << infile << " : " << errno << endl; return 0; } From 7912d66ccedddd964b78768e007bfc23c56d68ba Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Wed, 13 Nov 2024 20:10:44 +0100 Subject: [PATCH 13/15] Undo fix that wasn't actually a fix because the official docs are wrong --- src/devices/dspic33ck.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/devices/dspic33ck.cpp b/src/devices/dspic33ck.cpp index 1438ddd..7689f7e 100644 --- a/src/devices/dspic33ck.cpp +++ b/src/devices/dspic33ck.cpp @@ -258,6 +258,8 @@ bool dspic33ck::read_device_id(void) { subfamily = SF_DSPIC33CKxxMC; } + if (flags.debug) + fprintf(stderr, "program memory: 0x%06x, subfamily: %d\n", mem.program_memory_size, subfamily); mem.location = (uint16_t*) calloc(mem.program_memory_size,sizeof(uint16_t)); mem.filled = (bool*) calloc(mem.program_memory_size,sizeof(bool)); @@ -435,10 +437,10 @@ void dspic33ck::bulk_erase(void) send_cmd(0x8846B1); send_cmd(0x200AA1); send_cmd(0x8846B1); - if (subfamily == SF_DSPIC33CKxxMP) - send_cmd(0xA8F1A1); - else //if (subfamily == SF_DSPIC33CKxxMC) - send_cmd(0xA8E8D1); + //if (subfamily == SF_DSPIC33CKxxMP) + // send_cmd(0xA8F1A1); + //else //if (subfamily == SF_DSPIC33CKxxMC) + send_cmd(0xA8E8D1); // There seems to be something wrong with the official documentation, it says it should be 0xA8F1A1 for xxMP chips, but only 0xA8E8D1 works, as for MC chips. send_nop(); send_nop(); send_nop(); @@ -801,10 +803,10 @@ void dspic33ck::write(char *infile) send_cmd(0x8846B1); send_cmd(0x200AA1); send_cmd(0x8846B1); - if (subfamily == SF_DSPIC33CKxxMP) - send_cmd(0xA8F1A1); - else //if (subfamily == SF_DSPIC33CKxxMC) - send_cmd(0xA8E8D1); + //if (subfamily == SF_DSPIC33CKxxMP) + // send_cmd(0xA8F1A1); + //else //if (subfamily == SF_DSPIC33CKxxMC) + send_cmd(0xA8E8D1); // There seems to be something wrong with the official documentation, it says it should be 0xA8F1A1 for xxMP chips, but only 0xA8E8D1 works, as for MC chips. send_nop(); send_nop(); send_nop(); @@ -909,10 +911,10 @@ void dspic33ck::write(char *infile) send_cmd(0x8846B1); send_cmd(0x200AA1); send_cmd(0x8846B1); - if (subfamily == SF_DSPIC33CKxxMP) - send_cmd(0xA8F1A1); - else //if (subfamily == SF_DSPIC33CKxxMC) - send_cmd(0xA8E8D1); + //if (subfamily == SF_DSPIC33CKxxMP) + // send_cmd(0xA8F1A1); + //else //if (subfamily == SF_DSPIC33CKxxMC) + send_cmd(0xA8E8D1); // There seems to be something wrong with the official documentation, it says it should be 0xA8F1A1 for xxMP chips, but only 0xA8E8D1 works, as for MC chips. send_nop(); send_nop(); send_nop(); From fa6cfbc72f1b58ac2999cebd517baac95e12c0c9 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Tue, 19 Nov 2024 19:59:58 +0100 Subject: [PATCH 14/15] Fix blank check function --- src/devices/dspic33ck.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/devices/dspic33ck.cpp b/src/devices/dspic33ck.cpp index 7689f7e..c496416 100644 --- a/src/devices/dspic33ck.cpp +++ b/src/devices/dspic33ck.cpp @@ -275,12 +275,11 @@ bool dspic33ck::read_device_id(void) /* Check if the device is blank */ uint8_t dspic33ck::blank_check(void) { - // TODO - uint32_t addr; unsigned short i; uint16_t data[8], raw_data[6]; uint8_t ret = 0; + bool hasFoundNonemptyByte = false; if(!flags.debug) cerr << "[ 0%]"; @@ -296,12 +295,12 @@ uint8_t dspic33ck::blank_check(void) send_nop(); /* Output data to W0:W5; repeat until all desired code memory is read. */ - for(addr=0; addr < mem.code_memory_size; addr=addr+8) { + for (addr = 0; addr < mem.code_memory_size; addr = addr + 8) { - if((addr & 0x0000FFFF) == 0){ - send_cmd(0x200000 | ((addr & 0x00FF0000) >> 12) ); // MOV #, W0 + if ((addr & 0x0000FFFF) == 0) { + send_cmd(0x200000 | ((addr & 0x00FF0000) >> 12)); // MOV #, W0 send_cmd(0x8802A0); // MOV W0, TBLPAG - send_cmd(0x200006 | ((addr & 0x0000FFFF) << 4) ); // MOV #, W6 + send_cmd(0x200006 | ((addr & 0x0000FFFF) << 4)); // MOV #, W6 } /* Fetch the next four memory locations and put them to W0:W5 */ @@ -357,8 +356,8 @@ uint8_t dspic33ck::blank_check(void) send_nop(); /* read six data words (16 bits each) */ - for(i=0; i<6; i++){ - send_cmd(0x887C40 + i); + for (i = 0; i < 6; i++) { + send_cmd(0x887E60 + i); send_nop(); raw_data[i] = read_data(); send_nop(); @@ -392,10 +391,16 @@ uint8_t dspic33ck::blank_check(void) fprintf(stderr, "\n addr = 0x%06X data = 0x%04X", (addr+i), data[i]); if ((i%2 == 0 && data[i] != 0xFFFF) || (i%2 == 1 && data[i] != 0x00FF)) { - if(!flags.debug) cerr << "\b\b\b\b\b"; - ret = 1; - addr = mem.code_memory_size + 10; - break; + if(!flags.debug) + cerr << "\b\b\b\b\b"; + if (hasFoundNonemptyByte) // One single bit is 0 even when the chip is empty, for some reason + { + addr = mem.code_memory_size + 10; + ret = 1; + break; + } + else + hasFoundNonemptyByte = true; } } } From 46889791b389d1c21e199a7f13ad1743604e2054 Mon Sep 17 00:00:00 2001 From: Gitle Mikkelsen Date: Mon, 13 Jan 2025 08:31:19 +0100 Subject: [PATCH 15/15] change default mclr for dspic33ck, for my needs --- src/hosts/rk3308.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hosts/rk3308.h b/src/hosts/rk3308.h index a7aa78d..a8d1153 100644 --- a/src/hosts/rk3308.h +++ b/src/hosts/rk3308.h @@ -38,4 +38,4 @@ /* default GPIO <-> PIC connections */ #define DEFAULT_PIC_CLK 16 // GPIO2_C0 - PGC - Output #define DEFAULT_PIC_DATA 10 // GPIO2_B2 - PGD - I/O -#define DEFAULT_PIC_MCLR 4 // GPIO2_A4 - MCLR - Output +#define DEFAULT_PIC_MCLR 14 // GPIO2_B6 - MCLR - Output