Hey, so its my first time playing with a PIC, its 18F2550 and unfortunately I don't have any thing that could program it (and I have no parallel port). so I decided to write a "sketch" that will program the device using the Arduino. I've menaged to get it working, so it can erase, read, and write.
I compiled quite simple program using "HI-TECH C -MPLAB IDE 8.84"
#include <p18f2550.h>
void main(){
TRISA = 0;
TRISB = 0;
TRISC = 0;
PORTA = 0xFF;
PORTB = 0xFF;
PORTC = 0xFF;
while(1){}
}
HEX file:
:04000000F6EF3FF0E8
:107FEC000001F9EF3FF0926A936A946A80688168A5
:047FFC008268FFD7C1
:00000001FF
my way of writing it to the device (check source code at the end)
W0000F6EF3FF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFX
W7FE0FFFFFFFFFFFFFFFFFFFFFFFF0001F9EF3FF0926A936A946A806881688268FFD7X
my fuse settings are:
0005
1F1F
0083
8500
0FC0
0FE0
0F40
I don't thing it has something to do with the programming. Do you have any suggestion, by the way here is the source code of the arduino sketch:
// I wrote it according to the following datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/39622L.pdf
//pin out config
#define PGC 6
#define PGD 5
#define EN 7 //PGM & MCLR
#define P15 1
#define P12 1
String inputString = "";
boolean stringComplete = false;
unsigned long temp;
byte buffer[32];
byte address[3];
void setup(){
Serial.begin(9600);
pinMode(EN,OUTPUT);
pinMode(PGC,OUTPUT);
pinMode(PGD,OUTPUT);
inputString.reserve(200);
//insruction
Serial.println("This will program your PIC18F2550");
Serial.println("Read 32 bytes command: R< 6digit address >X works for 0x0 - 0x3FFFFF");
Serial.println("Write 32 bytes command: W< 4digit address >< 32 bytes of data>X works for 0x0 - 0x007FFF");
Serial.println("Erase all chip: EX");
Serial.println("Config bits programming is yet to be implemented");
Serial.println("");
Serial.println("I myself couldn't get an led flashing, hope you did");
Serial.println("I'd appreciate any help on the forum:");
Serial.println("http://goo.gl/kMjd6");
}
void loop(){ } //nothing here
//////THE MAIN CODE///////////
//////////////////////////////
//////////////////////////////
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == 'X') { //buffering till X
stringComplete = true;
break;
}
inputString += inChar;
}
if (stringComplete && inputString.charAt(0) == 'W'){ //WRITE
if(inputString.length() != 69) {
Serial.println("Input is wrong, should be: W<address - 4 digit><32bytes>X");
nullString();
goto endofthisif;
}
address[2] = 0;
address[1] = char2byte(inputString.charAt(2),inputString.charAt(1));
address[0] = char2byte(inputString.charAt(4),inputString.charAt(3));
nullBuffer(); // set everything FF
for(int i=0;i<32;i++){
buffer[i] = char2byte(inputString.charAt(2*i+6),inputString.charAt(2*i+5));
}
nullString();
Serial.print("Programming 32bytes,starting at:");
Serial.print("0x00");
if(address[1]<0x10) Serial.print("0"); Serial.print(address[1],HEX);
if(address[0]<0x10) Serial.print("0"); Serial.println(address[0],HEX);
for(int i=0;i<32;i++) { Serial.print(buffer[i],HEX); Serial.print(" "); }
Serial.println("");
///Write
digitalWrite(EN,HIGH);
delay(1);
programBuffer(address[2],address[1],address[0]);
digitalWrite(EN,LOW);
Serial.println("Programming complety");
}
endofthisif:;
if (stringComplete && inputString.charAt(0) == 'E'){ //Erase all
digitalWrite(EN,HIGH);
delay(1);
////erase
erase_all();
digitalWrite(EN,LOW);
Serial.println("Erase complety");
nullString();
}
if (stringComplete && inputString.charAt(0) == 'R'){ //READ
address[2] = char2byte(inputString.charAt(2),inputString.charAt(1));
address[1] = char2byte(inputString.charAt(4),inputString.charAt(3));
address[0] = char2byte(inputString.charAt(6),inputString.charAt(5));
//read
temp=0;
temp = ((long)address[2])<<(16); //doesn't work with out (long)
temp |= ((long)address[1])<<(8);
temp |= (long)address[0];
Serial.print(temp,HEX); Serial.print(":");
digitalWrite(EN,HIGH);
delay(1);
for(int i=0;i<32;i++){
address[2] = byte( (temp&0xFF0000)>>16 );
address[1] = byte( (temp&0xFF00)>>8 );
address[0] = byte( temp&0xFF );
Serial.print(readFlash(address[2],address[1],address[0]),HEX);
Serial.print(" ");
temp++;
}
Serial.println("");
digitalWrite(EN,LOW);
nullString();
}
//clear string incase the first CHAR isn't E,R,W
if(inputString.charAt(0) != 'E' && inputString.charAt(0) != 'R' && inputString.charAt(0) != 'W') nullString();
}
byte readFlash(byte usb,byte msb,byte lsb){
byte value=0;
send4bitcommand(B0000);
send16bit( 0x0e00 | usb ); //
send4bitcommand(B0000);
send16bit(0x6ef8);
send4bitcommand(B0000);
send16bit( 0x0e00 | msb ); //
send4bitcommand(B0000);
send16bit(0x6ef7);
send4bitcommand(B0000);
send16bit( 0x0e00 | lsb ); //
send4bitcommand(B0000);
send16bit(0x6ef6);
send4bitcommand(B1000); //
pinMode(PGD,INPUT); digitalWrite(PGD,LOW);
for(byte i=0;i<8;i++){ //read
digitalWrite(PGC,HIGH);
digitalWrite(PGC,LOW);
}
for(byte i=0;i<8;i++){ //shift out
digitalWrite(PGC,HIGH);
digitalWrite(PGC,LOW);
if(digitalRead(PGD) == HIGH) value += 1<<i; //sample PGD
}
return value;
}
void send4bitcommand(byte data){
pinMode(PGD,OUTPUT);
for(byte i=0;i<4;i++){
if( (1<<i) & data ) digitalWrite(PGD,HIGH); else digitalWrite(PGD,LOW);
digitalWrite(PGC,HIGH);
digitalWrite(PGC,LOW);
}
}
void send16bit(unsigned int data){
pinMode(PGD,OUTPUT);
for(byte i=0;i<16;i++){
if( (1<<i) & data ) digitalWrite(PGD,HIGH); else digitalWrite(PGD,LOW);
digitalWrite(PGC,HIGH);
digitalWrite(PGC,LOW);
}
}
void erase_all(){ //for some reason the chip stops respone, just reconnect voltage
send4bitcommand(B0000);
send16bit(0x0e3c); //
send4bitcommand(B0000);
send16bit(0x6ef8);
send4bitcommand(B0000);
send16bit(0x0e00); //
send4bitcommand(B0000);
send16bit(0x6ef7);
send4bitcommand(B0000);
send16bit(0x0e05); //
send4bitcommand(B0000);
send16bit(0x6ef6);
send4bitcommand(B1100);
send16bit(0x3F3F);
send4bitcommand(B0000);
send16bit(0x0e3c); //
send4bitcommand(B0000);
send16bit(0x6ef8);
send4bitcommand(B0000);
send16bit(0x0e00); //
send4bitcommand(B0000);
send16bit(0x6ef7);
send4bitcommand(B0000);
send16bit(0x0e04); //
send4bitcommand(B0000);
send16bit(0x6ef6);
send4bitcommand(B1100);
send16bit(0x8F8F);
send4bitcommand(B0000); //
send16bit(0x0000); //
delay(2);
send4bitcommand(B0000); //
send16bit(0x0000); //
Serial.println("Disconnect and reconnect the chip, or it won't respone! (Yet to be fixed)");
}
void programBuffer(byte usb,byte msb,byte lsb){
if( (lsb&0x0F) | ((lsb&0xF0)>>4)%2){
Serial.println("Error: First digit (refere as HEX) have to be 0, and the second digit have to be even.");
Serial.println("valid examples: 0x000000 , 0x000060, 0x006320, 0x0063E0");
Serial.println("INvalid examples: 0x000004 , 0x000014, 0x006328, 0x0063EA");
Serial.println("0,2,4,6,8,A,C,E are even");
return;
}
//step 1
send4bitcommand(B0000);
send16bit(0x8ea6);
send4bitcommand(B0000);
send16bit(0x9ca6);
//step 2
send4bitcommand(B0000);
send16bit( 0x0e00 | usb ); //
send4bitcommand(B0000);
send16bit(0x6ef8);
send4bitcommand(B0000);
send16bit( 0x0e00 | msb ); //
send4bitcommand(B0000);
send16bit(0x6ef7);
send4bitcommand(B0000);
send16bit( 0x0e00 | lsb ); //
send4bitcommand(B0000);
send16bit(0x6ef6);
//step 3
for(byte i=0;i<15;i++){
send4bitcommand(B1101);
send16bit( buffer[(2*i)+1]<<8 | buffer[(i*2)] );
}
//step 4
send4bitcommand(B1111);
send16bit( buffer[31]<<8 | buffer[30] );
//nop
digitalWrite(PGC,HIGH);
digitalWrite(PGC,LOW);
digitalWrite(PGC,HIGH);
digitalWrite(PGC,LOW);
digitalWrite(PGC,HIGH);
digitalWrite(PGC,LOW);
digitalWrite(PGC,HIGH);
delay(1);
digitalWrite(PGC,LOW);
delayMicroseconds(100);
send16bit(0x0000);
//done
}
/////////////////////////////
//nothing special underhere:
void nullString(){
inputString = "";
stringComplete = false;
}
void nullBuffer(){
for(byte i=0;i<32;i++) buffer[i] = 0xFF;
}
byte char2byte(char lsb,char msb){
byte result=0;
switch(lsb){
case '0': result = 0; break;
case '1': result = 1; break;
case '2': result = 2; break;
case '3': result = 3; break;
case '4': result = 4; break;
case '5': result = 5; break;
case '6': result = 6; break;
case '7': result = 7; break;
case '8': result = 8; break;
case '9': result = 9; break;
case 'A': result = 0xA; break;
case 'B': result = 0xB; break;
case 'C': result = 0xC; break;
case 'D': result = 0xD; break;
case 'E': result = 0xE; break;
case 'F': result = 0xF; break;
}
switch(msb){
case '0': result |= 0<<4; break;
case '1': result |= 1<<4; break;
case '2': result |= 2<<4; break;
case '3': result |= 3<<4; break;
case '4': result |= 4<<4; break;
case '5': result |= 5<<4; break;
case '6': result |= 6<<4; break;
case '7': result |= 7<<4; break;
case '8': result |= 8<<4; break;
case '9': result |= 9<<4; break;
case 'A': result |= 0xA<<4; break;
case 'B': result |= 0xB<<4; break;
case 'C': result |= 0xC<<4; break;
case 'D': result |= 0xD<<4; break;
case 'E': result |= 0xE<<4; break;
case 'F': result |= 0xF<<4; break;
}
return result;
}