'===============================================================================
' Узнаём причину сброса МК, Должно находиться именно здесь
'===============================================================================
'стр.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 = 0Dim 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 = Udr0If Temp_udr_usart_0 = 123 Then
Gosub Apply_bootloader
End If
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Apply_bootloader:
'-------------------------------------------------------------------------------
Config Watchdog = 16
Reset Watchdog
Start WatchdogWait 1
'-------------------------------------------------------------------------------
Return
'==============================================================================='===============================================================================
Причина_сброса_atmega328p:
'-------------------------------------------------------------------------------
' Print "&B_";
' Print Bin(причина_сброса_мк)If Причина_сброса_мк.3 = 1 Or Причина_сброса_мк = 0 Then
' Print "Reset от Watchdog"
Причина_сброса_мк.7 = 1
Mcusr.3 = 0
End IfIf Причина_сброса_мк.2 = 1 Then
' Print "Reset от снижения питания"
Причина_сброса_мк.2 = 0
Mcusr.2 = 0
End IfIf Причина_сброса_мк.1 = 1 Then
' Print "Reset от кнопки"
Причина_сброса_мк.1 = 0
Mcusr.1 = 0
End IfIf Причина_сброса_мк.0 = 1 Then
' Print "Reset от подачи питания"
Причина_сброса_мк.0 = 0
Mcusr.0 = 0
End If
'-------------------------------------------------------------------------------
Return
'===============================================================================
'----------------------------------------------------------------
' (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 = 0Const 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 valueDim 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 pagesDisable 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 200000Bretries = 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 "
#endifPrint 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
'NextIf Bkind = 0 Then
Spmcrval = 3 : Gosub Do_spm ' erase the first page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End IfBretries = 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
DoBstatus = 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 pagePage = Page + 1 'next page
Spmcrval = 3 : Gosub Do_spm ' erase next page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End If
NextElse '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 writeReturn
Do_spm:
Bitwait Spmcsr.0 , Reset ' check for previous SPM complete
Bitwait Eecr.1 , Reset 'wait for eepromZ = 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
#endifSpmcsr = 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.
'----------------------------------------------------------------
' (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 = 0Const 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 valueDim 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 pagesDisable 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 200000Bretries = 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 "
#endifPrint 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
'NextIf Bkind = 0 Then
Spmcrval = 3 : Gosub Do_spm ' erase the first page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End IfBretries = 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
DoBstatus = 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 pagePage = Page + 1 'next page
Spmcrval = 3 : Gosub Do_spm ' erase next page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End If
NextElse '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 writeReturn
Do_spm:
Bitwait Spmcsr.0 , Reset ' check for previous SPM complete
Bitwait Eecr.1 , Reset 'wait for eepromZ = 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
#endifSpmcsr = 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.
'----------------------------------------------------------------
' (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 = 0Const 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 valueDim 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 pagesDisable 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 200000Bretries = 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 "
#endifPrint 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
'NextIf Bkind = 0 Then
Spmcrval = 3 : Gosub Do_spm ' erase the first page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End IfBretries = 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
DoBstatus = 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 pagePage = Page + 1 'next page
Spmcrval = 3 : Gosub Do_spm ' erase next page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End If
NextElse '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 writeReturn
Do_spm:
Bitwait Spmcsr.0 , Reset ' check for previous SPM complete
Bitwait Eecr.1 , Reset 'wait for eepromZ = 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
#endifSpmcsr = 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.
'----------------------------------------------------------------
' (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 = 0Const 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 valueDim 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 pagesDisable 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 200000Bretries = 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 "
#endifPrint 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
'NextIf Bkind = 0 Then
Spmcrval = 3 : Gosub Do_spm ' erase the first page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End IfBretries = 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
DoBstatus = 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 pagePage = Page + 1 'next page
Spmcrval = 3 : Gosub Do_spm ' erase next page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End If
NextElse '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 writeReturn
Do_spm:
Bitwait Spmcsr.0 , Reset ' check for previous SPM complete
Bitwait Eecr.1 , Reset 'wait for eepromZ = 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
#endifSpmcsr = 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.
$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 = 0Const 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 valueDim 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 pagesDisable 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 200000Bretries = 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 "
#endifPrint 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 IfFor 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 = 0For J = 1 To 3 'this is a simple indication that we start the normal reset vector
Toggle Portb.2 : Waitms 50
NextIf Bkind = 0 Then
Spmcrval = 3 : Gosub Do_spm ' erase the first page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End IfBretries = 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
DoBstatus = 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 readyPortb.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 pagePage = Page + 1 'next page
Spmcrval = 3 : Gosub Do_spm ' erase next page
Spmcrval = 17 : Gosub Do_spm ' re-enable page
End If
NextElse '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
ReturnDo_spm:
Bitwait Spmcsr.0 , Reset ' check for previous SPM complete
Bitwait Eecr.1 , Reset 'wait for eepromZ = 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
#endifSpmcsr = Spmcrval 'assign register
spm 'this is an asm instruction
nop
nop
Return







