1

I am using the Arduino Due and I am programming it with Atmel Studio 6.2. I have had a HUGE learning curve using this IDE and the Atmel ASF. Nothing is straightforward as it is in the Arduino IDE. Nonetheless, I want to toggle an LED on and off with a simple interrupt on a pull-up configured tactile button. This is my code:

#include <asf.h>
#include "pio.h"

// Define the LED pins 
#define BLUE_LED2 PIO_PC28 // Arduino Due pin 3
#define BLUE_LED3 PIO_PC26 // Arduino Due pin 4
#define BLUE_LED4 PIO_PC25 // Arduino Due pin 5
#define BLUE_LED5 PIO_PC24 // Arduino Due pin 6
#define BLUE_LED6 PIO_PC23 // Arduino Due pin 7

// Define the button pins
#define BUTTON_1 PIO_PC22
#define BUTTON_2 PIO_PC21

// Define function prototype for button interrupt
void button_press_handler(uint32_t, uint32_t);
void toggle_LED(uint32_t);


int main (void)
{
    /* Initialize the SAM system. */
    sysclk_init();

    // Initialize input/out 
    ioport_init();
    pmc_enable_periph_clk(ID_PIOC);
    pmc_enable_periph_clk(ID_PIOB);


    // Set LED pins as outputs and set there default values (off)
    pio_set_output(PIOC, BLUE_LED2, LOW, DISABLE, ENABLE); 
    pio_set_output(PIOC, BLUE_LED3, LOW, DISABLE, ENABLE); 
    pio_set_output(PIOC, BLUE_LED4, LOW, DISABLE, ENABLE); 
    pio_set_output(PIOC, BLUE_LED5, LOW, DISABLE, ENABLE); 
    pio_set_output(PIOC, BLUE_LED6, LOW, DISABLE, ENABLE); 

    // Set button pins as pull-up inputs 
    pio_set_input(PIOC, BUTTON_1, PIO_PULLUP);
    pio_set_input(PIOC, BUTTON_2, PIO_PULLUP); 

    // Configure button input pin interrupt mode and handler (Falling Edge)
    pio_handler_set(PIOC, ID_PIOC, BUTTON_1,  PIO_IT_RISE_EDGE, button_press_handler);
    pio_handler_set(PIOC, ID_PIOC, BUTTON_2,  PIO_IT_RISE_EDGE, button_press_handler);

    // Enable the interrupts
    pio_enable_interrupt(PIOC, BUTTON_1); 
    pio_enable_interrupt(PIOC, BUTTON_2); 
    NVIC_EnableIRQ(PIOC_IRQn); 

    while(1){
         // Doing stuff in here...
    }
}

Then this is my interrupt routine:

// Interrupt handler for button press
void button_press_handler(uint32_t a, uint32_t b)
{
    // Turn the LED's on or off
    toggle_LED(BLUE_LED2);
    toggle_LED(BLUE_LED3);
    toggle_LED(BLUE_LED4);
    toggle_LED(BLUE_LED5);
    toggle_LED(BLUE_LED6);
}

// Function to toggle LED on/off
void toggle_LED(uint32_t LED){

    if (pio_get(PIOC, PIO_TYPE_PIO_OUTPUT_0, LED))
    pio_clear(PIOC, LED);
    else
    pio_set(PIOC, LED); 
}

Things work normal and as expected up until about 18 seconds in. After 18 seconds, the LED turns off if it is on. I tested this by setting LED 2 HIGH by default and removing the interrupt all together:

pio_set_output(PIOC, BLUE_LED2, HIGH, DISABLE, ENABLE); 

In this case, the LED will stay on forever, but about every 18 seconds, the LED will flash off then back on once quickly. Why is this happening?

3
  • I realized that the problem was occurring due to the fact that I was not initializing the board. All I needed to do was add "board_init();" underneath my system clock initialization code in main(void) and now it works. – Hooplator15 Apr 26 '15 at 21:03
  • 1
    You should answer yourself and mark that as the answer so that other people will realize the question has a solution. This is expected behavior arduino.stackexchange.com/help/self-answer – jdr5ca Apr 27 '15 at 0:08
  • accept your own answer to close this question – user31481 Nov 4 '17 at 23:36
2

Again, figured this out. I simply forgot to put in board_init(); Also, since board_init() already calls ioport_init(), I had to disable that.

Now I have this:

int main (void)
{
    /* Initialize the SAM system. */
    sysclk_init(); // Initialize the System Clock
    board_init();  // Initialize the board

....

1

The symptoms you describe are consistent with your program crashing after 18 seconds. I expect you will find something in this that is the problem:

while(1){
     // Doing stuff in here...
}

To debug this, add something to the startup that is unique or clearly identifiable:

  • a print "reset" to a serial port if you have one
  • in your case, blink the led's in sequence 2,3,4,5,6

Once you confirm that your program is resetting, strip out everything in the

// Doing stuff in here...

With the program stripped down, it should keep the LED's lit.

If the LED's still do not stay lit, but you see your reset indicator, consider power. Microcontrollers will reset when the voltage droops too low. The LED's might be consuming enough power to reduce the voltage below the trip point. Connect a voltmeter to the supply voltage to see if it is stable.

The time delay can be associated with the power supply heating at higher current. The LM2734 chip on the Due has a thermal shutdown, same as most voltage regulators. If your hardware draws enough current to overheat, the chip will shutoff, cool down and turn back on.

5
  • About drawing too much current, I don't think that is the case because all the LED's work perfectly in Arduino IDE. I made absolutely no hardware changes on the board. It works in Arduino, but not in Atmel Studio so I think this must be a software issue. – Hooplator15 Apr 26 '15 at 4:42
  • Also, as for the while loop, I literally have nothing in there. I simply have the comment to remind me to do stuff once I sort this issue out. – Hooplator15 Apr 26 '15 at 4:42
  • Improper handling of interrupts will cause a reset. – Gerben Apr 26 '15 at 12:36
  • @JohnAugust It would be best to add what you have already tried in the question. – jdr5ca Apr 26 '15 at 20:58
  • I fixed the issue, it was because I did not include "board_init();" – Hooplator15 Apr 26 '15 at 21:03
0

This may be because the ATSAM3X8E chip has a watchdog: from the datasheet section 15.1,

The Watchdog Timer can be used to prevent system lock-up if the software becomes trapped in a deadlock. It features a 12-bit down counter that allows a watchdog period of up to 16 seconds (slow clock at 32.768 kHz). It can generate a general reset or a processor reset only. In addition, it can be stopped while the processor is in debug mode or idle mode.

board_init() almost certainly disables the watchdog.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.