Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



Исследование BootLoadera

Сообщений 1 страница 8 из 8

1

Программный  Авто_Reset для BootLoadera

'===============================================================================
'           Узнаём причину сброса МК, Должно находиться именно здесь
'===============================================================================
  'стр.54 документации на МК
  '                  +------ Bit 1 – EXTRF: External Reset Flag
  '                  |+----- Bit 0 – PORF: Power-on Reset Flag
  '                  ||
  'MCUSR = &B_0000_0000   –  MCU Status Register
  '                ||
  '                |+------- Bit 2 – BORF: Brown-out Reset Flag
  '                +-------- Bit 3 – WDRF: Watchdog System Reset Flag
  Dim Причина_сброса_мк As Byte
  !sts {Причина_сброса_мк} , R0       'В регистр R0 Bascom забирает значение регистра MCUSR – MCU Status Register

'===============================================================================

  $regfile = "m328pdef.dat"
  $crystal = 8000000
  $framesize = 64
  $hwstack = 64
  $swstack = 64

'Скорость должна соответствовать скорости в BootLoader
  Config Com1 = 38400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

  Dim Temp_udr_usart_0 As Byte

  On Urxc Interrupts_urxc

  Gosub Причина_сброса_atmega328p


'===============================================================================
          '  Разрешаем работу необходимых прерываний
'===============================================================================
  Enable Urxc
'===============================================================================
          ' Разрешаем работу всех включенных прерываний
'===============================================================================
  Enable Interrupts
'===============================================================================
          ' Предварительная проверка и запуск
'===============================================================================

'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Main:
'===============================================================================

      !nop

'===============================================================================
  Goto Main
End
'
'===============================================================================

'===============================================================================
  Interrupts_urxc:
'-------------------------------------------------------------------------------
    Temp_udr_usart_0 = Udr0

    If Temp_udr_usart_0 = 123 Then
        Gosub Apply_bootloader
     End If
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'===============================================================================
  Apply_bootloader:
'-------------------------------------------------------------------------------
    Config Watchdog = 16
    Reset Watchdog
    Start Watchdog

    Wait 1
'-------------------------------------------------------------------------------
  Return
'===============================================================================


'===============================================================================
  Причина_сброса_atmega328p:
'-------------------------------------------------------------------------------
'    Print "&B_";
'    Print Bin(причина_сброса_мк)

      If Причина_сброса_мк.3 = 1 Or Причина_сброса_мк = 0 Then
'          Print "Reset от Watchdog"
          Причина_сброса_мк.7 = 1
          Mcusr.3 = 0
      End If

      If Причина_сброса_мк.2 = 1 Then
'          Print "Reset от снижения питания"
          Причина_сброса_мк.2 = 0
          Mcusr.2 = 0
      End If

      If Причина_сброса_мк.1 = 1 Then
'          Print "Reset от кнопки"
          Причина_сброса_мк.1 = 0
          Mcusr.1 = 0
      End If

      If Причина_сброса_мк.0 = 1 Then
'          Print "Reset от подачи питания"
          Причина_сброса_мк.0 = 0
          Mcusr.0 = 0
      End If
'-------------------------------------------------------------------------------
  Return
'===============================================================================

BootLoader Atmega328P 8МГц 38400 отключен PORTB

'----------------------------------------------------------------
'                          (c) 1995-2009, MCS
'                        Bootloader.bas
'  This sample demonstrates how you can write your own bootloader
'  in BASCOM BASIC
'  VERSION 2 of the BOOTLOADER. The waiting for the NAK is stretched
'  further a bug was resolved for the M64/M128 that have a big page size
'-----------------------------------------------------------------

  $crystal = 8000000
'  $crystal = 7372800
'  $crystal = 14745600

  $regfile = "m328pdef.dat"

  $baud = 38400

  Config Com1 = Baud , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
  'Ucsr0a.1 = 1       ' Двойная скорость работы USART, скорость трансляции = $baud * 2

  $loader = $3c00       ' 1024 words
  Const Maxwordbit = 6       'Z6 is maximum bit                                   '
  Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Const Maxword =(2 ^ Maxwordbit) * 2       '128
Const Maxwordshift = Maxwordbit + 1
Const Cdebug = 0       ' leave this to 0

'Dim the used variables
Dim Bstatus As Byte , Bretries As Byte , Bblock As Byte , Bblocklocal As Byte
Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte
Dim J As Byte , Spmcrval As Byte       ' self program command byte value

Dim Z As Long       'this is the Z pointer word
Dim Vl As Byte , Vh As Byte       ' these bytes are used for the data values
Dim Wrd As Word , Page As Word       'these vars contain the page and word address
Dim Bkind As Byte , Bstarted As Byte
'Mega 88 : 32 words, 128 pages

Disable Interrupts       'we do not use ints

'Waitms 100                                                  'wait 100 msec sec
'We start with receiving a file. The PC must send this binary file

'some constants used in serial com
Const Nak = &H15
Const Ack = &H06
Const Can = &H18

'we use some leds as indication in this sample , you might want to remove it
'Config Pinb.2 = Output
'Portb.2 = 1       'the stk200 has inverted logic for the leds
'Config Pinb.3 = Output
'Portb.3 = 1

$timeout = 400000       'we use a timeout
'When you get LOADER errors during the upload, increase the timeout value
'for example at 16 Mhz, use 200000

Bretries = 5       'we try 5 times
Testfor123:
#if Cdebug
    Print "Try " ; Bretries
    Print "Wait"
#endif
Bstatus = Waitkey()       'wait for the loader to send a byte
#if Cdebug
   Print "Got "
#endif

Print Chr(bstatus);

If Bstatus = 123 Then       'did we received value 123 ?
   Bkind = 0       'normal flash loader
   Goto Loader
Elseif Bstatus = 124 Then       ' EEPROM
   Bkind = 1       ' EEPROM loader
   Goto Loader
Elseif Bstatus <> 0 Then
   Decr Bretries
   If Bretries <> 0 Then Goto Testfor123       'we test again
End If

'For J = 1 To 2       'this is a simple indication that we start the normal reset vector
'   Toggle Portb.2 :
    Waitms 50
'Next

#if Cdebug
  Print "RESET"
#endif
Goto _reset       'goto the normal reset vector at address 0

'this is the loader routine. It is a Xmodem-checksum reception routine
Loader:
  #if Cdebug
      Print "Clear buffer"
  #endif
  Do
     Bstatus = Waitkey()
  Loop Until Bstatus = 0

  'For J = 1 To 3       'this is a simple indication that we start the normal reset vector
     'Toggle Portb.2 :
     Waitms 50
  'Next

  If Bkind = 0 Then
     Spmcrval = 3 : Gosub Do_spm       ' erase  the first page
     Spmcrval = 17 : Gosub Do_spm       ' re-enable page
  End If

Bretries = 10       'number of retries

Do
  Bstarted = 0       ' we were not started yet
  Csum = 0       'checksum is 0 when we start
  Print Chr(nak);       ' firt time send a nack
  Do

    Bstatus = Waitkey()       'wait for statuse byte

    Select Case Bstatus
       Case 1:       ' start of heading, PC is ready to send
            Incr Bblocklocal       'increase local block count
            Csum = 1       'checksum is 1
            Bblock = Waitkey() : Csum = Csum + Bblock       'get block
            Bcsum1 = Waitkey() : Csum = Csum + Bcsum1       'get checksum first byte
            For J = 1 To 128       'get 128 bytes
              Buf(j) = Waitkey() : Csum = Csum + Buf(j)
            Next
            Bcsum2 = Waitkey()       'get second checksum byte
            If Bblocklocal = Bblock Then       'are the blocks the same?
               If Bcsum2 = Csum Then       'is the checksum the same?
                  Gosub Writepage       'yes go write the page
                  Print Chr(ack);       'acknowledge
               Else       'no match so send nak
                  Print Chr(nak);
               End If
            Else
               Print Chr(nak);       'blocks do not match
            End If
       Case 4:       ' end of transmission , file is transmitted
             If Wrd > 0 And Bkind = 0 Then       'if there was something left in the page
                 Wrd = 0       'Z pointer needs wrd to be 0
                 Spmcrval = 5 : Gosub Do_spm       'write page
                 Spmcrval = 17 : Gosub Do_spm       ' re-enable page
             End If
            '  Waitms 100                                   ' OPTIONAL REMARK THIS IF THE DTR SIGNAL ARRIVES TO EARLY
             Print Chr(ack);       ' send ack and ready

             'Portb.3 = 0       ' simple indication that we are finished and ok
             Waitms 20
             Goto _reset       ' start new program
       Case &H18:       ' PC aborts transmission
             Goto _reset       ' ready
       Case 123 : Exit Do       'was probably still in the buffer
       Case 124 : Exit Do
       Case Else
          Exit Do       ' no valid data
    End Select
  Loop
  If Bretries > 0 Then       'attempte left?
     Waitms 1000
     Decr Bretries       'decrease attempts
  Else
     Goto _reset       'reset chip
  End If
Loop

'write one or more pages
Writepage:
If Bkind = 0 Then
   For J = 1 To 128 Step 2       'we write 2 bytes into a page
      Vl = Buf(j) : Vh = Buf(j + 1)       'get Low and High bytes
      !lds r0, {vl}       'store them into r0 and r1 registers
      !lds r1, {vh}
      Spmcrval = 1 : Gosub Do_spm       'write value into page at word address
      Wrd = Wrd + 2       ' word address increases with 2 because LS bit of Z is not used
      If Wrd = Maxword Then       ' page is full
          Wrd = 0       'Z pointer needs wrd to be 0
          Spmcrval = 5 : Gosub Do_spm       'write page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page

          Page = Page + 1       'next page
          Spmcrval = 3 : Gosub Do_spm       ' erase  next page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page
      End If
   Next

Else       'eeprom
     For J = 1 To 128
       Writeeeprom Buf(j) , Wrd
       Wrd = Wrd + 1
     Next
End If

'Toggle Portb.2 :
Waitms 10
': Toggle Portb.2       'indication that we write

Return

Do_spm:
  Bitwait Spmcsr.0 , Reset       ' check for previous SPM complete
  Bitwait Eecr.1 , Reset       'wait for eeprom

  Z = Page       'make equal to page
  Shift Z , Left , Maxwordshift       'shift to proper place
  Z = Z + Wrd       'add word
  !lds r30,{Z}
  !lds r31,{Z+1}

  #if _romsize > 65536
      !lds r24,{Z+2}
      !sts rampz,r24       ' we need to set rampz also for the M128
  #endif

  Spmcsr = Spmcrval       'assign register
  !spm       'this is an asm instruction
  nop
  nop
Return

'How you need to use this program:
'1- compile this program
'2- program into chip with sample elctronics programmer
'3- select MCS Bootloader from programmers
'4- compile a new program for example M88.bas
'5- press F4 and reset your micro
' the program will now be uploaded into the chip with Xmodem Checksum
' you can write your own loader.too
'A stand alone command line loader is also available

'How to call the bootloader from your program without a reset ???
'Do
'   Print "test"
'   Waitms 1000
'   If Inkey() = 27 Then
'      Print "boot"
'      Goto &H1C00
'   End If
'Loop

'The GOTO will do the work, you need to specify the correct bootloader address
'this is the same as the $LOADER statement.

BootLoader Atbanned284P 8МГц 38400 отключен PORTB

'----------------------------------------------------------------
'                          (c) 1995-2009, MCS
'                        Bootloader.bas
'  This sample demonstrates how you can write your own bootloader
'  in BASCOM BASIC
'  VERSION 2 of the BOOTLOADER. The waiting for the NAK is stretched
'  further a bug was resolved for the M64/M128 that have a big page size
'-----------------------------------------------------------------

  $crystal = 8000000
'  $crystal = 7372800
'  $crystal = 14745600

$regfile = "m1284pdef.dat"

  $baud = 38400

  Config Com1 = Baud , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
'Ucsr0a.1 = 1       ' Двойная скорость работы USART, скорость трансляции = $baud * 2

  $loader = &HFC00       ' 1024 words
  Const Maxwordbit = 7       'Z6 is maximum bit                                   '
  Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Const Maxword =(2 ^ Maxwordbit) * 2       '128
Const Maxwordshift = Maxwordbit + 1
Const Cdebug = 0       ' leave this to 0

'Dim the used variables
Dim Bstatus As Byte , Bretries As Byte , Bblock As Byte , Bblocklocal As Byte
Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte
Dim J As Byte , Spmcrval As Byte       ' self program command byte value

Dim Z As Long       'this is the Z pointer word
Dim Vl As Byte , Vh As Byte       ' these bytes are used for the data values
Dim Wrd As Word , Page As Word       'these vars contain the page and word address
Dim Bkind As Byte , Bstarted As Byte
'Mega 88 : 32 words, 128 pages

Disable Interrupts       'we do not use ints

'Waitms 100                                                  'wait 100 msec sec
'We start with receiving a file. The PC must send this binary file

'some constants used in serial com
Const Nak = &H15
Const Ack = &H06
Const Can = &H18

'we use some leds as indication in this sample , you might want to remove it
'Config Pinb.2 = Output
'Portb.2 = 1       'the stk200 has inverted logic for the leds
'Config Pinb.3 = Output
'Portb.3 = 1

$timeout = 400000       'we use a timeout
'When you get LOADER errors during the upload, increase the timeout value
'for example at 16 Mhz, use 200000

Bretries = 5       'we try 5 times
Testfor123:
#if Cdebug
    Print "Try " ; Bretries
    Print "Wait"
#endif
Bstatus = Waitkey()       'wait for the loader to send a byte
#if Cdebug
   Print "Got "
#endif

Print Chr(bstatus);

If Bstatus = 123 Then       'did we received value 123 ?
   Bkind = 0       'normal flash loader
   Goto Loader
Elseif Bstatus = 124 Then       ' EEPROM
   Bkind = 1       ' EEPROM loader
   Goto Loader
Elseif Bstatus <> 0 Then
   Decr Bretries
   If Bretries <> 0 Then Goto Testfor123       'we test again
End If

'For J = 1 To 2       'this is a simple indication that we start the normal reset vector
'   Toggle Portb.2 :
    Waitms 50
'Next

#if Cdebug
  Print "RESET"
#endif
Goto _reset       'goto the normal reset vector at address 0

'this is the loader routine. It is a Xmodem-checksum reception routine
Loader:
  #if Cdebug
      Print "Clear buffer"
  #endif
  Do
     Bstatus = Waitkey()
  Loop Until Bstatus = 0

  'For J = 1 To 3       'this is a simple indication that we start the normal reset vector
     'Toggle Portb.2 :
     Waitms 50
  'Next

  If Bkind = 0 Then
     Spmcrval = 3 : Gosub Do_spm       ' erase  the first page
     Spmcrval = 17 : Gosub Do_spm       ' re-enable page
  End If

Bretries = 10       'number of retries

Do
  Bstarted = 0       ' we were not started yet
  Csum = 0       'checksum is 0 when we start
  Print Chr(nak);       ' firt time send a nack
  Do

    Bstatus = Waitkey()       'wait for statuse byte

    Select Case Bstatus
       Case 1:       ' start of heading, PC is ready to send
            Incr Bblocklocal       'increase local block count
            Csum = 1       'checksum is 1
            Bblock = Waitkey() : Csum = Csum + Bblock       'get block
            Bcsum1 = Waitkey() : Csum = Csum + Bcsum1       'get checksum first byte
            For J = 1 To 128       'get 128 bytes
              Buf(j) = Waitkey() : Csum = Csum + Buf(j)
            Next
            Bcsum2 = Waitkey()       'get second checksum byte
            If Bblocklocal = Bblock Then       'are the blocks the same?
               If Bcsum2 = Csum Then       'is the checksum the same?
                  Gosub Writepage       'yes go write the page
                  Print Chr(ack);       'acknowledge
               Else       'no match so send nak
                  Print Chr(nak);
               End If
            Else
               Print Chr(nak);       'blocks do not match
            End If
       Case 4:       ' end of transmission , file is transmitted
             If Wrd > 0 And Bkind = 0 Then       'if there was something left in the page
                 Wrd = 0       'Z pointer needs wrd to be 0
                 Spmcrval = 5 : Gosub Do_spm       'write page
                 Spmcrval = 17 : Gosub Do_spm       ' re-enable page
             End If
            '  Waitms 100                                   ' OPTIONAL REMARK THIS IF THE DTR SIGNAL ARRIVES TO EARLY
             Print Chr(ack);       ' send ack and ready

             'Portb.3 = 0       ' simple indication that we are finished and ok
             Waitms 20
             Goto _reset       ' start new program
       Case &H18:       ' PC aborts transmission
             Goto _reset       ' ready
       Case 123 : Exit Do       'was probably still in the buffer
       Case 124 : Exit Do
       Case Else
          Exit Do       ' no valid data
    End Select
  Loop
  If Bretries > 0 Then       'attempte left?
     Waitms 1000
     Decr Bretries       'decrease attempts
  Else
     Goto _reset       'reset chip
  End If
Loop

'write one or more pages
Writepage:
If Bkind = 0 Then
   For J = 1 To 128 Step 2       'we write 2 bytes into a page
      Vl = Buf(j) : Vh = Buf(j + 1)       'get Low and High bytes
      !lds r0, {vl}       'store them into r0 and r1 registers
      !lds r1, {vh}
      Spmcrval = 1 : Gosub Do_spm       'write value into page at word address
      Wrd = Wrd + 2       ' word address increases with 2 because LS bit of Z is not used
      If Wrd = Maxword Then       ' page is full
          Wrd = 0       'Z pointer needs wrd to be 0
          Spmcrval = 5 : Gosub Do_spm       'write page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page

          Page = Page + 1       'next page
          Spmcrval = 3 : Gosub Do_spm       ' erase  next page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page
      End If
   Next

Else       'eeprom
     For J = 1 To 128
       Writeeeprom Buf(j) , Wrd
       Wrd = Wrd + 1
     Next
End If

'Toggle Portb.2 :
Waitms 10
': Toggle Portb.2       'indication that we write

Return

Do_spm:
  Bitwait Spmcsr.0 , Reset       ' check for previous SPM complete
  Bitwait Eecr.1 , Reset       'wait for eeprom

  Z = Page       'make equal to page
  Shift Z , Left , Maxwordshift       'shift to proper place
  Z = Z + Wrd       'add word
  !lds r30,{Z}
  !lds r31,{Z+1}

  #if _romsize > 65536
      !lds r24,{Z+2}
      !sts rampz,r24       ' we need to set rampz also for the M128
  #endif

  Spmcsr = Spmcrval       'assign register
  !spm       'this is an asm instruction
  nop
  nop
Return

'How you need to use this program:
'1- compile this program
'2- program into chip with sample elctronics programmer
'3- select MCS Bootloader from programmers
'4- compile a new program for example M88.bas
'5- press F4 and reset your micro
' the program will now be uploaded into the chip with Xmodem Checksum
' you can write your own loader.too
'A stand alone command line loader is also available

'How to call the bootloader from your program without a reset ???
'Do
'   Print "test"
'   Waitms 1000
'   If Inkey() = 27 Then
'      Print "boot"
'      Goto &H1C00
'   End If
'Loop

'The GOTO will do the work, you need to specify the correct bootloader address
'this is the same as the $LOADER statement.

BootLoader Atbanned284P 16МГц 115200 отключен PORTB

'----------------------------------------------------------------
'                          (c) 1995-2009, MCS
'                        Bootloader.bas
'  This sample demonstrates how you can write your own bootloader
'  in BASCOM BASIC
'  VERSION 2 of the BOOTLOADER. The waiting for the NAK is stretched
'  further a bug was resolved for the M64/M128 that have a big page size
'-----------------------------------------------------------------

  $crystal = 16000000
'  $crystal = 7372800
'  $crystal = 14745600

  $regfile = "m1284pdef.dat"

  $baud = 115200

  Config Com1 = Baud , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
'Ucsr0a.1 = 1       ' Двойная скорость работы USART, скорость трансляции = $baud * 2

  $loader = &HFC00       ' 1024 words
  Const Maxwordbit = 7       'Z6 is maximum bit                                   '
  Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Const Maxword =(2 ^ Maxwordbit) * 2       '128
Const Maxwordshift = Maxwordbit + 1
Const Cdebug = 0       ' leave this to 0

'Dim the used variables
Dim Bstatus As Byte , Bretries As Byte , Bblock As Byte , Bblocklocal As Byte
Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte
Dim J As Byte , Spmcrval As Byte       ' self program command byte value

Dim Z As Long       'this is the Z pointer word
Dim Vl As Byte , Vh As Byte       ' these bytes are used for the data values
Dim Wrd As Word , Page As Word       'these vars contain the page and word address
Dim Bkind As Byte , Bstarted As Byte
'Mega 88 : 32 words, 128 pages

Disable Interrupts       'we do not use ints

'Waitms 100                                                  'wait 100 msec sec
'We start with receiving a file. The PC must send this binary file

'some constants used in serial com
Const Nak = &H15
Const Ack = &H06
Const Can = &H18

'we use some leds as indication in this sample , you might want to remove it
'Config Pinb.2 = Output
'Portb.2 = 1       'the stk200 has inverted logic for the leds
'Config Pinb.3 = Output
'Portb.3 = 1

$timeout = 400000       'we use a timeout
'When you get LOADER errors during the upload, increase the timeout value
'for example at 16 Mhz, use 200000

Bretries = 5       'we try 5 times
Testfor123:
#if Cdebug
    Print "Try " ; Bretries
    Print "Wait"
#endif
Bstatus = Waitkey()       'wait for the loader to send a byte
#if Cdebug
   Print "Got "
#endif

Print Chr(bstatus);

If Bstatus = 123 Then       'did we received value 123 ?
   Bkind = 0       'normal flash loader
   Goto Loader
Elseif Bstatus = 124 Then       ' EEPROM
   Bkind = 1       ' EEPROM loader
   Goto Loader
Elseif Bstatus <> 0 Then
   Decr Bretries
   If Bretries <> 0 Then Goto Testfor123       'we test again
End If

'For J = 1 To 2       'this is a simple indication that we start the normal reset vector
'   Toggle Portb.2 :
    Waitms 50
'Next

#if Cdebug
  Print "RESET"
#endif
Goto _reset       'goto the normal reset vector at address 0

'this is the loader routine. It is a Xmodem-checksum reception routine
Loader:
  #if Cdebug
      Print "Clear buffer"
  #endif
  Do
     Bstatus = Waitkey()
  Loop Until Bstatus = 0

  'For J = 1 To 3       'this is a simple indication that we start the normal reset vector
     'Toggle Portb.2 :
     Waitms 50
  'Next

  If Bkind = 0 Then
     Spmcrval = 3 : Gosub Do_spm       ' erase  the first page
     Spmcrval = 17 : Gosub Do_spm       ' re-enable page
  End If

Bretries = 10       'number of retries

Do
  Bstarted = 0       ' we were not started yet
  Csum = 0       'checksum is 0 when we start
  Print Chr(nak);       ' firt time send a nack
  Do

    Bstatus = Waitkey()       'wait for statuse byte

    Select Case Bstatus
       Case 1:       ' start of heading, PC is ready to send
            Incr Bblocklocal       'increase local block count
            Csum = 1       'checksum is 1
            Bblock = Waitkey() : Csum = Csum + Bblock       'get block
            Bcsum1 = Waitkey() : Csum = Csum + Bcsum1       'get checksum first byte
            For J = 1 To 128       'get 128 bytes
              Buf(j) = Waitkey() : Csum = Csum + Buf(j)
            Next
            Bcsum2 = Waitkey()       'get second checksum byte
            If Bblocklocal = Bblock Then       'are the blocks the same?
               If Bcsum2 = Csum Then       'is the checksum the same?
                  Gosub Writepage       'yes go write the page
                  Print Chr(ack);       'acknowledge
               Else       'no match so send nak
                  Print Chr(nak);
               End If
            Else
               Print Chr(nak);       'blocks do not match
            End If
       Case 4:       ' end of transmission , file is transmitted
             If Wrd > 0 And Bkind = 0 Then       'if there was something left in the page
                 Wrd = 0       'Z pointer needs wrd to be 0
                 Spmcrval = 5 : Gosub Do_spm       'write page
                 Spmcrval = 17 : Gosub Do_spm       ' re-enable page
             End If
            '  Waitms 100                                   ' OPTIONAL REMARK THIS IF THE DTR SIGNAL ARRIVES TO EARLY
             Print Chr(ack);       ' send ack and ready

             'Portb.3 = 0       ' simple indication that we are finished and ok
             Waitms 20
             Goto _reset       ' start new program
       Case &H18:       ' PC aborts transmission
             Goto _reset       ' ready
       Case 123 : Exit Do       'was probably still in the buffer
       Case 124 : Exit Do
       Case Else
          Exit Do       ' no valid data
    End Select
  Loop
  If Bretries > 0 Then       'attempte left?
     Waitms 1000
     Decr Bretries       'decrease attempts
  Else
     Goto _reset       'reset chip
  End If
Loop

'write one or more pages
Writepage:
If Bkind = 0 Then
   For J = 1 To 128 Step 2       'we write 2 bytes into a page
      Vl = Buf(j) : Vh = Buf(j + 1)       'get Low and High bytes
      !lds r0, {vl}       'store them into r0 and r1 registers
      !lds r1, {vh}
      Spmcrval = 1 : Gosub Do_spm       'write value into page at word address
      Wrd = Wrd + 2       ' word address increases with 2 because LS bit of Z is not used
      If Wrd = Maxword Then       ' page is full
          Wrd = 0       'Z pointer needs wrd to be 0
          Spmcrval = 5 : Gosub Do_spm       'write page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page

          Page = Page + 1       'next page
          Spmcrval = 3 : Gosub Do_spm       ' erase  next page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page
      End If
   Next

Else       'eeprom
     For J = 1 To 128
       Writeeeprom Buf(j) , Wrd
       Wrd = Wrd + 1
     Next
End If

'Toggle Portb.2 :
Waitms 10
': Toggle Portb.2       'indication that we write

Return

Do_spm:
  Bitwait Spmcsr.0 , Reset       ' check for previous SPM complete
  Bitwait Eecr.1 , Reset       'wait for eeprom

  Z = Page       'make equal to page
  Shift Z , Left , Maxwordshift       'shift to proper place
  Z = Z + Wrd       'add word
  !lds r30,{Z}
  !lds r31,{Z+1}

  #if _romsize > 65536
      !lds r24,{Z+2}
      !sts rampz,r24       ' we need to set rampz also for the M128
  #endif

  Spmcsr = Spmcrval       'assign register
  !spm       'this is an asm instruction
  nop
  nop
Return

'How you need to use this program:
'1- compile this program
'2- program into chip with sample elctronics programmer
'3- select MCS Bootloader from programmers
'4- compile a new program for example M88.bas
'5- press F4 and reset your micro
' the program will now be uploaded into the chip with Xmodem Checksum
' you can write your own loader.too
'A stand alone command line loader is also available

'How to call the bootloader from your program without a reset ???
'Do
'   Print "test"
'   Waitms 1000
'   If Inkey() = 27 Then
'      Print "boot"
'      Goto &H1C00
'   End If
'Loop

'The GOTO will do the work, you need to specify the correct bootloader address
'this is the same as the $LOADER statement.

BootLoader Atmega2561 8МГц 38400 отключен PORTB

'----------------------------------------------------------------
'                          (c) 1995-2009, MCS
'                        Bootloader.bas
'  This sample demonstrates how you can write your own bootloader
'  in BASCOM BASIC
'  VERSION 2 of the BOOTLOADER. The waiting for the NAK is stretched
'  further a bug was resolved for the M64/M128 that have a big page size
'-----------------------------------------------------------------

  $crystal = 8000000
'  $crystal = 7372800
'  $crystal = 14745600

  $regfile = "m2561def.dat"

  $baud = 38400

$loader = &H1FC00       ' Размер 1024 байт
Const Maxwordbit = 7       'Z7 is maximum bit                                   '
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Const Maxword =(2 ^ Maxwordbit) * 2       '128
Const Maxwordshift = Maxwordbit + 1
Const Cdebug = 0       ' leave this to 0

'Dim the used variables
Dim Bstatus As Byte , Bretries As Byte , Bblock As Byte , Bblocklocal As Byte
Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte
Dim J As Byte , Spmcrval As Byte       ' self program command byte value

Dim Z As Long       'this is the Z pointer word
Dim Vl As Byte , Vh As Byte       ' these bytes are used for the data values
Dim Wrd As Word , Page As Word       'these vars contain the page and word address
Dim Bkind As Byte , Bstarted As Byte
'Mega 88 : 32 words, 128 pages

Disable Interrupts       'we do not use ints

'Waitms 100                                                  'wait 100 msec sec
'We start with receiving a file. The PC must send this binary file

'some constants used in serial com
Const Nak = &H15
Const Ack = &H06
Const Can = &H18

'we use some leds as indication in this sample , you might want to remove it
'Config Pinb.2 = Output
'Portb.2 = 1       'the stk200 has inverted logic for the leds
'Config Pinb.3 = Output
'Portb.3 = 1

$timeout = 400000       'we use a timeout
'When you get LOADER errors during the upload, increase the timeout value
'for example at 16 Mhz, use 200000

Bretries = 5       'we try 5 times
Testfor123:
#if Cdebug
    Print "Try " ; Bretries
    Print "Wait"
#endif
Bstatus = Waitkey()       'wait for the loader to send a byte
#if Cdebug
   Print "Got "
#endif

Print Chr(bstatus);

If Bstatus = 123 Then       'did we received value 123 ?
   Bkind = 0       'normal flash loader
   Goto Loader
Elseif Bstatus = 124 Then       ' EEPROM
   Bkind = 1       ' EEPROM loader
   Goto Loader
Elseif Bstatus <> 0 Then
   Decr Bretries
   If Bretries <> 0 Then Goto Testfor123       'we test again
End If

'For J = 1 To 2       'this is a simple indication that we start the normal reset vector
'   Toggle Portb.2 :
    Waitms 50
'Next

#if Cdebug
  Print "RESET"
#endif
Goto _reset       'goto the normal reset vector at address 0

'this is the loader routine. It is a Xmodem-checksum reception routine
Loader:
  #if Cdebug
      Print "Clear buffer"
  #endif
  Do
     Bstatus = Waitkey()
  Loop Until Bstatus = 0

  'For J = 1 To 3       'this is a simple indication that we start the normal reset vector
     'Toggle Portb.2 :
     Waitms 50
  'Next

  If Bkind = 0 Then
     Spmcrval = 3 : Gosub Do_spm       ' erase  the first page
     Spmcrval = 17 : Gosub Do_spm       ' re-enable page
  End If

Bretries = 10       'number of retries

Do
  Bstarted = 0       ' we were not started yet
  Csum = 0       'checksum is 0 when we start
  Print Chr(nak);       ' firt time send a nack
  Do

    Bstatus = Waitkey()       'wait for statuse byte

    Select Case Bstatus
       Case 1:       ' start of heading, PC is ready to send
            Incr Bblocklocal       'increase local block count
            Csum = 1       'checksum is 1
            Bblock = Waitkey() : Csum = Csum + Bblock       'get block
            Bcsum1 = Waitkey() : Csum = Csum + Bcsum1       'get checksum first byte
            For J = 1 To 128       'get 128 bytes
              Buf(j) = Waitkey() : Csum = Csum + Buf(j)
            Next
            Bcsum2 = Waitkey()       'get second checksum byte
            If Bblocklocal = Bblock Then       'are the blocks the same?
               If Bcsum2 = Csum Then       'is the checksum the same?
                  Gosub Writepage       'yes go write the page
                  Print Chr(ack);       'acknowledge
               Else       'no match so send nak
                  Print Chr(nak);
               End If
            Else
               Print Chr(nak);       'blocks do not match
            End If
       Case 4:       ' end of transmission , file is transmitted
             If Wrd > 0 And Bkind = 0 Then       'if there was something left in the page
                 Wrd = 0       'Z pointer needs wrd to be 0
                 Spmcrval = 5 : Gosub Do_spm       'write page
                 Spmcrval = 17 : Gosub Do_spm       ' re-enable page
             End If
            '  Waitms 100                                   ' OPTIONAL REMARK THIS IF THE DTR SIGNAL ARRIVES TO EARLY
             Print Chr(ack);       ' send ack and ready

             'Portb.3 = 0       ' simple indication that we are finished and ok
             Waitms 20
             Goto _reset       ' start new program
       Case &H18:       ' PC aborts transmission
             Goto _reset       ' ready
       Case 123 : Exit Do       'was probably still in the buffer
       Case 124 : Exit Do
       Case Else
          Exit Do       ' no valid data
    End Select
  Loop
  If Bretries > 0 Then       'attempte left?
     Waitms 1000
     Decr Bretries       'decrease attempts
  Else
     Goto _reset       'reset chip
  End If
Loop

'write one or more pages
Writepage:
If Bkind = 0 Then
   For J = 1 To 128 Step 2       'we write 2 bytes into a page
      Vl = Buf(j) : Vh = Buf(j + 1)       'get Low and High bytes
      !lds r0, {vl}       'store them into r0 and r1 registers
      !lds r1, {vh}
      Spmcrval = 1 : Gosub Do_spm       'write value into page at word address
      Wrd = Wrd + 2       ' word address increases with 2 because LS bit of Z is not used
      If Wrd = Maxword Then       ' page is full
          Wrd = 0       'Z pointer needs wrd to be 0
          Spmcrval = 5 : Gosub Do_spm       'write page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page

          Page = Page + 1       'next page
          Spmcrval = 3 : Gosub Do_spm       ' erase  next page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page
      End If
   Next

Else       'eeprom
     For J = 1 To 128
       Writeeeprom Buf(j) , Wrd
       Wrd = Wrd + 1
     Next
End If

'Toggle Portb.2 :
Waitms 10
': Toggle Portb.2       'indication that we write

Return

Do_spm:
  Bitwait Spmcsr.0 , Reset       ' check for previous SPM complete
  Bitwait Eecr.1 , Reset       'wait for eeprom

  Z = Page       'make equal to page
  Shift Z , Left , Maxwordshift       'shift to proper place
  Z = Z + Wrd       'add word
  !lds r30,{Z}
  !lds r31,{Z+1}

  #if _romsize > 65536
      !lds r24,{Z+2}
      !sts rampz,r24       ' we need to set rampz also for the M128
  #endif

  Spmcsr = Spmcrval       'assign register
  !spm       'this is an asm instruction
  nop
  nop
Return

'How you need to use this program:
'1- compile this program
'2- program into chip with sample elctronics programmer
'3- select MCS Bootloader from programmers
'4- compile a new program for example M88.bas
'5- press F4 and reset your micro
' the program will now be uploaded into the chip with Xmodem Checksum
' you can write your own loader.too
'A stand alone command line loader is also available

'How to call the bootloader from your program without a reset ???
'Do
'   Print "test"
'   Waitms 1000
'   If Inkey() = 27 Then
'      Print "boot"
'      Goto &H1C00
'   End If
'Loop

'The GOTO will do the work, you need to specify the correct bootloader address
'this is the same as the $LOADER statement.

BootLoader Atmega2560 16 МГц 500000

$crystal = 16000000
'$crystal = 14745600
$baud = 500000       ' 38400       ' Частота трансляции USART

$regfile = "m2560def.dat"

$loader = &H1FC00       ' Размер 1024 байт
Const Maxwordbit = 7       'Z7 is maximum bit                                   '
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

Const Maxword =(2 ^ Maxwordbit) * 2       '128
Const Maxwordshift = Maxwordbit + 1
Const Cdebug = 0       ' leave this to 0

#if Cdebug
   Print Maxword
   Print Maxwordshift
#endif

'Dim the used variables
Dim Bstatus As Byte , Bretries As Byte , Bblock As Byte , Bblocklocal As Byte
Dim Bcsum1 As Byte , Bcsum2 As Byte , Buf(128) As Byte , Csum As Byte
Dim J As Byte , Spmcrval As Byte       ' self program command byte value

Dim Z As Long       'this is the Z pointer word
Dim Vl As Byte , Vh As Byte       ' these bytes are used for the data values
Dim Wrd As Word , Page As Word       'these vars contain the page and word address
Dim Bkind As Byte , Bstarted As Byte
'Mega 88 : 32 words, 128 pages

Disable Interrupts       'we do not use ints

'Waitms 100                                                  'wait 100 msec sec
'We start with receiving a file. The PC must send this binary file

'some constants used in serial com
Const Nak = &H15
Const Ack = &H06
Const Can = &H18

'we use some leds as indication in this sample , you might want to remove it
Config Pinb.2 = Output
Portb.2 = 1       'the stk200 has inverted logic for the leds
Config Pinb.3 = Output
Portb.3 = 1

$timeout = 400000       'we use a timeout
'When you get LOADER errors during the upload, increase the timeout value
'for example at 16 Mhz, use 200000

Bretries = 5       'we try 5 times
Testfor123:
#if Cdebug
    Print "Try " ; Bretries
    Print "Wait"
#endif
Bstatus = Waitkey()       'wait for the loader to send a byte
#if Cdebug
   Print "Got "
#endif

Print Chr(bstatus);

If Bstatus = 123 Then       'did we received value 123 ?
   Bkind = 0       'normal flash loader
   Goto Loader
Elseif Bstatus = 124 Then       ' EEPROM
   Bkind = 1       ' EEPROM loader
   Goto Loader
Elseif Bstatus <> 0 Then
   Decr Bretries
   If Bretries <> 0 Then Goto Testfor123       'we test again
End If

For J = 1 To 10       'this is a simple indication that we start the normal reset vector
   Toggle Portb.2 : Waitms 100
Next

#if Cdebug
  Print "RESET"
#endif
Goto _reset       'goto the normal reset vector at address 0

'this is the loader routine. It is a Xmodem-checksum reception routine
Loader:
  #if Cdebug
      Print "Clear buffer"
  #endif
  Do
     Bstatus = Waitkey()
  Loop Until Bstatus = 0

  For J = 1 To 3       'this is a simple indication that we start the normal reset vector
     Toggle Portb.2 : Waitms 50
  Next

  If Bkind = 0 Then
     Spmcrval = 3 : Gosub Do_spm       ' erase  the first page
     Spmcrval = 17 : Gosub Do_spm       ' re-enable page
  End If

Bretries = 10       'number of retries

Do
  Bstarted = 0       ' we were not started yet
  Csum = 0       'checksum is 0 when we start
  Print Chr(nak);       ' firt time send a nack
  Do

    Bstatus = Waitkey()       'wait for statuse byte

    Select Case Bstatus
       Case 1:       ' start of heading, PC is ready to send
            Incr Bblocklocal       'increase local block count
            Csum = 1       'checksum is 1
            Bblock = Waitkey() : Csum = Csum + Bblock       'get block
            Bcsum1 = Waitkey() : Csum = Csum + Bcsum1       'get checksum first byte
            For J = 1 To 128       'get 128 bytes
              Buf(j) = Waitkey() : Csum = Csum + Buf(j)
            Next
            Bcsum2 = Waitkey()       'get second checksum byte
            If Bblocklocal = Bblock Then       'are the blocks the same?
               If Bcsum2 = Csum Then       'is the checksum the same?
                  Gosub Writepage       'yes go write the page
                  Print Chr(ack);       'acknowledge
               Else       'no match so send nak
                  Print Chr(nak);
               End If
            Else
               Print Chr(nak);       'blocks do not match
            End If
       Case 4:       ' end of transmission , file is transmitted
             If Wrd > 0 And Bkind = 0 Then       'if there was something left in the page
                 Wrd = 0       'Z pointer needs wrd to be 0
                 Spmcrval = 5 : Gosub Do_spm       'write page
                 Spmcrval = 17 : Gosub Do_spm       ' re-enable page
             End If
            '  Waitms 100                                   ' OPTIONAL REMARK THIS IF THE DTR SIGNAL ARRIVES TO EARLY
             Print Chr(ack);       ' send ack and ready

             Portb.3 = 0       ' simple indication that we are finished and ok
             Waitms 20
             Goto _reset       ' start new program
       Case &H18:       ' PC aborts transmission
             Goto _reset       ' ready
       Case 123 : Exit Do       'was probably still in the buffer
       Case 124 : Exit Do
       Case Else
          Exit Do       ' no valid data
    End Select
  Loop
  If Bretries > 0 Then       'attempte left?
     Waitms 1000
     Decr Bretries       'decrease attempts
  Else
     Goto _reset       'reset chip
  End If
Loop

'write one or more pages
Writepage:
If Bkind = 0 Then
   For J = 1 To 128 Step 2       'we write 2 bytes into a page
      Vl = Buf(j) : Vh = Buf(j + 1)       'get Low and High bytes
      lds r0, {vl}       'store them into r0 and r1 registers
      lds r1, {vh}
      Spmcrval = 1 : Gosub Do_spm       'write value into page at word address
      Wrd = Wrd + 2       ' word address increases with 2 because LS bit of Z is not used
      If Wrd = Maxword Then       ' page is full
          Wrd = 0       'Z pointer needs wrd to be 0
          Spmcrval = 5 : Gosub Do_spm       'write page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page

          Page = Page + 1       'next page
          Spmcrval = 3 : Gosub Do_spm       ' erase  next page
          Spmcrval = 17 : Gosub Do_spm       ' re-enable page
      End If
   Next

Else       'eeprom
     For J = 1 To 128
       Writeeeprom Buf(j) , Wrd
       Wrd = Wrd + 1
     Next
End If
Toggle Portb.2 : Waitms 10 : Toggle Portb.2       'indication that we write
Return

Do_spm:
  Bitwait Spmcsr.0 , Reset       ' check for previous SPM complete
  Bitwait Eecr.1 , Reset       'wait for eeprom

  Z = Page       'make equal to page
  Shift Z , Left , Maxwordshift       'shift to proper place
  Z = Z + Wrd       'add word
  lds r30,{Z}
  lds r31,{Z+1}

  #if _romsize > 65536
      lds r24,{Z+2}
      sts rampz,r24       ' we need to set rampz also for the M128
  #endif

  Spmcsr = Spmcrval       'assign register
  spm       'this is an asm instruction
  nop
  nop
Return

+2

2

"Собаку" по прямому назначению использовать не получится.

0

3

Пётр написал(а):

"Собаку" по прямому назначению использовать не получится.

Аргументируйте ?

0

4

sasha_1973 написал(а):

Аргументируйте ?

sasha_1973 написал(а):

Apply_bootloader:
Config Watchdog = 16
Reset Watchdog
Start Watchdog
Wait 1
Return

В загрузчике наверняка проверяется произошла ли перезагрузка из-за собаки (это было бы логично) и это приводит к его активации. Если собака не сработала, сразу переход в основную прогу.
Это только предположение, т. к. кода загрузчика в первом сообщении нет.

0

5

Пётр написал(а):

В загрузчике наверняка проверяется произошла ли перезагрузка из-за собаки (это было бы логично) и это приводит к его активации. Если собака не сработала, сразу переход в основную прогу.
Это только предположение, т. к. кода загрузчика в первом сообщении нет.

В стандартном загрузчике Bascom проверки нет, проверено неоднократно, точнее, последнее 3 года только таким методом и пользуюсь, всё работает прекрасно.

0

6

Если ничего не получается, пробуем пошагово, как на картинках

Фьюзы для BootLoadera в картинках

http://s3.uploads.ru/t/WkfCo.jpg
http://s8.uploads.ru/t/HEh4w.jpg
http://sh.uploads.ru/t/nviVR.jpg
http://s9.uploads.ru/t/9ueX8.jpg
http://s7.uploads.ru/t/Qplam.jpg
http://s7.uploads.ru/t/Oycrt.jpg
http://s9.uploads.ru/t/3nN1Y.jpg
http://sh.uploads.ru/t/aSRFC.jpg

После манипуляций с фьюзами, заливаем BootLoader.

!  ВНИМАНИЕ  !

Частота МК и скорость usart в BootLoadere должны соответствовать исходнику.
Учитывайте размер исходника, может затереться BootLoader

BootLoader занимает последний килобайт в исходнике

!  ВНИМАНИЕ  !

0

7

Читаю ветку и возник такой вопрос. А зачем вообще такая морока с этим бутлоадером? Так ли он нужен?
Не проще ли взять программатор и прошить?
Единственное, что пришло на ум, так это дистанционное обновление программы МК.
Это не стёб, реально интересно.

0

8

sva-don написал(а):

Единственное, что пришло на ум, так это дистанционное обновление программы МК.

Вы сами ответили на свой вопрос.

0