EEVblog Electronics Community Forum

Electronics => Projects, Designs, and Technical Stuff => Topic started by: kirill578 on March 05, 2012, 06:30:09 pm

Title: Programming PIC18F2550 via the Arduino
Post by: kirill578 on March 05, 2012, 06:30:09 pm
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"
Code: [Select]
#include <p18f2550.h>

void main(){
  TRISA = 0;
  TRISB = 0;
  TRISC = 0;

  PORTA = 0xFF;
  PORTB = 0xFF;
  PORTC = 0xFF;
 
while(1){}
 
}

HEX file:
Code: [Select]
:04000000F6EF3FF0E8
:107FEC000001F9EF3FF0926A936A946A80688168A5
:047FFC008268FFD7C1
:00000001FF

my way of writing it to the device (check source code at the end)
Code: [Select]
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:

Code: [Select]
// 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;
 
}