Skip to content

Timer1c support and per-variant initialization function #2080

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

Merged
merged 4 commits into from
Jul 1, 2014

Conversation

matthijskooijman
Copy link
Collaborator

These are two fairly unrelated improvements, other than that I need them both for a sleep timing improvement in our Pinoccio project.

The first commit adds support for timer 1c, on hardware that supports it. The second commit allows a variant file to supply a custom initialization function, to allow for board-specific code to be included by third parties.

@cmaglie, I'd be thankful if you could have a look at these soon and merge them if they look ok to you? I need these changes merged before I can publish some of my own Pinoccio work. Thanks!

Some devices, such as the atmega2560 or the atmega256rfr2 have a timer1c
output. It seems this output is not connected to anything on the Arduino
Mega, but this allows using it on third party hardware nonetheless.
@matthijskooijman
Copy link
Collaborator Author

Oh, when this is merged, can it also be merged into ide-1.5.x-avr-toolchain-gcc-4.8.1 right away? Or should I ask @ffissore about that?

@cmaglie
Copy link
Member

cmaglie commented May 19, 2014

I've already did similar hooks for the Arduino Due using weak functions, maybe is better doing it in the same way so we can avoid to introduce another define constant?
https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/sam/cores/arduino/hooks.c

Another aspect to consider is that variant initialization was already made on the Arduino Due where the init() function is placed on variant.cpp:
https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/sam/variants/arduino_due_x/variant.cpp#L365
honestly, I consider that a design error, and my efforts was to remove initialization code from the variants and put it back into the core, but this pull request make me think about that: has the initVariant() some use?

if we consider initVariant() really useful, a way to sort all this out may be:

  1. Add initVariant() as a weak-function to main.cpp
  2. rename init() to initVariant on the sam core

I can push the commit into ide-1.5.x-avr-toolchain-gcc-4.8.1, no problem for that
C

@matthijskooijman
Copy link
Collaborator Author

Woah, totally missed your comment a month ago, w00ps.

I agree that having the full init function in the variant.cpp is not a good approach. For AVR, we can't really adopt this approach either, since that would require modifying all third party variants out there in a non-compatible manner.

The problem with making initVariant a weak function, is that it will not pull in variant.cpp into the link. It's included in core.a, but then only included into the final link if there is a strong reference to it. For the Due, this might happen through the g_APinDescription array, but there is nothing like that for AVR (in fact, there is no variant.cpp / pins_arduino.cpp at all for AVR). This means that we cannot introduce an unconditional strong reference to something in variant.cpp without breaking existing variants (that don't define initVariant).

At first glance it seems that another option would be to supply a weak definitino of initVariant in the core, so it can be overridden by a strong definition in variant.cpp. However, I think that once the symbol is available, even if only weakly, the linker will no longer pull in variant.cpp into the build. We could probably do some magic wrt ordering of files to make variant.cpp have preference over an in-core variant, but I'm not entirely sure that's reliable.

Looking at the Due a bit more - it seems that the Due uses variant.h / variant.cpp instead of pins_arduino.h. I actually like that better, but changing it for AVR in a compatible manner seems tricky. You can include both variant.h and pins_arduino.h, but you'd have to supply empty fallback versions of both, later on the include path. Since currently the core is before the variant in the include path, they'd have to live in a completely separate place...

Btw, I'm no longer in a hurry to get these merged - I found a different solution for my problem not using timer1c. Would still be useful to merge the commit, though. I thought I left a comment about this, but apparently I didn't. W00ps.

@vicatcu
Copy link
Contributor

vicatcu commented Jun 18, 2014

I would like to add my support for this commit to be merged and become a part of the standard distribution. I feel it would be a substantial benefit to any 3rd party board that needs pins configured in a certain way at start-up, and creates little to no impact to boards that do not need the post-init hook. Is there anything we can do to help move this pull-request forward?

When a core directory without boards.txt file was encountered, the IDE
would show:

	Could not find boards.txt in /path/to/core/boards.txt.  Is it pre-1.5?

Which appears confusing: Is it looking inside a directory called
boards.txt? Now this is improved to:

	Could not find boards.txt in /path/to/core/.  Is it pre-1.5?

which makes a lot more sense.
If a variant supplied source files, these would be included in core.a
before. However, object files from core.a would only actually be
included in the build if they supplied a symbol for a strong reference
that was still missing.

In practice, this meant that a variant source file that only defines
interrupt handlers, or only defines strong versions of functions that
already had weak versions available, was not included.

By moving the variant .o files out of core.a and including them in the
build directly, this problem is solved.

Furthermore, the compilation of variant files is moved to after the
generation of core.a, to make it clearer in the code and verbose output
what is now happening.
@matthijskooijman
Copy link
Collaborator Author

I updated this pullrequest to:

@matthijskooijman
Copy link
Collaborator Author

Oh, and I included a small error message improvement I just stumbled upon and didn't want to create a new pullreq for.

@cmaglie cmaglie added this to the Release 1.5.7 milestone Jun 27, 2014
cmaglie added a commit to cmaglie/Arduino that referenced this pull request Jun 27, 2014
@cmaglie cmaglie merged commit 4014dd6 into arduino:ide-1.5.x Jul 1, 2014
@NicoHood
Copy link
Contributor

Is there any documentation on how to actually use it? How do I have to name the file and where to place it?
Am I also able to place ISRs in this file that get compiled? Will this work?

@cmaglie
Copy link
Member

cmaglie commented Feb 19, 2015

Basically, if you define a function void initVariant() this function is called at init time before void setup().
You can define this function anywhere but the intended place is inside your variant/xxx folder, typically in a file named pins_arduino.c that performs specific initialization required for the board (in addition to the pins_arduino.h that contains metadata about the board itself).

You can define ISR as usual, it's a C file that is compiled and linked like any other source file.

@vicatcu
Copy link
Contributor

vicatcu commented Feb 19, 2015

Nico,

I don't know how much documentation there is or where to find it, but take
a look at the core for WildFire here:
http://github.com/wickeddevice/wildfire-arduino-core for a working example
of using this functionality. The variant files are in
/WickedDevice/avr/variants/wildfirev3

Cheers,
Vic

Victor Aprea // Wicked Device
[email protected]
T: @vicatcu http://twitter.com/vicatcu/

On Thu, Feb 19, 2015 at 10:22 AM, Nico [email protected] wrote:

Is there any documentation on how to actually use it? How do I have to
name the file and where to place it?


Reply to this email directly or view it on GitHub
#2080 (comment).

@NicoHood
Copy link
Contributor

Thank you so much!

Some results:
The cpp has to be placed in the same directory as the pins file (of course).
The cpp name doesnt matter.
You dont need a variants.h like in the example.
You dont need this initvariants function, you can also put other stuff in there, that gets compiled, like ISRs.

Thats my file for example: no_usb_isr.cpp

#include <Arduino.h>
#include <pins_arduino.h>

// workaround for undefined USBCON has to be placed in every sketch
// otherwise the timings wont work correctly
ISR(USB_GEN_vect)
{
    UDINT = 0;
}

@matthijskooijman matthijskooijman deleted the ide-1.5.x-timer-variant branch June 12, 2015 15:36
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