Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
AVRISP.cpp
00001 #include "AVRISP.h" 00002 00003 // constructor 00004 AVRISP::AVRISP(PinName mosi, PinName miso, PinName sclk, PinName reset) 00005 { 00006 spiPort = new SPI(mosi,miso,sclk); 00007 spiPort->frequency(TARGET_CLK>>2); 00008 spiPort->format(8,1); 00009 resetPin = new DigitalOut(reset); 00010 } 00011 00012 //A function to poll BSY to prevent loading a new instruction prematurely 00013 void AVRISP::StillProgramming() 00014 { 00015 int check = 1; 00016 while(check == 1) 00017 { 00018 spiPort->write(0xF0); 00019 spiPort->write(0x00); 00020 spiPort->write(0x00); 00021 check = spiPort->write(0x00); //read data byte out 00022 } 00023 } 00024 00025 // enable programming mode 00026 bool AVRISP::EnableProgrammingMode() 00027 { 00028 int failed = 0; 00029 00030 *resetPin = 1; 00031 wait(0.02); 00032 *resetPin = 0; 00033 wait(0.02); 00034 00035 while(failed < 5) //loop to try to enable programming mode 5 times 00036 { 00037 spiPort->write(0xAC); 00038 spiPort->write(0x53); 00039 int echoBack= spiPort->write(0x00); 00040 if(echoBack == 0x53) 00041 { //if data read on 3rd byte load is 0x53 00042 spiPort->write(0x00); //programming mode was enabled...good job! 00043 return true; 00044 } 00045 else 00046 { 00047 failed++; 00048 *resetPin = 1; //pulse reset and try again 00049 *resetPin = 0; 00050 wait(0.5); 00051 } 00052 } 00053 return false; //Bummer... 00054 } 00055 00056 void AVRISP::LeaveProgrammingMode() 00057 { 00058 *resetPin = 1; 00059 wait(0.02); 00060 } 00061 00062 // read chip signature byte 1 00063 int AVRISP::ReadChipSignatureByte1() 00064 { 00065 // read byte 1 00066 spiPort->write(0x30); 00067 spiPort->write(0x00); 00068 spiPort->write(0x00); 00069 int signatureByte1 = spiPort->write(0x00); 00070 StillProgramming(); 00071 00072 return signatureByte1; 00073 } 00074 00075 // read chip signature byte 2 00076 int AVRISP::ReadChipSignatureByte2() 00077 { 00078 // read byte 1 00079 spiPort->write(0x30); 00080 spiPort->write(0x00); 00081 spiPort->write(0x01); 00082 int signatureByte2 = spiPort->write(0x00); 00083 StillProgramming(); 00084 00085 return signatureByte2; 00086 } 00087 00088 // read chip signature byte 3 00089 int AVRISP::ReadChipSignatureByte3() 00090 { 00091 // read byte 1 00092 spiPort->write(0x30); 00093 spiPort->write(0x00); 00094 spiPort->write(0x02); 00095 int signatureByte3 = spiPort->write(0x00); 00096 StillProgramming(); 00097 00098 return signatureByte3; 00099 } 00100 00101 // erase chip 00102 void AVRISP::ChipErase() 00103 { 00104 spiPort->write(0xAC); 00105 spiPort->write(0x80); 00106 spiPort->write(0x00); 00107 spiPort->write(0x00); 00108 StillProgramming(); 00109 *resetPin = 1; 00110 wait(0.02); 00111 *resetPin = 0; 00112 wait(0.02); 00113 EnableProgrammingMode(); 00114 } 00115 00116 // write fuse byte low 00117 void AVRISP::WriteFuseLow(uint8_t fuseLow) 00118 { 00119 fuseLow = fuseLow&0xFF; 00120 spiPort->write(0xAC); 00121 spiPort->write(0xA0); 00122 spiPort->write(0x00); 00123 spiPort->write(fuseLow); 00124 StillProgramming(); 00125 } 00126 00127 // read fuse byte low 00128 int AVRISP::ReadFuseLow() 00129 { 00130 spiPort->write(0x50); 00131 spiPort->write(0x00); 00132 spiPort->write(0x00); 00133 int readBack = spiPort->write(0x00); 00134 StillProgramming(); 00135 00136 return readBack; 00137 } 00138 00139 // write fuse byte high 00140 void AVRISP::WriteFuseHigh(uint8_t fuseHigh) 00141 { 00142 fuseHigh = fuseHigh&0xFF; 00143 spiPort->write(0xAC); 00144 spiPort->write(0xA8); 00145 spiPort->write(0x00); 00146 spiPort->write(fuseHigh); 00147 StillProgramming(); 00148 } 00149 00150 // read fuse byte high 00151 int AVRISP::ReadFuseHigh() 00152 { 00153 spiPort->write(0x58); 00154 spiPort->write(0x08); 00155 spiPort->write(0x00); 00156 int readBack = spiPort->write(0x00); 00157 StillProgramming(); 00158 00159 return readBack; 00160 } 00161 00162 // write fuse byte extended 00163 void AVRISP::WriteFuseExtended(uint8_t fuseExtended) 00164 { 00165 fuseExtended = fuseExtended&0xFF; 00166 spiPort->write(0xAC); 00167 spiPort->write(0xA4); 00168 spiPort->write(0x00); 00169 spiPort->write(fuseExtended); 00170 StillProgramming(); 00171 } 00172 00173 // read fuse byte extended 00174 int AVRISP::ReadFuseExtended() 00175 { 00176 spiPort->write(0x50); 00177 spiPort->write(0x08); 00178 spiPort->write(0x00); 00179 int readBack = spiPort->write(0x00); 00180 StillProgramming(); 00181 00182 return readBack; 00183 } 00184 00185 // write lock byte 00186 void AVRISP::WriteLockByte(uint8_t lockByte) 00187 { 00188 lockByte = lockByte&0xFF; 00189 spiPort->write(0xAC); 00190 spiPort->write(0xE0); 00191 spiPort->write(0x00); 00192 spiPort->write(lockByte); 00193 StillProgramming(); 00194 } 00195 00196 // read lock byte 00197 int AVRISP::ReadLockByte() 00198 { 00199 spiPort->write(0x58); 00200 spiPort->write(0x00); 00201 spiPort->write(0x00); 00202 int readBack = spiPort->write(0x00); 00203 StillProgramming(); 00204 00205 return readBack; 00206 } 00207 00208 // write program page 00209 void AVRISP::WriteProgramPage(uint16_t addr) 00210 { 00211 //write program memory page 00212 spiPort->write(0x4C); 00213 spiPort->write(MSB(addr)); 00214 spiPort->write(LSB(addr)); 00215 spiPort->write(0x00); 00216 StillProgramming(); //make sure the operation worked 00217 } 00218 00219 //function to load and write program memory 00220 //args: addr is the 12 bit address of the memory location 00221 // low_data and high_data are the values to write to that location 00222 void AVRISP::LoadProgramPage(uint16_t addr,uint8_t lowData,uint8_t highData)//int addr_MSB, 00223 { 00224 //load program memory low byte (little endian) 00225 spiPort->write(0x40); 00226 spiPort->write(0x00); 00227 spiPort->write(LSB(addr)); 00228 spiPort->write(lowData); 00229 00230 //load program memory high byte 00231 spiPort->write(0x48); 00232 spiPort->write(0x00); 00233 spiPort->write(LSB(addr)); 00234 spiPort->write(highData); 00235 00236 // write page if 32 words have now been written 00237 if(addr % MAX_PAGE_SIZE == (MAX_PAGE_SIZE-1)) 00238 { 00239 WriteProgramPage(addr); 00240 } 00241 } 00242 00243 uint8_t AVRISP::ReadByte(FILE *file) 00244 { 00245 char ascii_char[2]; 00246 fread(&ascii_char, 1, 2, file); 00247 return (((ascii_char[0] < 65) ? (ascii_char[0]-48) : (ascii_char[0]-55)) << 4) 00248 | ((ascii_char[1] < 65) ? (ascii_char[1]-48) : (ascii_char[1]-55)); 00249 } 00250 00251 void AVRISP::ReadProgramFlash(uint8_t addrMSB, uint8_t addrLSB) 00252 { 00253 spiPort->write(0x28); 00254 spiPort->write(addrMSB); 00255 spiPort->write(addrLSB); 00256 spiPort->write(0x00); 00257 spiPort->write(0x20); 00258 spiPort->write(addrMSB); 00259 spiPort->write(addrLSB); 00260 } 00261 00262 // program flash 00263 bool AVRISP::ProgramFlash(char *hexFileName) 00264 { 00265 int flag = 0; 00266 FILE *hexFile; 00267 hexFile = fopen(hexFileName,"r"); 00268 if(hexFile != NULL) 00269 { 00270 uint16_t address = 0; 00271 char temp; 00272 temp = fgetc(hexFile); 00273 while(flag == 0) 00274 { 00275 if(temp == ':') 00276 { 00277 uint8_t length = ReadByte(hexFile); 00278 if(length == 0) 00279 { 00280 flag = 1; 00281 } 00282 else 00283 { 00284 fseek(hexFile,6,SEEK_CUR); //2 if reading address 00285 00286 for(uint8_t i=0;i<length;i+=2) 00287 { 00288 uint8_t lowData = ReadByte(hexFile); 00289 uint8_t highData = ReadByte(hexFile); 00290 00291 //load data bytes here 00292 LoadProgramPage(address,lowData,highData); 00293 00294 address++; 00295 } 00296 while((temp = fgetc(hexFile)) != ':'); 00297 } 00298 } 00299 else flag = 1; 00300 } 00301 WriteProgramPage(address); 00302 fclose(hexFile); 00303 } 00304 else 00305 { 00306 return false; 00307 } 00308 00309 return true; 00310 } 00311
Generated on Fri Jul 15 2022 13:15:25 by
1.7.2