0
\$\begingroup\$

I'm completely new to Atmel ARM microcontrollers and beyond a single class a couple of years ago and some arduino tinkering, new to "proper" mcu's in general.

So therefore I am having trouble with the simplest of tasks, that is building a simple LED blink program and programming it to the chip.

The MCU is an ATSAM3X8E, mounted on an arduino due (but I am not using any arduino software, I'm trying to treat it as a simple breakout board for the MCU).

I am using an example project that came with Atmel studio 7 called clock_example11 (which is apparently made for the arduino due so the board config should be okay?) except I just tried to modify the blinking LED to pin 14 of port B. It builds seemingly fine.

So then I tried programming it over USB, using the SAM-BA 2.15 software. I start the program, connect to the chip successfully (with the "at91sam3x8-ek" board preset), I select the built .bin file as the send file name in the flash tab and send it to address 0x80000 which if I understand correctly is the start of the flash and is where the chip boots from if I set the boot from flash bit. Then I send the file, and when I try comparing the memory with the sent file, it matches, so the flash was programmed successfully it seems. Then I execute the "boot from flash" script and even "select flash0 for boot" for good measure.

But, nothing happens. The LED doesn't blink. And I don't know where to go from here. I don't know which of the steps I did, if not all of them, are wrong. Can someone give me some tips? Here is the main source file:

#include "asf.h"

/* Global ul_ms_ticks in milliseconds since start of application */
volatile uint32_t ul_ms_ticks = 0;

/**
 * \brief Wait for the given number of milliseconds (using the ul_ms_ticks generated
 * by the SAM microcontroller system tick).
 *
 * \param ul_dly_ticks  Delay to wait for, in milliseconds.
 */
static void mdelay(uint32_t ul_dly_ticks)
{
    uint32_t ul_cur_ticks;

    ul_cur_ticks = ul_ms_ticks;
    while ((ul_ms_ticks - ul_cur_ticks) < ul_dly_ticks) {
    }
}

/**
 * \brief Handler for System Tick interrupt.
 *
 * Process System Tick Event and increments the ul_ms_ticks counter.
 */
void SysTick_Handler(void)
{
    ul_ms_ticks++;
}

/**
 * \brief Initialize the clock system and blink a LED at a constant 1 Hz frequency.
 *
 * \return Unused (ANSI-C compatibility).
 */
int main(void)
{
    sysclk_init();
    board_init();

    /* Setup SysTick Timer for 1 msec interrupts */
    if (SysTick_Config(sysclk_get_cpu_hz() / 1000)) {
        while (1) {  /* Capture error */
        }
    }

    while (1) {
        ioport_toggle_pin_level(IOPORT_CREATE_PIN(PIOA,14));
        mdelay(500);
    }
}

EDIT: I think my code was the problem, because now I was able to program the chip. For the record I modified the main function to this: http://pastebin.com/f0Vnw2Q3

\$\endgroup\$
3
  • \$\begingroup\$ it would be useful to see what does the board_init() function. to get the led blinking you need to enable PIOA by "pmc_enable_periph_clk(ID_PIOA);", init the ioport service by "ioport_init();", set the pin direction to output by "ioport_set_pin_dir(PIO_PA14_IDX,IOPORT_DIR_OUTPUT);". These steps are essential. \$\endgroup\$
    – bakcsa83
    Jan 14, 2016 at 16:11
  • \$\begingroup\$ also, if you want to learn Atmel SAM ARM's i would highly recommend to buy an xplained board. Atmel Studio is full with example projects which you can run on it. It helps a lot to understand ASF and the MCU. \$\endgroup\$
    – bakcsa83
    Jan 14, 2016 at 16:50
  • 1
    \$\begingroup\$ You need to send a "boot image" for it to automatically load from flash, I believe Atmel SAM Bootloader checks for a specific byte sequence at the beginning of the image. I would recommend writing your application to RAM first, then using SAM-BA to jump to the first address, if it works as expected then you can debug why the flash loading isn't working. \$\endgroup\$
    – crasic
    Jan 14, 2016 at 18:39

1 Answer 1

4
\$\begingroup\$

Something I noticed is that you have the following line to toggle the state:

ioport_toggle_pin_level(IOPORT_CREATE_PIN(PIOA,14));

While technically there's nothing wrong with that most Atmel examples define the port in conf_board.h so if you haven't changed that you've probably also missed configuring the port as an output. Try adding the following to configure the port as an output and it's probably a better practice to define the port name in a define:

#define LED IOPORT_CREATE_PIN(PIOA,14)
ioport_set_pin_dir(LED, IOPORT_DIR_OUTPUT);

Then in your main code:

ioport_toggle_pin_level(LED);

Regardless of whether that works on not it's worth taking a look through some of the ASF generated code in the subdirectories of the project to become familiar with where Atmel normally place the port configuration and initialisation code. There may be other pins being defined as outputs that your board doesn't like. I couldn't find a schematic for the Arduino Due but it might also be worth finding out what crystal frequency it uses, it may be different enough that the clock initialisation code selects a frequency that is too high to work.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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