Ellips Development / Mbed 2 deprecated AVRisp

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, uint32_t targetClk, uint16_t pageSize, PRGCB pCB )
00005 : spiPort(mosi, miso, sclk )
00006 , resetPin(reset)
00007 , mPageSize(pageSize)
00008 , progressCB(pCB)
00009 {
00010     spiPort.frequency(targetClk>>2);//1/4 th of the clock frequency of the unit
00011     spiPort.format(8,0);
00012 }
00013 
00014 AVRISP::~AVRISP()
00015 {
00016 }
00017 
00018 //A function to poll BSY to prevent loading a new instruction prematurely
00019 void AVRISP::StillProgramming() 
00020 {
00021     uint8_t check = 1;
00022     while(check & 0x1){//check LSB only
00023         spiPort.write(0xF0);
00024         spiPort.write(0x00);
00025         spiPort.write(0x00);
00026         check = spiPort.write(0x00); //read data byte out
00027     }
00028 }
00029 
00030 // enable programming mode
00031 bool AVRISP::EnableProgrammingMode()
00032 {
00033     int failed = 0;
00034     
00035     resetPin = 1;
00036     wait(0.02);
00037     resetPin = 0;
00038     wait(0.02);
00039     
00040     while(failed < 5)               //loop to try to enable programming mode 5 times
00041     {
00042         spiPort.write(0xAC);
00043         spiPort.write(0x53);
00044         int echoBack= spiPort.write(0x00);
00045         if(echoBack == 0x53)
00046         {                           //if data read on 3rd byte load is 0x53
00047             spiPort.write(0x00);   //programming mode was enabled...good job!
00048             return true;
00049         }
00050         else
00051         {
00052             failed++;
00053             resetPin = 1;          //pulse reset and try again
00054             resetPin = 0;
00055             wait(0.5);
00056         }
00057      }
00058     return false;                   //Bummer...
00059 }
00060 
00061 void AVRISP::LeaveProgrammingMode()
00062 {
00063     resetPin = 1;
00064     wait(0.02);
00065 }
00066 
00067 // read chip signature byte
00068 uint8_t AVRISP::ReadChipSignatureByte(SignatureByte Nr)
00069 {
00070     spiPort.write(0x30);
00071     spiPort.write(0x00);
00072     spiPort.write(Nr);
00073     return spiPort.write(0x00);
00074 }
00075 
00076 // erase chip
00077 void AVRISP::ChipErase()
00078 {
00079     spiPort.write(0xAC);
00080     spiPort.write(0x80);
00081     spiPort.write(0x00);
00082     spiPort.write(0x00);
00083     StillProgramming();
00084     resetPin = 1;
00085     wait(0.02);
00086     resetPin = 0;
00087     wait(0.02);
00088     EnableProgrammingMode();
00089 }
00090 
00091 // write fuse byte
00092 void AVRISP::WriteFuse(FuseType Typ, uint8_t fuse)
00093 {
00094     spiPort.write(0xAC);
00095     switch ( Typ ){
00096         case eFTLo:
00097         spiPort.write(0xA0); break;
00098         case eFTHi:
00099         spiPort.write(0xA8); break;
00100         case eFTEx:
00101         spiPort.write(0xA4); break;
00102         case eFTLock:
00103         spiPort.write(0xE0); break;
00104         default:
00105         spiPort.write(0x00); break;
00106     };        
00107     spiPort.write(0x00);
00108     spiPort.write(fuse&0xff);
00109     StillProgramming();
00110 }
00111 
00112 // read fuse byte
00113 uint8_t AVRISP::ReadFuse(FuseType Typ)
00114 {
00115     switch (Typ){    
00116     case eFTLo:
00117     spiPort.write(0x50);
00118     spiPort.write(0x00);
00119     break;
00120     case eFTHi:
00121     spiPort.write(0x58);
00122     spiPort.write(0x08);
00123     break;
00124     case eFTEx:
00125     spiPort.write(0x50);
00126     spiPort.write(0x08);
00127     break;
00128     case eFTLock:
00129     spiPort.write(0x58);
00130     spiPort.write(0x00);
00131     break;
00132     default:
00133     spiPort.write(0x00);
00134     spiPort.write(0x00);
00135     break;
00136     }
00137     spiPort.write(0x00);
00138     return spiPort.write(0x00);
00139 }
00140 #define LSB(I) ((I) & 0xFF)
00141 #define MSB(I) (((I) & 0xF00) >> 8)
00142 // write program page
00143 void AVRISP::WriteProgramPage(uint16_t addr)
00144 {
00145     //write program memory page
00146     spiPort.write(0x4C);
00147     spiPort.write(MSB(addr));
00148     spiPort.write(LSB(addr));
00149     spiPort.write(0x00);
00150     
00151     StillProgramming(); //make sure the operation worked
00152 }
00153 
00154 
00155 //function to load and write program memory
00156 //args: addr is the 12 bit address of the memory location
00157 //      low_data and high_data are the values to write to that location
00158 void AVRISP::LoadProgramPage(uint16_t addr,uint8_t lowData,uint8_t highData)//int addr_MSB, 
00159 {
00160     //load program memory low byte (little endian)
00161     spiPort.write(0x40);
00162     spiPort.write(0x00);
00163     spiPort.write(LSB(addr));
00164     spiPort.write(lowData);
00165     
00166     //load program memory high byte
00167     spiPort.write(0x48);
00168     spiPort.write(0x00);
00169     spiPort.write(LSB(addr));
00170     spiPort.write(highData);    
00171 }
00172 
00173 inline uint8_t AVRISP::ReadByte(FILE *file)
00174 {
00175     char ascii_char[2];
00176     fread(&ascii_char, 1, 2, file);
00177     return   (((ascii_char[0] < 65) ? (ascii_char[0]-48) : (ascii_char[0]-55)) << 4)
00178             | ((ascii_char[1] < 65) ? (ascii_char[1]-48) : (ascii_char[1]-55));
00179 }
00180 
00181 uint8_t AVRISP::ReadProgramFlash(uint16_t addr, bool highByte)
00182 {
00183     spiPort.write(highByte ? 0x28: 0x20 );
00184     spiPort.write(MSB(addr));
00185     spiPort.write(LSB(addr));
00186     return spiPort.write(0x00);
00187 }
00188 #define AT_BOUNDARY(addr,size) ((addr % size) == (size -1))
00189 // program flash
00190 
00191 //TODO: Implement address gaps in the hex file format
00192 bool AVRISP::ProgramFlash(FILE *hexFile)
00193 {
00194     int flag = 0;    
00195     if(hexFile != NULL)
00196     {    
00197         uint16_t address = 0;
00198         char temp;        
00199         temp = fgetc(hexFile);
00200         while(flag == 0)
00201         {
00202             if(temp == ':')
00203             {
00204                 uint8_t length = ReadByte(hexFile);
00205                 if(length == 0)
00206                 {
00207                     flag = 1;
00208                 }
00209                 else
00210                 {
00211                     fseek(hexFile,6,SEEK_CUR); //2 if reading address
00212                     
00213                     for(uint8_t i=0;i<length;i+=2)
00214                     {
00215                         uint8_t lowData = ReadByte(hexFile);                        
00216                         uint8_t highData = ReadByte(hexFile);
00217                        
00218                         //load data bytes here
00219                         LoadProgramPage(address,lowData,highData);
00220                         
00221                         if (AT_BOUNDARY(address, mPageSize))        // write page if 32 words have now been written                        
00222                         {                    
00223                             WriteProgramPage(address);                            
00224                             if( progressCB ) (*progressCB)(); //activity callback                            
00225                         }
00226                         
00227                         address++;
00228                     }
00229                     while((temp = fgetc(hexFile)) != ':');            
00230                 }
00231             }
00232             else flag = 1;
00233         }
00234         WriteProgramPage(address);//write the last part
00235     }
00236     else
00237     {
00238         return false;
00239     }
00240     return true;
00241 }
00242 
00243 //TODO: Implement address gaps in the hex file format
00244 bool AVRISP::VerifyFlash(FILE* hexFile)
00245 {
00246     int flag = 0;  
00247     bool Error = false;  
00248     if(hexFile != NULL)
00249     {    
00250         uint16_t address = 0;
00251         char temp;        
00252         temp = fgetc(hexFile);
00253         while(flag == 0)
00254         {
00255             if(temp == ':')
00256             {
00257                 uint8_t length = ReadByte(hexFile);
00258                 if(length == 0)
00259                 {
00260                     flag = 1;
00261                 }
00262                 else
00263                 {
00264                     fseek(hexFile,6,SEEK_CUR); //2 if reading address
00265                     
00266                     for(uint8_t i=0;i<length;i+=2)
00267                     {
00268                         uint8_t lowData = ReadByte(hexFile);                        
00269                         uint8_t highData = ReadByte(hexFile);
00270                         uint8_t lowDataF = ReadProgramFlash(address, false);
00271                         uint8_t highDataF = ReadProgramFlash(address, true);                        
00272                         
00273                         if( lowData != lowDataF || highData != highDataF )
00274                         {
00275                             printf( "\n@%04x src %02x,%02x != %02x,%02x\n", address, lowData, highData, lowDataF,highDataF);                            
00276                             Error = true;
00277                         }                          
00278                         
00279                         if (AT_BOUNDARY(address, mPageSize))
00280                         {
00281                             if( progressCB ) (*progressCB)(); //activity callback      
00282                         }
00283                         address++;
00284                     }
00285                     while((temp = fgetc(hexFile)) != ':');                    
00286                 }                            
00287             }
00288             else flag = 1;
00289         }
00290         if(Error)
00291             return false;
00292     }
00293     else
00294     {
00295         return false;
00296     }                  
00297     
00298     return true;
00299 }