Estoy intentando implementar un programador de modo de bajo voltaje para el PIC18F2550 en un Arduino Uno de acuerdo con estos especificaciones de programación.
Las secuencias de bits se escriben en el bit menos significativo PIC al bit más significativo. También he tenido en cuenta los retrasos mínimos especificados en la hoja de datos, no parece haber retrasos máximos, excepto por el tiempo de subida de MCLR / Vpp.
Para validar mi código, quiero leer el ID de dispositivo en las direcciones 0x3ffffe y 0x3fffff. Aquí está mi código:
/*
* Trying to build an arduino pic programmer for the PIC18F2550
* Programming specifications: http://ww1.microchip.com/downloads/en/DeviceDoc/39622L.pdf
* Author: Ingmar Jager
*/
//Arduino Pinout
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);
digitalWrite(pgc, LOW);
digitalWrite(pgd, LOW);
digitalWrite(pgm, LOW);
digitalWrite(MCLR, LOW);
delay(500);
enterProgramming();
delay(500);
tableRead(0x3F, 0xFF, 0xFF); //read DeviceID2 at 0x3FFFFF. Should be 0x12 = 00010010
//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, (0x0E << 8) + 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, (0x0E << 8) + addr_half_byte);
writeBits(4, 0x0);
writeBits(16, 0x6EF7); //TBLPTR_H
writeBits(4, 0x0);
writeBits(16, (0x0E << 8) + 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, 0x9); //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)
{
for (int i = 0; i < n; i++) {
if(boolean ((value >> i) & 1))
{
digitalWrite(pgd,HIGH);
// Serial.println("Write High");
} // else Serial.println("Write Low");
}
digitalWrite(pgc, 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()
{
}
Este código ingresa al modo de programación, luego intenta leer de 0x3fffff tres veces seguidas, finalmente sale del modo de programación. Lástima que estoy obteniendo tres resultados diferentes, aparentemente no estoy leyendo el ID de dispositivo ... El resultado impreso es:
Entered Low Voltage Programming
Set TablePTR to: 0x3FFFFE
Read bits from LSB to MSB: 00000111
Reading result: 224
Set TablePTR to: 0x3FFFFF
Read bits from LSB to MSB: 00011111
Reading result: 248
Set TablePTR to: 0x3FFFFF
Read bits from LSB to MSB: 00000000
Reading result: 0
Exiting Low Voltage Programming
Cuando conecto otro PIC18F2550 los resultados difieren. Ahora no sé cómo seguir depurando este proyecto. ¿Alguien tiene experiencia con este asunto y / o algunas sugerencias?
p.s. Sé que es más fácil usar un programador, pero esto es más divertido;)