├── Arduino code ├── ARD_code.ino └── BufferConfig.h ├── PIC18F_EEPROM.pdf ├── README.md └── console app code └── PC_CODE.cpp /Arduino code/ARD_code.ino: -------------------------------------------------------------------------------- 1 | ///**********************************************************************************************/// 2 | /// >> PIC18F2XXX/4XXX PROGRAMMER << /// 3 | /// created by : Assaous Oussama /// 4 | /// programme description : this program is for programing the PIC18F2XXX/4XXX microcontroller /// 5 | /// date : 25/09/2020 19:36 /// 6 | ///**********************************************************************************************/// 7 | 8 | #include "BufferConfig.h" 9 | 10 | #define ERASE 0 11 | #define PROGM 1 12 | #define CONFIG 2 13 | #define IDV 3 14 | #define EEPROG 4 15 | 16 | #define VPP 2 17 | #define PGM 5 18 | #define PGC 4 19 | #define PGD 3 20 | 21 | 22 | char instBuffer,bitselect,comp; 23 | int bitnumbr; 24 | char buffin[100]; 25 | int i,j,k,p,z,addr,addrh,data; 26 | int num; 27 | int val,val1,val2; 28 | 29 | bool WR =true; 30 | 31 | void startLowProg(); 32 | void endprog(); 33 | void EraseDevice(); 34 | void program(); 35 | void eepromWrite(); 36 | void idWrite(); 37 | void configWrite(); 38 | void senddata(int,int,int); 39 | 40 | void setup() { 41 | 42 | Serial.end(); 43 | 44 | pinMode(VPP,OUTPUT); 45 | pinMode(PGM,OUTPUT); 46 | pinMode(PGC,OUTPUT); 47 | pinMode(PGD,OUTPUT); 48 | 49 | digitalWrite(VPP,LOW); 50 | digitalWrite(PGM,LOW); 51 | digitalWrite(PGC,LOW); 52 | digitalWrite(PGD,LOW); 53 | 54 | Serial.begin(57600); 55 | 56 | } 57 | 58 | void loop() { 59 | 60 | i=0; 61 | 62 | 63 | if(Serial.available() == 38 ) 64 | { 65 | 66 | num = Serial.available(); 67 | while (i < num ) 68 | { 69 | buffin[i] = Serial.read(); 70 | i++; 71 | } 72 | 73 | 74 | if(buffin[0] == 'P' && buffin[1] == 'I' && buffin[2] == 'C' && buffin[3] == 'P' && buffin[4] == 'R' && buffin[5] == 'O' && buffin[6] == 'G' && buffin[7] == '!') 75 | { 76 | startLowProg(); 77 | Serial.write("YESIAM"); 78 | } 79 | if(buffin[0] == 'E' && buffin[1] == 'R' && buffin[2] == 'E' && buffin[3] == 'S' ) 80 | { 81 | EraseDevice(); 82 | Serial.write("DONE"); 83 | } 84 | if(buffin[0] == 'P' && buffin[1] == 'R' && buffin[2] == 'O' ) 85 | { 86 | program(); 87 | Serial.write("*OK*"); 88 | } 89 | if(buffin[0] == 'U' && buffin[1] == 'S' && buffin[2] == 'I' && buffin[3] == 'D' ) 90 | { 91 | idWrite(); 92 | Serial.write("*OK*"); 93 | } 94 | if(buffin[0] == 'E' && buffin[1] == 'E' && buffin[2] == 'P' && buffin[3] == 'R' ) 95 | { 96 | eepromWrite(); 97 | Serial.write("*OK*"); 98 | } 99 | if(buffin[0] == 'C' && buffin[1] == 'O' && buffin[2] == 'N' && buffin[3] == 'F' && buffin[4] == 'I' && buffin[5] == 'G') 100 | { 101 | configWrite(); 102 | Serial.write("*OK*"); 103 | } 104 | if(buffin[0] == 'O' && buffin[1] == 'F' ) 105 | { 106 | endprog(); 107 | Serial.write("*OK*"); 108 | } 109 | 110 | 111 | buffin[0] = 0x00; 112 | buffin[1] = 0x00; 113 | buffin[2] = 0x00; 114 | buffin[3] = 0x00; 115 | buffin[4] = 0x00; 116 | buffin[5] = 0x00; 117 | buffin[6] = 0x00; 118 | 119 | } 120 | 121 | } 122 | 123 | ///***************************************************/// 124 | /// FUNCTION : startLowProg /// 125 | /// OUTPUT : start programming /// 126 | ///***************************************************/// 127 | 128 | void startLowProg() 129 | { 130 | digitalWrite(PGM,HIGH); 131 | delay(10); 132 | digitalWrite(VPP,HIGH); 133 | delay(2); 134 | } 135 | ///***************************************************/// 136 | 137 | ///***************************************************/// 138 | /// FUNCTION : endprog() /// 139 | /// OUTPUT : end programming /// 140 | ///***************************************************/// 141 | void endprog() 142 | { 143 | digitalWrite(PGD,LOW); 144 | digitalWrite(PGC,LOW); 145 | delay(4); 146 | digitalWrite(VPP,LOW); 147 | delay(4); 148 | digitalWrite(PGM,LOW); 149 | delay(1000); 150 | digitalWrite(VPP,HIGH); 151 | } 152 | //****************************************************/// 153 | 154 | ///***************************************************/// 155 | /// FUNCTION : EraseDevice() /// 156 | /// OUTPUT : erase the whole device memory /// 157 | ///***************************************************/// 158 | void EraseDevice() 159 | { 160 | senddata(0,16,ERASE); 161 | digitalWrite(PGD,LOW); 162 | delay(5); 163 | } 164 | ///***************************************************/// 165 | 166 | ///***************************************************/// 167 | /// FUNCTION : program() /// 168 | /// OUTPUT : program the program memory /// 169 | ///***************************************************/// 170 | void program() 171 | { 172 | ProgramBuffer[3][1] = buffin[3]; 173 | ProgramBuffer[5][1] = buffin[4]; 174 | ProgramBuffer[7][1] = buffin[5]; 175 | 176 | j=6; 177 | for(i = 9 ; i<=24 ; i++) 178 | { 179 | ProgramBuffer[i][0] = buffin[j+1]; 180 | ProgramBuffer[i][1] = buffin[j]; 181 | j+=2; 182 | } 183 | senddata(0,26,PROGM); 184 | } 185 | ///**************************************************/// 186 | 187 | ///**************************************************/// 188 | /// FUNCTION : idWrite() /// 189 | /// OUTPUT : write the id data to PIC18F /// 190 | ///**************************************************/// 191 | void idWrite() 192 | { 193 | j=8; 194 | for(p = 4 ; p<=11 ; p+=2) 195 | { 196 | idBuffer[j][0] = buffin[p] ; 197 | idBuffer[j][1] = buffin[p+1] ; 198 | j++; 199 | } 200 | senddata(0,13,IDV); 201 | } 202 | ///**************************************************/// 203 | 204 | ///**************************************************/// 205 | /// FUNCTION : void eepromWrite() /// 206 | /// OUTPUT : program the EEPROM memory /// 207 | ///**************************************************/// 208 | void eepromWrite() 209 | { 210 | senddata(0,2,EEPROG); 211 | eeprombuffer[2][1] = buffin[5]; 212 | eeprombuffer[4][1] = buffin[4]; 213 | addr = buffin[5]; 214 | addrh = buffin[4]; 215 | for(p = 6 ; p<=38 ; p++) 216 | { 217 | eeprombuffer[6][1] = buffin[p]; 218 | senddata(2,10,EEPROG); 219 | 220 | while(WR) 221 | { 222 | senddata(10,14,EEPROG); 223 | } 224 | 225 | WR =true; 226 | delayMicroseconds(200); 227 | if(addr == 0xff) 228 | { 229 | addrh++; 230 | addr = 0; 231 | } 232 | else addr++; 233 | eeprombuffer[2][1] = addr; 234 | eeprombuffer[4][1] = addrh; 235 | senddata(14,15,EEPROG); 236 | } 237 | } 238 | ///**************************************************/// 239 | 240 | ///**************************************************/// 241 | /// FUNCTION : configWrite() /// 242 | /// OUTPUT : program the configuration bits /// 243 | ///**************************************************/// 244 | void configWrite() 245 | { 246 | senddata(0,6,CONFIG); 247 | j=0; 248 | for(p = 6 ; p <=18 ; p+=2) 249 | { 250 | configbuffer[6][1] = j; 251 | configbuffer[10][1] = j+1; 252 | configbuffer[8][1] = buffin[p]; 253 | configbuffer[12][0] = buffin[p+1]; 254 | senddata(6,14,CONFIG); 255 | j+=2; 256 | } 257 | } 258 | ///**************************************************/// 259 | 260 | 261 | ///**************************************************/// 262 | /// FUNCTION : senddata() /// 263 | /// OUTPUT : send data to the PIC18F /// 264 | ///**************************************************/// 265 | void senddata(int startbyte,int stopbyte,int bufselect) 266 | { 267 | 268 | for(j = startbyte ; j =0;k--) 271 | { 272 | bitselect = 0x1; 273 | 274 | switch(bufselect) 275 | { 276 | case ERASE : 277 | { 278 | instBuffer = EraseBufer[j][k]; 279 | } 280 | break; 281 | case PROGM: 282 | { 283 | instBuffer = ProgramBuffer[j][k]; 284 | } 285 | break; 286 | case CONFIG: 287 | { 288 | instBuffer = configbuffer[j][k]; 289 | } 290 | break; 291 | case IDV : 292 | { 293 | instBuffer = idBuffer[j][k]; 294 | } 295 | break; 296 | case EEPROG : 297 | { 298 | instBuffer = eeprombuffer[j][k]; 299 | } 300 | break; 301 | } 302 | 303 | if(k == 2) 304 | { 305 | bitnumbr = 4; 306 | } 307 | else 308 | { 309 | bitnumbr = 8; 310 | } 311 | 312 | for(i=0;i> PIC18F2XXX/4XXX PROGRAMMER << /// 3 | /// created by : ASSAOUS OUSSAMA /// 4 | /// buffer configuration /// 5 | ///**************************************************/// 6 | //------------------------------------------------------> erase device memory <---------------------------------------------------------------- 7 | // 4-Bit command | Data Payload | Core Instruction 8 | char EraseBufer[16][3] = {{0x0E , 0x3C , 0x00 } , // 0000 | 0E 3C | MOVLW 3Ch 9 | {0x6E , 0xF8 , 0x00 } , // 0000 | 6E F8 | MOVWF TBLPTRU 10 | {0x0E , 0x00 , 0x00 } , // 0000 | 0E 00 | MOVLW 00h 11 | {0x6E , 0xF7 , 0x00 } , // 0000 | 6E F7 | MOVWF TBLPTRH 12 | {0x0E , 0x05 , 0x00 } , // 0000 | 0E 05 | MOVLW 05h 13 | {0x6E , 0xF6 , 0x00 } , // 0000 | 6E F6 | MOVWF TBLPTRL 14 | {0x3F , 0x3F , 0x0C } , // 1100 | 3F 3F | Write 3F3Fh to 3C0005h 15 | {0x0E , 0x3C , 0x00 } , // 0000 | 0E 3C | MOVLW 3Ch 16 | {0x6E , 0xF8 , 0x00 } , // 0000 | 6E F8 | MOVWF TBLPTRU 17 | {0x0E , 0x00 , 0x00 } , // 0000 | 0E 00 | MOVLW 00h 18 | {0x6E , 0xF7 , 0x00 } , // 0000 | 6E E7 | MOVWF TBLPTRH 19 | {0x0E , 0x04 , 0x00 } , // 0000 | 0E 04 | MOVLW 04h 20 | {0x6E , 0xF6 , 0x00 } , // 0000 | 6E F6 | MOVWF TBLPTRL 21 | {0x8F , 0x8F , 0x0C } , // 1100 | 8F 8F | Write 8F8Fh TO 3C0004h to erase entire device. 22 | {0x00 , 0x00 , 0x00 } , // 0000 | 00 00 | NOP 23 | {0x00 , 0x00 , 0x00 } } ;// 0000 | 00 00 | Hold PGD low until erase completes 24 | //--------------------------------------------------------------------------------------------------------------------------------------------- 25 | 26 | //---------------------------------------------------------> program memory <------------------------------------------------------------------ 27 | // 4-Bit command | Data Payload | Core Instruction 28 | char ProgramBuffer[26][3] = {{0x8E , 0xA6 , 0x00 } , // 0000 | 8E A6 | BSF EECON1, EEPGD 29 | {0x9C , 0xA6 , 0x00 } , // 0000 | 9C A6 | BCF EECON1, CFGS 30 | {0x84 , 0xA6 , 0x00 } , // 0000 | 84 A6 | BSF EECON1, WREN 31 | {0x0E , 0x00 , 0x00 } , // 0000 | 0E | MOVLW 32 | {0x6E , 0xF8 , 0x00 } , // 0000 | 6E F8 | MOVWF TBLPTRU 33 | {0x0E , 0x00 , 0x00 } , // 0000 | 0E | MOVLW 34 | {0x6E , 0xF7 , 0x00 } , // 0000 | 6E F7 | MOVWF TBLPTRH 35 | {0x0E , 0x00 , 0x00 } , // 0000 | 0E | MOVLW 36 | {0x6E , 0xF6 , 0x00 } , // 0000 | 6E F6 | MOVWF TBLPTRL 37 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 38 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 39 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 40 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 41 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 42 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 43 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 44 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 45 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 46 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 47 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 48 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 49 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 50 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 51 | {0x00 , 0x00 , 0x0D } , // 1101 | | Write 2 bytes and post-increment address by 2. 52 | {0x00 , 0x00 , 0x0F } , // 1111 | | Write 2 bytes and start programming. 53 | {0x00 , 0x00 , 0x00 } } ; // 0000 | 00 00 | NOP - hold PGC high for time P9 and low for time P10. 54 | //--------------------------------------------------------------------------------------------------------------------------------------------------- 55 | 56 | //-------------------------------------------------------> write EEPROM memory <---------------------------------------------------------------------- 57 | // 4-Bit command | Data Payload | Core Instruction 58 | char eeprombuffer[15][3] = {{0x9E , 0xA6 , 0x00} ,// 0000 | 9E A6 | BCF EECON1, EEPGD 59 | {0x9C , 0xA6 , 0x00} ,// 0000 | 9C A6 | BCF EECON1, CFGS 60 | {0x0E , 0x00 , 0x00} ,// 0000 | 0E | MOVLW 61 | {0x6E , 0xA9 , 0x00} ,// 0000 | 6E A9 | MOVWF EEADR 62 | {0x0E , 0x00 , 0x00} ,// 0000 | OE | MOVLW 63 | {0x6E , 0xAA , 0x00} ,// 0000 | 6E AA | MOVWF EEADRH 64 | {0x0E , 0x00 , 0x00} ,// 0000 | 0E | MOVLW 65 | {0x6E , 0xA8 , 0x00} ,// 0000 | 6E A8 | MOVWF EEDATA 66 | {0x84 , 0xA6 , 0x00} ,// 0000 | 84 A6 | BSF EECON1, WREN 67 | {0x82 , 0xA6 , 0x00} ,// 0000 | 82 A6 | BSF EECON1, WR 68 | {0x50 , 0xA6 , 0x00} ,// 0000 | 50 A6 | MOVF EECON1, W, 0 69 | {0x6E , 0xF5 , 0x00} ,// 0000 | 6E F5 | MOVWF TABLAT 70 | {0x00 , 0x00 , 0x00} ,// 0000 | 00 00 | NOP 71 | {0x00 , 0x00 , 0x02} ,// 0010 | | Shift out data 72 | {0x94 , 0xA6 , 0x00} };// 0000 | 94 A6 | BCF EECON1, WREN 73 | 74 | //--------------------------------------------------------------------------------------------------------------------------------------------------- 75 | 76 | //---------------------------------------------------> ID Location Programming <--------------------------------------------------------------------- 77 | // 4-Bit command | Data Payload | Core Instruction 78 | char idBuffer[13][3] = {{0x8E , 0xA6 , 0x00} ,// 0000 | 8E A6 | BSF EECON1, EEPGD 79 | {0x9C , 0xA6 , 0x00} ,// 0000 | 9C A6 | BCF EECON1, CFGS 80 | {0x0E , 0x20 , 0x00} ,// 0000 | 0E 20 | MOVLW 20h 81 | {0x6E , 0xF8 , 0x00} ,// 0000 | 6E F8 | MOVWF TBLPTRU 82 | {0x0E , 0x00 , 0x00} ,// 0000 | 0E 00 | MOVLW 00h 83 | {0x6E , 0xF7 , 0x00} ,// 0000 | 6E F7 | MOVWF TBLPTRH 84 | {0x0E , 0x00 , 0x00} ,// 0000 | 0E 00 | MOVLW 00h 85 | {0x6E , 0xF6 , 0x00} ,// 0000 | 6E F6 | MOVWF TBLPTRL 86 | {0x00 , 0x00 , 0x0D} ,// 1101 | | Write 2 bytes and post-increment address by 2. 87 | {0x00 , 0x00 , 0x0D} ,// 1101 | | Write 2 bytes and post-increment address by 2. 88 | {0x00 , 0x00 , 0x0D} ,// 1101 | | Write 2 bytes and post-increment address by 2. 89 | {0x00 , 0x00 , 0x0F} ,// 1111 | | Write 2 bytes and start programming. 90 | {0x00 , 0x00 , 0x00} };// 0000 | 00 00 | NOP - hold PGC high for time P9 and low for time P10. 91 | 92 | //--------------------------------------------------------------------------------------------------------------------------------------------------- 93 | 94 | //-----------------------------------------------------> program configuration <--------------------------------------------------------------------- 95 | // 4-Bit command | Data Payload | Core Instruction 96 | char configbuffer[14][3] = {{0x8E , 0xA6 , 0x00} ,// 0000 | 8E A6 | BSF EECON1, EEPGD 97 | {0x8C , 0xA6 , 0x00} ,// 0000 | 8C A6 | BSF EECON1, CFGS 98 | {0x0E , 0x30 , 0x00} ,// 0000 | 0E 30 | MOVLW 30h 99 | {0x6E , 0xF8 , 0x00} ,// 0000 | 6E F8 | MOVWF TBLPTRU 100 | {0x0E , 0x00 , 0x00} ,// 0000 | 0E 00 | MOVLW 00h 101 | {0x6E , 0xF7 , 0x00} ,// 0000 | 6E F7 | MOVWF TBLPRTH 102 | {0x0E , 0x00 , 0x00} ,// 0000 | 0E 00 | MOVLW 00h 103 | {0x6E , 0xF6 , 0x00} ,// 0000 | 6E F6 | MOVWF TBLPTRL 104 | {0x00 , 0x00 , 0x0F} ,// 1111 | | Load 2 bytes and start programming. 105 | {0x00 , 0x00 , 0x00} ,// 0000 | 00 00 | NOP - hold PGC high for time P9 and low for time P10. 106 | {0x0E , 0x01 , 0x00} ,// 0000 | 0E 01 | MOVLW 01h 107 | {0x6E , 0xF6 , 0x00} ,// 0000 | 6E F6 | MOVWF TBLPTRL 108 | {0x00 , 0x00 , 0x0F} ,// 1111 | | Load 2 bytes and start programming. 109 | {0x00 , 0x00 , 0x00} };// 0000 | 00 00 | NOP - hold PGC high for time P9 and low for time P10. 110 | 111 | //--------------------------------------------------------------------------------------------------------------------------------------------------- 112 | -------------------------------------------------------------------------------- /PIC18F_EEPROM.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AssaousOussama/PIC18F2XXX-4XXX-PROGRAMMER-based-on-arduino-/ecb163f45ceb125dd81ed3a6fa47a74b2e73ff3c/PIC18F_EEPROM.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PIC18F2XXX-4XXX-PROGRAMMER-based-on-arduino- 2 | this is a PIC18F2XXX/4XXX programmer using arduino UNO and a simple Windows console app , 3 | it is simple to use , just copy the HEX file path generated by MPLAB or other programes then pass it 4 | to the app and connect your arduino UNO to your computer then press OK , the programmer start programming immediately 5 | with a nice progress bar showing up , after the programmer finish programming a message box will pop up telling you the programming proccess was done 6 | 7 | # list of supported PIC18F devices 8 | 9 | • PIC18F2221 • PIC18F2580 • PIC18F4480 10 | • PIC18F2321 • PIC18F2585 • PIC18F4510 11 | • PIC18F2410 • PIC18F2610 • PIC18F4515 12 | • PIC18F2420 • PIC18F2620 • PIC18F4520 13 | • PIC18F2423 • PIC18F2680 • PIC18F4523 14 | • PIC18F2450 • PIC18F2682 • PIC18F4525 15 | • PIC18F2455 • PIC18F2685 • PIC18F4550 16 | • PIC18F2458 • PIC18F4221 • PIC18F4553 17 | • PIC18F2480 • PIC18F4321 • PIC18F4580 18 | • PIC18F2510 • PIC18F4410 • PIC18F4585 19 | • PIC18F2515 • PIC18F4420 • PIC18F4610 20 | • PIC18F2520 • PIC18F4423 • PIC18F4620 21 | • PIC18F2523 • PIC18F4450 • PIC18F4680 22 | • PIC18F2525 • PIC18F4455 • PIC18F4682 23 | • PIC18F2550 • PIC18F4458 • PIC18F4685 24 | • PIC18F2553 25 | 26 | # pin connection 27 | 28 | **notice :** The programmer use the LVP mode to program the PIC18F 29 | 30 | 31 | 32 | | pin name | pin name | pin type | pin Description | Arduino UNO pins | 33 | |:---:|:---:|:---:| :---: | :---: | 34 | | MCCRL/Vpp/RE3 | VPP | P | Programming Enable | connected to pin 2 on Arduino UNO | 35 | | VDD | VDD | P | Power Supply | connected to pin 5V on Arduino UNO | 36 | | VSS | VSS | P | Ground | connected to pin GND on Arduino UNO | 37 | | RB5 | PGM | I | Low_Voltage ICSP input | connected to pin 5 on Arduino UNO | 38 | | RB6 | PGC | I | Serial Clock | connected to pin 4 on Arduino UNO | 39 | | RB7 | PGD | I/O | Serial Data | connected to pin 3 on Arduino UNO | 40 | 41 | 42 | for more details on PIC18 memory programming read the **Flash Microcontroller Programming Specification (by microchip)** found on **PIC18F_EEPROM** pdf file 43 | 44 | 45 | # programmer testing 46 | 47 |
48 | 49 | Everything Is AWESOME 53 | 54 |
55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /console app code/PC_CODE.cpp: -------------------------------------------------------------------------------- 1 | ///*********************************************************************************/// 2 | /// >> PIC18F2XXX/4XXX PROGRAMMER PROGRAMMER << /// 3 | /// created by : ASSAOUS OUSSAMA /// 4 | /// project description : this program is for reading the PIC18F HEX file .. /// 5 | /// and then load it to the PIC18F microcontroller using the Arduino UNO /// 6 | /// creation date: 10/10/2020 /// 7 | ///*********************************************************************************/// 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | using namespace std; 17 | 18 | 19 | //------all functions used on this program------- 20 | string dec_to_hex(int); 21 | int hex_to_dec(string); 22 | void gotoxy(int, int); 23 | bool readFile(); 24 | void sendData(); 25 | bool deviceSerch(); 26 | bool eraseDevice(); 27 | bool sendProgData(); 28 | bool sendIdByte(); 29 | bool sendEepromByte(); 30 | bool sendConfigByte(); 31 | void stopPrograming(); 32 | //----------------------------------------------- 33 | 34 | 35 | 36 | DCB dcbSerialParams = { 0 }; // Initializing DCB structure 37 | COMMTIMEOUTS timeouts = { 0 }; 38 | 39 | 40 | DWORD dwEventMask = 0x1; 41 | HANDLE hComm; 42 | DWORD nNumberOfBytesToRead = 1; 43 | DWORD lpNumberOfBytesRead = 0; 44 | 45 | DWORD dNoOFBytestoWrite; // No of bytes to write into the port 46 | DWORD dNoOfBytesWritten = 0; // No of bytes written to the port 47 | DWORD NoBytesRead = 0; 48 | 49 | 50 | long int realAdress = 0; 51 | int adressU; 52 | int dataType = 0; 53 | long int adress=0; 54 | long int adresspoint=0; 55 | int byteNumb; 56 | string line = "aa"; 57 | string val = ""; 58 | string val0 = ""; 59 | string val1 = ""; 60 | string val2 = ""; 61 | int point = 0; 62 | int point1 = 0; 63 | int point2 = 0; 64 | int point3 = 0; 65 | 66 | char progData[98304]; 67 | char configData[14]; 68 | char idData[8]; 69 | char eepromData[1024]; 70 | 71 | char resp[4]; 72 | bool endfile = false; 73 | bool eepromE = false; 74 | char buffer[38]; 75 | bool endbuffer = false; 76 | int i = 0; 77 | int j = 0; 78 | int p = 0; 79 | int blockselect = 0; 80 | int bytenum=0; 81 | int blockprog = 0; 82 | int block[3072]; 83 | int blocknum=0; 84 | int blockpoint=0; 85 | 86 | 87 | ///************************************************************/// 88 | /// FUNCTION :main() /// 89 | /// OUTPUT : the main function /// 90 | ///************************************************************/// 91 | int main() 92 | { 93 | if(readFile()) sendData(); 94 | cout << "press any key to excite ..."; 95 | _getch(); 96 | } 97 | ///************************************************************/// 98 | 99 | 100 | 101 | ///************************************************************/// 102 | /// FUNCTION : readFile() /// 103 | /// OUTPUT : read the hex file /// 104 | ///************************************************************/// 105 | bool readFile() 106 | { 107 | cout << "+---------------------------------------------------------------------------------+" << endl; 108 | cout << "| PIC18F2XXX/4XXX PROGRAMMER (based on arduino UNO) |" << endl; 109 | cout << "| created by : ASSAOUS OUSSAMA |" << endl; 110 | cout << "| creation date : 15/10/2020 |" << endl; 111 | cout << "+---------------------------------------------------------------------------------+" << endl; 112 | string filepath; 113 | cout << ">> type the HEX file path " << endl; 114 | cout << ">> "; 115 | cin >> filepath; 116 | cout << endl; 117 | fstream myfile; 118 | myfile.open(filepath); 119 | 120 | 121 | if (myfile.is_open()) 122 | { 123 | 124 | while (!endfile) 125 | { 126 | myfile >> line; 127 | 128 | val = line[7]; 129 | val += line[8]; 130 | dataType = hex_to_dec(val); 131 | 132 | switch (dataType) 133 | { 134 | case 0: 135 | { 136 | if (realAdress == 0x200000) 137 | { //------------------------------- id bits------------------------------------ 138 | 139 | for (i = 9; i <= 24; i = i + 2) 140 | { 141 | val = line[i]; 142 | val += line[i + 1]; 143 | idData[point1] = hex_to_dec(val); 144 | 145 | point1++; 146 | } 147 | 148 | 149 | } 150 | else if (realAdress == 0x300000) 151 | { //------------------------- configuration bits------------------------------ 152 | 153 | for (i = 9; i <= 36; i = i + 2) 154 | { 155 | val = line[i]; 156 | val += line[i + 1]; 157 | configData[point2] = hex_to_dec(val); 158 | 159 | point2++; 160 | } 161 | 162 | } 163 | else if (realAdress == 0xF00000) 164 | { // ----------------------------EEPROM memory------------------------------- 165 | 166 | eepromE = true; 167 | val = line[1]; 168 | val += line[2]; 169 | 170 | byteNumb = hex_to_dec(val); 171 | 172 | for (i = 0; i < byteNumb * 2; i = i + 2) 173 | { 174 | val = line[i + 9]; 175 | val += line[i + 10]; 176 | 177 | eepromData[point3] = hex_to_dec(val); 178 | 179 | point3++; 180 | 181 | } 182 | 183 | } 184 | else 185 | { // ---------------------------program memory --------------------------- 186 | val = line[3]; 187 | val += line[4]; 188 | val += line[5]; 189 | val += line[6]; 190 | 191 | adress = hex_to_dec(val); 192 | adress += realAdress; 193 | j = 0; 194 | if ((adress - adresspoint) != 0) 195 | { 196 | for (i = 0; i < (adress - adresspoint); i++) 197 | { 198 | 199 | progData[point] = 0xFF; 200 | if (p == 31) 201 | { 202 | blockpoint++; 203 | p = 0; 204 | } 205 | else p++; 206 | 207 | j++; 208 | point++; 209 | 210 | } 211 | adresspoint += j; 212 | } 213 | 214 | 215 | val = line[1]; 216 | val += line[2]; 217 | 218 | byteNumb = hex_to_dec(val); 219 | 220 | for (i = 0; i < byteNumb * 2; i = i + 2) 221 | { 222 | val = line[i + 9]; 223 | val += line[i + 10]; 224 | 225 | progData[point] = hex_to_dec(val); 226 | 227 | if (progData[point] != 0xff) 228 | { 229 | block[blockpoint] = 1; 230 | 231 | } 232 | 233 | if (p == 31) 234 | { 235 | blockpoint++; 236 | p = 0; 237 | } 238 | else p++; 239 | 240 | 241 | point++; 242 | adresspoint++; 243 | bytenum++; 244 | 245 | } 246 | } 247 | 248 | } 249 | break; 250 | case 1: 251 | { 252 | endfile = true; 253 | } 254 | break; 255 | case 4: 256 | { 257 | val = line[9]; 258 | val += line[10]; 259 | val += line[11]; 260 | val += line[12]; 261 | adressU = hex_to_dec(val); 262 | realAdress = adressU; 263 | realAdress = realAdress << 16; 264 | } 265 | break; 266 | } 267 | 268 | } 269 | 270 | } 271 | else { 272 | int msgboxID = MessageBox(NULL,L"Can't open file",L"can't open ", MB_ICONSTOP | MB_OK ); 273 | return false; 274 | } 275 | 276 | myfile.close(); 277 | 278 | 279 | for (i = 0; i < 3072; i++) 280 | { 281 | if(block[i]) blocknum++; 282 | } 283 | 284 | 285 | return true; 286 | } 287 | ///************************************************************/// 288 | 289 | 290 | 291 | ///************************************************************/// 292 | /// FUNCTION : sendData() /// 293 | /// OUTPUT : send data to the arduino to be programed on PIC /// 294 | ///************************************************************/// 295 | void sendData() 296 | { 297 | 298 | //-----------------------------COM PORT CONFIG ----------------------------------------- 299 | 300 | dcbSerialParams.DCBlength = sizeof(dcbSerialParams); 301 | dcbSerialParams.BaudRate = CBR_57600; // Setting BaudRate = 57600 302 | dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8 303 | dcbSerialParams.StopBits = ONESTOPBIT;// Setting StopBits = 1 304 | dcbSerialParams.Parity = NOPARITY; // Setting Parity = None 305 | 306 | 307 | 308 | timeouts.ReadIntervalTimeout = 50; // in milliseconds 309 | timeouts.ReadTotalTimeoutConstant = 50; // in milliseconds 50 310 | timeouts.ReadTotalTimeoutMultiplier = 50; // in milliseconds 50 311 | timeouts.WriteTotalTimeoutConstant = 50; // in milliseconds 312 | timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds 313 | //-------------------------------------------------------------------------------------- 314 | 315 | 316 | if (!deviceSerch()) return; 317 | 318 | if (!eraseDevice()) return; 319 | 320 | if (!sendProgData()) return; 321 | 322 | if (!sendIdByte()) return; 323 | 324 | if (!sendEepromByte()) return; 325 | 326 | if (!sendConfigByte()) return; 327 | 328 | stopPrograming(); 329 | 330 | CloseHandle(hComm); //Closing the Serial Port 331 | 332 | MessageBox(NULL, L"DONE PROGRAMING",L"DONE",MB_ICONEXCLAMATION | MB_OK ); 333 | 334 | } 335 | ///************************************************************/// 336 | 337 | 338 | 339 | ///************************************************************/// 340 | /// FUNCTION : deviceSerch() /// 341 | /// OUTPUT : searching for device COM PORT /// 342 | ///************************************************************/// 343 | bool deviceSerch() 344 | { 345 | bool portstat = false; 346 | int portnum = 0; 347 | cout << ">> searching for device ..." << endl<> no device was found !!" << endl<> PIC18F PROGRAMMER found on COMPORT : " << portnum << endl<> the PIC18 was erased successfully !! " << endl<> the device is not responding corectly" << endl; 448 | return false; 449 | } 450 | return true; 451 | } 452 | ///************************************************************/// 453 | 454 | 455 | ///************************************************************/// 456 | /// FUNCTION : sendProgData() /// 457 | /// OUTPUT : send program bytes /// 458 | ///************************************************************/// 459 | bool sendProgData() 460 | { 461 | 462 | buffer[0] = 'P'; 463 | buffer[1] = 'R'; 464 | buffer[2] = 'O'; 465 | 466 | 467 | j = 0; 468 | int loc = 0; 469 | gotoxy(0, 14); 470 | cout << ">> programing the device : " << endl; 471 | gotoxy(82, 14); 472 | cout << "0%"; 473 | 474 | float cx = 100.0000 / blocknum; 475 | float zez = 0; 476 | bool test = false; 477 | 478 | 479 | blockselect = 0; 480 | while (!endbuffer) 481 | { 482 | 483 | if (block[blockselect]) 484 | { 485 | 486 | j = ((blockselect + 1) * 32) - 32; 487 | val = dec_to_hex(j); 488 | val0 = val[0]; 489 | val0 += val[1]; 490 | val1 = val[2]; 491 | val1 += val[3]; 492 | val2 = val[4]; 493 | val2 += val[5]; 494 | buffer[3] = hex_to_dec(val0); 495 | buffer[4] = hex_to_dec(val1); 496 | buffer[5] = hex_to_dec(val2); 497 | 498 | for (i = 6; i < 38; i++) 499 | { 500 | buffer[i] = progData[j]; 501 | 502 | j++; 503 | } 504 | 505 | WriteFile(hComm, buffer, 38, 0, NULL); 506 | SetCommMask(hComm, EV_RXCHAR); 507 | dwEventMask = 0x1; 508 | WaitCommEvent(hComm, &dwEventMask, NULL); 509 | 510 | ReadFile(hComm, &resp, sizeof(resp), &NoBytesRead, NULL); 511 | if ((zez + cx) > 99) zez = 100; 512 | else zez += cx; 513 | loc = (zez * 52) / 100; 514 | 515 | 516 | //-------progress bar ----------- 517 | gotoxy(80, 14); 518 | cout << (char)0x5D; 519 | gotoxy(26, 14); 520 | cout << (char)0x5B; 521 | 522 | 523 | for (int f = 0; f <= loc; f++) 524 | { 525 | cout << (char)0xFE; 526 | } 527 | 528 | gotoxy(82, 14); 529 | cout << (int)zez << "%" << endl< 11) 564 | { 565 | buffer[i] = 0xFF; 566 | } 567 | else 568 | { 569 | buffer[i] = idData[j]; 570 | } 571 | j++; 572 | 573 | } 574 | WriteFile(hComm, buffer, 38, 0, NULL); 575 | SetCommMask(hComm, EV_RXCHAR); 576 | dwEventMask = 0x1; 577 | WaitCommEvent(hComm, &dwEventMask, NULL); 578 | 579 | ReadFile(hComm, &resp, sizeof(resp), &NoBytesRead, NULL); 580 | cout << ">> id bits programed successfully !!" << endl<> programing the EEPROM ..." << endl << endl; 599 | buffer[0] = 'E'; 600 | buffer[1] = 'E'; 601 | buffer[2] = 'P'; 602 | buffer[3] = 'R'; 603 | 604 | p = 0; 605 | endbuffer = false; 606 | 607 | while(!endbuffer) 608 | { 609 | val = dec_to_hex(p); 610 | val1 = val[2]; 611 | val1 += val[3]; 612 | val2 = val[4]; 613 | val2 += val[5]; 614 | buffer[4] = hex_to_dec(val1); 615 | buffer[5] = hex_to_dec(val2); 616 | 617 | 618 | for (i = 6; i < 38; i++) 619 | { 620 | if (p+6 > point3) 621 | { 622 | buffer[i] = 0xFF; 623 | endbuffer = true; 624 | } 625 | else 626 | { 627 | buffer[i] = eepromData[p]; 628 | } 629 | p++; 630 | } 631 | 632 | 633 | WriteFile(hComm, buffer, 38, 0, NULL); 634 | SetCommMask(hComm, EV_RXCHAR); 635 | dwEventMask = 0x1; 636 | WaitCommEvent(hComm, &dwEventMask, NULL); 637 | 638 | ReadFile(hComm, &resp, sizeof(resp), &NoBytesRead, NULL); 639 | 640 | 641 | } 642 | cout << ">> eeprom bits programed successfully !!" << endl< 19) 669 | { 670 | buffer[i] = 0xFF; 671 | } 672 | else 673 | { 674 | buffer[i] = configData[j]; 675 | } 676 | j++; 677 | 678 | } 679 | WriteFile(hComm, buffer, 38, 0, NULL); 680 | SetCommMask(hComm, EV_RXCHAR); 681 | dwEventMask = 0x1; 682 | WaitCommEvent(hComm, &dwEventMask, NULL); 683 | 684 | ReadFile(hComm, &resp, sizeof(resp), &NoBytesRead, NULL); 685 | cout << ">> config bits programed successfully !!" << endl<> the device was programed successfully !!" << endl<= 0; j22--) 786 | { 787 | num11 = num11 + (num0[j22] * pow(16, j33)); 788 | j33++; 789 | } 790 | j33 = 0; 791 | 792 | return num11; 793 | } 794 | 795 | ///***********************************************************/// 796 | 797 | 798 | ///***********************************************************/// 799 | /// /// 800 | /// FUNCTION : dec_to_hex(int ) /// 801 | /// OUTPUT : convert int value to DEC to hex /// 802 | /// /// 803 | ///***********************************************************/// 804 | string dec_to_hex(int num4) 805 | { 806 | int num5[100]; 807 | int ji; 808 | for (ji = 0; ji < 100; ji++) 809 | { 810 | num5[ji] = 0; 811 | } 812 | string str4 = ""; 813 | 814 | if (num4 == 0) 815 | { 816 | return "000000"; 817 | } 818 | else 819 | { 820 | for (ji = 0; num4 > 0; ji++) 821 | { 822 | num5[ji] = num4 % 16; 823 | num4 = num4 / 16; 824 | } 825 | 826 | for (ji = 5; ji >= 0; ji--) 827 | { 828 | switch (num5[ji]) 829 | { 830 | case 0: 831 | str4 = str4 + "0"; 832 | break; 833 | case 1: 834 | str4 = str4 + "1"; 835 | break; 836 | case 2: 837 | str4 = str4 + "2"; 838 | break; 839 | case 3: 840 | str4 = str4 + "3"; 841 | break; 842 | case 4: 843 | str4 = str4 + "4"; 844 | break; 845 | case 5: 846 | str4 = str4 + "5"; 847 | break; 848 | case 6: 849 | str4 = str4 + "6"; 850 | break; 851 | case 7: 852 | str4 = str4 + "7"; 853 | break; 854 | case 8: 855 | str4 = str4 + "8"; 856 | break; 857 | case 9: 858 | str4 = str4 + "9"; 859 | break; 860 | case 10: 861 | str4 = str4 + "A"; 862 | break; 863 | case 11: 864 | str4 = str4 + "B"; 865 | break; 866 | case 12: 867 | str4 = str4 + "C"; 868 | break; 869 | case 13: 870 | str4 = str4 + "D"; 871 | break; 872 | case 14: 873 | str4 = str4 + "E"; 874 | break; 875 | case 15: 876 | str4 = str4 + "F"; 877 | break; 878 | default: 879 | str4 = str4 + "0"; 880 | break; 881 | } 882 | } 883 | return str4; 884 | } 885 | 886 | } 887 | ///***********************************************************/// 888 | 889 | 890 | ///***********************************************************/// 891 | /// FUNCTION : gotoxy(int,int) /// 892 | /// OUTPUT : move the console cursor position /// 893 | ///***********************************************************/// 894 | void gotoxy(int x, int y) 895 | { 896 | COORD coord; 897 | coord.X = x; 898 | coord.Y = y; 899 | SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); 900 | } 901 | ///************************************************************/// 902 | --------------------------------------------------------------------------------