unzeitig
Joined: 31 Jan 2008 Posts: 25
|
Posted: Fri Aug 09, 2019 5:31 pm Post subject: XMEGA MCS bootloader problem |
|
|
I would like use MCS bootloader for my ATXMEGA128A3U application.
Unfortunatelly I have strange problem with loading of my code. Time to time bootloader stops and it seems like some part of bootloader is rewritten - there is no way connect to bootloader again and a new programming of bootloader must be done. When I try my application without bootloader it works without any problem. If anybody can help me or offer your version it will be welcome.
[code]
'----------------------------------------------------------------
' BootloaderXmega128a3u.bas
' This sample demonstrates how you can write your own bootloader
' in BASCOM BASIC for the XMEGA
'-----------------------------------------------------------------
'The loader is supported from the IDE
$regfile = "xm128a3udef.dat"
Const Crystalfrekq = 32000000 '32MHz
$crystal = Crystalfrekq
$hwstack = 64
$swstack = 64
$framesize = 64
$lib "xmega.lib" : $external _xmegafix_clear : $external _xmegafix_rol_r1014
Config Osc = Disabled , 32mhzosc = Enabled , 32khzosc = Enabled
Config Sysclock = 32mhz , Prescalea = 1 , Prescalebc = 1_1 'CPU Clock = 32MHz
Bitwait Osc_status.1 , Set 'Check if 32MHz Oscillator is ready
Bitwait Osc_status.2 , Set 'Check if internal 32.768 KHz Oscillator is ready
Osc_dfllctrl.0 = 0
Dfllrc32m_ctrl.0 = 1 'enable
$loader = &H10000 ' bootloader starts after the application
Config Com3 = 115200 , Mode = Asynchroneous , Parity = None , Stopbits = 1 , Databits = 8
Open "com3:" For Binary As #1 'PORTC.1 - command
Const Maxwordbit = 7 ' Z7 is maximum bit '
Const Maxword =(2 ^ Maxwordbit) * 2 '128
Const Maxwordshift = Maxwordbit + 1
Const Cdebug = 0 ' leave this to 0
Config Portd.0 = Output
Ledcom Alias Portd.0
Ledcom = 1
'Dim the used variables
Dim Bstatus As Byte , Bretries As Byte , Bmincount 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
Disable Interrupts 'we do not use ints
'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
$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 : Bmincount = 3 'we try 10 times and want to get 123 at least 3 times
Do
Bstatus = Waitkey(#1) 'wait for the loader to send a byte
Toggle Ledcom
If Bstatus = 123 Then 'did we received value 123 ?
If Bmincount > 0 Then
Decr Bmincount
Else
Print #1 , Chr(bstatus);
Goto Loader ' yes so run bootloader
End If
Else 'we received some other data
If Bretries > 0 Then 'retries left?
Bmincount = 3
Decr Bretries
Else
Rampz = 0
Goto Proces_reset 'goto the normal reset vector at address 0
End If
End If
Loop
'this is the loader routine. It is a Xmodem-checksum reception routine
Loader:
Do
Bstatus = Waitkey(#1)
Loop Until Bstatus = 0
Spmcrval = &H20 : Gosub Do_spm ' erase all app pages
Bretries = 10 'number of retries
Do
Csum = 0 'checksum is 0 when we start
Print #1, Chr(nak); ' firt time send a nack
Do
Bstatus = Waitkey(#1) '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(#1) : Csum = Csum + Bblock 'get block
Bcsum1 = Waitkey(#1) : Csum = Csum + Bcsum1 'get checksum first byte
For J = 1 To 128 'get 128 bytes
Buf(j) = Waitkey(#1) : Csum = Csum + Buf(j)
Next
Bcsum2 = Waitkey(#1) 'get second checksum byte
If Bblocklocal = Bblock Then 'are the blocks the same?
If Bcsum2 = Csum Then 'is the checksum the same?
toggle Ledcom
Gosub Writepage 'yes go write the page
Print #1, Chr(ack); 'acknowledge
Else 'no match so send nak
Print #1 , Chr(nak);
End If
Else
Print #1 , Chr(nak); 'blocks do not match
End If
Case 4: ' end of transmission , file is transmitted
If Wrd > 0 Then 'if there was something left in the page
Wrd = 0 'Z pointer needs wrd to be 0
Spmcrval = &H24 : Gosub Do_spm 'write page
End If
Print #1 , Chr(ack); ' send ack and ready
Waitms 20
Goto Proces_reset
Case &H18: ' PC aborts transmission
Goto Proces_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 Proces_reset 'reset chip
End If
Loop
'write one or more pages
Writepage:
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 = &H23 : 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 = &H24 : Gosub Do_spm 'write page
Page = Page + 1 'next page
End If
Next
Return
Do_spm:
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
Nvm_cmd = Spmcrval
Cpu_ccp = &H9D
! spm 'this is an asm instruction
Do_spm_busy:
! lds r23, NVM_STATUS
! sbrc r23,7 ;if busy bit is cleared skip next instruc tion
! rjmp do_spm_busy
Return
Proces_reset:
Ledcom = 1
Rampz = 0
Goto _reset 'start at address 0
[/code]
[b][color=red](BASCOM-AVR version : 2.0.8.2 )[/b][/color] |
|