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

boards/common/atmega: gracefully handle CKDIV8 fuse #8952

Merged
merged 1 commit into from
May 14, 2018

Conversation

ZetaR60
Copy link
Contributor

@ZetaR60 ZetaR60 commented Apr 16, 2018

So far as I can tell, all ATmega chips ship with the CLKDIV8 fuse bit set. Some boards ship with the fuse unprogrammed, others do not (such as the mega-xplained board). If this fuse is programmed, the system clock starts with the wrong frequency. This PR gracefully handles initialization on ATmega boards that start with a divided clock. Incidentally, this also allows setting a custom division setting in board.h.

Tested on ATmega1284p / mega-xplained.

@aabadie aabadie added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Platform: AVR Platform: This PR/issue effects AVR-based platforms labels Apr 16, 2018
@kYc0o kYc0o self-assigned this Apr 16, 2018
@bergzand
Copy link
Member

@ZetaR60 Do I understand correctly that this effectively overrides the CLKDIV8 fuse setting?

static inline void set_prescaler(void)
{
/* Enable clock change */
CLKPR = 0x80;
Copy link
Member

Choose a reason for hiding this comment

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

Is there a define available for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented Apr 27, 2018

@bergzand Yes. When the CLKDIV8 fuse bit is set, it initializes the clock prescaler as set to divide the clock by 8. This just overwrites that change with the chosen clock prescaler setting.

void led_init(void);

static inline void set_prescaler(void)
Copy link
Member

Choose a reason for hiding this comment

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

This function looks CPU-related to me. Would it be problematic to move it to cpu/atmega_common/include/cpu.h together with the #define you added above? Maybe rename it to atmega_set_prescaler then.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note to others: bergzand and I discussed this in IRC. There are some issues with moving it due to wanting to have the ability to override CPU_ATMEGA_CLK_SCALE_INIT in board.h, which would require adding an include for board.h to cpu.h if it is moved. We haven't decided yet the best way to handle this.

@bergzand
Copy link
Member

Tested it on an arduino mega2560 with the timer_periodic_wake example, works perfectly, booting is a lot slower though, but that's to be expected :)

Copy link
Member

@bergzand bergzand left a comment

Choose a reason for hiding this comment

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

I've tested a bit with moving the code around to a more cpu based approach.

I suggest moving the CPU_ATMEGA_CLK_SCALE_INIT define to the common atmega periph_conf.h file as this is the place where clock configuration and other CPU initialization parameters are defined.

The function can be moved to the cpu.h file as inline with atmega_ prefixed to the name.

This way only the include for periph_conf.h has to be added to the cpu.h file and everything should work.

I've compiled it in a local branch here and everything seems to work

@@ -23,10 +23,25 @@
#include "irq.h"
#include "periph/gpio.h"

#ifndef CPU_ATMEGA_CLK_SCALE_INIT
#define CPU_ATMEGA_CLK_SCALE_INIT CPU_ATMEGA_CLK_SCALE_DIV1
Copy link
Member

Choose a reason for hiding this comment

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

This should go into ./boards/common/arduino-atmega/include/periph_conf.h preferably under the CLOCK_CORECLOCK definition and with a small bit of doxygen.

Can be done without the #ifndef construction but I don't mind keeping it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Problem though: not all boards using boards/common/atmega are Arduinos.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can solve that problem in a follow up PR. Discussed a bit offline with @bergzand and maybe found a solution.

void led_init(void);

static inline void set_prescaler(void)
Copy link
Member

Choose a reason for hiding this comment

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

This one into cpu/atmega_common/include/cpu.h as static inline void atmega_set_prescaler(void).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed, but also takes the clock scale as an argument, which means that cpu.h doesn't need another include.

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented May 2, 2018

Did another quick test just to make sure that I made no mistakes when moving things around. Everything is working fine.

Shall we now push the remaining movement of code to a refactor PR, squash, and merge?

@bergzand
Copy link
Member

bergzand commented May 2, 2018

@ZetaR60 Squash please, I think this is good to go, but I'll let @kYc0o do the final ACK.

@ZetaR60 ZetaR60 force-pushed the RIOT_atmega_graceful_clock branch from 10f2a9d to 2979626 Compare May 2, 2018 18:10
@ZetaR60
Copy link
Contributor Author

ZetaR60 commented May 2, 2018

Squashed. Thanks for helping with this!

@ZetaR60
Copy link
Contributor Author

ZetaR60 commented May 11, 2018

@bergzand I think you forgot to approve the changes from your review.

Copy link
Contributor

@kYc0o kYc0o left a comment

Choose a reason for hiding this comment

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

ACK. Thanks @bergzand for the offline explanation!

@bergzand bergzand added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label May 14, 2018
Copy link
Member

@bergzand bergzand left a comment

Choose a reason for hiding this comment

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

ACK!

@bergzand bergzand merged commit 3f1657f into RIOT-OS:master May 14, 2018
@ZetaR60 ZetaR60 mentioned this pull request May 17, 2018
24 tasks
@cladmi cladmi added this to the Release 2018.07 milestone Jul 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: AVR Platform: This PR/issue effects AVR-based platforms Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants