# How to read Pic16F1703 program memory (With custom PIC programmer)

Context

Following a tutorial, I build a simple PIC programmer hardware using the Raspberry Pi (google: rpp programmer). I tested it with the provided software for a PIC16F628A, and the result is working.

I am currently implementing my own software, with the goal to program the Pic16F170x family. The new software is able to read correctly the Pic16F628A, but on the Pic16F1703 it only read up to the first value>=0x2000 (MSB=1), after that, all values return 0. If the program skip those values, it read all the pic program memory "correctly", so I guess the writing is correct.

Question

Why the programmer stop reading correctly after the first program word with MSB=1?

Or in a more generic way:

How to read the PIC16F170X program memory?

Program

I use the following program to read the pic (simplified code):

// Values only used for Pic16F1703
int delay= 2; //us
// End values

{
// Enter programming mode
gpio->set(pinMclr);
usleep(delay);

for ( int i=0; i<30; i++)
{
usleep(delay);
std::cout << " " << +data;
}

// Exit programming mode
gpio->clr(pinMclr);
usleep(delay);
}

// Read 14bit program memory word
{
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);
}
}


References

Initial tutorial

PIC16(L)F170x Memory Programming specification

Hardware circuit

simulate this circuit – Schematic created using CircuitLab

Pic content

: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


Note: This is the program that is supposed to be in the PIC (I may read all correctly skipping values>=0x2000). The program is probably not working, I did not really pushed on that for now.

As an example, if I skip addresses 0,1,2,3 and 5, I read:

04=0x018c, 06=0x008e, 07=0x303f, 08=0x046, 09 and further = 0x0000


04=0x018c, 06=0x008e, 08=0x008c, 09=0x118e, 10=0x200e, 11=0x0ac7, 12 and further = 0x0000


Following a full test, with X when value is skipped:

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

• What did you write to the memory? What is 's'? – TisteAndii Jun 22 '16 at 20:32
• @TisteAndii: In the program memory, it supposed to be written a very minimal .hex, generated with gputils. s is a status/error variable, that I should have remove for this question, but I apparently missed once, sorry (will edit). – Adrian Maire Jun 23 '16 at 10:04
• Looking at the "Real" value and the "Read" value, it seem an additional bit is read in the most significant byte, which shift all the content and probably make the pic to do not understand the next command. – Adrian Maire Jun 23 '16 at 17:17
• It appears you're using INHX16 and not the usual INHX32. How was the data written to the PIC in the first place? Have you tried reading the program memory with a PICkit, if you have one, to know if the PIC program was written correctly to flash? What is the return type of this method: gpio->getLevel(). If it is not uint16_t, you're probably losing data. Also try increasing the delay to 5us to give enough head room for any weird stuff. – TisteAndii Jun 24 '16 at 0:59
• @TisteAndii: Thanks. Gputils is generating INHX16, which seem enough for a mid-range (14bits) pic. The data was written with the same programmer, so I do not have 100% insurance of it correctness, but as I may read it correctly in some circumstances, my supposition is against the reading. I do not have any Pickit available unfortunately. set() and clr() are inputs to the PIC, while getLevel() is the output of the PIC. getLevel() return the 0/1 level of the given pin, in this case, the DTA of the pic. – Adrian Maire Jun 24 '16 at 6:29