Xmega Application Note | |||||
#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 ADDR_T unsigned long |
#define BLOCKSIZE PAGESIZE |
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
Generated on Fri Mar 27 14:05:26 2009 for AVR1605: XMEGA BOOTLOADER by ![]() |