Context
Siguiendo un tutorial, construyo un hardware simple de programador PIC usando la Raspberry Pi (programador de google: rpp). Lo probé con el software provisto para un PIC16F628A
, y el resultado está funcionando.
Actualmente estoy implementando mi propio software, con el objetivo de programar la familia Pic16F170x
. El nuevo software puede leer correctamente el Pic16F628A, pero en el Pic16F1703 solo lee hasta el primer value>=0x2000 (MSB=1)
, después de eso, todos los valores devuelven 0
. Si el programa omite esos valores, lee toda la memoria del programa pic "correctamente", así que supongo que la escritura es correcta.
Pregunta
¿Por qué el programador deja de leer correctamente después de la primera palabra del programa con MSB = 1?
O de una manera más genérica:
¿Cómo leer la memoria del programa PIC16F170X?
Programa
Uso el siguiente programa para leer la imagen (código simplificado):
// Values only used for Pic16F1703
int delay= 2; //us
uint8_t ReadDataFromProgramMemory = 0x04;
uint8_t IncrementAddress = 0x06;
// End values
virtual void readProgram() const
{
// Enter programming mode
gpio->set(pinMclr);
usleep(delay);
// Read
for ( int i=0; i<30; i++)
{
sendCommand(ReadDataFromProgramMemory);
uint16_t data = receive14();
usleep(delay);
std::cout << " " << +data;
sendCommand(IncrementAddress);
}
// Exit programming mode
gpio->clr(pinMclr);
usleep(delay);
}
// Read 14bit program memory word
virtual uint16_t receive14() const
{
uint16_t word = 0x00;
for( int i=0; i<16; ++i)
{
gpio->set(pinClk);
usleep(delay);
gpio->clr(pinClk);
word |= gpio->getLevel(pinDataIn) << i;
usleep(delay);
}
word = (word >> 1 ) & 0x3fff;
usleep(delay);
return word;
}
// Send a command to the pic
virtual void sendCommand( uint8_t cmd ) const
{
for( int i=0; i<6; ++i )
{
gpio->set(pinClk);
if ((cmd>>i) & 0x01) gpio->set(pinData);
else gpio->clr(pinData);
usleep(delay);
gpio->clr(pinClk);
usleep(delay);
}
gpio->clr(pinData);
usleep(delay);
}
// Send 14bit data for writing the pic. suppose mclr already set
virtual void send14( uint16_t word) const
{
word = (word << 1) & 0x7FFE;
for( int i=0; i<16; ++i )
{
gpio->set(pinClk);
if ((word>>i) & 0x01) gpio->set(pinData);
else gpio->clr(pinData);
usleep(delay);
gpio->clr(pinClk);
usleep(delay);
}
}
Referencias
PIC16 (L) F170x Especificación de programación de memoria
Circuito de hardware
Contenido de la imagen
:01000000 2804 D3
:04000400 018C 3037 008E 303F 07
:08000800 008C 118E 200E 158E 200E 2809 30FF 00A1 C5
:06001000 00A0 0BA0 2811 0BA1 2810 0008 7A
:02002000 3FFF 3FFF 62
:00000001FF
Nota: este es el programa que se supone que está en el PIC (puedo leer todos los valores omitidos correctamente > = 0x2000). Probablemente el programa no esté funcionando, no lo presioné por el momento.
Como ejemplo, si omito las direcciones 0,1,2,3 y 5, leo:
04=0x018c, 06=0x008e, 07=0x303f, 08=0x046, 09 and further = 0x0000
Si omito las direcciones 0,1,2,3,5,7, leo:
04=0x018c, 06=0x008e, 08=0x008c, 09=0x118e, 10=0x200e, 11=0x0ac7, 12 and further = 0x0000
Después de una prueba completa, con X cuando se omite el valor:
Data: 2804 3fff 0 0
Data: X 3fff 3fff 0 0
Data: X X 3fff 3fff 0 0
Data: X X X 3fff c6 0 0
Data: X X X X 18c 3037 47 0 0
Data: X X X X 18c X 8e 303f 46 0 0
Data: X X X X 18c X 8e X 8c 118e 200e ac7 0 0
Data: X X X X 18c X 8e X 8c 118e X 158e 200e 3404 0 0
Data: X X X X 18c X 8e X 8c 118e X 158e X 2809 387f 0 0
Data: X X X X 18c X 8e X 8c 118e X 158e X X 30ff 50 0 0
Data: X X X X 18c X 8e X 8c 118e X 158e X X X a1 a0 ba0 2811 5d0 0 0
Data: X X X X 18c X 8e X 8c 118e X 158e X X X a1 a0 ba0 X ba1 2810 4 0 0