1
+ // Pin mappings for the PIC programming shield.
2
+ #define PIN_MCLR A1 // 0: MCLR is VPP voltage, 1: Reset PIC
3
+ #define PIN_ACTIVITY 13 // LED that indicates read/write activity
4
+ #define PIN_VDD 2 // Controls the power to the PIC
5
+ #define PIN_VDD2 3 // Controls the power to the PIC
6
+ #define PIN_CLOCK 4 // Clock pin
7
+ #define PIN_DATA 7 // Data pin
8
+
9
+ #define MCLR_RESET HIGH // PIN_MCLR state to reset the PIC
10
+ #define MCLR_VPP LOW // PIN_MCLR state to apply 13v to MCLR/VPP pin
11
+
12
+ // All delays are in microseconds.
13
+ #define DELAY_SETTLE 1000 // Delay for lines to settle for reset
14
+ #define DELAY_TPPDP 1000 // Hold time after raising MCLR
15
+ #define DELAY_THLD0 1000 // Hold time after raising VDD
16
+
17
+ void setup ()
18
+ {
19
+ // Need a serial link to the host.
20
+ Serial.begin (115200 );
21
+
22
+ // Hold the PIC in the powered down/reset state until we are ready for it.
23
+ pinMode (PIN_MCLR, OUTPUT);
24
+ pinMode (PIN_VDD, OUTPUT);
25
+ pinMode (PIN_VDD2, OUTPUT);
26
+ digitalWrite (PIN_MCLR, MCLR_RESET);
27
+
28
+ digitalWrite (PIN_VDD, HIGH);
29
+ digitalWrite (PIN_VDD2, HIGH);
30
+
31
+ // Clock and data are floating until the first PIC command.
32
+ pinMode (PIN_CLOCK, INPUT);
33
+ pinMode (PIN_DATA, INPUT);
34
+
35
+ // Turn off the activity LED initially.
36
+ pinMode (PIN_ACTIVITY, OUTPUT);
37
+ digitalWrite (PIN_ACTIVITY, LOW);
38
+ }
39
+
40
+ void loop (){
41
+ if (Serial.available ()){
42
+ int ch = Serial.read ();
43
+ if (ch == ' d' ) {
44
+ // Serial.println("Attempting dump...");
45
+ exitProgramMode ();
46
+
47
+ while (true ){
48
+ if (readDeviceId ()){
49
+ // Serial.println("Device ID is OK!");
50
+ // Serial.println("Trying to read data...");
51
+
52
+ setAddress (0 );
53
+ char tmp[2 ];
54
+ for (uint32_t i=0 ; i<0xC000 ; i++){
55
+ sprintf (tmp, " %.2x" , readPostIncrement ());
56
+ Serial.print (tmp);
57
+ }
58
+ Serial.println ();
59
+ break ;
60
+
61
+ } else {
62
+ // Serial.println("Device ID did not match!");
63
+ }
64
+
65
+ exitProgramMode ();
66
+ }
67
+ }
68
+ }
69
+ }
70
+
71
+ // Enter high voltage programming mode.
72
+ void enterProgramMode () {
73
+ // Lower MCLR, VDD, DATA, and CLOCK initially. This will put the
74
+ // PIC into the powered-off, reset state just in case.
75
+ digitalWrite (PIN_MCLR, MCLR_RESET);
76
+ digitalWrite (PIN_VDD, HIGH);
77
+ digitalWrite (PIN_VDD2, HIGH);
78
+ digitalWrite (PIN_DATA, LOW);
79
+ digitalWrite (PIN_CLOCK, LOW);
80
+
81
+ // Wait for the lines to settle.
82
+ delayMicroseconds (DELAY_SETTLE);
83
+
84
+ // Switch DATA and CLOCK into outputs.
85
+ pinMode (PIN_DATA, OUTPUT);
86
+ pinMode (PIN_CLOCK, OUTPUT);
87
+
88
+ // Raise MCLR, then VDD.
89
+ digitalWrite (PIN_MCLR, MCLR_VPP);
90
+ delayMicroseconds (DELAY_TPPDP);
91
+ digitalWrite (PIN_VDD, LOW);
92
+ digitalWrite (PIN_VDD2, LOW);
93
+ delayMicroseconds (DELAY_THLD0);
94
+ }
95
+
96
+ // Exit programming mode and reset the device.
97
+ void exitProgramMode (){
98
+
99
+ // Lower MCLR, VDD, DATA, and CLOCK.
100
+ digitalWrite (PIN_MCLR, MCLR_RESET);
101
+ digitalWrite (PIN_VDD, HIGH);
102
+ digitalWrite (PIN_VDD2, HIGH);
103
+ digitalWrite (PIN_DATA, LOW);
104
+ digitalWrite (PIN_CLOCK, LOW);
105
+
106
+ // Float the DATA and CLOCK pins.
107
+ pinMode (PIN_DATA, INPUT);
108
+ pinMode (PIN_CLOCK, INPUT);
109
+ }
110
+
111
+ #define CMD_CORE 0b0000
112
+ #define CMD_SHIFT_OUT_TABLAT 0b0010
113
+ #define CMD_READ 0b1000
114
+ #define CMD_READ_POST_INC 0b1001
115
+ #define CMD_READ_POST_DEC 0b1010
116
+ #define CMD_READ_PRE_INC 0b1011
117
+ // don't define write now!
118
+
119
+ void sendCommand (byte cmd) {
120
+ pinMode (PIN_DATA, OUTPUT);
121
+ for (int i=0 ; i<4 ; i++){
122
+ digitalWrite (PIN_CLOCK, HIGH);
123
+ if (cmd & 1 )
124
+ digitalWrite (PIN_DATA, HIGH);
125
+ else
126
+ digitalWrite (PIN_DATA, LOW);
127
+ delayMicroseconds (1 );
128
+ digitalWrite (PIN_CLOCK, LOW);
129
+ delayMicroseconds (1 );
130
+ cmd >>= 1 ;
131
+ }
132
+ }
133
+
134
+ void sendData (uint16_t data) {
135
+ pinMode (PIN_DATA, OUTPUT);
136
+ for (int i=0 ; i<16 ; i++){
137
+ digitalWrite (PIN_CLOCK, HIGH);
138
+ if (data & 1 )
139
+ digitalWrite (PIN_DATA, HIGH);
140
+ else
141
+ digitalWrite (PIN_DATA, LOW);
142
+ delayMicroseconds (1 );
143
+ digitalWrite (PIN_CLOCK, LOW);
144
+ delayMicroseconds (1 );
145
+ data >>= 1 ;
146
+ }
147
+ }
148
+
149
+ void sendCore (uint16_t data) {
150
+ sendCommand (CMD_CORE);
151
+ sendData (data);
152
+ }
153
+
154
+ void setAddress (uint32_t addr) {
155
+ sendCore (0x0E00 | ((addr >> 16 ) & 0xFF ));
156
+ sendCore (0x6EF8 );
157
+ sendCore (0x0E00 | ((addr >> 8 ) & 0xFF ));
158
+ sendCore (0x6EF7 );
159
+ sendCore (0x0E00 | ((addr >> 0 ) & 0xFF ));
160
+ sendCore (0x6EF6 );
161
+ }
162
+
163
+ uint8_t readByte (){
164
+ // First data byte: send empty
165
+ pinMode (PIN_DATA, OUTPUT);
166
+ for (int i=0 ; i<8 ; i++){
167
+ digitalWrite (PIN_CLOCK, HIGH);
168
+ digitalWrite (PIN_DATA, LOW);
169
+ delayMicroseconds (1 );
170
+ digitalWrite (PIN_CLOCK, LOW);
171
+ delayMicroseconds (1 );
172
+ }
173
+
174
+ delayMicroseconds (1 );
175
+ pinMode (PIN_DATA, INPUT_PULLUP);
176
+
177
+ uint8_t data = 0 ;
178
+ // Second data byte: read!
179
+ for (int i=0 ; i<8 ; i++){
180
+ digitalWrite (PIN_CLOCK, HIGH);
181
+ delayMicroseconds (1 );
182
+ data >>= 1 ;
183
+ data |= ((digitalRead (PIN_DATA) & 1 ) << 7 );
184
+ digitalWrite (PIN_CLOCK, LOW);
185
+ delayMicroseconds (1 );
186
+ }
187
+
188
+ return data;
189
+ }
190
+
191
+ uint8_t readPostIncrement (){
192
+ sendCommand (CMD_READ_POST_INC);
193
+ return readByte ();
194
+ }
195
+
196
+ boolean readDeviceId (){
197
+ exitProgramMode ();
198
+ enterProgramMode ();
199
+
200
+ setAddress (0x3FFFFE );
201
+ uint8_t DEVID1 = readPostIncrement ();
202
+ uint8_t DEVID2 = readPostIncrement ();
203
+
204
+ // Serial.print("DEVID1: 0x"); Serial.println(DEVID1, HEX);
205
+ // Serial.print("DEVID2: 0x"); Serial.println(DEVID2, HEX);
206
+
207
+ return ((DEVID2 == 0x13 ) && ((DEVID1 & 0xF0 ) == 0x40 ));
208
+ }
0 commit comments