Xmega Application Note


main.c File Reference

#include "defines.h"
#include "serial.h"
#include "sp_driver.h"
#include "eeprom_driver.h"

Go to the source code of this file.

Defines

#define ADDR_T   unsigned long
#define BLOCKSIZE   PAGESIZE
#define C_TASK

Functions

unsigned char BlockLoad (unsigned int size, unsigned char mem, ADDR_T *address)
void BlockRead (unsigned int size, unsigned char mem, ADDR_T *address)
C_TASK void main (void)


Define Documentation

#define ADDR_T   unsigned long

Definition at line 52 of file main.c.

Referenced by BlockLoad(), and main().

#define BLOCKSIZE   PAGESIZE

Definition at line 62 of file main.c.

Referenced by BlockLoad(), and main().

#define C_TASK

Definition at line 69 of file main.c.


Function Documentation

unsigned char BlockLoad ( unsigned int  size,
unsigned char  mem,
ADDR_T *  address 
)

Definition at line 353 of file main.c.

References ADDR_T, BLOCKSIZE, EEPROM_BYTE_ADDRESS_MASK, EEPROM_BYTES_IN_PAGE, EEPROM_DisableMapping, EEPROM_FlushBuffer(), EEPROM_WriteByte(), recchar(), SP_LoadFlashWord(), SP_WaitForSPM(), and SP_WriteApplicationPage().

Referenced by main().

00354 {   
00355     unsigned int data;    
00356     ADDR_T tempaddress;
00357                 
00358     // EEPROM memory type.
00359     if(mem=='E')
00360     {
00361         unsigned char pageAddr, byteAddr, value;
00362         unsigned char buffer[BLOCKSIZE];
00363     
00364         EEPROM_FlushBuffer();
00365         // disable mapping of EEPROM into data space (enable IO mapped access)
00366         EEPROM_DisableMapping();
00367 
00368         // Fill buffer first, as EEPROM is too slow to copy with UART speed 
00369         for(tempaddress=0;tempaddress<size;tempaddress++){
00370             buffer[tempaddress] = recchar();
00371         }
00372         
00373       // Then program the EEPROM 
00374         for( tempaddress=0; tempaddress < size; tempaddress++)
00375         {
00376             // void EEPROM_WriteByte( uint8_t pageAddr, uint8_t byteAddr, uint8_t value )
00377             pageAddr = (unsigned char)( (*address) / EEPROM_BYTES_IN_PAGE);
00378             byteAddr = (unsigned char)( (*address) & EEPROM_BYTE_ADDRESS_MASK);
00379             value = buffer[tempaddress];
00380             
00381             EEPROM_WriteByte(pageAddr, byteAddr, value);
00382             
00383             (*address)++; // Select next EEPROM byte
00384         }
00385 
00386         return '\r'; // Report programming OK
00387     } 
00388     
00389     // Flash memory type
00390         else if(mem=='F')
00391     { // NOTE: For flash programming, 'address' is given in words.
00392         (*address) <<= 1; // Convert address to bytes temporarily.
00393         tempaddress = (*address);  // Store address in page.
00394         
00395         do
00396                 {
00397             data = recchar();
00398             data |= (recchar() << 8);
00399 #ifdef __ICCAVR__
00400 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00401 #endif
00402             SP_LoadFlashWord(*address, data);
00403 #ifdef __ICCAVR__
00404 #pragma diag_default=Pe1053 // Back to default.
00405 #endif
00406             (*address)+=2; // Select next word in memory.            
00407             size -= 2; // Reduce number of bytes to write by two.
00408         } while(size); // Loop until all bytes written.
00409 
00410 #ifdef __ICCAVR__
00411 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00412 #endif
00413         SP_WriteApplicationPage(tempaddress);
00414                 
00415 #ifdef __ICCAVR__
00416 #pragma diag_default=Pe1053 // Back to default.
00417 #endif        
00418 //      _WAIT_FOR_SPM();
00419         SP_WaitForSPM();
00420         (*address) >>= 1; // Convert address back to Flash words again.
00421         return '\r'; // Report programming OK
00422     }
00423     
00424     // Invalid memory type?
00425     else
00426     {
00427         return '?';
00428     }
00429 }

void BlockRead ( unsigned int  size,
unsigned char  mem,
ADDR_T *  address 
)

Definition at line 433 of file main.c.

References EEPROM_BYTE_ADDRESS_MASK, EEPROM_BYTES_IN_PAGE, EEPROM_DisableMapping, EEPROM_FlushBuffer(), EEPROM_ReadByte(), sendchar(), and SP_ReadByte().

Referenced by main().

00434 {
00435     // EEPROM memory type.
00436         
00437     if (mem=='E') // Read EEPROM
00438     {
00439         unsigned char byteAddr, pageAddr;
00440         
00441         EEPROM_DisableMapping();
00442         EEPROM_FlushBuffer();
00443 
00444         do
00445         {
00446             pageAddr = (unsigned char)(*address / EEPROM_BYTES_IN_PAGE);
00447             byteAddr = (unsigned char)(*address & EEPROM_BYTE_ADDRESS_MASK);
00448             
00449             sendchar( EEPROM_ReadByte( pageAddr, byteAddr ) );
00450              // Select next EEPROM byte
00451             (*address)++;            
00452             size--; // Decrease number of bytes to read
00453         } while (size); // Repeat until all block has been read
00454     }
00455     
00456     // Flash memory type.
00457         else if(mem=='F')
00458         {
00459         (*address) <<= 1; // Convert address to bytes temporarily.
00460         
00461         do
00462         {
00463 #ifdef __ICCAVR__
00464 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00465 #endif
00466           sendchar( SP_ReadByte( *address) );
00467           sendchar( SP_ReadByte( (*address)+1) );
00468 #ifdef __ICCAVR__
00469 #pragma diag_default=Pe1053     // Back to default.
00470 #endif
00471             (*address) += 2;    // Select next word in memory.
00472             size -= 2;          // Subtract two bytes from number of bytes to read
00473         } while (size);         // Repeat until all block has been read
00474 
00475         (*address) >>= 1;       // Convert address back to Flash words again.
00476     }
00477 }

C_TASK void main ( void   ) 

Definition at line 72 of file main.c.

References ADDR_T, APP_END, BlockLoad(), BlockRead(), BLOCKSIZE, EEPROM_BYTE_ADDRESS_MASK, EEPROM_BYTES_IN_PAGE, EEPROM_DisableMapping, EEPROM_EraseAll(), EEPROM_FlushBuffer(), EEPROM_LoadPage(), EEPROM_ReadByte(), EEPROM_WriteByte(), initbootuart(), PAGESIZE, PARTCODE, PROG_NO, PROGPIN, PROGPORT, recchar(), sendchar(), SIGNATURE_BYTE_1, SIGNATURE_BYTE_2, SIGNATURE_BYTE_3, SP_EraseApplicationPage(), SP_LoadFlashWord(), SP_LockSPM(), SP_ReadByte(), SP_ReadFuseByte(), SP_ReadLockBits(), SP_WaitForSPM(), SP_WriteApplicationPage(), and SP_WriteLockBits().

00073 {
00074         ADDR_T address = 0;
00075         //uint8_t address;
00076     unsigned int temp_int;
00077         unsigned char val;
00078     /* Initialization */    
00079     void (*funcptr)( void ) = 0x0000; // Set up function pointer to RESET vector.
00080   
00081     EEPROM_FlushBuffer();
00082         EEPROM_DisableMapping();
00083 
00084     PROGPORT |= (1<<PROG_NO); // Enable pull-up on PROG_NO line on PROGPORT.
00085     initbootuart(); // Initialize UART.
00086                 
00087         /* Branch to bootloader or application code? */
00088     if( !(PROGPIN & (1<<PROG_NO)) ) // If PROGPIN is pulled low, enter programmingmode.
00089     {
00090             /* Main loop */
00091         for(;;)
00092         {
00093             val = recchar(); // Wait for command character.
00094             // Check autoincrement status.
00095             if(val=='a')
00096             {
00097                 sendchar('Y'); // Yes, we do autoincrement.
00098             }
00099             // Set address.
00100             else if(val == 'A') // Set address...
00101             { // NOTE: Flash addresses are given in words, not bytes.                                            
00102                 address = (recchar() << 8) | recchar(); // Read address high and low byte.
00103                 sendchar('\r'); // Send OK back.
00104             }
00105             // Chip erase.
00106             else if(val=='e')
00107             {
00108                 for(address = 0; address < APP_END; address += PAGESIZE)
00109                 { // NOTE: Here we use address as a byte-address, not word-address, for convenience.
00110                     SP_WaitForSPM();
00111 #ifdef __ICCAVR__
00112 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00113 #endif
00114                             SP_EraseApplicationPage( address );
00115 #ifdef __ICCAVR__
00116 #pragma diag_default=Pe1053 // Back to default.
00117 #endif
00118                 }
00119                 
00120                 // Writing random values to the page buffer
00121                 EEPROM_LoadPage(&val);
00122                 // Erasing all pages in the EEPROM
00123                 EEPROM_EraseAll();
00124                 
00125                 sendchar('\r'); // Send OK back.
00126             }
00127             
00128 #ifndef REMOVE_BLOCK_SUPPORT
00129             // Check block load support.
00130             else if(val=='b')
00131                     {
00132                         sendchar('Y'); // Report block load supported.
00133                         sendchar((BLOCKSIZE>>8) & 0xFF); // MSB first.
00134                         sendchar(BLOCKSIZE&0xFF); // Report BLOCKSIZE (bytes).
00135                 }
00136 
00137             // Start block load.
00138                 else if(val=='B')
00139                 {
00140                     temp_int = (recchar()<<8) | recchar(); // Get block size.
00141                     val = recchar(); // Get memtype.
00142                         sendchar( BlockLoad(temp_int, val, &address) ); // Block load.                          
00143                     }       
00144                     // Start block read.
00145                 else if(val=='g')
00146                 {
00147                     temp_int = (recchar()<<8) | recchar(); // Get block size.
00148                     val = recchar(); // Get memtype
00149                         BlockRead(temp_int, val, &address); // Block read
00150                 }               
00151 #endif /* REMOVE_BLOCK_SUPPORT */
00152 
00153 #ifndef REMOVE_FLASH_BYTE_SUPPORT            
00154             // Read program memory.
00155                     else if(val=='R')
00156             {        
00157                 // Send high byte, then low byte of flash word.
00158                         SP_WaitForSPM();
00159 #ifdef __ICCAVR__
00160 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00161 #endif
00162                 sendchar( SP_ReadByte( (address << 1)+1) );
00163                 sendchar( SP_ReadByte( (address << 1)+0) );
00164 #ifdef __ICCAVR__
00165 #pragma diag_default=Pe1053 // Back to default.
00166 #endif
00167                 address++; // Auto-advance to next Flash word.
00168             }
00169         
00170 
00171             // Write program memory, low byte.        
00172             else if(val=='c')
00173             { // NOTE: Always use this command before sending high byte.
00174                 temp_int=recchar(); // Get low byte for later SP_LoadFlashWord
00175                 sendchar('\r'); // Send OK back.
00176             }
00177 
00178             // Write program memory, high byte.
00179             else if(val=='C')
00180             {
00181                 temp_int |= (recchar()<<8); // Get and insert high byte.
00182                         SP_WaitForSPM();
00183 #ifdef __ICCAVR__
00184 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00185 #endif
00186                 SP_LoadFlashWord( (address << 1), temp_int );
00187 #ifdef __ICCAVR__
00188 #pragma diag_default=Pe1053 // Back to default.
00189 #endif
00190                 address++; // Auto-advance to next Flash word.
00191                 sendchar('\r'); // Send OK back.
00192             }
00193         
00194         
00195             // Write page.       
00196             else if(val== 'm')
00197             {
00198                 if( address >= (APP_END>>1) ) // Protect bootloader area.                   
00199                 {
00200                     sendchar('?');
00201                 } 
00202                 else
00203                 {
00204                             SP_WaitForSPM();
00205 #ifdef __ICCAVR__
00206 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00207 #endif
00208                     // Convert word-address to byte-address and write.
00209                     SP_WriteApplicationPage( address << 1);
00210 #ifdef __ICCAVR__
00211 #pragma diag_default=Pe1053 // Back to default.
00212 #endif
00213                  
00214                     sendchar('\r'); // Send OK back.
00215                 }
00216 #endif // REMOVE_FLASH_BYTE_SUPPORT
00217 
00218 #ifndef REMOVE_EEPROM_BYTE_SUPPORT
00219             }
00220             // Write EEPROM memory.
00221             else if (val == 'D')
00222             {
00223                 EEPROM_WriteByte( (unsigned char)(address / EEPROM_BYTES_IN_PAGE) , (unsigned char)(address & EEPROM_BYTE_ADDRESS_MASK), recchar() );
00224                 // Select next EEPROM byte
00225                 address++;
00226             }
00227 
00228              // Read EEPROM memory.
00229             else if (val == 'd')
00230             {
00231                   
00232                 sendchar( EEPROM_ReadByte( (unsigned char)(address / EEPROM_BYTES_IN_PAGE), (unsigned char)(address & EEPROM_BYTE_ADDRESS_MASK) ) );
00233                 // Select next EEPROM byte
00234                 address++;
00235              }
00236                         
00237 #endif /* REMOVE_EEPROM_BYTE_SUPPORT */
00238 
00239 #ifndef REMOVE_FUSE_AND_LOCK_BIT_SUPPORT
00240             // Write lockbits.
00241             else if(val=='l')
00242             {
00243                 // Wait for NVM to finish.              
00244                 SP_WaitForSPM();
00245                 // Read and set lock bits.
00246                 SP_WriteLockBits( recchar() );
00247                 sendchar('\r'); // Send OK back.
00248             }
00249 #if defined(_GET_LOCK_BITS)
00250             // Read lock bits.
00251             else if(val=='r')
00252             {                
00253                 SP_WaitForSPM();        
00254                 sendchar( SP_ReadLockBits() );
00255             }
00256             // Read low fuse bits.
00257             else if(val=='F')
00258             {
00259                 SP_WaitForSPM();
00260                 sendchar(SP_ReadFuseByte(0));
00261             }
00262             // Read high fuse bits
00263             else if(val=='N')
00264             {
00265                 SP_WaitForSPM();
00266                 sendchar(SP_ReadFuseByte(1));
00267             }
00268             // Read extended fuse bits.
00269             else if(val=='Q')
00270             {
00271                 SP_WaitForSPM();      
00272                 sendchar(SP_ReadFuseByte(2));
00273             }
00274 #endif /* defined(_GET_LOCK_BITS) */
00275 #endif /* REMOVE_FUSE_AND_LOCK_BIT_SUPPORT */
00276 
00277 #ifndef REMOVE_AVRPROG_SUPPORT        
00278             // Enter and leave programming mode.
00279             else if((val=='P')||(val=='L'))
00280             {
00281                 sendchar('\r'); // Nothing special to do, just answer OK.
00282             }
00283             // Exit bootloader.
00284             else if(val=='E')
00285             {
00286                 SP_WaitForSPM();
00287                // SP_LockSPM();
00288                 sendchar('\r');
00289                 funcptr(); // Jump to Reset vector 0x0000 in Application Section.
00290             }
00291                  // Get programmer type.        
00292             else if (val=='p')
00293             {
00294                 sendchar('S'); // Answer 'SERIAL'.
00295             }
00296             // Return supported device codes.
00297             else if(val=='t')
00298             {
00299 #if PARTCODE+0 > 0
00300                  sendchar( PARTCODE ); // Supports only this device, of course.
00301 #endif /* PARTCODE */
00302                  sendchar( 0 ); // Send list terminator.
00303             }
00304             // Set LED, clear LED and set device type.
00305             else if((val=='x')||(val=='y')||(val=='T'))
00306             {
00307                 recchar(); // Ignore the command and it's parameter.
00308                 sendchar('\r'); // Send OK back.
00309             }
00310 #endif /* REMOVE_AVRPROG_SUPPORT */
00311             // Return programmer identifier.
00312             else if(val=='S')
00313             {
00314                 sendchar('A'); // Return 'AVRBOOT'.
00315                 sendchar('V'); // Software identifier (aka programmer signature) is always 7 characters.
00316                 sendchar('R');
00317                 sendchar('B');
00318                 sendchar('O');
00319                 sendchar('O');
00320                 sendchar('T');
00321             }
00322             // Return software version.
00323             else if(val=='V')
00324             {
00325                 sendchar('1');
00326                 sendchar('6');
00327             }        
00328             // Return signature bytes.
00329             else if(val=='s')
00330             {                                                   
00331                 sendchar( SIGNATURE_BYTE_3 );
00332                 sendchar( SIGNATURE_BYTE_2 );
00333                 sendchar( SIGNATURE_BYTE_1 );
00334             }       
00335                  // The last command to accept is ESC (synchronization).
00336             else if(val!=0x1b) // If not ESC, then it is unrecognized...
00337             {
00338                sendchar('?');
00339             }
00340         } // end: for(;;)
00341     }
00342     else
00343     {
00344         SP_WaitForSPM();
00345         SP_LockSPM();
00346         funcptr(); // Jump to Reset vector 0x0000 in Application Section.
00347     }
00348 } // end: main

@DOC_TITLE@
Generated on Fri Mar 27 14:05:26 2009 for AVR1605: XMEGA BOOTLOADER by doxygen 1.5.8