Skip to content

Due: solve issues with nonstandard pin operations #3524

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 5 commits into from
Jan 7, 2016

Conversation

facchinm
Copy link
Member

This PR solves the following Due broken behaviours:

8- acd trigger #1819 #2286 (#3064)

The Due has lots of RAM so the solution uses 80 bytes to keep track of the pinmux state. A lot of AVR behaviours are "emulated" using this array.

The solution has been benchmarked and the speed tradeoff is:

  • -10% on pure digitalWrite and digitalRead
  • -5% to -25% on pure analogRead()
  • -400% on analogRead()followed by digitalWrite() on different pins 😱

All other cases were broken with the actual code so it's useless to test them

mtayler and others added 4 commits July 14, 2015 10:34
When a pin is designated as an output on the Arduino Due, the pin is set
to a HIGH logic level. Changing the default pin state to LOW makes the
behaviour correspond with AVR.
to avoid the bug arduino#2198 simply reconfigure the pin -> no additional overhead if pinMode configuration is performed at the beginning of the sketch, 4 to 25% overhead on all analogRead() due to the additional check
This commit adds 80 bytes to RAM usage and some overhead in normal operations.
@facchinm
Copy link
Member Author

It's important to notice that every core based on Due should add the g_pinStatus array to its variant.cpp

@facchinm facchinm added the Board: Arduino Due Applies only to the Due label Jul 14, 2015
@facchinm
Copy link
Member Author

BTW, the 400% performance drop can be solved completely if pinMode(INPUT) and pinMode(OUTPUT) are performed outside loop() (which is a best practice in case of different static pins)

@facchinm
Copy link
Member Author

@HanaJin @trickedj @Tamul @DavidEGrayson @JiapengLi @billroy @3esmit , could you please test the PR? Could it be a good solution for your issues?

@3esmit
Copy link

3esmit commented Jul 15, 2015

Test is not possible, Arduino SAM Boards module not found in the pull request file, there is no 'sam' folder inside 'hardware/arduino' in pull_requests/arduino-PR-3524-BUILD-361-windows.zip

Download Arduino SAM Boards (1.6.4) files from Board Manager and test it anyway?

@3esmit
Copy link

3esmit commented Jul 15, 2015

But looking at the code changed, one line is exactly what I did to fix it. But in #3310 @DavidEGrayson realised that is not a "default output state" problem. The problem is that if you send digitalWrite(LOW) before pinMode(OUTPUT) arduino will not output LOW, will output the initial output state, that by default is HIGH.

@DavidEGrayson
Copy link

I'm not sure what @3esmit is talking about in the last comment. This pull request adds the following code in pinMode(x, OUTPUT) (in wiring_digital.c) to determine if the output should be high or low:

g_pinStatus[ulPin] = ((g_pinStatus[ulPin] & 0xF0) >> 4 ? PIO_OUTPUT_1 : PIO_OUTPUT_0)

That's a step in the right direction. I haven't looked carefully at the rest of the code or tested any of it.

break ;

case OUTPUT:
PIO_Configure(
g_APinDescription[ulPin].pPort,
PIO_OUTPUT_1,
g_pinStatus[ulPin] = ((g_pinStatus[ulPin] & 0xF0) >> 4 ? PIO_OUTPUT_1 : PIO_OUTPUT_0),

Choose a reason for hiding this comment

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

There is no need to set g_pinStatus if you are going to do it again on the next line. There is no need to do & 0xF0 because those bits you are masking off would get shifted anyway.

Copy link

Choose a reason for hiding this comment

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

I didn't checked all diffs, I'm not that deep into arduino code, but your comments makes sense. Thanks for the note.

Copy link
Member Author

Choose a reason for hiding this comment

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

@DavidEGrayson , I'm aware there's no need to mask the variable but all the patch is explicitly masked so there's no need to remove it only here (I bet it will be removed by the compiler anyway, but I'll check later). If you wish something fancier it could be converted to use bit fields, but there won't be any speed improvement

Copy link
Member Author

Choose a reason for hiding this comment

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

You also spotted a leftover that made its way into the PR , thank you 😄 . Fixed with 5a37e94

@facchinm
Copy link
Member Author

Sorry for the inconvenience guys, the board manager is a great beast but, being the Due core still inside the IDE, it takes extra care to generate a custom core based on this PR (like we already do with the Zero). More news later today!

#define PIN_STATUS_TIMER (0x06)
#define PIN_STATUS_SERIAL (0x07)
#define PIN_STATUS_DW_LOW (0x10)
#define PIN_STATUS_DW_HIGH (0x11)
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't these definitions be put in a typedef'ed enum?

Copy link
Member Author

Choose a reason for hiding this comment

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

Being a mashup between an enum and a mask (to save some bytes) I'd prefer to keep the hardcoded values, but it's a matter of choice 😄

@DenDanny
Copy link

@facchinm et al.

I was wondering if you could give this beginner a push in the right direction..

I want to switch an Analogue pin between INPUT and OUTPUT in order to switch a LED between a "receiving" and emitting state (LedComm) - which since 1.5.4 don't work no more. Also, i want to use multiple analogue pins (each with an LED).

I can sort of follow (in theory) what's been going on, but practically I have no idea where/how I can these fixes and patches you (and others) seem to have created. Where/what can I download to obtain these fixes?

Regards,
Danny
PS. see my example (that doesn't work) on: https://forum.arduino.cc/index.php?topic=344560.0

@facchinm
Copy link
Member Author

Hi @DenDanny, the PR builder for Due core is still far from being complete, so in the meantime, if you wish to test this PR, I'd suggest to extract this file into sketchbook/hardware folder. A new menu entry (called Arduino ARM (32-bits) Boards PR3524) should appear the next time you restart the IDE, and it contains all the patches.

@HanaJin @trickedj @Tamul @DavidEGrayson @JiapengLi @billroy @3esmit sorry for the long delay, if you could test using this quick and dirty method it would be a great help for inclusion. Sorry again.

@HanaJin
Copy link

HanaJin commented Sep 8, 2015

Hi @facchinm , I tempted to try the patches, but I got this error when I tried to upload the sketch. Please help.

capture

@facchinm
Copy link
Member Author

facchinm commented Sep 9, 2015

Hi @HanaJin , the packet contains only the core, not the tools, so you need to download the SAM core first using Board manager and then the IDE will know where to find the compiler.
Sorry for not explaining this in the previous post and thanks for testing this patch!

@HanaJin
Copy link

HanaJin commented Sep 9, 2015

Hi @facchinm sorry to bug you again. I've downloaded the core and tested the original Due which compils fine, but with the patches, it still does not compile.
capture

Note that I checked the .c.o file was right in the build folder.

@facchinm
Copy link
Member Author

Ok, found, the source of your problems is the IDE and more specifically platform.keys.rewrite.txt file. The fastest (and safest) method to fix compilation is to use nightly build (https://www.arduino.cc/download.php?f=/arduino-nightly-windows.zip) 😉

@facchinm
Copy link
Member Author

To test the PR completely, here you can find a board-to-board test with wiring instructions on top.

@HanaJin
Copy link

HanaJin commented Sep 10, 2015

Yes, the patches fix the issue I described in #2455. Now I get similar results. Hope this helps.

facchinm added a commit that referenced this pull request Jan 7, 2016
Due: solve issues with nonstandard pin operations
@facchinm facchinm merged commit 74c70ba into arduino:master Jan 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Board: Arduino Due Applies only to the Due
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants