// ********************************************************************** 
// This application runs completely in the boot section of the AVR. 
// Some library functions and drivers are used and also interrupts 
// are running. If the FlashDownloader is started then also here 
// the standard interrupt driven UART/SerPort is used for communication. 
// Please note that the constant "BootCheckF" is placed to a fixed 
// address, but is outside of the boot area. A valid main application 
// residing in the "normal" code area $0000 and up must provide this 
// constant in order do an immediate jump to $0000 into the standard 
// application area. 
// The Main Application must be build and compiled separately and can 
// be downloaded with this Application/Bootloader 
// ********************************************************************** 

program BootAppMega16; 

{$NOSHADOW}
{ $WG}                     {global Warnings off} 

Device = mega168, VCC = 5; 
{$BOOTAPPLICATION $1c00}   // 8kByte Boot size 

define_fuses
  Override_Fuses; 
  NoteBook   = A; 
  COMport    = USB; 
  LockBits0  = []; 
  FuseBits0  = [CKSEL3, CKSEL2, CKSEL0, SUT0, CKDIV8]; 
  FuseBits1  = [BODLEVEL1, BODLEVEL0]; 
  FuseBits2  = [BOOTSZ1, BOOTSZ0, BOOTRST]; 
  ProgMode   = SPI; 
  
  ProgFuses  = true; 
  ProgLock   = true; 
  ProgFlash  = true; 
  ProgEEprom = true; 
//  AddApp     = 'c:\PROJEKTE\Pascal_sc\AVR\EvaBoard\AVR EvaBoardI'; 
               // Info for programmer, joining hexfiles, using this project name 
  
import SysTick, FlashWrite, SerPort; 

from System import Traps; 

define
  ProcClock      = 4000000;       {Hertz} 
  SysTick        = 10;             {msec} 
  StackSize      = $0030, iData; 
  FrameSize      = $0064, iData; 
  SerPort        = 19200, Stop2;    {Baud, StopBits|Parity} 
  RxBuffer       = 8, iData; 
  TxBuffer       = 8, iData; 
  
implementation

{$IDATA}

{--------------------------------------------------------------} 
{ Type Declarations } 

type
  
{--------------------------------------------------------------} 
{ Const Declarations } 
const
  BootCheckF[$37FE] : word = $AA55;          // in the standard app area 
//  BootCheckF[BootEntry -2] : word = $AA55;      // in the standard app area 
  DownLoaderID      : word = 1234; 
  DownLoaderPWD     : word = $ADBB; 
  
  cStr              : string = 'BootApp started'; 
  
{--------------------------------------------------------------} 
{ Var Declarations } 
{$IDATA}
var
  st      : string[10]; 
  
{--------------------------------------------------------------} 
{ functions } 



// Brücke BR1 mit BR2 für Flashloader 
procedure BootTest; 
begin
  portD:= %11110111; //BR1,BR2,BR3,BR4,pwrOn,resin,txo,rxi 
  ddrd:= %01001010;     // PD7 = input, PD6 = output 
  
  portD.6:= true; 
  if pinD.7 = pinD.6 then
    portD.6:= false; 
    if pinD.7 = pinD.6 then
      FlashDownLoader; 
    endif; 
  endif; 
end; 

procedure FlashLoaderInit; 
begin
  EnableInts;                // because the Downloader disabled it 
  FlushBuffer(RxBuffer); 
 // ... 
end; 

procedure FlashLoaderRecv; 
begin
  asm: Push    _ACCB
  asm: Push    _ACCALO
  asm: Push    _ACCCLO
  asm: Push    _ACCCHI
  _ACCA:= SerInp; 
  asm: Pop     _ACCCHI
  asm: Pop     _ACCCLO
  asm: Pop     _ACCALO
  asm: Pop     _ACCB
end; 

procedure FlashLoaderTransm; 
begin
  asm: Push    _ACCB
  asm: Push    _ACCALO
  asm: Push    _ACCCLO
  asm: Push    _ACCCHI
  Serout(_ACCA); 
  asm: Pop     _ACCCHI
  asm: Pop     _ACCCLO
  asm: Pop     _ACCALO
  asm: Pop     _ACCB
end; 

procedure FlashLoaderExit; 
begin
  Application_Startup;        // enter the main application 
end; 

// lösche BootFlag und Restart 
procedure StartFlashLoader; Trap; 
begin
  FlashInitPage(addr(BootCheckF)); 
  FlashErasePage; 
  System_Reset; 
end; 

{--------------------------------------------------------------} 
{ Main Program } 
{$IDATA}

begin
  // if the BootTest fails it enters the FlashDownloader 
  BootTest; 
  
  // if the BootTest was valid then normally this Boot Application 
  // should jump to the Main Application entry $0000 with this procedure: 
  Application_Startup;        // enter the main application 
  
  // This part is only for demonstration of the BootApp functuality 
  EnableInts; 
  Writeln(Serout, cStr); 
  loop
    if Serstat then 
      SerInp; 
    endif; 
  endloop; 
end BootAppMega16.

