Electrical – Programming Atmel SAM MCU using SAM-BA

atmelcmicrocontrollerprogramming

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

Best Answer

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.