Giter Site home page Giter Site logo

arduinocore-sam's Introduction

Arduino Core for SAM3X CPU

This repository contains the source code and configuration files of the Arduino Core for Atmel's SAM3X processor (used on the Arduino Due board).

Installation on Arduino IDE

This core is available as a package in the Arduino IDE cores manager. Just open the "Boards Manager" and install the package called:

  • Arduino SAM Boards (32-bit ARM Cortex-M3)

Support

There is a dedicated section of the Arduino Forum for general discussion and project assistance:

http://forum.arduino.cc/index.php?board=87.0

Bugs or Issues

If you find a bug you can submit an issue here on github:

https://github.com/arduino/ArduinoCore-sam/issues

Before posting a new issue, please check if the same problem has been already reported by someone else to avoid duplicates.

Contributions

Contributions are always welcome. The preferred way to receive code contribution is by submitting a Pull Request on github.

arduinocore-sam's People

Contributors

aethaniel avatar agdl avatar bluesign2k avatar bobc avatar championswimmer avatar chris--a avatar cmaglie avatar collin80 avatar dpslwk avatar facchinm avatar fede85 avatar ivan-perez avatar jcbuda avatar matteosuppo avatar matthijskooijman avatar mattwlowe avatar mtayler avatar nkrkv avatar paulstoffregen avatar per1234 avatar pigeo avatar reillyeon avatar roncapat avatar sandeepmistry avatar shfitz avatar stimmer avatar techpaul avatar travisg avatar vdorr avatar westfw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arduinocore-sam's Issues

incorrect/useless call to printf() in _exit()

in cores/arduino/syscalls_sam3.c, the implementation of _exit() includes:

extern void _exit( int status )
{
    printf( "Exiting with status %d.\n", status ) ;

    for ( ; ; ) ;
}

This causes something like 12k of printf and stdio code to be included in every sketch, and probably doesn't do anything useful since there is no guarantee that the UART has been initialized at all (even assuming that printf() ends up using the skeleton _write() code that is also there...)

Trouble with static buffer sizes within the I2C libray.

From @DieterBurandt on January 17, 2017 17:16

(Arduino 1.6.18.1)

  • I2C communication:

The I2C buffer has a fixed size of 32byte in the Arduino library. If you like to use an EEPROM with a page size of e.g. 128 byte, then you must patch the buffer size in the Arduino library.

Please implement a simple method, that the user can set the size of the buffer from within the project (AVR, SAM, and SAMD(?)).

(SAM: "Wire.h" => "#define BUFFER_LENGTH 32")

Copied from original issue: arduino/Arduino#5871

Arduino Due - CPU init will run the user into trouble on using SPI-devices

From @DieterBurandt on January 17, 2017 17:13

(Arduino 1.6.18.1) Variant.cpp

For Arduino Due ONLY:

The two SPI chip select lines logical pin 4 (sd-card) and logical pin 10 (Ethernet) are also connected to pin 87 and pin 77 respectable. (You can measure it for example with an Ohm-meter.)

All pins from 0 to PINS_COUNT are initialised to digital output low in variant.cpp. If a user takes the standard code and tries work with the SD-card or Ethernet the pins 87 and 77 are still low and the SPI device chip select never reaches a full swing to high.

Curiously it works sometimes but is instable, causing complete failures or slow devices.

Set at least pin 87 and pin 77 to input high. This will not influence the output, not the driver, and works very well.

(It will be great if initialisation of the CPU results in a chip select to disable all potentially connected devices on startup. That is pin 4, 10, 52, 77, 87 to input high. This simplifies using of SD-card and Ethernet devices.)

Copied from original issue: arduino/Arduino#5869

Using pins 6-9 causes the Due to crash when using the Ethernet R3 shield and WebServer example

From @SeanDS on August 13, 2013 22:12

I'm using the Arduino Ethernet R3 shield with a Due board. The Ethernet shield uses the ICSP connector to communicate with the Due via the SPI socket on the Due, so it frees up pins 11, 12 and 13 for general I/O. Pin 10 is still used for chip select / slave select.

When I use the Ethernet and SPI libraries to set up a simple web server (basically the WebServer example but with an added function to set pins 2-13, excluding 10, to high, when a specific GET command is issued), setting any of pins 6-9 to high (via analogWrite(4095)) causes the web server to become unresponsive.

Copied from original issue: arduino/Arduino#1539

[Due] pgm_read_ptr causes error

From @bobc on December 10, 2016 12:31

Arduino IDE 1.6.8
Arduino AVR Boards 1.6.10
Arduino SAM Boards 1.6.9

On Mega2560, the following sketch compiles OK:

void setup() {
  // put your setup code here, to run once:
  char str_debug_1[] PROGMEM = "ECHO";
  Serial.print((char*)pgm_read_ptr(&str_debug_1));
}

void loop() {
  // put your main code here, to run repeatedly:
}

On Due, the same sketch has a compile error :

In file included from C:\Users\bob\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.9\cores\arduino/Arduino.h:31:0,

                 from C:\Users\bob\AppData\Local\Temp\build3a01f77cc023d803352a39f55ca441db.tmp\sketch\sketch_pgm_read_test.ino.cpp:1:

C:\Users\bob\Documents\Arduino\sketch_pgm_read_test\sketch_pgm_read_test.ino: In function 'void setup()':

C:\Users\bob\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.9\cores\arduino/avr/pgmspace.h:106:49: error: 'const void*' is not a pointer-to-object type

 #define pgm_read_ptr(addr) (*(const void *)(addr))

                                                 ^

C:\Users\bob\Documents\Arduino\sketch_pgm_read_test\sketch_pgm_read_test.ino:6:23: note: in expansion of macro 'pgm_read_ptr'

   Serial.print((char*)pgm_read_ptr(&str_debug_1));

                       ^

exit status 1
Error compiling for board Arduino Due (Programming Port).

Inspection of pgm_read_ptr (in avr/pgmspace.h) for Due shows : -
#define pgm_read_ptr(addr) (*(const void *)(addr))

This macro casts the argument void *, then tries to dereference a void *, which is guaranteed to never work.

Probably, the cast to (void *) is not needed.

Copied from original issue: arduino/Arduino#5698

digitalWrite() is embarassingly slow on Due...

From @WestfW on October 27, 2015 4:13

There's a relatively senseless use of Atmel Libraries that duplicate a lot of the effort. The attached patch approximately doubles the speed of a pin-toggle loop...
(umm. I can't attach a diff...)


--- wiring_digital.c~   2015-04-23 08:30:36.000000000 -0700
+++ wiring_digital.c    2015-10-26 20:59:25.000000000 -0700
@@ -84,7 +84,12 @@
   }
   else
   {
-    PIO_SetOutput( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin, ulVal, 0, PIO_PULLUP ) ;
+      if (ulVal) {
+     digitalPinToPort(ulPin)->PIO_SODR = digitalPinToBitMask(ulPin);
+      } else {
+     digitalPinToPort(ulPin)->PIO_CODR = digitalPinToBitMask(ulPin);
+      }
+//    PIO_SetOutput( g_APinDescription[ulPin].pPort, g_APinDescription[ulPin].ulPin, ulVal, 0, PIO_PULLUP ) ;
   }
 }

Copied from original issue: arduino/Arduino#4030

Arduino due can't exit from bootloader mode often

From @sined23 on April 3, 2016 11:59

Hello! PC is connected to Arduino Due by Native USB. Often after sketch uploading through Native USB or when I plug usb cable or after OS restarted (power restart), Arduino Due still keep in Bootloader mode and usb communication with PC doesn't work and sketch doesn't work.
After hardware reset of Arduino Due it become normal.

lsusb | grep boot
Bus 001 Device 020: ID 03eb:6124 Atmel Corp. at91sam SAMBA bootloader

I run manually bossac's command to reset Arduino Due but it doesn't help:

~/.arduino15/packages/arduino/tools/bossac/1.6.1-arduino$ ./bossac -p ttyACM0 -R

lsusb | grep boot
Bus 001 Device 020: ID 03eb:6124 Atmel Corp. at91sam SAMBA bootloader

Why can't Bossac reset CPU? Is this bug or need send some additional command to CPU to reset?

BTW: Arduino Due can recieve new sketches but can't be reseted by Bossac.

Copied from original issue: arduino/Arduino#4805

Arduino Due + ILI9341 TFT + Adafruit libs: Arduino SPI extended mode does not work

Arduino Due + ILI9341 TFT + Adafruit libs (IDE 1.6.3): Arduino SPI extended mode does not work:
when I start the test sketch by the following code, the program shows no TFT output, screen is light grey, just the Serial output:

// Adafruit ILI9340 / ILI9341

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9340.h"

#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

#define    tft_cs     10
#define    tft_dc      9
#define    tft_rst     8

Adafruit_ILI9340 tft = Adafruit_ILI9340(tft_cs, tft_dc, tft_rst);

void setup() { 
  Serial.begin(9600);
  // Setup the LCD
  SPI.begin(tft_cs);
  SPI.setClockDivider(tft_cs,21); // 21==4MHz (standard)
  tft.begin();
  tft.setRotation(3);
  tft.setTextColor(ILI9340_WHITE); tft.setTextSize(1);  
  Serial.println("tft started");
}

nevertheless, in the normal (AVR?) mode it works:

// Adafruit ILI9340 / ILI9341

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9340.h"

#if defined(__SAM3X8E__)
    #undef __FlashStringHelper::F(string_literal)
    #define F(string_literal) string_literal
#endif

#define    tft_cs     10
#define    tft_dc      9
#define    tft_rst     8

Adafruit_ILI9340 tft = Adafruit_ILI9340(tft_cs, tft_dc, tft_rst);

void setup() { 
  Serial.begin(9600);
  // Setup the LCD
  tft.begin();
  tft.setRotation(3);
  tft.setTextColor(ILI9340_WHITE); tft.setTextSize(1);  
  Serial.println("tft started");
}

Is it an Arduino IDE SPI issue?

bug on CS line using SPI library

From @schwingkopf on February 13, 2013 19:59

when using the SPI library with the predefined SPI-CS0 and SPI-CS1 pins (digital pins 10 and 4), the voltage during SPI communication on these lines doesn't drop to 0V (only to 1.6V), when defining the digital pins for SPI-CS0 and SPI-CS1 prior as pinMode OUTPUT.
with the SPI-CS2 on digital pin 52 it worked fine for me.

for details please see http://arduino.cc/forum/index.php/topic,148463.0.html

Copied from original issue: arduino/Arduino#1280

Arduino DUE - slow communication rate using Wire1 with Adafruit Motor Shield V2

From @HanaJin on February 19, 2015 20:39

I am using the Adafruit Motor Shield V2 library to control stepper motors. Their source code uses I2C communication under the hood to control the shield. The library uses Wire on Uno and Wire1 on Due, but both have the same default I2C bus speed. An important fact is that this is THE only difference between Uno and Due as far as the 3P library source code is concerned.

However, the same command in the library is taking a lot more (hundreds or thousands times) time on Due than Uno.

I have originally posted this question to Adafruit and am recommended by Adafruit to ask here. The original post is here
https://forums.adafruit.com/viewtopic.php?f=31&t=68292&p=346159#p346159

Is there any know issue for Wire1 on Due? Thanks for any help.

Copied from original issue: arduino/Arduino#2669

Dropped bytes at serial inputs for up to 6.6ms after reading bytes via native USB

From @EmbedHA on January 3, 2014 13:19

On the Arduino DUE, using IDE 1.5.4, following issue was found.
For a time of up to ca. 6.6ms after a SerialUSB.readBytes statement, the reception of serial bytes is corrupted by randomly dropped bytes - mostly one byte, sometimes two. This was tested tested from 115200baud down to 28800baud for the serial input and for serial1 and serial2.

An extensive description of a setup to check the issue, sample code to demonstrate the problem, test logs etc. can be found in the Arduino forum: http://forum.arduino.cc/index.php?topic=207299.0

Copied from original issue: arduino/Arduino#1784

Atmel SAM UHD_Pipe_Read can't handle packet size >255 bytes

When reading USB packets with USBHost::intransfer, packet sizes of 512 bytes would read 0 bytes.

In UHD_Pipe_Read, nb_byte_received is declared uint8_t, whereas it needs to be at least uint16_t.

Recompiling the system library using this, everything works as expected.

Not sure where to report this, but hopefully I'll be set straight if this is not the right place.

Add PERIPH_A and PERIPH_B to Due pinMode() options

From @CF20852 on August 24, 2014 16:47

I wanted to configure TIOA7 to come out on D3 on my Due. I found that I could do so by adding

#define PERIPH_A 0x3
#define PERIPH_B 0x4

to wiring_constants.h in the hardware/arduino/sam/cores/arduino folder, and

    case PERIPH_A:
        PIO_Configure(
            g_APinDescription[ulPin].pPort,
            PIO_PERIPH_A,
            g_APinDescription[ulPin].ulPin,
            g_APinDescription[ulPin].ulPinConfiguration ) ;

        break ;

    case PERIPH_B:
        PIO_Configure(
            g_APinDescription[ulPin].pPort,
            PIO_PERIPH_B,
            g_APinDescription[ulPin].ulPin,
            g_APinDescription[ulPin].ulPinConfiguration ) ;

        break ;

to the switch/case statement in the pinMode code in wiring_digital.c in the same folder.
Then in my sketch I can just write

  pinMode(3, PERIPH_B);

I figure if this is was a good idea, someone would have already done it :-) But here it is, just in case.
And yes, the PERIPH_A stuff is superfluous to my immediate need.

Copied from original issue: arduino/Arduino#2257

I2C Slave race condition leads to handler being out of sync

From @shahokun on August 18, 2015 20:42

We have an Arduino Due acting as the slave device on an I2C bus. Rarely, we will see the Arduino get "stuck" and be unresponsive. When we attached a debugger to the running processor, we saw that it was constantly getting bombarded with I2C interrupts (WIRE_ISR_HANDLER). The status flag indicated that the Arduino was in SLAVE_SEND mode and had already transmitted data (TWI TXRDY bit = 0). However, the I2C transmission would never complete, the I2C clock was pulled low, and the processor was stuck in an infinite loop of servicing an interrupt but not doing anything (i.e. none of the if blocks were entered).

The confounding factor was that the SVREAD bit of the TWI status register was 0, indicating a Master Write. If this were the case, then the correct status should be SLAVE_RECV. Working backwords from this, the likely culprit would result from a race condition at the following lines (339-343) in TwoWire::onService()

// Transfer completed
TWI_EnableIt(twi, TWI_SR_SVACC);
TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
    | TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
status = SLAVE_IDLE;

Assume a Master Read operation just completed and the Arduino has status = SLAVE_SEND. The Arduino is wrapping up the I2C transaction and enables the SVACC interrupt (TWI_EnableIt(twi, TWI_SR_SVACC);). After this happens, but before the status = SLAVE_IDLE; line is executed, a new I2C transaction comes in and triggers an interrupt. This time, it is a Master Write operation. It jumps into the handler, but because status has not been set to SLAVE_IDLE, it does not execute the first if block which would properly set status to SLAVE_RECV. Moreover, all of our Master Write transactions are two or more bytes, so the TWI would stretch the clock indefinitely because it never reads the first byte due to status being incorrect.

This is a bit theoretical because we will need to do extended testing to see if the problem goes away. The proposed solution is to reverse the order of the cleanup steps:

// Transfer completed
status = SLAVE_IDLE;
TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
    | TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IDR_TXCOMP);
TWI_EnableIt(twi, TWI_IER_SVACC);

This keeps the status flag protected against synchronization issues. It also reverses the order of the DisableIt()/EnableIt() at lines 301-303 so that you never have both groups of interrupts enabled at once. I would change the flags to use TWI_IDR_* for all DisableIt() and TWI_IER_* for all EnableIt() operations, for posterity; however, TWI_IDR_x, TWI_IER_x, and TWI_SR_x are the same value for all x, so this does not lead to any incorrect behavior.

Could anyone provide advice on whether these sorts of nested interrupts could occur in the TWI peripheral? I wasn't able to find explicit information about how the NVIC on the Due interacts with the TWI interrupt registers. I assume that since specific TWI flags are explicitly enabled and disabled that they are treated separately. In the proposed scenario, the Due would be in the handler for a TXCOMP interrupt, then get interrupted by a SVACC interrupt.

Copied from original issue: arduino/Arduino#3699

Flash Page Error in Arduino Due while programming on programming port

Hi,

I am using Arduino due in my project. The project has 14 volt battery power supply. The custom board has power supply unit that converts from 14 volts to 5 volts which goes to arduino due Vin pin.

However, most of the time I am getting the following error after which I can not use the Arduino board. Please help me how can we avoid the error. This was my 5th board and do not want to bye once in a week.

I also tried uploading the blink code, but same error. Please find the error below.

Sketch uses 22124 bytes (4%) of program storage space. Maximum is 524288 bytes.
Atmel SMART device 0x285e0a60 found
Erase flash
done in 0.032 seconds

Write 24392 bytes to flash (96 pages)

[ ] 0% (0/96 pages)
Flash page is locked
An error occurred while uploading the sketch

Due hangs with Serial.write and interrupts disable/enable

Hi,

I tried the following code on Due and found the board hung after sending "startcst". Same code on Uno or Mega worked fine with "startcstopstartcstop...." output.

The Serial.write between the two interrupt APIs seemed to have caused the problem. I know it is probably not good to call serial functions with interrupts all disabled as serial relies on them to work. But it seems that, in avr core, some logic has been added to still work with such situation(please correct me if wrong). I did not see a similar logic in the sam core, hence used the following code to try it out. My expectation(not that I like it) was that Due shall hang on the Serial.write('c') line rather than in the middle of the last Serial.write where all interrupts have been re-enabled.

I saw and read issue arduino/Arduino#2405, but not sure if this is a result of it.

void setup() {
Serial.begin(9600);
}

void loop() {
Serial.write("start\0");
noInterrupts();
Serial.write('c');
interrupts();
Serial.write("stop\0");
}

Interrupts on Due with pinMode OUTPUT, and switching pinMode

From @robinhedwards on November 20, 2013 10:16

There are two differences in the behaviour of interrupts on a Due, after comparison to an Uno (well actually a Duemilanove).

First - When I attachInterrupt() to FALLING on a digital pin, and drive the pin as an OUTPUT between HIGH and LOW, I would expect the interrupt to trigger each time the output pin is set low. This happens on the Uno, but NOT on the Due, where the interrupt only seems to fire once.

Test case:

// Interrupt comparison between Uno & Due
// Expected output (obtained on Uno)
// Pin high, count=0
// Pin low, count=1
// Pin high, count=1
// Pin low, count=2
// BUT...
// On due, count remains 1

int pin = 3;    // INT 1 on UNO
volatile int i = 0;

void test() { i++; }

void setup() {            
  Serial.begin(9600);   
  pinMode(pin, OUTPUT);
//  attachInterrupt(1, test, FALLING);    // Uno
  attachInterrupt(pin, test, FALLING);    // Due
}

void loop() {
  digitalWrite(pin, HIGH);
  Serial.print("Pin high, count="); Serial.println(i);
  delay(500);
  digitalWrite(pin, LOW);
  Serial.print("Pin low, count="); Serial.println(i);
  delay(500);
}

The expected behaviour can be obtained on the Due by replacing the digitalWrite() with digitalWriteDirect():

inline void digitalWriteDirect(int pin, boolean val){
  if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}

Now both Uno and Due count up as expected.

Second - Switching the pinMode() on a Due seems to detach the interrupts set up on the pin. You need to call attachInterrupt() again after changing e.g. from input to output mode. Again this is different behaviour from the Uno, where there is no need to do this.

Test case (replaces loop in first test case):

void loop() {
  static int secs = 3;
  digitalWriteDirect(pin, HIGH);
  Serial.print("Pin high, count=");
  Serial.println(i);
  delay(500);
  digitalWriteDirect(pin, LOW);
  Serial.print("Pin low, count=");
  Serial.println(i);
  delay(500);
  secs--;
  if (secs == 0) {
      pinMode(pin, INPUT);
      pinMode(pin, OUTPUT);
  }

More details on the forum:
http://forum.arduino.cc/index.php?topic=199320.0

Note that this difference in behaviour causes e.g. the PS2KeyboardExt2 library not to work on a Due, since the library relies on either the host or the keyboard being able to send data on the CLOCK & DATA lines. The call to pinMode() causes the interrupt on the CLOCK line to stop triggering.

Copied from original issue: arduino/Arduino#1693

Initial current leakage in Arduino Due during port initialization

Hi Arduino Support Team,

I have integrated my arduino due board with matlab for my application. I found that whenever I start to establish the connection, I found a small current leakage which always triggered my motor for (200ms).

I also contacted the MATLAB support team, and they have also encountered the same problem. I have also attached the voltage-time graph for 'due' board better understanding.

Please have a look at this bug and If it is a genuine bug Please fix it.

due

compiler.c.elf.extra_flags is in the wrong place - precompiled libs, ldflags

In platform.txt, the recipe for combining the elf file is incorrect. It should be placed before the linker flags for other static libraries like below.

Background:
In order for the arduino-builder to be able to use precompiled libs, the ldflags are loaded into compiler.c.elf.extra_flags (as per @facchinm 's commits in March 2017).

As per ld conventions, one should list the linker flags at the end. This stackoverflow issue highlights a case.

## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}"  "-L{build.path}" {compiler.c.elf.flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nano.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} -Wl,--start-group {compiler.arm.cmsis.ldflags} {compiler.c.elf.extra_flags} -lm "{build.path}/{archive_file}" -Wl,--end-group

Due / SerialUSB losing bytes (high write rate/small buffer size)

From @pottedplant on August 23, 2013 21:55

dd if=foo of=/dev/ttyACM1 bs=64 # works fine
dd if=foo of=/dev/ttyACM1 bs=1 # ~13% byte loss
dd if=foo of=/dev/ttyACM1 bs=2 # ~5% byte loss
dd if=foo of=/dev/ttyACM1 bs=3 # seems to work fine

-- edit: test sketch:
void setup() {
Serial.begin(115200);
SerialUSB.begin(115200);
}

void loop() {
char buffer[512];
int l = SerialUSB.readBytes(buffer,512);
if(l) Serial.println(l);
}

-- edit: stty settings: disabled everything except: cs8 cread clocal 115200

Copied from original issue: arduino/Arduino#1551

Interrupts problem on Arduino Due

From @mvladic on January 22, 2017 0:11

Here is relatively small sketch that I extracted from my much larger project.

In this sketch there are 2 interrupt handlers:

  • ADC (Analog-to-Digital Converter) interrupt handler is running all the time, approx. 20 times per second.
  • FAN interrupt handler is enabled for the brief period of time every 5 seconds when it should run 3 to 4 times. (In my project I use FAN interrupts to measure speed of the 3-wire fan.)

For the purpose of debugging, I'm counting, for both FAN and ADC, the number of interrupts occurred and print this counters to serial port every 1 second when I also reset them back to zero.

Here is what I get on serial port output when I run my sketch:

In the first 5 seconds, there is no FAN interrupts (as expected) and there are 20 ADC interrupts per second (also, as expected):

FAN interrupt counter = 0, ADC interrupt counter = 3
FAN interrupt counter = 0, ADC interrupt counter = 20
FAN interrupt counter = 0, ADC interrupt counter = 20
FAN interrupt counter = 0, ADC interrupt counter = 20

At this moment FAN interrupts are enabled for the brief period of time, and as expected now there are some FAN interrupts to process:

FAN interrupt counter = 1, ADC interrupt counter = 20

Now, FAN speed is measured (and printed on serial port) and FAN interrupts are again disabled:

RPM=4452

But now, suddenly, we started to receive 20 FAN interrupts per second all the time, when we should receive no FAN interrupt because they should be disabled!?

FAN interrupt counter = 22, ADC interrupt counter = 20
FAN interrupt counter = 20, ADC interrupt counter = 20
FAN interrupt counter = 20, ADC interrupt counter = 20
FAN interrupt counter = 20, ADC interrupt counter = 20
FAN interrupt counter = 21, ADC interrupt counter = 20
RPM=4419
FAN interrupt counter = 23, ADC interrupt counter = 20
FAN interrupt counter = 20, ADC interrupt counter = 20
FAN interrupt counter = 20, ADC interrupt counter = 20
FAN interrupt counter = 20, ADC interrupt counter = 20
FAN interrupt counter = 21, ADC interrupt counter = 20
RPM=4388
FAN interrupt counter = 23, ADC interrupt counter = 20
FAN interrupt counter = 20, ADC interrupt counter = 20
FAN interrupt counter = 19, ADC interrupt counter = 19
FAN interrupt counter = 20, ADC interrupt counter = 20
FAN interrupt counter = 21, ADC interrupt counter = 20
...

I checked the implementation of the functions attachInterrupt and detachInterrupt inside file WInterrupts.c from the Arduino library for the SEM boards. I have two observations/questions I think are interesting:

  1. At the beginning of the file WInterrupts.c, there is initialization of the callbacksPioB (interrupt PIN's inside my sketch belongs to port B) for every pin (32 of them) to NULL:
int i;
for (i=0; i<32; i++) {
	callbacksPioA[i] = NULL;
	callbacksPioB[i] = NULL;
	callbacksPioC[i] = NULL;
	callbacksPioD[i] = NULL;
}

When attachInterrupt is called, callbacksPioB is set to given callback:

// Set callback function
if (pio == PIOA)
	callbacksPioA[pos] = callback;
if (pio == PIOB)
	callbacksPioB[pos] = callback;
if (pio == PIOC)
	callbacksPioC[pos] = callback;
if (pio == PIOD)
	callbacksPioD[pos] = callback;

I was expecting, that in detachInterrupt, callbacksPioB will again be set to NULL, but there is no such code!?

void detachInterrupt(uint32_t pin)
{
	// Retrieve pin information
	Pio *pio = g_APinDescription[pin].pPort;
	uint32_t mask = g_APinDescription[pin].ulPin;

	// Disable interrupt
	pio->PIO_IDR = mask;
}
  1. Interrupt handler for the port B looks like this:
void PIOB_Handler(void) {
  uint32_t isr = PIOB->PIO_ISR;
  uint8_t leading_zeros;
  while((leading_zeros=__CLZ(isr))<32)
  {
    uint8_t pin=32-leading_zeros-1;
    if(callbacksPioB[pin]) callbacksPioB[pin]();
    isr=isr&(~(1<<pin));
  }
}

So, depending of PIO_ISR, multiple callbacks (given with attachInterrupt) could be called during single port B interrupt handler.

And indeed, in my case, after first 5 seconds, every time when ADC interrupt has been triggered, both ADC bit and FAN bit of PIO_ISR are set to 1 (I repeat, at this point FAN interrupts should be disabled).

Consequently, both (FAN and ADC) interrupt handlers that are set with attachIntterupt are called.

If detachInterrupt had reset callback to NULL (see point 1) FAN interrupt handler wouldn't be called. But still, the question is why ISR bit for the FAN pin is marked when FAN interrupts should be disabled?

Copied from original issue: arduino/Arduino#5897

Serial.print causes ovf when printing doubles > 10 decimal digits (Due)

Serial.print causes ovf when printing doubles > 10 decimal digits (Due)
(AVR not tested but probably similar)


void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);
  char str[30];
  
  double f1=1234567.66;
  double f2=12345678.66;
  double f3=123456789.66;
  double f4=1234567890.66;
  double f5=12345678901.66;

  Serial.println( f1 );
  Serial.println( f2 );
  Serial.println( f3 );
  Serial.println( f4 );
  Serial.println( f5 );
  sprintf(str, "%.2f", f5 );
  Serial.println(str);
  
  

}

void loop() {
  // put your main code here, to run repeatedly:

}

output:

1234567.66
12345678.66
123456789.66
1234567890.66
ovf
12345678901.66

Due: issues about Wire plus SPI, DueTimer + Scheduler + pwm + PID_v1

From @shiftleftplusone on December 14, 2015 9:25

is it possible that there are still unresolved issues about the DUE using Wire plus SPI, DueTimer + Scheduler +pwm + PID_v1 ?
I'm always runing into issues for SD init (either if SD.h or SdFat) when running those different other libs additionally, simultaneously - when outcommenting SD init, everything runs fine though.

see, e.g.
http://forum.arduino.cc/index.php?topic=365405.msg2520360#msg2520360

Copied from original issue: arduino/Arduino#4301

USB_Host.h is missing extern "C" on function prototypes from uotghs_host.c

The prototypes in USB_Host.h for the functions from uotghs_host.c should be tagged as extern "C" since the header can be included into C++ source and is referencing C code. Without this, it will fail to locate the export names in libsam_sam3x8e_gcc_rel.a, since they are not C++ decorated.

In other words, it needs the following:

#ifdef __cplusplus
extern "C" {
#endif

//extern uhd_speed_t uhd_get_speed(void);

extern void UHD_SetStack(void (*pf_isr)(void));
extern void UHD_Init(void);
extern void UHD_BusReset(void);
extern uhd_vbus_state_t UHD_GetVBUSState(void);
extern uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size);
extern uint32_t UHD_Pipe_Alloc(uint32_t ul_dev_addr, uint32_t ul_dev_ep, uint32_t ul_type, uint32_t ul_dir, uint32_t ul_maxsize, uint32_t ul_interval, uint32_t ul_nb_bank);
extern void UHD_Pipe_Free(uint32_t ul_pipe);
extern uint32_t UHD_Pipe_Read(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data);
extern void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data);
extern void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type);
extern uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type);

#ifdef __cplusplus
}
#endif

Without tagging them as extern "C", you get errors such as the following, which I encountered while experimenting with adding USB Keyboard support to an Arduino Due project using the USBHost library:

./libarduino_due_x_dbg_myproj.a(myproj.cpp.obj): In function `HIDBoot<(unsigned char)1>::Release()':
myproj.cpp:(.text._ZN7HIDBootILh1EE7ReleaseEv[_ZN7HIDBootILh1EE7ReleaseEv]+0x28): warning: undefined reference to `UHD_Pipe_Free(unsigned long)'
./libarduino_due_x_dbg_myproj.a(myproj.cpp.obj): In function `HIDBoot<(unsigned char)1>::EndpointXtract(unsigned long, unsigned long, unsigned long, unsigned long, USB_ENDPOINT_DESCRIPTOR const*)':
myproj.cpp:(.text._ZN7HIDBootILh1EE14EndpointXtractEmmmmPK23USB_ENDPOINT_DESCRIPTOR[_ZN7HIDBootILh1EE14EndpointXtractEmmmmPK23USB_ENDPOINT_DESCRIPTOR]+0x60): warning: undefined reference to `UHD_Pipe_Alloc(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)'

I would have submitted this as a pull-request, but I've just been using the auto-downloaded library and haven't bothered forking it yet.

I don't know how the Arudino IDE deals with this problem, as I'm building via a combination of the command-line and QtCreator on Linux using CMake as my build system.

Arduino Zero (SAM) SerialUSB.print(-2147483648);

Printing at the Arduino Zero (SAM) gives an error with:

SerialUSB.print(-2147483648);

Error message:
exit status 1
call of overloaded 'print(long long int)' is ambiguous

This goes well:
int s = -2147483648;
SerialUSB << s << endl;

Rapid Long term A/D faulty on Due in 1.5.7

Somewhere between Ardunio 1.5.1 and 1.5.7 the Analog Read function has been changed and in 1.5.7 after about 5000 minutes of continuously reading the A/D inputs, the function will start failing and will readout either off scale or NaN values. This was not the case in version 1.5.1 and the same exact code compiled under 1.5.1 works perfectly.

The only other clue is that the speed at which the reads occur is much faster (roughly 80 hz vs 500 hz) for the software (which does a bunch of stuff in between reads) indicating that the Analog read function is much quicker now, but has a significant issue.

Tuning malloc() on Arduino DUE

On AVR, malloc() can be tuned by setting "extern char *__malloc_heap_end;" to some value. This will prevent malloc() to use the current stack pointer for top of memory and it will create an heap for malloc().

Is there anything similar in the Arduino DUE library? malloc() implementation seems to be different.

Regards

Too many Global String constructs on Due

Too many Global String or C++ constructs in Due makes the software not running at all. Likewise if code amount goes over 100 Kbytes. Have used F-macro where there are constants for Serial port printing and response, this does not help. Seems like bss/data area gets broken during build on the Due board.
According to the stack pointer the stack size changes between 4 and 10 Kbytes, so this should not be a problem.

invalid conversion from 'void (*)()' to 'void (*)()' when using optimization flags with interrupts

I had some toruble recently with a simple program using interrupts and optimization flags on the due:

#pragma GCC push_options
#pragma GCC optimize ("O3")
void setup() {
  Serial.begin(115200);
  pinMode(7, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(7), changeState, RISING);
}
void loop() {
  Serial.println("loop");
  delay(1000);
}
void changeState() {
  Serial.println("changed state");
}

When trying to compile with the optimization options, I get the following error:

sketch_feb02a:6: error: invalid conversion from 'void (*)()' to 'void (*)()' [-fpermissive]
attachInterrupt(digitalPinToInterrupt(7), changeState, RISING);
                                                                                                 ^
arduino-1.8.5\portable\packages\arduino\hardware\sam\1.6.11\cores\arduino/WInterrupts.h:28:6: error:   initializing argument 2 of 'void attachInterrupt(uint32_t, void (*)(), uint32_t)' [-fpermissive]
 void attachInterrupt(uint32_t pin, void (*callback)(void), uint32_t mode);
        ^
exit status 1
invalid conversion from 'void (*)()' to 'void (*)()' [-fpermissive]

Which seems really odd to me. When removing the first two lines of my code, it compiles fine.

I really have no clue why this happens but maybe someone here can use this. Maybe it's a bug, maybe I shouldn't have used these flags in the first place.

variant.h or variant.cpp file for DUE to assign PC20

From @castfxman on January 19, 2016 20:15

I have an Arduino DUE based board and need to have PC20 on the SAM3X8E chip go to one of my motors. This was done by DigiX for a board based on the DUE and I am trying to do the same thing but just with one pin. I don't know if I should be rewriting the variant.h file or variant.cpp file in the Hardware\arduino\sam\variants\arduino_due_x section. Any help would be appreciated so I don't have to just print the board differently. Thank you in advance!

Copied from original issue: arduino/Arduino#4455

SAM HardwareSerial.h missing availableForWrite

I noticed that SAM UARTClass.h contains availableForWrite, but HardwareSerial.h does not. So could you add
virtual int availableForWrite(void) = 0; to SAM HardwareSerial.h
so I can use it as
HardwareSerial *port;
...
port=&Serial3
...
if ( port->availableForWrite()>0 ) ...

IDE 1.6 hampers serial speed on Due (SAM3X8E)

From @cjbaar on November 7, 2016 17:8

I have been using several Arduino Due boards under the beta IDE (1.5.8). Previously, I was able to successfully maintain a continuous serial connection between two boards (using native Serial ports) at 5,000,000bps. Using the exact same boards and code, but being programmed using a current IDE (1.6.11), I am not able to get above roughly 500,000. This is only 10% of the previous speed. I am not sure what may have changed in the Serial libraries from beta, but I would like request it be reverted to allow higher speeds.

Copied from original issue: arduino/Arduino#5577

CMSIS-DSP included with Arduino Due is not up to date

From @mochr on February 8, 2016 17:35

The CMSIS-DSP library included with the Arduino Due board installation is dated 25 July 2011 (CMSIS version 2.10), while the latest version of CMSIS-DSP is dated 20 October 2015 (CMSIS version 4.5.0).

The CMSIS package seem to contain lots of useful functions, and it would be great to have it included in the Arduino IDE. Also the included CMSIS library did not work "out of the box", but required "{build.variant.path}/libarm_cortexM3l_math.a" to be added to platforms.txt, and the .a file to be copied to "..AppData\Local\arduino15\packages\arduino\hardware\sam\1.6.6\variants\arduino_due_x".

Is there a specific reason to why the library has not been updated, or should it be possible to exchange the old library with the new without too much work?

Copied from original issue: arduino/Arduino#4544

Binary file size increased by 7kB

Final binary size has increased by almost 7 kBytes with recent changes to build options.

I think I've traced this issue back to this commit: e88a29a

Instead of "syscall_sam3.c" the standard library implementation is used, and that adds quite a lot of extra size to the final binary. Is that really necessary?

SPIClass::transfer function always return 0xEE(238) after some data exchange while using WiFi shield and Arduino Due board

From @PradeepMW on October 30, 2013 7:22

Use case: Arduino Due and WiFi shield is used to send and receive data to/from host PC(desktop) through a router.
Application is running every 10ms and WiFiClient.read() is called in this application loop.

SPIClass::transfer function always return 0xEE(238) after some data exchange while using WiFi shield and Arduino Due board.
START_CMD(0xE0) is never read in SPI_RDR register even though data is sent from host(PC) side. Once this occurs, SPI communication on Arduino Due never reads any data sent from WiFi shield.

In file \arduino-1.5.4\libraries\WiFi\arch\sam\utility\spi_drv.cpp, if the "DELAY_TRANSFER() DELAY_SPI(10)" is changed to "DELAY_TRANSFER() DELAY_SPI(200)", this behavior is not observed.

Copied from original issue: arduino/Arduino#1654

Additional SPI Interfaces using USART: SPI1, SPI2, etc.

This is mainly intended for Arduino Due, but I assume other boards could benefit from this also.

It seems that most if not all USARTs can be used in SPI Master mode, so with the Arduino Due, interfaces SPI1 & SPI2 can easily be provided via USART0 and USART1

The functionality is not so beneficial to the 328/Uno or 2560/Mega boards, due to limited interfaces and pins broken out on the board.

I would say some of the benefits are as follows:

  • Uses main female headers for SPI instead of icsp header to make Due more similar to Uno, Mega, etc.
  • Uses same type of male connecting wires/pins as used with Uno, Mega etc
  • Addresses problems with SPI devices that either don't play nice with other devices or sensitive/high speed devices like radio components that require very short leads
  • Reduced complexity with no need for additional Software SPI libraries
  • All of the above contribute to making the Due easier to interact with and more user friendly

These are some of the issues that I encountered when I first purchased a Due, since everything was so different, including a 3.3v vs 5v system, and I ended up leaving the Due on the shelf for quite a while.

The change requirements appear to be fairly minimal, with only a few lines in 4 files needing to change in my implementation. I've put together some (rough) POC code for Arduino: https://github.com/TMRh20/Arduino

I thought it best to ask if this would be considered for implementation before finalizing the code, including an additional SPI interface, and making a pull request.

The code is based on my SPI_UART driver for AVR/328, Mega & Due

Also a mandatory thanks to everybody that maintains these libraries, its been a blast using them so far!

UARTClass::write function loses the first character when it is called many times in series.

Series like this:

Serial.print("r="); 
Serial.print(25); 
Serial.print(","); 
Serial.print(1); 
Serial.print(";");

Output: r=25,1;r=25,1;r=25,1;r=5,1;r=25,1;r=25,1;

Temporary fix (in UARTClass.cpp):

size_t UARTClass::write( const uint8_t uc_data )
{
    int nextWrite = (_tx_buffer->_iHead + 1);
    if(nextWrite >= SERIAL_BUFFER_SIZE) nextWrite = 0;
    while (_tx_buffer->_iTail == nextWrite)
      ; // Spin locks if we're about to overwrite the buffer. This continues once the data is sent

    _tx_buffer->_aucBuffer[_tx_buffer->_iHead] = uc_data;
    _tx_buffer->_iHead = nextWrite;

    // Make sure TX interrupt is enabled
    _pUart->UART_IER = UART_IER_TXRDY;
   return 1;
}

USB DUEr3 Host powering cutoff with ext pwr >7Vs

If the USB port is to be used as HOST and is to supply power, then there needs to be an external power supply capable of delivering the 0.5A on the USB Host +5V.
The LM2734 is capable of doing that from 7-12V
However if the input voltage is >7V it switches off the USB Host voltage supply.
I think it should support the full range of input voltage.

Analysis: It seems to me the IC1B/LMV3518 +/- inputs are switched around (easy to do - I've got +/- wrong way round before)
I verified it working with the DUE hardware for Vin < 7V.
Workaround: There is a software fix for disabling the UOTGVBOF hw processing so that a Vin>7V can be used, but its a kluge and OTG isn't then supported.
Other messages that have discussed this
http://arduino.cc/forum/index.php/topic,140839.0.html
http://arduino.cc/forum/index.php/topic,135399.0.html
http://arduino.cc/forum/index.php/topic,146574.msg1173826.html#msg1173826
It seems to me the "Taijiuino_Pro_ArduinoDue_V1.1" has an approach that works (but I haven't tested the hw), however it doesn't detect in hw if the input drops below 7V

Due: Wire.write(int) throws away information

I noticed this when browsing the Wire.h source for the Arduino Due:

    inline size_t write(unsigned long n) { return write((uint8_t)n); }
    inline size_t write(long n) { return write((uint8_t)n); }
    inline size_t write(unsigned int n) { return write((uint8_t)n); }
    inline size_t write(int n) { return write((uint8_t)n); }

Isn't this blind casting throwing away important parts of the number? Seems to me that this could be very confusing to people when their code isn't sending their I2C device the numbers they feed it. I'm guessing these are in there to make it easy for beginners, but it's not going to make it easy, just make it harder to debug.

I propose removing them, so people have to purposefully cast and throw away the extra bytes, or implementing versions that send all the bytes separately. Of course, with the latter, then you have to worry about Endianness and I'm not sure we should be making that decision for the user.

DUE missing sfr_defs.h AVR macros causes pre DUE code to break

There a are few macros in avr/sfr_defs.h that are not provided when using a
DUE board which can cause pre DUE code to break when used on DUE.
Those most notable macro is _BV()
But there are also a few others:
bit_is_set()
bit_is_clear()
loop_until_bit_is_set()
loop_until_bit_is_clear()

None of these macros are architecture specific and could
be used on any architecture.

My recommendation would be to create a sfr_defs.h down in the DUE avr
compatibility directory with appropriate versions of these macros.
And then include <avr/sfr_defs.h> in Arduino.h

bitWrite macro incorrectly expands ternary operator

From @svatoun on December 13, 2016 8:34

let's have a bitWrite(data, bitIndex, computedValue == 5 ? 1: 0);

bitWrite macro definition lacks parenthesis around the `bitvalue' parameter, so it expands as follows

(computedValue == 5 ? 1 : 0 ? bitSet(value, bit) : bitClear(value, bit))

and the `0 ? bitSet...' is then compiled as the false branch of the ternary operator in the passed expression.
Please correct the definition as follows:

#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))

(parenthesis added)

Copied from original issue: arduino/Arduino#5714

PWML0, PWML1, PWML2, and PWML3 channels for Arduino Due

Hi,

I've found a bug and missing things in the SAM core for the Arduino Due (SAM3Xe).

First, I added the channels PWML0, PWML1, PWML2, and PWML3 in the file "hardware\arduino\sam\variants\arduino_due_x\variant.cpp" (pin 34, 36, 38 and 40).
For example for the pin 34 , I replaced the corresponding definition line by :
{ PIOC, PIO_PC2B_PWML0, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH0, NOT_ON_TIMER }, // PWML0 / PIN 34

And so on for the other pins.
I works well for PWML1, PWML2, and PWML3, however when I try to configure PWML0 it doesn't work. I think I know why :
in the file "hardware\arduino\sam\system\libsam\source\pwm.c", line 148 there is this crap line : "pPwm->PWM_CH_NUM[0].PWM_CMR = 1;"

which overwrites any configuration done on channel 0 when configuring other channel. I checked by initializing channel 0 as the last one I configure, and it works.

However modifications done in pwm.c are not taken into account. I guess I have to recompile libsam_sam3x8e_gcc_rel but I don't know how to do that. How can I do to correct this bug until it's fixed ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.