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?