Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

MCSbootloader and Tiny45/Tiny85

 
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here
View previous topic :: View next topic  
Author Message
EDC

Bascom Expert



Joined: 26 Mar 2014
Posts: 1136

poland.gif
PostPosted: Wed Jul 31, 2024 10:39 am    Post subject: MCSbootloader and Tiny45/Tiny85 Reply with quote

Hello.
Tiny85 family dont have dedicated bootloader area. They have a SELFPRGEN fusebit that only enable SPM instruction.

I was curious if one have enough ROM left that MCSbootloader can be used.
So I modify bootloader code. I remove eeprom handling and add software serial.

I burn that bootloader as a main application at &H00 address and enable SELFPRGEN FuseBit.
Then I made a "proper target" application with $loader = &H260 , Bootonly so I get binary that should even service jumps.
Address results from bootloader have ~1184B. Pages they have 64B so I must use 19 pages and app starts after that.
...and everything working like a charm I can flash that uC multiple times with MCSbootloader and FT232RL with DTR signal attached into Reset pin.


Code:
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 4
$framesize = 24

'$reduceivr
'$noramclear

Config Clockdiv = 1
$projecttime = 52

Open "COMB.0:38400,8,n,1" For Output As #1                  'TX-MOSI PIN5

Open "COMB.1:38400,8,n,1" For Input As #2                   'RX-MISO PIN6


Const Maxwordbit = 5                                        'Z5 is maximum bit

Const Maxword =(2 ^ Maxwordbit) * 2
Const Maxwordshift = Maxwordbit + 1

'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


'19pages x 64B=1216B |/2=608
Page = 19
Const _app = 608

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

$timeout = 1000000                                          'we use a timeout

Bretries = 5                                                'we try 5 times
Testfor123:

Bstatus = Waitkey(#2)                                       'wait for the loader to send a byte

Print #1 , Chr(bstatus);

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

Goto _app                                                   'goto the normal reset vector at address 0


'this is the loader routine. It is a Xmodem-checksum reception routine
Loader:
  Do
     Bstatus = Waitkey(#2)
  Loop Until Bstatus = 0

  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
  Bblocklocal = 1
  Bstarted = 0                                              ' we were not started yet
  Csum = 0                                                  'checksum is 0 when we start
  Print #1 , Chr(nak);                                      ' firt time send a nack
  Do

    Bstatus = Waitkey(#2)                                   'wait for statuse byte

    Select Case Bstatus
       Case 1:                                              ' start of heading, PC is ready to send
            Csum = 1                                        'checksum is 1
            Bblock = Waitkey(#2) : Csum = Csum + Bblock     'get block
            Bcsum1 = Waitkey(#2) : Csum = Csum + Bcsum1     'get checksum first byte
            For J = 1 To 128                                'get 128 bytes
              Buf(j) = Waitkey(#2) : Csum = Csum + Buf(j)
            Next
            Bcsum2 = Waitkey(#2)                            '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 #1 , Chr(ack);                      'acknowledge
                  Incr Bblocklocal                          'increase local block count
               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 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 #1 , Chr(ack);                           ' send ack and ready

             Waitms 20
             Goto _app                                      ' start new program
       Case &H18:                                           ' PC aborts transmission
             Goto _app                                      ' ready
       Case 123 : Exit Do                                   'was probably still in the buffer
       Case Else
          Exit Do                                           ' no valid data
    End Select
  Loop
  If Bretries > 0 Then                                      'attempte left?
     Waitms 1000
     Decr Bretries                                          'decrease attempts
  Else
     Goto _app                                              '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
 End If

Return


Do_spm:
  Bitwait Spmcsr.0 , Reset                                  ' check for previous SPM complete

  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}

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


Simple test code:

Code:
$regfile = "attiny85.dat"
$crystal = 8000000
$hwstack = 32
$swstack = 4
$framesize = 24

$loader = &H260 , Bootonly                                  'for proper addressing

Led Alias Portb.3 : Config Led = Output

Do
 Gosub Jump_sub
 Waitms 500
Loop

Jump_sub:
 Toggle Led
Return

_________________
Check B-Flash -my MCS bootloader app for Android (updated)
Back to top
View user's profile Visit poster's website
jaceklx

Bascom Member



Joined: 08 Oct 2022
Posts: 1

poland.gif
PostPosted: Sat Aug 03, 2024 9:55 am    Post subject: MCSbootloader and Tiny45/Tiny85 Reply with quote

Hi there,

Thank you for sharing this, of course it is because of my generosity Wink .

Everything works well but bootloader is hanging time to time due to below code :

Code:

Loader:
  Do
     Bstatus = Waitkey(#2)
  Loop Until Bstatus = 0
 


Since software uart is used there is no buffer and usually uart lines are already cleaned before we get there . Replacing "waitkey" with "inkey" fix it.

This my first post on the forum so i would like to thank you all for great community and the bascom language - simple and effective.

_________________
impossible is just a word
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    www.mcselec.com Forum Index -> Share your working BASCOM-AVR code here All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum