Arduino as a Pic Programmer!

Hi, watchinofoye

I was also trying to build an Arduino PIC programmer for the PIC18F2550. So far without much success.

Here is my code:

/* 
 * Trying to build an arduino pic programmer for the PIC18F2550
 * Programming specifications: http://ww1.microchip.com/downloads/en/DeviceDoc/39622L.pdf
 * Author: Ingmar Jager
 */
 
//Pin layout
int pgc = 9;  // program clock
int pgd = 8;  // program data
int pgm = 10;  // program mode
int MCLR = 11; //Master Clear Reset / Vpp

void setup()
{
  Serial.begin(9600);
  
  pinMode(pgc, OUTPUT);
  pinMode(pgd, OUTPUT);
  pinMode(pgm, OUTPUT);
  pinMode(MCLR, OUTPUT);
  delay(500);
  
  enterProgramming();
  delay(500);
  tableRead(0x3F, 0xFF, 0xFF);
  delay(500);
  tableRead(0x3F, 0xFF, 0xFF);
  exitingProgramming();
}

/*
 * @param: three bytes which form the tablepointer address
 */
void setTablePTR(int addr_upper_byte,int addr_half_byte,int addr_lower_byte)
{
  
 Serial.print("Set TablePTR to: 0x");
 Serial.print(addr_upper_byte, HEX);
 Serial.print(addr_half_byte, HEX);
 Serial.println(addr_lower_byte, HEX);
 
 writeBits(4, 0x0); // 4 bit command
 writeBits(16, 0x0E00 + addr_upper_byte); // 16 bit data payload: load address
 writeBits(4, 0x0); 
 writeBits(16, 0x6EF8);  // set TBLPTR_U to addr_upper_byte
 
 writeBits(4, 0x0);
 writeBits(16, 0x0E00 + addr_half_byte);
 writeBits(4, 0x0);
 writeBits(16, 0x6EF7); //TBLPTR_H
 
 writeBits(4, 0x0);
 writeBits(16, 0x0E00 + addr_lower_byte);
 writeBits(4, 0x0);
 writeBits(16, 0x6EF6); //TBLPTR_L
  
}
/*
 * Read byte from the given address
 */
void tableRead(int high_byte, int mid_byte, int low_byte)
{
  
  setTablePTR(high_byte,mid_byte,low_byte);
  
  writeBits(4, 0x8); //1000 = Read and no increment
  writeBits(8, 0x00);
  pinMode(pgd, INPUT);
  delayMicroseconds(5); //P6 
  
  byte data = 0;
  //actual read
  Serial.print("Read bits from LSB to MSB: ");
  for (int i = 0; i < 8; i++)
  {
    digitalWrite(pgc, HIGH);
    delayMicroseconds(3); //P14 
    
    if (digitalRead(pgd)==HIGH)
    {
      Serial.print("1");
      data += (1 << i);
    }
    else
    {
      Serial.print("0");
    }
      
    digitalWrite(pgc, LOW);
        delayMicroseconds(3); 
  }  
  
  delayMicroseconds(5); //P5A
  pinMode(pgd, OUTPUT);
  Serial.println();
  Serial.print("Reading result: ");
  Serial.println(data);
}
  
/* Write LSB to MSB
 * @param n = number of bits to write
 * @param value = value to write in n bits
 */
void writeBits(int n, int value)
{
  digitalWrite(pgc, HIGH);
  for (int i = 0; i < n; i++) {
     if( (boolean) ((value >> i) & 1))
        digitalWrite(pgd,HIGH);
  }   
  delayMicroseconds(3);
  digitalWrite(pgc, LOW);
  delayMicroseconds(3);
  digitalWrite(pgd,LOW);
  delayMicroseconds(5); //P5A
} 

/*
 * Entering low voltage programming signals
 */
void enterProgramming()
{
   digitalWrite(pgc, LOW);
   digitalWrite(pgd, LOW);
   digitalWrite(pgm, LOW);
   digitalWrite(MCLR, LOW);
   
   delayMicroseconds(20);
   
   digitalWrite(pgm, HIGH);
   delayMicroseconds(3);//P15
   digitalWrite(MCLR, HIGH);
   delayMicroseconds(3);//P12
   Serial.println("Entered Low Voltage Programming");
}

/*
 * Exiting low voltage programming signals
 */
void exitingProgramming()
{
   digitalWrite(pgc, LOW);
   digitalWrite(pgd, LOW);
   delayMicroseconds(1); //P16
   digitalWrite(MCLR, LOW);
   delayMicroseconds(1); //P18
   digitalWrite(pgm, LOW);
   Serial.println("Exiting Low Voltage Programming");
}


void loop()
{
 
}

I'm trying to read the deviceID on address 0x3FFFFF. According to the programming specifications the DEVID1 = 010x xxxx and DEVID2 = 0x12.
When I run my program, this is the output:

Entered Low Voltage Programming
Set TablePTR to: 0x3FFFFF
Read bits from LSB to MSB: 00000000
Reading result: 0
Set TablePTR to: 0x3FFFFF
Read bits from LSB to MSB: 00011111
Reading result: 248
Exiting Low Voltage Programming

So the first time I try to read the ID register it returns 0. However the second time the result is 00011111 (248). If I read it a third time it is 0 again. So I'm not quite sure what is happening here.

Have you got some better results?