mitxela.com forum
Welcome. Please log in or register.

Kiloboot - Atmega1284P support
coolnicks Posted: 3 Nov 2018, 06:48 PM
Avatar


Member
Posts: 7
Joined: 3-November 18
Hi Tim,

I recently came across kiloboot while looking for a TFTP client boot loader, and found your project. I must say, I think its quite underrated! A very awesome, small and fast loader! Its now running on all my Atmega328p boards around the home, saving the hassle of flashing manually!

Which leads me on to my question - some of the boards I need to run it on are Atmega1284's. I've had a go at tweaking the code to get it working, but can't quite manage it, and wonder if you would be able to help:

On the Atmega1284:

-CS is PB4, MOSI is PB5, MISO is PB6 and SCK is PB7. So I've modified line 425 with the new pins (compared to PB3/4/5 on 328)
-The boot address for the 512 word section is FE00 (compared to 3E00 on 328), so I modified line 302 to 0xFD00
-It has 128kB of flash (compared to 32kB on 328), so I modified line 718 to ignore blocks above 254
-The page size is 128 words / 256 bytes (compared to 64 words / 128 bytes on 328) so I changed line 797 to 128
-I replaced the m328pdef.inc include with the m1284pdef.inc one

Then I got stuck! I think there might be checks/usage of the page size in other places, or interactions with the block size, but I'm not sure. I may have missed other things too!

Do you think you might be able to have a look? (And check my assumptions too!)

Regards

-------------
[top]
mit Posted: 3 Nov 2018, 07:23 PM
Avatar
yeah whatever

Admin
Posts: 566
Joined: 4-May 16
Hi, I'm glad you like it!

Sounds like you've made some good progress with porting it. What I would do is check each of the changes, one at a time. So with the new SPI pins, check that it is correctly talking to the chip. It might be possible to re-enable the ICMP echo section, and disable the bootloader part, so you can just ping it to see if the ethernet chip is working correctly.

Boot address sounds fine. I think the .inc files have a FLASHEND definition, so I probably should have made that line something like
.org (FLASHEND-512)

I haven't checked that but it should probably work for different chips then.

Again with the block numbers it might be possible to define that based on the .inc definitions which would make it more portable.

Writing to the different sized pages will need a bit of changing. The TFTP block size is fixed to 512 bytes, and so on the m328p there are four pages per TFTP block. If the pages are now 256 bytes, we need to call the SPM routine only twice. It might be enough to change the line
rcall SPMfourpages
to
rcall SPMtwopages

You will also need to change how many bytes are written, there's a simple ldi r18, 64 in there, but also it looks like I'm subtracting and adding to the Z pointer. If we need to subtract/add 256 bytes instead of 128, that's easy, we can just subtract and add 1 to the high byte. So it would be subi ZH, 1 followed by subi ZH, -1 after the page write.

There might be other things. When developing I changed the line jmp 0 to be a "hang" so that it just stops, and then I could use the ISP adapter to read out the flash memory and see if it worked correctly.

Good luck, let me know how you get on. I don't have a mega1284 to hand but I might be able to take a closer look at some point next week.

-------------
[top]
coolnicks Posted: 3 Nov 2018, 10:43 PM
Avatar


Member
Posts: 7
Joined: 3-November 18
Many thanks Tim for the speedy reply!

So, I tried those, and it still wasn't working, did some more reading, and it looks like I was led down the wrong path on the flash page sizes, there was a typo in the datasheet originally (https://www.avrfreaks.net/comment/1353651#comment-1353651) and it is actually 64 words / 128 bytes (should have just read the datasheet)! Also the chip include has it as ".equ PAGESIZE = 128" but it must be in words (atmega328 is in bytes!)

When I leave the start address as ".org 0x3e00", the boot loader requests the file over and over again from the TFTP, when I set the start address to ".org 0xfe00", nothing happens.

Although I'm sure the address is correct as its defined as "FIRSTBOOTSTART" and "SMALLBOOTSTART" in the include: ".equ FIRSTBOOTSTART = 0xfe00". Pretty cool (never looked at these files before, so didn't know that was there)

I'm wondering if its anything to do with separate commands for the extended address space? Although as far as I can see, it might only apply to SRAM ("For the Extended I/O space from $060 - $FF in SRAM, only the ST/STS/STD and LD/LDS/LDD instructions can be used.")

Need to get serial connected and see what's going on, although not really sure what I'm looking for!

(There is also example code in the datasheet for programming from a boot loader (Section 24.8.13 Simple Assembly Code Example for a Boot Loader))

Regards

-------------
[top]
coolnicks Posted: 3 Nov 2018, 11:38 PM
Avatar


Member
Posts: 7
Joined: 3-November 18
Trying to work out what the baud rate is set to (UBRR0H = 0, UBRR0L = 3). I'm running at 16Mhz. Could you confirm?

-------------
[top]
coolnicks Posted: 4 Nov 2018, 12:05 AM
Avatar


Member
Posts: 7
Joined: 3-November 18
Talking out loud sorry (lots of learning going on here!).

Changed "ldi r16,3" for UBRR0L to "ldi r16,8" to get 115200 baud.

The data I get is:

XXT FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 FF FF FF FF 00 XT FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 FF FF FF FF 00 XT FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 FF FF FF FF 00 XXT FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 FF FF FF FF 00 XT FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 FF FF FF FF 00 


and it loops there

-------------
[top]
mit Posted: 4 Nov 2018, 01:56 AM
Avatar
yeah whatever

Admin
Posts: 566
Joined: 4-May 16
Ah, yes, sorry. I forgot about that. 64K is the size of a 16-bit address space, so parts with more than 64K of flash memory have the RAMPZ register to extend the Z pointer addressing. That UART message is saying it tried to transmit a packet of nearly all 0xFF, because it loaded the data from the wrong part of memory. That also explains why it worked when the start address was at 0x3e00.

It's going to take some thinking to get it to work with the full 128kB. If your program is small enough to fit under 63kB, you could just put the bootloader at the end of the first half of memory. So I suppose that would be .org 0x7e00 and then put a jump to there from the actual boot vector.

If you need the full 128Kb... you will need to use the RAMPZ register and the ELPM instruction. I would have to look through the code to list everywhere this is going to affect, basically every LPM instruction will need to be an ELPM, and RAMPZ will have to be set to 1 for when it's loading the settings and packet prototypes, but during the checking and writing of pages RAMPZ will need to be set correctly. The Z pointer is calculated based on the block number, so RAMPZ needs to be set there. We might also need to check that none of the adding or subtracting to the Z pointer is going to cause RAMPZ to need updating.

-------------
[top]
coolnicks Posted: 4 Nov 2018, 11:07 AM
Avatar


Member
Posts: 7
Joined: 3-November 18
Thanks Tim,

The code is currently < 63kB, so I tried putting the boot loader at 0x7c00 and a jump to that at 0xfc00.

It runs the boot loader, but requests the file from the TFTP server in a loop again. Tried what you suggested and put back the hang under handleWatchdog, which does stop the loop. So after it downloaded the file once, I dumped the flash, but its empty apart from the boot loader. So looks like its failing to write for some reason?

I must be missing something still!

For the line "cpi ZH, 63 ; ignore block numbers above 62 = 31kB" can I just change the 63 to 255, to allow 254 blocks? Is 255 valid in ZH?

If you do get a chance to have a look at RAMPZ/ELPM that would be amazing!

Regards

-------------
[top]
mit Posted: 4 Nov 2018, 01:53 PM
Avatar
yeah whatever

Admin
Posts: 566
Joined: 4-May 16
Hmm, well the next step is probably to compare the example bootloader code from the datasheets of the mega328p and the mega1284 and see if there are any obvious differences.

Actually it might be to do with the RWW/NRWW hardware restrictions, it's possible that SPM can only be called from the NRWW section, I'm not sure. You could try moving the SPM code to the end, and making the rcall into just a call.

-------------
[top]
coolnicks Posted: 4 Nov 2018, 05:20 PM
Avatar


Member
Posts: 7
Joined: 3-November 18
Good idea, just compared the two pieces of example code, and they are exactly the same, but it did make me notice their comment at the top: "the routine must be placed inside the Boot space (at least the Do_spm sub routine). Only code inside NRWW section can be read during Self-Programming (Page Erase and Page Write)."

So I think you are exactly right! You know your stuff!

So I moved "doSPM" label code into its own ".org 0xfC10" and changed "rcall doSPM" to "call doSPM", unfortunately the TFTP transfer doesn't complete now, and it still tries over again. No flash written either.

Unfortunately I'm at the edge of my knowledge here, so don't understand why its failing! :)

-------------
[top]
mit Posted: 8 Nov 2018, 06:37 PM
Avatar
yeah whatever

Admin
Posts: 566
Joined: 4-May 16
Hi, sorry I'm pretty busy right now. Keep trying if you can! It will probably be a while before I can take a closer look at this and/or the ELPM/RAMPZ stuff.

You say the transfer doesn't complete - that could mean that the SPM routine doesn't return properly, and the program counter loops round and starts the bootloader over again. If you share your code somewhere I might be able to look it over at some point.

-------------
[top]
coolnicks Posted: 8 Nov 2018, 11:18 PM
Avatar


Member
Posts: 7
Joined: 3-November 18
No worries, I appreciate your help so far.

I think you are right, the doSPM isn't returning correctly. Could it be something on the stack is getting overwritten/broken - with the rcall using 8bit address, but call using 16bit address (is that right?)? I've seen some random ASM code where people push stuff at the beginning of the function, and pop stuff at the end? Maybe the stack pointer?

I'll PM you a link to the modified code.

-------------
[top]
mit Posted: 12 Nov 2018, 07:35 PM
Avatar
yeah whatever

Admin
Posts: 566
Joined: 4-May 16
Thanks, I only took a very quick look at the code, nothing obvious jumped out at me. Maybe you could move all of the SPM stuff (from SPMfourpages) into the NRWW section.

It should be possible to get this working, but it was only meant as an easy solution, if it's too much work it might be worth trying the proper way, using RAMPZ and ELPM. Unfortunately I'm going to be really really busy for at least the next few days. I'm sure you can do it!

-------------
[top]

Sign in to post a reply.