Bo Qiang / Mbed 2 deprecated TestAVRISP

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AVRISP.cpp Source File

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