MYSBootloader for atmega168
Hi, I'm still relatively new to MySensors however it has successfully 100% consumed me for the past few weeks and I'm unsure now how I managed to miss such an amazing project and community until now!! This is my first post so please be gentle!
I have done quite a lot of searching and I don't think I've found this topic discussed before but apologies if I just missed it.
I am aware that atmega168 is considered by many to be of limited use to MySensors due to the limited flash, but unfortunately I accidentally ordered a batch of 168 based pro minis recently, waited ~5 weeks(!) for them to arrive and these are now the majority of what I have spare to use. Due to COVID19 it's becoming much slower and more expensive to source parts like this so I'm making do with what I have....
I've am now actually having good success with the 168 and MySensors - it's certainly forced me to hone my skills in space optimisation but that's a good thing anyway...
I have successfully set up FOTA using the one spare atmega328 pro mini I had left and it's given me a taste of how amazing it is.... so I turned my attention to the 168.
I have succeeded in modifying/building/flashing the MYSBootloader for the 168, it registers against MyController and I can assign a firmware upgrade! This unfortunately is where I've run into the current roadblock. The node apparently begins to download the firmware but I suspect it's failing to write the first block. I guess mostly likely this is because the flash layout on the 168 is unavoidably different and this is tripping up the process of writing the data to flash. I've trawled the code for some hours trying to digest it and figure out what could be wrong but without any feedback from the node to give me clues I'm running out of steam...
I have a few thoughts on why this might be happening and I've spent some time trying to figure it out but unfortunately I'm not knowledgeable enough on the self-programming facility to go much further. Just wondering if someone (@Tekka) ? would be willing to assist me with debugging this?
Thanks and best regards
Ok well I got it working in the end. Apparently my code changes were correct already but it seems I was accidentally setting some fuses wrong when burning it causing the download process to fail. Turns out there's not to many things to change to get this to work. I haven't integrated the changes into a proper selectable build option or anything which would probably be a better patch, however would a patch for my changes to simply convert the code for a 168p be appreciated still as a reference? If so could someone who knows please advise me how best to submit it?
@mfalkvidd What do you recommend he do to make a code submission? It would be a nice contribution, and It might show the way for what needs to be done to get the code working on other atmega chips also.
I have no experience with bootloader code, but as long as it doesn't affect atmega328 it should be fine I guess.
I don't know if the contribution guidelines are applicable for the bootloader code bit reading the guidelines could be a good start.
I bought a few atmega168 by mistake but I think I threw them away. Couldn't fit anyhing useful onto them; ram and flash is very small.
@mfalkvidd Getting it to run on the ATmega328PB seems like it might be worthwhile upgrade. Actually, it's so similar maybe it already does. The atmega328pb is a slightly more capable chip than the atmega328p, and yet (oddly enough) it's priced lower than the atmega328p. It's priced 95 cents/chip from Mouser/digikey in quantity 1, so there's no need to risk getting counterfeit atmega328p's from aliexpress or similar, which would probably cost more anyway.
Circling back to this to close off the thread with an answer at least.
Here are the changes I used to convert the bootloader codebase to build for 168p.
Note that this change set is not complete enough to fully handle choosing between either MCU - some changes will become hard coded for 168 instead of 328 so it would not be suitable as a formal submission as it is. Unfortunately I got busy and now also have plenty of 328s back in my inventory. Also I cannot guarantee it's 100% correct but it seems to work well for me on the ~8 nodes I've used it on:
--- MySensorsBootloaderRF24/boards.txt 2020-10-14 22:50:32.182131357 +1030 +++ MySensorsBootloaderRF24.at168clean/boards.txt 2020-10-14 21:34:35.482909793 +1030 @@ -1,18 +1,18 @@ ## Add these lines to your boards.txt file in the Arduino installation directory ## -## Arduino Pro or Pro Mini (3V3 & 5V, 1 - 16 MHz) w/ ATmega328 MYSBootloader +## Arduino Pro or Pro Mini (3V3 & 5V, 1 - 16 MHz) w/ ATmega168 MYSBootloader ## ------------------------------------------------- menu.frequency=Frequency -MYSBL.name=ATmega328 with MYSBootloader 1.3.0 +MYSBL.name=ATmega168 with MYSBootloader 1.3.0 MYSBL.upload.tool=avrdude MYSBL.upload.protocol=arduino MYSBL.upload.maximum_size=30720 MYSBL.upload.maximum_data_size=2048 MYSBL.bootloader.tool=avrdude -MYSBL.build.mcu=atmega328p +MYSBL.build.mcu=atmega168p MYSBL.build.board=AVR_UNO MYSBL.build.core=arduino MYSBL.build.variant=standard diff -u MySensorsBootloaderRF24/Core.h MySensorsBootloaderRF24.at168clean/Core.h --- MySensorsBootloaderRF24/Core.h 2020-10-14 22:50:32.181131338 +1030 +++ MySensorsBootloaderRF24.at168clean/Core.h 2020-10-14 22:52:38.760633493 +1030 @@ -14,8 +14,8 @@ #define MYSBOOTLOADER_VERSION ((MYSBOOTLOADER_MINVER << 8) + MYSBOOTLOADER_MAJVER) // size setting ******************************************************************************************************** -#define BOOTLOADER_SIZE (2048) -#define BOOTLOADER_START_ADDRESS (0x8000 - BOOTLOADER_SIZE) +#define BOOTLOADER_SIZE (1024) +#define BOOTLOADER_START_ADDRESS (0x4000 - BOOTLOADER_SIZE) // DEBUG led patterns ************************************************************************************************* diff -u MySensorsBootloaderRF24/Definitions.h MySensorsBootloaderRF24.at168clean/Definitions.h --- MySensorsBootloaderRF24/Definitions.h 2020-10-14 22:50:32.181131338 +1030 +++ MySensorsBootloaderRF24.at168clean/Definitions.h 2020-10-04 23:30:41.494466259 +1030 @@ -9,7 +9,7 @@ #define Definitions_H #define FIRMWARE_BLOCK_SIZE (16) -#define EEPROM_SIZE 1024 // 1024 bytes for ATMEGA328 +#define EEPROM_SIZE 512 // 512 bytes for ATMEGA168 #define false (0) #define true (1) diff -u MySensorsBootloaderRF24/Makefile MySensorsBootloaderRF24.at168clean/Makefile --- MySensorsBootloaderRF24/Makefile 2020-10-14 22:50:32.181131338 +1030 +++ MySensorsBootloaderRF24.at168clean/Makefile 2020-10-14 21:43:48.433871688 +1030 @@ -1,6 +1,6 @@ PROJECT = MYSBootloader -MCU = atmega328p +MCU = atmega168pa CLK = 1000000L BAUDRATE = 9600 @@ -8,16 +8,16 @@ ISP_PORT = com5 ISP_SPEED = $(BAUDRATE) ISP_PROTOCOL = stk500v2 -ISP_MCU = m328p -ISP_HFUSE = DA -ISP_LFUSE = F7 -ISP_EFUSE = 06 +ISP_MCU = m168p +ISP_HFUSE = DD +ISP_LFUSE = FF +ISP_EFUSE = F8 ISP_ARGS = -c$(ISP_PROTOCOL) -P$(ISP_PORT) -b$(ISP_SPEED) -p$(ISP_MCU) BINPATH = /usr/bin/ CFLAGS = -funsigned-char -funsigned-bitfields -DF_CPU=$(CLK) -DBAUD_RATE=$(BAUDRATE) -Os -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -Wall -Wextra -Wundef -pedantic -mmcu=$(MCU) -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -LDFLAGS = -nostartfiles -Wl,-s -Wl,-static -Wl,-Map="$(OutputFileName).map" -Wl,--start-group -Wl,--end-group -Wl,--gc-sections -mrelax -Wl,-section-start=.text=0x7800 -mmcu=$(MCU) +LDFLAGS = -nostartfiles -Wl,-s -Wl,-static -Wl,-Map="$(OutputFileName).map" -Wl,--start-group -Wl,--end-group -Wl,--gc-sections -mrelax -Wl,-section-start=.text=0x3800 -mmcu=$(MCU) all: clean out
Hopefully this helps someone...
skywatch last edited by
@pillarama I eventually went to MiniCore for all atmega chips I use here 168P and 328P. It is so simple to install and use it is crazy! It works well and is has very detailed instructions for complete beginners to use.
@skywatch I had a quick look at Minicore - it does look like an interesting bootloader - thanks for the tip. "Write to own flash" is certainly intriguing! I guess in theory a feature like that could be used to stream firmware updates directly to flash on a running node without needing external flash? I specifically use MYSBootloader for the amazing NRF24 OTA support so that I can firmware update hard to reach/remote nodes without having physical access. Does Minicore (or Minicore+MySensors) support OTA? I couldn't see any references from a quick skim of the site....
skywatch last edited by skywatch
@pillarama I don't know about FOTA, but I see no reason why it would not work. I guess it depends what you do with it!
I like being able to burn bootloader from within arduino ide and not having to swap to avrdudess et al - now I can boot load and program in the same window. I was amazed at how easy it is to install and use. No need for fuse calculators, just choose clock speed, internal or external and brownout and click burn.
I do hope to try FOTA in April (real life allowing) and so will comment more then....
Only snag is it dosn;t work with the ardudriod on android, I have contacted the dev of that app and sent the error message but as yet no solution. Maybe it will be possible in the future to do all this from phone and needing PC..... It is very close.