crycode-de / mcp-can-boot

CAN bus bootloader for AVR microcontrollers attached to an MCP2515 CAN controller.
Other
33 stars 12 forks source link

Atmega32U4 #7

Closed hughkojack closed 1 year ago

hughkojack commented 1 year ago

Hi Peter,

Can I use this bootloader on Atmega32U4 micro controller? it is connected to MCP2515 and TJA1050T as can transceiver.

Thanks

crycode-de commented 1 year ago

Hi, I've added support for the ATmega32U4 mcu according to the datasheet. Should be working, but can't test it cause of missing hardware.

I've also released v2.2.2 of the flash app with support for the ATmega32U4.

Can yout test it and give me some feedback if it's working?

hughkojack commented 1 year ago

Sure, I will test it and will let you know. Thanks

hughkojack commented 1 year ago

Hi Peter, I couldn't upload a new bootloader still, I have an issue with platformio.ini configuration. this is my new configuration for ATMEGA32U4, can you please see what is wrong.

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
default_envs = ATmega32U4

[env]
platform = atmelavr
framework = arduino

build_flags = 
    -Os
    -funsigned-char
    -funsigned-bitfields
    -fpack-struct
    -fshort-enums
    -fno-exceptions
    -fno-jump-tables
    -mrelax
    -Wl,--relax
    -Wl,--cref
    -Wl,-Map=$BUILD_DIR/firmware.map

board_build.f_cpu = 16000000L

upload_protocol = costom
upload_flags =
    -C
    ; use "tool-avrdude-megaavr" for the atmelmegaavr platform
    ${platformio.packages_dir}/tool-avrdude/avrdude.conf
    -p
    $BOARD_MCU
    -P
    $UPLOAD_PORT
    -c
    usbasp
upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i

upload_port = COM7
upload_speed = 19200

[env:ATmega32]
board = leonardo
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0x7000

[env:ATmega32U4]
board = leonardo
board_build.mcu = atmega32u4
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0x7000 ; 2048 words bootloader, 0x3800 * 2

board_fuses.lfuse = 0xDE
board_fuses.hfuse = 0x98
board_fuses.efuse = 0xFB

[env:ATmega328P]
board = ATmega328P
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0x7000

[env:ATmega64]
board = ATmega64
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0xF000

[env:ATmega644P]
board = ATmega644P
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0xF000

[env:ATmega128]
board = ATmega128
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0x01F000

[env:ATmega1284P]
board = ATmega1284P
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0x01F000

[env:ATmega2560]
board = ATmega2560
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0x03F000

;board_fuses.lfuse = 0xFF
;board_fuses.hfuse = 0xDA
;board_fuses.efuse = 0xFC

; ***
; Additional environments as examples below
; ***

; ATmega328P with AVR ISP MK2
[env:ATmega328P_via_AVRISP_mkII]
board = ATmega328P
build_flags = 
    ${env.build_flags}
    -Wl,--section-start=.text=0x7000

board_build.f_cpu = 16000000L

board_fuses.lfuse = 0xFF
board_fuses.hfuse = 0xD8
board_fuses.efuse = 0xFC

upload_protocol = custom
upload_port = usb
upload_flags = 
    -C
    ${platformio.packages_dir}/tool-avrdude/avrdude.conf
    -p
    $BOARD_MCU
    -P
    $UPLOAD_PORT
    -c
    stk500v2
upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i
hughkojack commented 1 year ago

I am using USBasp programmer which works fine with Arduino IDE. this is the error I receive and couldn't resolve it.

Processing ATmega32U4 (board: leonardo; platform: atmelavr; framework: arduino)
------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/leonardo.html
PLATFORM: Atmel AVR (4.1.0) > Arduino Leonardo
HARDWARE: ATMEGA32U4 16MHz, 2.50KB RAM, 28KB Flash
DEBUG: Current (simavr) External (simavr)
PACKAGES:
 - framework-arduino-avr @ 5.1.0
 - toolchain-atmelavr @ 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 5 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode

Selected fuses: [lfuse = 0xFF, hfuse = 0xD8, efuse = 0xCB]
Setting fuses
avrdude: ser_open(): can't open device "\\.\COM7": The system cannot find the file specified.
crycode-de commented 1 year ago

Seams like avrdude can't find your selected port COM7. Have checked that this is the correct port? Windows sometimes likes to assign new port numbers.

Also

upload_protocol = costom

should be

upload_protocol = custom

😉

Additional remark: One the fuses are set, you should comment out the board_fuses.* lines to not set the fuses again on each flash.

hughkojack commented 1 year ago

Thanks for your comment, the usb port was not correct.

hughkojack commented 1 year ago

after uploading the new bootloader the USB of Atmega32U4 is not responding

crycode-de commented 1 year ago

Don't know what exactly you mean and I've no personal experience with the ATmega32U4 so far.

But if it's something like programming via USB ... this will most likely work via a bootloader which handles the USB communication. If you flashed the mcp-can-boot bootloader, you have overwritten the original bootloader. There can only be one bootloader at a time. 😉

hughkojack commented 1 year ago

how did you find these numbers

elif defined(__AVR_ATmega32U4__)

define IV_REG MCUCR

define SPI_DDR DDRB

define SPI_PORT PORTB

define SPI_SS 0

define SPI_MOSI 2

define SPI_MISO 3

define SPI_SCK 1

as per pinout shouldn't be as following:

define SPI_SS 17

define SPI_MOSI 16

define SPI_MISO 14

define SPI_SCK 15

crycode-de commented 1 year ago

from the datasheet of the ATmega32U4

Pinout on page 3 or chapter "10.3.1 Alternate Functions of Port B" on page 74.

Your pin numbers 14..17 looks like Arduino pin numbers. The bootloader uses the real pin numbers of the controller.

hughkojack commented 1 year ago

it seems that I'm not able to identify the exact location where the bootloader is getting stuck. I can observe that the LED is flashing with a period of approximately 1000ms, indicating that the bootloader is running. However, for some reason, the main sketch is not starting.

crycode-de commented 1 year ago

Seams like the bootloader is starting but the main application is missing, so the controller restarts every time the bootloader tries to start the main application. Did you flash your application after flashing the bootloader?

hughkojack commented 1 year ago

You were correct. The application was erased for some reason, so I uploaded it again. However, the bootloader is still not working as expected.

I want to clarify if there could be an issue with uploading the application via Arduino and the bootloader from PlatformIO. Is this a potential problem?

As per my understanding, when powering on the board, the bootloader should always send the start message. However, I have not received any messages from the bootloader during restart.

I would like to know how I can verify if the MCP2515 initialization in the bootloader is correct and if there are any errors occurring during the process."

hughkojack commented 1 year ago

I just realized that burning the bootloader will erase the existing application code. and by uploading the application from Arduino IDE the bootloader will be replaced.

It seems that I should add my application into same project on platformIO, is that correct?

crycode-de commented 1 year ago

Your application should be flashed using the bootloader. :wink:

The bootloader is just a special part of the memory. When programing via ISP normally the whole flash is erased first. So in you case the bootloader and you application will be erased.

If you remove -e from the upload_flags in platformio.ini file, the flash should not be erased on uploading the bootloader. So it should work to flash you application from Arduino IDE first and then the bootloader. But again: You application should be flashed using the bootloader.

You're right, the bootloader always sends the start message on start. If the init of the MCP2515 fails, the LED (if used) will flash in a infinite loop with 50ms on, 50ms off.

hughkojack commented 1 year ago

I am making progress every day with your advice, thank you for that. I have discovered through debugging that the bootloader is getting stuck at the memset(flashBuffer, 0xFF, SPM_PAGESIZE); line, and the blinking LED is a result of the reset that occurs during the memset operation. so it never gets to the mcp2515.reset() any idea why?

this is part of the bootloader.ccp that the reset occurs.

// init CAN controller mcp2515.init();

// init LED (if defined) LED_INIT; LED_ON;

// fill flash buffer with predefined data memset(flashBuffer, 0xFF, SPM_PAGESIZE);

// reset the CAN controller, go into infinite loop with LED blinking on errors if (mcp2515.reset() != MCP2515::ERROR_OK) { while (1) { LED_OFF; delay(50); LED_ON; delay(50); } }

hughkojack commented 1 year ago

I added the infinite blinking code right after the main() function, but even with a few fast blinks, it eventually goes into a reset loop. I suspect that the configuration of the Atmega32U4 is not quite matching or there may be something missing.

https://github.com/crycode-de/mcp-can-boot/assets/20266419/031e6d69-6d77-45ca-be1a-52e98017c962

crycode-de commented 1 year ago

I have discovered through debugging that the bootloader is getting stuck at the memset(flashBuffer, 0xFF, SPM_PAGESIZE);

How did you debug this? I've no idea what should get stuck there. The memset command simply fills the flashBuffer array with 0xFF. SPM_PAGESIZE is 128 for the ATmega32U4. So the flashBuffer is an array of 128 bytes.

With the default config, the bootloader should init/reset the MCP2515, send the start message and wait 250ms for a response to got into flash mode. If no command to enter flash mode is received the bootloader tries to start the main application. If no main application is flashed the bootloader will be started again.

crycode-de commented 1 year ago

What kind of board/pcb are you using? Looks like the MCP2515 is embedded on this board, right?

hughkojack commented 1 year ago

What kind of board/pcb are you using? Looks like the MCP2515 is embedded on this board, right?

This a custom designed board with MCP2515 for can communication and some other sensors, such as light, temp and noise which I am going to use it as smart switch in my home. it's canbus working with no issue.

hughkojack commented 1 year ago

how can I make sure the bootloader is executing? is there any specific conditions for the bootloader to start? I added the infinite LED blinking code after the main() function, but it didn't work. whatever changes I do the led blinking rhythm doesn't change. as you can see in the uploaded video.

crycode-de commented 1 year ago

The bootloader always starts first if the fuses are set correctly. See here to get your right fuse values. There are no specific conditions. To enter flash mode the bootloader needs to get the "flash init" command via CAN before the timeout (250ms default) occurs. Without the "flash init" command the bootloader just tries to start the main application.

Did you set the correct ...?

Do you use a custom pin? If so, is the original SPI_SS pin connected to an external pullup resistor or did you enable the #define SET_SPI_SS_OUTPUT HIGH part in config.h? Otherwise the MCU may enter SPI slave mode and get stuck.

What exactly do you mean with "after the main() function"? If you want to add some check LED blinks, you have to do this inside the main() function. In the main() function there is an infinite loop while (1) {...} which is only be left/stopped when starting the main application. So some code after this loop or after the main function will never be executed.

hughkojack commented 1 year ago

I double checked all the items you mentioned, and they are all good.

I have added the check LED blinks inside the main() function before and after the init() and couldn't notice any difference.

As this the first project that I am using platformio, can you please confirm to upload the mcp-can-boot which of the following command is correct? platformio.exe run --target bootloader --environment ATmega32U4 platformio.exe run --target upload --environment ATmega32U4 --upload-port COM7

how can make sure what is written in the bootloader memory?

because as I am changing the code for debugging by using LED on/off, I don't notice any changes in the LED blinking pattern. I always see the same pattern as I posted in this video. (WhatsApp.Video.2023-05-19.at.6.32.22.PM.mp4 )

Thanks

hughkojack commented 1 year ago

I think I found the way to upload the bootloader, finally I got a can message after restart. can0 1FFFFF01 [8] 00 42 02 00 1E 95 87 01

😂

hughkojack commented 1 year ago

I double checked all the items you mentioned, and they are all good.

I have added the check LED blinks inside the main() function before and after the init() and couldn't notice any difference.

As this the first project that I am using platformio, can you please confirm to upload the mcp-can-boot which of the following command is correct? platformio.exe run --target bootloader --environment ATmega32U4 platformio.exe run --target upload --environment ATmega32U4 --upload-port COM7

how can make sure what is written in the bootloader memory?

because as I am changing the code for debugging by using LED on/off, I don't notice any changes in the LED blinking pattern. I always see the same pattern as I posted in this video. (WhatsApp.Video.2023-05-19.at.6.32.22.PM.mp4 )

Thanks

the correct way of upload is --target upload.

then I can not understand what the --target bootloader is doing?

crycode-de commented 1 year ago

Yes, you need --target upload to upload the mcp-can-boot bootloader.

The bootloader target of pio can be used in other projects to specify a bootloader hex file which will then be uploaded. Example: When using pio for you main application, you may set the board_bootloader.file etc. options and then you are able to flash the prebuild bootloader from within you main project.

crycode-de commented 1 year ago

I'll close this issue for now. If you encounter any problems, feel free to reopen.