void write_data_P16F87( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; if( (lastblock & BLOCKTYPE_FIRST) && (address > 0) ) { set_address_P16( address ); //set the initial address } for( blockcounter = 0; blockcounter < blocksize; blockcounter++ ) { //load data pic_send_14_bits( 6, 0x03, ((unsigned int) data[blockcounter]) );//LSB only //begin programming command pic_send_n_bits( 6, 0x18 );// begin programming only cycle //wait Tprog // 8MS, should be 20 ms for other? DelayMs( Tdprog ); pic_send_n_bits( 6, 0x17 );//end programming //read data from data memory (to verify) not yet impl... //increment address pic_send_n_bits( 6, 0x06 ); } }
void write_code_P16F54( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; if( lastblock & BLOCKTYPE_FIRST ) { pic_send_n_bits( 6, 0x06 );//increment address to go from 1FF / 3FF to 0 set_address_P16( address ); //set the initial address //pic_send_n_bits(6,0x09);//bulk erase, which is necessary anyway... //DelayMs(20); } for( blockcounter = 0; blockcounter < blocksize; blockcounter += 2 ) { pic_send_14_bits( 6, 0x02, (((unsigned int) data[blockcounter])) | //MSB (((unsigned int) data[blockcounter + 1]) << 8) );//LSB DelayMs( 1 ); pic_send_n_bits( 6, 0x08 ); //begin programming DelayMs( 3 ); pic_send_n_bits( 6, 0x0E ); //end programming DelayMs( 1 ); //payload=pic_read_14_bits(6,0x04); //read code memory //if(payload!=((((unsigned int)data[blockcounter]))|(((unsigned int)data[blockcounter+1])<<8))) //{ // set_vdd_vpp(pictype,picfamily,0); // return 4;//verify error. //} pic_send_n_bits( 6, 0x06 ); //increment address } }
void write_code_P16F87( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { unsigned int i; char blockcounter; if( (lastblock & BLOCKTYPE_FIRST) && (address > 0) ) { set_address_P16( address ); //set the initial address } //4 word programming for( blockcounter = 0; blockcounter < blocksize; blockcounter += 8 ) //4 words of data = 8 bytes { for( i = 0; i < 8; i += 2 ) { pic_send_14_bits( 6, 0x02, (((unsigned int) data[blockcounter + i])) | //MSB (((unsigned int) data[blockcounter + i + 1]) << 8) );//LSB if( i < 6 ) pic_send_n_bits( 6, 0x06 ); //increment address } pic_send_n_bits( 6, 0x18 ); //begin programming only, externally timed DelayMs( 2 ); pic_send_n_bits( 6, 0x17 ); //end programming //for(i=0;i<100;i++); //wait Tdis pic_send_n_bits( 6, 0x06 ); //increment address } }
void write_code_P16F84A( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; if( lastblock & BLOCKTYPE_FIRST ) { set_address_P16( address ); //set the initial address } for( blockcounter = 0; blockcounter < blocksize; blockcounter += 2 ) { pic_send_14_bits( 6, 0x02, (((unsigned int) data[blockcounter])) | //MSB (((unsigned int) data[blockcounter + 1]) << 8) );//LSB pic_send_n_bits( 6, 0x08 ); //begin programming DelayMs( Tprog ); DelayMs( 10 ); pic_send_n_bits( 6, 0x06 ); //increment address } /*if(pictype==P12F629&&((lastblock&2)&&((address+blocksize)<0x3FF))) //restore osccal register { for(i=0;i<(0x3FF-(address+blocksize));i++) pic_send_n_bits(6,0x06); //increment address pic_send_14_bits(6,0x02,osccal); pic_send_n_bits(6,0x08); //begin programming, internally timed DelayMs(8); //pic_send_n_bits(6,0x0A); //end programming }*/ }
void write_code_P16C6XX( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; char i; unsigned int payload; if( (lastblock & BLOCKTYPE_FIRST) && (address > 0) ) { set_address_P16( address ); //set the initial address } for( blockcounter = 0; blockcounter < blocksize; blockcounter += 2 ) { for(i=0;i<25;i++) { payload = (((unsigned int) data[blockcounter])) | //MSB (((unsigned int) data[blockcounter + 1]) << 8); pic_send_14_bits( 6, 0x02, payload);//LSB pic_send_n_bits( 6, 0x08 ); //begin programming DelayUs( 100 ); pic_send_n_bits( 6, 0x0E ); //end programming if(pic_read_14_bits( 6, 0x04 )==payload&&i<22)i=22; //correct? do 3 more programming cycles. } pic_send_n_bits( 6, 0x06 ); //increment address } }
void write_code_P12F61X( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; if( (lastblock & BLOCKTYPE_FIRST) && (address > 0) ) { set_address_P16( address ); //set the initial address } for( blockcounter = 0; blockcounter < blocksize; blockcounter += 2 ) { pic_send_14_bits( 6, 0x02, (((unsigned int) data[blockcounter])) | //MSB (((unsigned int) data[blockcounter + 1]) << 8) );//LSB pic_send_n_bits( 6, 0x18 ); //begin programming DelayMs( Tprog ); pic_send_n_bits( 6, 0x0A ); //end programming DelayMs( 10 ); /*payload=pic_read_14_bits(6,0x04); //read code memory if(payload!=((((unsigned int)data[blockcounter]))|(((unsigned int)data[blockcounter+1])<<8))) { set_vdd_vpp(pictype, picfamily,0); //do a hard reset to target processor set_vdd_vpp(pictype, picfamily,1); DelayMs(10); //wait a while set_address(picfamily, address+(blockcounter>>1)); //go back to the address where it was pic_send_14_bits(6,0x02,(((unsigned int)data[blockcounter]))| //MSB (((unsigned int)data[blockcounter+1])<<8));//LSB switch(pictype) { case P12F61X: pic_send_n_bits(6,0x18); //begin programming DelayMs(Tprog); pic_send_n_bits(6,0x0A); //end programming break; default: pic_send_n_bits(6,0x08); //begin programming DelayMs(Tprog); break; } payload=pic_read_14_bits(6,0x04); //read code memory if(payload!=((((unsigned int)data[blockcounter]))|(((unsigned int)data[blockcounter+1])<<8))) { return 4; //verify error } }*/ pic_send_n_bits( 6, 0x06 ); //increment address } /*if(pictype==P12F629&&((lastblock&2)&&((address+blocksize)<0x3FF))) //restore osccal register { for(i=0;i<(0x3FF-(address+blocksize));i++) pic_send_n_bits(6,0x06); //increment address pic_send_14_bits(6,0x02,osccal); pic_send_n_bits(6,0x08); //begin programming, internally timed DelayMs(8); //pic_send_n_bits(6,0x0A); //end programming }*/ }
void set_address_P16( unsigned long address ) { unsigned long int i; for( i = 0; i < address; i++ ) pic_send_n_bits( 6, 0x06 ); //increment address }
void enter_ISCP_PIC24K() { int i; enablePGC_D(); //PGC/D output & PGC/D_LOW appropriate VPP_RUNoff(); //MCLR low VDDon(); DelayMs( 10 ); VPP_RUNon(); //VPP to 4.5V for( i = 0; i < 300; i++ ) continue; //aprox 0.5ms //clock_delay(); //P19 = 40ns min //write 0x4D43, high to low, other than the rest of the commands which are low to high... //0x3D43 => 0100 1101 0100 0011 //from low to high => 1100 0010 1011 0010 //0xC2B2 pic_send_word( 0xC2B2 ); //write 0x4851 => 0100 1000 0101 0001 => 1000 1010 0001 0010 => 0x0A12 pic_send_word( 0x8A12 ); DelayMs( 1 ); DelayMs( 25 ); pic_send_n_bits( 5, 0 ); dspic_send_24_bits( 0 ); //send a nop instruction with 5 additional databits dspic_send_24_bits( 0x000000 ); //NOP dspic_send_24_bits( 0x040200 ); //GOTO 0x200 dspic_send_24_bits( 0x000000 ); //NOP }
void enter_ISCP_PIC24E() { enablePGC_D(); //PGC/D output & PGC/D_LOW appropriate VPP_RUNoff(); //MCLR low VDDon(); clock_delay(); // P6 100ns DelayMs( 10 ); VPP_RUNon(); //VPP to 4.5V DelayMs( 1 ); //P21 500us // PIC24E 500us min VPP_RUNoff(); //and immediately back to 0... VPP_RSTon(); DelayMs( 2 ); //P18 = 1ms min PIC24E 1ms min //write 0x4D43, high to low, other than the rest of the commands which are low to high... //0x4D43 => 0100 1101 0100 0011 //from low to high => 1100 0010 1011 0010 //0xC2B2 pic_send_word( 0xC2B2 ); //write 0x4851 => 0100 1000 0101 0001 => 1000 1010 0001 0010 => 0x8A12 pic_send_word( 0x8A12 ); // P19 25ns DelayMs( 1 ); VPP_RSToff(); //release from reset VPP_RUNon(); DelayMs( 60 ); // P7 50ms + P1*5 //PIC24E 50ms min pic_send_n_bits( 5, 0 ); dspic_send_24_bits( 0x000000 ); //NOP //PIC24E (doc 70633) says 3 nops dspic_send_24_bits( 0x000000 ); //NOP dspic_send_24_bits( 0x000000 ); //NOP dspic_send_24_bits( 0x040200 ); //GOTO 0x200 dspic_send_24_bits( 0x000000 ); //NOP dspic_send_24_bits( 0x000000 ); //NOP dspic_send_24_bits( 0x000000 ); //NOP }
void write_code_P18FX220( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { unsigned int i; char blockcounter; //FIXME: this only needs to be done on FIRST_BLOCK //direct access to code memory pic_send( 4, 0x00, 0x8EA6 ); //BSF EECON1, EEPGD pic_send( 4, 0x00, 0x9CA6 ); //BCF EECON1, CFGS set_address_P18( address ); for( blockcounter = 0; blockcounter < (blocksize); blockcounter += 8 ) //blocks of 8 bytes { for( i = 0; i < 6; i += 2 ) { //write 2 bytes and post increment by 2 // MSB LSB pic_send( 4, 0x0D, ((unsigned int) *(data + blockcounter + i)) | (((unsigned int) *(data + 1 + blockcounter + i)) << 8) ); } //write last 2 bytes of the block and start programming pic_send( 4, 0x0F, ((unsigned int) *(data + blockcounter + 6)) | (((unsigned int) *(data + 7 + blockcounter)) << 8) ); pic_send_n_bits( 3, 0 ); PGChigh(); //hold PGC high for P9 and low for P10 DelayMs( P9 ); PGClow(); DelayMs( P10 ); pic_send_word( 0x0000 ); pic_read_byte2( 4, 0x09 ); //perform 2 reads to increase the address by 2 pic_read_byte2( 4, 0x09 ); } }
void write_code_P18F4XK22( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; //FIXME: this only needs to be done on FIRST_BLOCK pic_send( 4, 0x00, 0x8EA6 ); //BSF EECON1, EEPGD pic_send( 4, 0x00, 0x9CA6 ); //BCF EECON1, CFGS pic_send( 4, 0x00, 0x84A6 ); //BSF EECON1, WREN set_address_P18( address ); for( blockcounter = 0; blockcounter < (blocksize - 2); blockcounter += 2 ) { //write 2 bytes and post increment by 2 // MSB LSB pic_send( 4, 0x0D, ((unsigned int) *(data + blockcounter)) | (((unsigned int) *(data + 1 + blockcounter)) << 8) ); } //write last 2 bytes of the block and start programming pic_send( 4, 0x0F, ((unsigned int) *(data + blockcounter)) | (((unsigned int) *(data + 1 + blockcounter)) << 8) ); pic_send_n_bits( 3, 0 ); PGChigh(); //hold PGC high for P9 and low for P10 DelayMs( P9 ); PGClow(); DelayMs( P10 ); pic_send_word( 0x0000 ); }
void write_code_P18F6XKXX( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; //FIXME: this only needs to be done on FIRST_BLOCK if( (address & 0x20) == 0 ) //package must be 64 bytes, so only do this every two packages. { pic_send( 4, 0x00, 0x8E7F ); //BSF EECON1, EEPGD pic_send( 4, 0x00, 0x9C7F ); //BSF EECON1, CFGS pic_send( 4, 0x00, 0x847F ); //BSF EECON1, WREN set_address_P18( address ); } for( blockcounter = 0; blockcounter < (blocksize - 2); blockcounter += 2 ) { //write 2 bytes and post increment by 2 // MSB LSB pic_send( 4, 0x0D, ((unsigned int) *(data + blockcounter)) | (((unsigned int) *(data + 1 + blockcounter)) << 8) ); } if( (address & 0x20) == 0x20 || (lastblock & BLOCKTYPE_LAST) ) { //write last 2 bytes of the block and start programming pic_send( 4, 0x0F, ((unsigned int) *(data + blockcounter)) | (((unsigned int) *(data + 1 + blockcounter)) << 8) ); pic_send_n_bits( 3, 0 ); PGChigh(); //hold PGC high for P9 and low for P10 DelayMs( P9 ); PGClow(); DelayMs( P10 ); pic_send_word( 0x0000 ); } else pic_send( 4, 0x0D, ((unsigned int) *(data + blockcounter)) | (((unsigned int) *(data + 1 + blockcounter)) << 8) ); }
void write_code_P18F45J10( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; if( !(address & 0x20) ) { pic_send( 4, 0x00, 0x84A6 ); //BSF EECON1, WREN set_address_P18( address ); //blocks of 64 bytes, but divided into two chunks } for( blockcounter = 0; blockcounter < (blocksize - 2); blockcounter += 2 ) { //write 2 bytes and post increment by 2 // MSB LSB pic_send( 4, 0x0D, ((unsigned int) *(data + blockcounter)) | (((unsigned int) *(data + 1 + blockcounter)) << 8) ); } //write last 2 bytes of the block and start programming if( address & 0x20 ) { pic_send( 4, 0x0F, ((unsigned int) *(data + blockcounter)) | (((unsigned int) *(data + 1 + blockcounter)) << 8) ); pic_send_n_bits( 3, 0 ); PGChigh(); //hold PGC high for P9 and low for P10 DelayMs( 10 ); PGClow(); DelayMs( 1 ); pic_send_word( 0x0000 ); } else { pic_send( 4, 0x0D, ((unsigned int) *(data + blockcounter)) | (((unsigned int) *(data + 1 + blockcounter)) << 8) ); if( lastblock & BLOCKTYPE_LAST ) //if the last block is the first half of 64 bytes, it needs to be finished with a dummy block to finish. { for( blockcounter = 0; blockcounter < 30; blockcounter += 2 ) pic_send( 4, 0x0D, 0xFFFF ); pic_send( 4, 0x0F, 0xFFFF ); pic_send_n_bits( 3, 0 ); PGChigh(); //hold PGC high for P9 and low for P10 DelayMs( 10 ); PGClow(); DelayMs( 1 ); pic_send_word( 0x0000 ); } } }
void write_code_P16F18XX( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { char blockcounter; if( lastblock & BLOCKTYPE_FIRST ) { pic_send_n_bits( 6, 0x16 ); //reset address set_address_P16( address ); //set the initial address } for( blockcounter = 0; blockcounter < blocksize; blockcounter += 2 ) { pic_send_14_bits( 6, 0x02, (((unsigned int) data[blockcounter])) | //MSB (((unsigned int) data[blockcounter + 1]) << 8) );//LSB pic_send_n_bits( 6, 0x08 ); //begin programming DelayMs( Tprog ); DelayMs( 10 ); pic_send_n_bits( 6, 0x06 ); //increment address } }
void write_code_P16F87XA( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { unsigned int i; char blockcounter; if( (lastblock & BLOCKTYPE_FIRST) && (address > 0) ) { set_address_P16( address ); //set the initial address } for( blockcounter = 0; blockcounter < blocksize; blockcounter += 16 ) //8 words of data = 16 bytes { for( i = 0; i < 16; i += 2 ) { pic_send_14_bits( 6, 0x02, (((unsigned int) data[blockcounter + i])) | //MSB (((unsigned int) data[blockcounter + i + 1]) << 8) );//LSB if( i < 14 ) pic_send_n_bits( 6, 0x06 ); //increment address } pic_send_n_bits( 6, 0x08 ); //begin erase / programming DelayMs( 16 ); //pic_send_n_bits(5,0x17); //end programming pic_send_n_bits( 6, 0x06 ); //increment address } }
void write_code_P18FXX20( unsigned long address, unsigned char* data, char blocksize, char lastblock ) { unsigned int i; char blockcounter; if( lastblock & BLOCKTYPE_FIRST ) { pic_send( 4, 0x00, 0x8EA6);// BSF EECON1, EEPGD pic_send( 4, 0x00, 0x8CA6);// BSF EECON1, CFGS pic_send( 4, 0x00, 0x86A6);// BSF EECON1, WREN set_address_P18( 0x3C0006 ); pic_send( 4, 0x0C, 0x0040 ); //Write 40h to 3C0006h to enable multi-panel writes. //direct access to code memory pic_send( 4, 0x00, 0x8EA6 ); //BSF EECON1, EEPGD pic_send( 4, 0x00, 0x9CA6 ); //BCF EECON1, CFGS } set_address_P18( address ); for( blockcounter = 0; blockcounter < (blocksize); blockcounter += 8 ) //blocks of 8 bytes { for( i = 0; i < 6; i += 2 ) { //write 2 bytes and post increment by 2 // MSB LSB pic_send( 4, 0x0D, ((unsigned int) *(data + blockcounter + i)) | (((unsigned int) *(data + 1 + blockcounter + i)) << 8) ); } if((lastblock & BLOCKTYPE_LAST)&& (blockcounter==(blocksize-8))) { //write last 2 bytes of the block and start programming pic_send( 4, 0x0F, ((unsigned int) *(data + blockcounter + 6)) | (((unsigned int) *(data + 7 + blockcounter)) << 8) ); } else { //write last 2 bytes of the block and start programming pic_send( 4, 0x0C, ((unsigned int) *(data + blockcounter + 6)) | (((unsigned int) *(data + 7 + blockcounter)) << 8) ); pic_send_n_bits( 3, 0 ); PGChigh(); //hold PGC high for P9 and low for P10 DelayMs( P9 ); PGClow(); DelayMs( P10 ); pic_send_word( 0x0000 ); } pic_read_byte2( 4, 0x09 ); //perform 2 reads to increase the address by 2 pic_read_byte2( 4, 0x09 ); } }