Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental serial support for atmega 328p #24

Open
wants to merge 48 commits into
base: master
Choose a base branch
from

Conversation

JadinAndrews
Copy link

@JadinAndrews JadinAndrews commented Apr 30, 2017

Hi Zevero,

I have added serial support for atmega328p, and have made it an option in the Makefile. When enabled, the bootloader will first wait for serial, and if it detects serial flashing took place, mmc flashing will be skipped. The option is disabled if UART debugging is enabled, for obvious reasons.

I have also added a few compiler optimizations, they are not strictly necessary, I get a bootloader for 328p, with serial at 3992 bytes. But with the optimizations, size is reduced to 3696 bytes, which is almost an 8% saving.

PS: Sorry my commit history is a bit messy.

Regards,

Jadin

@JadinAndrews
Copy link
Author

JadinAndrews commented May 4, 2017

@SergeantSeven Here's what I found, stk500 calls a function write_flash_page() inside the function handle_write(). If you look at the definition of write_flash_page() in prog_flash.c, you will see that it is somewhat similar to the doFlash() definition in main.c. The big differences are how the pagebuffers are filled and the page compare stuff.

avr_boot fills the buffer with a call to pf_read (on line 124 of main.c) and stk500 fills it with a for loop on line 428 of stk500v1.c.

A good start would be to use the same pagebuffer for both functions, at least that will save some ram, but won't reduce the size much. The next step would be to modify one of the functions to handle filling the buffer, from either flash or sd. I think it is a good idea to keep the page compare stuff, for both serial and sd flashing, so might be a good idea to modify doFlash() to work with stk500v1.c.

(EDIT: I am not so sure that this will really save as much flash as I had initially hoped. Adding stk500 to avr_boot adds ~700 bytes, but optiboot is less than 512 bytes, which is already a nice saving.)

All this said, I think it is better to focus on 1284p support, by switching to using optiboot instead of stk500v1.

@JadinAndrews
Copy link
Author

JadinAndrews commented May 4, 2017

So, I decided to try add definitions to stk500 for 1284, and it compiled (3992 bytes or so). It should work for 1284p as well, I made a build with cs4, could one of you guys please flash and see if it works?

I have a feeling it might work, but I'm not sure which usart port it will use, I assume it will use one of them though...

https://github.com/JadinAndrews/avr_boot/blob/master/build/atmega1284p_cs4_16000000L_serial_fat32.hex

@JadinAndrews
Copy link
Author

It uses uart port 1, this can be changed in stk500v1.c. If the bootloader works on 1284p devices, I can add an option to the makefile to choose between the two available ports.

@per1234
Copy link
Contributor

per1234 commented May 4, 2017

I have been able to do serial and SD card upload to ATmega1284P and ATmega328P using your bootloader file. Good work!

I must admit that even though you warned us I was a bit confused when AVRDUDE kept thinking my chip was an ATmega1284 instead of ATmega1284P. I forgot that the bootloader supplies the signature during serial uploads.

I was sidetracked by the uart port 1 comment, actually the bootloader works on port 0, not 1.

@JadinAndrews
Copy link
Author

JadinAndrews commented May 4, 2017

@per1234 I am really glad it worked, it was a bit of a shot in the dark, but I realized that the only thing that was missing from stk500 was the initialization of the usart port, and looking over some other bootloaders, I saw that the setup was the same as on atmega 128, and 1280. So literally all I did to get this working on 1284 was to add || defined (__AVR_ATmega1284__) in a few places in stk500. Have a look at the commit for yourself: JadinAndrews@2e5f34a

It really was that easy..

Sorry about the confusion with regard to the port numbering, I forgot that the ports were zero indexed, this is actually also an error in stk500v1.c, where the ports are numbered from 1-4 for atmega1280. I'll fix this at some point and look at adding defs specifically for 1284p. It wouldn't compile for 1284p, and I didn't have time to figure out why. I literally threw this together during my coffee break.

So after a few small issues are fixed, I believe serial + sd is confirmed working for atmega328p and 1284p, and should be working on atmega128, atmega168, atmega1280 but I doubt there is much demand for those chips.

@per1234
Copy link
Contributor

per1234 commented May 4, 2017

I can also test ATmega32A and ATmega32U4. ATmega32A is not so commonly used in the Arduino world but there is already good support for it in MightyCore and it's a great price for a DIP-40 microcontroller.

ATmega168 doesn't have 4 kB boot section option (2 kB max) so that one won't be possible to support without optimizing the code down a lot. I can test ATmega168 if the time comes when that is necessary.

Arduino used to make a "Mega 1280" so there are probably still some of those floating around. The Wiring 1.0 board was ATmega128 so there are probably some of those out there, maybe collectors items at this point. ATmega644 has been on multiple semi-popular boards.

@JadinAndrews
Copy link
Author

JadinAndrews commented May 4, 2017

Well as far as I know atmega1284 and atmega644 are almost identical, so that should be pretty easy to support. I believe the atmega644 has been used a lot in the 3d printing world? I'm sure they would love to have serial + sd support.

I am curious if my builds for the atmega328p will work on a atmega32u4 or atmega 32A? they seem pretty similar on paper, either way, supporting them would just be a matter of adding definitions as I did for the atmega1284. Unless they're wildly different.

Thanks for pointing out that this will not work on the atmega168, shaving this down to 2kB, seems pretty hard at this stage, but not impossible. I have some ideas to trim this bootloader down a bit, but I think that's a separate issue for now.

Thanks for testing my bootloader files, did you compile, or just use the ones in the build directory?

@per1234
Copy link
Contributor

per1234 commented May 4, 2017

I agree that the focus of this pull request should be just adding serial upload support. Any optimizations that can be done after that are great but adding this feature in 4 kB is wonderful by itself. It's hard to believe that 2 kB could be shaved off but 2boots has shown it can be done and optiboot did manage to go from the 2 kB standard serial bootloader to 0.5 kB. Even if it's not possible to get to 2 kB, getting it smaller could allow FAT16 to be added back in with FAT32 or leave room for other new features.

I used the files you provided. I figured it was best that we all test with the same files to reduce the number of variables.

@JadinAndrews
Copy link
Author

@per1234 I'm curious if the readme for avr_boot is incorrect, it says that avr_boot was tested successfully on ATmega168? How is that possible with its 2kB boot section? I am very curious to figure out how 2boots managed all this in 2kB. It does only support fat16, but the difference between fat16 and fat32 with petit fat is really not that massive. There must be more (or less) going on than meets the eye.

@zevero @SergeantSeven do you guys have a 644p to test on? I think that it would be nice to support that mcu with this pull as well, but I don't have one to test.

@per1234
Copy link
Contributor

per1234 commented May 5, 2017

@zevero wrote that about the ATmega168:
2f2cefa
It would be great if I was wrong and it is possible to use with avr_boot. You can get ATmega168 Pro Minis for a little cheaper than the ATmega328P ones and some people even end up buying them by mistake because the sellers use misleading titles on their listings so that is a pretty common part.

If nobody else has an ATmega644P I'd be willing to buy one. I've been meaning to put one on my next Digikey order but haven't recently needed to buy enough components at one time to make one economical. Surprisingly Aliexpress and eBay don't have the usual super low prices on these parts in the DIP-40 package..

@JadinAndrews
Copy link
Author

I'll also be making a few purchases, but in most cases shipping takes about a month or two to South Africa from abroad.

@SergeantSeven
Copy link

I do not have a 644P right now. but I will be testing it extensively on my 1284P projects. I'm very happy about this development, great work! and thank you for doing what I started to do but got confused on. lol. As far as optimizations go, trimming this down in size would also be great so that I could add in some features that I need such as version checking and a couple other things. I'll look forward to that branch.

@per1234
Copy link
Contributor

per1234 commented May 10, 2017

I have a couple ATmega644P on their way to me from Digikey.

@JadinAndrews
Copy link
Author

JadinAndrews commented May 10, 2017

@SergeantSeven Thanks, let us know if it works or if you find some bug in some corner case. I really don't need to be thanked though, if you look at my changes to get serial working I hardly did anything, just included stk500 from 2boots and made a few changes. I'm really glad it's working though!

@per1234 That's perfect! I had a look at some local suppliers and they had 644p's and 1284p's at about the same price as Aliexpress and Ebay. Really surprising, but I guess I will get some as well.

By the way, I've started working on my own bootloader in the meantime, and found this resource very helpful:
http://www.avrfreaks.net/sites/default/files/bootloader_faq.pdf

@per1234
Copy link
Contributor

per1234 commented May 13, 2017

@JadinAndrews the ATmega644Ps arrived today so I'm ready to do testing whenever you are.

@JadinAndrews
Copy link
Author

JadinAndrews commented May 13, 2017

@per1234 That was fast.. Glad you received it, I'm still waiting for my orders. I have added a build for Atmega644P, and included the makefile I used, so you can double check the ports I used for the CS pin. I used the same port settings as for the Atmega1284P build.

Let me know if it works!

PS: UART is on port 0

Makefile Outdated
MCU_TARGET = atmega328p # Target device to be used (32K or larger)
BOOT_ADR = 0x07000 # Boot loader start address [byte] NOT [word] as in http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega1284p
MCU_TARGET = atmega644p # Target device to be used (32K or larger)
BOOT_ADR = 0x7000 # Boot loader start address [byte] NOT [word] as in http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega644p
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The correct value for BOOT_ADR is 0xF000

@per1234
Copy link
Contributor

per1234 commented May 15, 2017

Yeah, the price with shipping was $0.60 USD/ea more but I figured in this case it would be better not to deal with shipping delay of as much as 2 months sometimes. There's also that extra feeling of confidence of getting parts from a trusted supplier. I really haven't had many problems with the super cheap Chinese parts but I'm always a bit suspicious of them.

Once I corrected the BOOT_ADR value and rebuilt the bootloader I was able to upload over serial and SD card to the ATmega644P.

@JadinAndrews
Copy link
Author

Thank you for pointing that out, may I ask how you get that boot adr? I used the default value from here:
http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega644p
Will make the correction now.

Apart from the usual, colors not being as in the picture, or receiving the wrong part, I've also mostly had a good experience ordering from China, the worst issue I had was mislabeled RX/TX pins on some controller. Simple fix, but it took me an hour to check everything else.

@per1234
Copy link
Contributor

per1234 commented May 15, 2017

You look up the boot start address for the 2048 words boot flash section, which is 0x7800, but that address is in words and we need bytes so to convert you multiply it by two bytes per word, which comes out to be 0xF000. There's also a "Boot size configuration" table in the datasheets, which lists it (also in words) in the "Boot reset address (start bootloader section)" column but I do usually use that fuse calculator because it makes it easy to get the fuse values at the same time.

I got a Chinese Pro Mini or Micro with those pins mislabeled also, definitely confused me for a while.

@JadinAndrews
Copy link
Author

JadinAndrews commented May 15, 2017

Thanks for clearing that up, I made that change and rebuilt for Atmega644p. The commit is before your comment, because I was working in a vm and the clock wasn't synchronized. I need to be careful of that.

I think we are almost ready to pull, I just want to get the signature issue sorted out for Atmega1284p and test a bit more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants