Getting started with ARM

Go To Last Post
40 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have had SAMD21 Xplained pro demo for a few years and I finally decided to give it a try. So far I have been using AVR8, mainly Xmega lately. I prefer to work outside Atmel Studio, so with my own Makefile and editing files with Emacs using GCC toolchain, the one that came with Atmel Studio.

 

So I'm trying to make my first led toggling program in C, but can't really get started. What needs to be included? Where do I get the io definitions? With a quick search I didn't find any example codes. What changes are needed to the Makefile, except the paths?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I prefer to work outside Atmel Studio, so with my own Makefile and editing files with Emacs using GCC toolchain, the one that came with Atmel Studio.

 

Yeah, me too.   You should probably START with Atmel Studio, anyway...

Check out https://github.com/WestfW/SAMD10... , which has a bunch of observations about Atmel include file "standards", and maybe https://github.com/WestfW/Minima... which is STM32-based, but has some info on setting up non-IDE toolchains.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You would get all info from building a project in Atmel Studio first and save the output from a build. The include paths, compiler options, startup code and linker script location will be visible in the build output.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jmaja1 wrote:
With a quick search I didn't find any example codes. What changes are needed to the Makefile, except the paths?
There are examples in Atmel START for SAM D21 Xplained Pro.

Once you've configured a project in Atmel START then a Makefile can be created for it.

http://start.atmel.com/

Makefile :

http://atmel-studio-doc.s3-website-us-east-1.amazonaws.com/webhelp/GUID-4E095027-601A-4343-844F-2034603B4C9C-en-US-1/index.html?GUID-86FFBA6F-E550-4924-BEEB-EC13672F39C9

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is my first bare bone led flasher, see if it works in your environment. The delay routine is very rough but it works for now.

 

So in order to use the CODE function one must use the http version of the thread and not the https! Now I know the trick.

 

/*
 * My_flashing_led.c
 *
 * Created: 20/03/2017 8:05:06 AM
 * Author : John Samperi
 */ 

#include "sam.h"

#define LED0 PORT_PB30
#define SW0 PORT_PA15

void delay_ms (uint16_t ms)
{
	uint16_t delay;
	volatile uint32_t i;

	for (delay = ms; delay >0 ; delay--)

		{
		for (i=80; i >0;i--);	// Calibrated by ear for 1MHz clock
		}
}

int main(void)
{
    /* Initialize the SAM system */
    SystemInit();
	
	REG_PORT_DIRCLR0 = SW0;
	REG_PORT_DIRSET1 = LED0;
	
//SW0 - input enable & pull enable
	REG_PORT_OUT0 |= SW0;
	PORT->Group[0].PINCFG[15].reg = PORT_PINCFG_INEN | PORT_PINCFG_PULLEN;

    while (1) 
    {
	if (REG_PORT_IN0 & (SW0)) 	// Button off
		
		{
		REG_PORT_OUT1 &= ~ (LED0);	// LED on
		delay_ms (500);
		REG_PORT_OUT1 |= LED0;		// LED off
		delay_ms (500);
		}
		
    }
}

 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks John! I tried your code with my own Makefile, which I edited from the one I use for Xmega. First it had some unsupported compiler options, which I removed, Then it didn't find "sam.h". I copied that from the Toolchain to my working directory. Now I get errors from every definition starting from

led.c:13:16: error: unknown type name 'uint16_t'
 void delay_ms (uint16_t ms)

So clearly I should add more includes. Which ones?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried to start with Atmel Studio 6.2, which I have. It recognized the board and downloaded a new FW for the debugger. But I couldn't start a new nor an example project.

22:39:44: [ERROR] Failed to create project 'LED_TOGGLE1'. The system cannot find the file specified. (Exception from HRESULT: 0x80070002)

Maybe there are some parts of AS missing. I have never used AS for anything else but programming the SW I have compiled stand alone to the flash and debugging.  I don't like AS, too big and slow (I should by a new computer!).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
error: unknown type name 'uint16_t'
 void delay_ms (uint16_t ms)

So clearly I should add more includes. Which ones?

stdint.h

There's a set of command-line tools that you can download instead of AS:  http://www.atmel.com/tools/atmel...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

error: unknown type name 'uint16_t'
 void delay_ms (uint16_t ms)

So clearly I should add more includes. Which ones?

stdint.h

There's a set of command-line tools that you can download instead of AS:  http://www.atmel.com/tools/atmel...

 

 

Yes that solves that error, but there are many more. It seems I should

#include <samd21j18a.h>

But then I need to add include dir path to two places in CMSIS. Is that the way to do it? Now I can compile to LED.o, but not to hex/elf file. I get

(full PATH removed) arm-none-eabi/lib/armv7-m\libg.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x16): undefined reference to `_exit'
led.o: In function `main':
(full PATH removed) led.c:30: undefined reference to `SystemInit'
collect2.exe: error: ld returned 1 exit status
Makefile:25: recipe for target 'LED.elf' failed
make: *** [LED.elf] Error 1

So I guess there is a library missing. From CMSIS? Which one(s)?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"The delay routine is very rough but it works for now" - I know you don't want ASF. I (almost) don't use it either. But you can use it as an example. As far as the delay is concerned, there is a pretty simple one in common2/services/delay/sam0/cycle_counter.*

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm trying to install AS7. Seems to be quite complicated. Wants me to install an optional Windows Update first etc. Then maybe I can get ASF examples working.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You don't really have to install the whole Studio to get the ASF examples. You can just get the standalone ASF zip.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK. I just got AS7 installed before I read this. I plugged the board in and it updated drivers. Then I started a project and exported it to ASF and as a Makefile. Makefile didn't work outside AS and is very complicated. I was able to build with AS7. Then I tried to program the device in AS7. It wanted to update the FW of the EDBG driver on board. Well it failed! Now Windows sees the board as a disk drive and wants to import pictures from it. And AS7 reports a failure when I try to select EDBG as a tool. Is the board bricked now? I have JTAGICE3, but there is no probrammin connector, just the USB for programmin. How can I get it working again?

 

So frustrating to wait several hours for AS7 to install (totally jammed the PC) and nothing good as a result!

 

Now the board is working again! The solution was to restart AS7.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK. I can now work in AS7 (not without it). I'm trying to figure out what my code does. It start by calling "atmel_start_init()", which I found in atmel_start.c and it turns out to actually be "system_init()". After some more searching I found "system_init()" in dirver_init.c, but again it is just a recall to "init_mcu()". Then "init_mcu()" can be found in hal/hal_init.h and it is just "_init_chip()". Then you can find "_init_chip()" from hpl/core/hpl_init.c and it is

void _init_chip(void)
{
        hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, CONF_NVM_WAIT_STATE);

        _pm_init();
        _sysctrl_init_sources();
        _gclk_init_generators();
        _sysctrl_init_referenced_generators();

#if CONF_DMAC_ENABLE
        _pm_enable_bus_clock(PM_BUS_AHB, DMAC);
        _pm_enable_bus_clock(PM_BUS_APBB, DMAC);
        _dma_init();
#endif

So a lot of work to find yet another pussle. What's the point of this very confusing hiararchy? Is it hard to do the initialisation without these "help" files? With Xmega it would just a few lines.

 

From this I have e.g. no idea what frequency the MCU is running.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I believe the chip runs at 1MHz without messing around with the clock settings, so you have discovered the wonderful ASF which cover what you want to know...very deeply..

 

From SystemInit in system_samd21.c

 

#include "samd21.h"

/**
 * Initial system clock frequency. The System RC Oscillator (RCSYS) provides
 *  the source for the main clock at chip startup.
 */
#define __SYSTEM_CLOCK    (1000000)

uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/

/**
 * Initialize the system
 *
 * @brief  Setup the microcontroller system.
 *         Initialize the System and update the SystemCoreClock variable.
 */
void SystemInit(void)
{
	// Keep the default device state after reset
	SystemCoreClock = __SYSTEM_CLOCK;
	return;
}

 

Did you get ye olde flashing led working?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

there is a pretty simple one in common2/services/delay/sam0/cycle_counter.*

Care to expand the path please? I can't find it on my disk or is it an ASF thing?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The cycle_counter path is from the standalone ASF 3.33.0 that can be downloaded from:
http://www.atmel.com/tools/avrso...

The two files are basically like this (no idea whose github project is that):
https://github.com/marekr/asf/bl...
https://github.com/marekr/asf/bl...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Of course, to compile their OPTIMIZE_HIGH and RAMFUNC you would need to include a gazillion of include files. But in the end for gcc it expands to:
__attribute__((optimize("s")))
__attribute__((section(".ramfunc")))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using ASF without AS sounds like torture, since AS normally copies individual asf files into your project, rather than referencing them via a long string of include paths.

I haven't used "Start" (ASF4) enough to see how/whether it's different in that respect from the previous versions.  ASF3 used to bring in 1k+ of code to initialize clocks...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I'll stick with my simple delay routine, I was trying to see how may zillion instructions it takes in the delay loop when I was rudely interrupted by Studio not allowing me to change register values.

 

All I need to do.....(last famous words) is to work out a macro that is dependent on the main clock and put in the number of cycles into the loop. Worked OK with the above for a M0 NXP board, need some delay while initialising a GLCD.

 

And sorry for the inevitable derailing of the thread jmaja1. smiley

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm.  That would be the "cycle counter" and "basic delay" code that I earlier complained was lacking in any connection to reality?

https://community.atmel.com/foru...

(actually, this looks somewhat better than the code I quoted.  Perhaps it's been fixed?)

At least a 5-cycle loop, so "cycles" isn't CPU clocks...

void portable_delay_cycles(unsigned long n)
{

    __asm (
        "loop: DMB    \n"
        "SUB r0, r0, #1 \n"
        "CMP r0, #0  \n"
        "BNE loop         "
    );
}

MAYBE the weird constants here correct for that?

#define cpu_us_2_cy(us, f_cpu)  \
    (((uint64_t)(us) * (f_cpu) + (uint64_t)(7e6-1ul)) / (uint64_t)7e6)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I cut-and-pasted the delay functions into my projects a while a ago. They seem to provide delays that are close to my reality. (I usually double check everything I cut-and-paste from ASF. Not this time. But again, it seems to work. I used it in projects with 8MHz and 48MHz clocks. I cut-and-pasted it back when it was ASF 3.26.0. But diff between 3.26.0 and the current, 3.33.0, shows no differences. So, it has not changed since.)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:

I believe the chip runs at 1MHz without messing around with the clock settings, so you have discovered the wonderful ASF which cover what you want to know...very deeply..

 

Did you get ye olde flashing led working?

 

Yes I did with a project started in AS7 and compiled there. Had to rename your delay, since there was already anothe with the same name. The LED flashed much faster with your delay, so maybe the chip runs at a higher clock.

 

Still haven't been able to compile with a Makefile in the CygWin environment I like to work in. The Makefile I got from export using the AS7 project start doesn't work either. It can't locate gcc. In AS7 you can see all the multiple -I  etc options given to gcc. Maybe I can learn from there how to make my own Makefile.

 

Is it so that almost all use ASF with SAM? Hard to find any example codes without! This is the best I found so far, but it is only very basic and doesn't include Makefile: https://eewiki.net/display/micro...

 

For AVR there are so many good examples without ASF. I would prefer to use my own AVR code with just changing what is needed to change. Then I would know what I'm doing.

 

I guess for USB you almost must use ASF. Haven't used USB yet with Xmega or any other than FTDI.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is it so that almost all use ASF with SAM?

 I don't think so.  The Arduino core itself does not use ASF,  for instance...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

Is it so that almost all use ASF with SAM?

 I don't think so.  The Arduino core itself does not use ASF,  for instance...

 

But still a similar one. So very few do everything by them selves?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't use ASF (except for USB (host)). Over time I have seen a number of others who don't seem to use it either.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ezharkov wrote:
I don't use ASF (except for USB (host)). Over time I have seen a number of others who don't seem to use it either.

So how do you compile? What kind of init fucntions do you use? Still haven't had luck with my Makefile. I'm just testing the options AS7 use.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jmaja1 wrote:
Is it so that almost all use ASF with SAM?

I just started with ARM/SAM devices about a year ago. At first, I tried ASF and found it to be very bloated (same with START). I looked at what ASF did for many of the peripherals and then rewrote them to minimize the bloat. The last peripheral to fall was the USB, but thanks to Alex Taradov, I even got that under control. See thread here.

Since then all of my code is ASF free.

P.S. Alex has starter projects for several devices on github.

David (aka frog_jr)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How can I get that LED flasher work without ASF and AS7? I can now get it to comply with my Makefile, but nothing seems to happen when I after flashng the board and debugging online shows just

FFFFFFFE  ??? 		Memory out of bounds or read error

I tried the sys_init() from Alex (in main.c needs nvw_data.h). What else is needed or is my Makefile doing something wrong? Alex seems to link startup_samd21.c. What is that used for?

 

Glad I asked (myself)! Adding startup_samd21.c made it all work! Now I can even see normal source code in the debugger. Are there some other files you must take from CMSIS or ASF?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

startup_samd21.c is the only one. Once you get to your main(), the rest is completely up to you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the above flashing light code I only include sam.h then studio pulls in a zillion files when compiling. (break at sam.h as the list is too long)

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks! Now I got a timer working etc. Finally a bit of light out of the tunnel. Next project is to get USART working with my own code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And don't forget to share. wink

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>> The Arduino core itself does not use ASF,  for instance...

But still a similar one. So very few do everything by them selves?

The SAM3X Arduino core looks to be built on "libsam", which I guess was the predecessor to ASF.

The SAMD Arduino core looks to be built on "bare metal."

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is an interesting thread. I usually start with ASF example project and, step by step, extract useful code from ASF, greatly simplify it and move in my folders (usually ports/sam/...).

Most of the time I'm able to exclude completely ASF files. The only ASF files I need (moved in my folder) are the following:

- syscalls.c file (I don't know exactly why)

- cmsis folder (there are some useful ARM-standard macros here, for example those related to SysTick)

- utils/cmsis/samdxx folder (all the symbols and register definitions for the chosen MCU)

- linker script

 

With those file, moved in my folder, I could have a project that doesn't need ASF files at all.

 

Regarding initialization, you need to configure clocks and peripherals.

 

If your application can run with internal oscillator, it's enough (this is the default at startup). Otherwise you need to configure and enable the oscillator (XOSC, XOSC32, ...) and at least a Generic Clock Generator 0 that feeds the ARM core.

For example, if you have the classical configuration with a crystal connected to XOSC:

SYSCTRL->XOSC.reg = SYSCTRL_XOSC_XTALEN | SYSCTRL_XOSC_STARTUP(0xF) | SYSCTRL_XOSC_GAIN(3);
SYSCTRL->XOSC.reg |= SYSCTRL_XOSC_ENABLE;
    while(!SYSCTRL->PCLKSR.bit.XOSCRDY)
        ;
GCLK->GENCTRL.reg = GCLK_GENCTRL_ID_GCLK0 | GCLK_GENCTRL_SRC_XOSC | GCLK_GENCTRL_GENEN;

Maybe you need to change wait state for Flash access (the number of wait states depend on the frequency): 

 NVMCTRL->CTRLB.bit.RWS = 1;     // 1 wait-state for Flash access

Regarding peripheral. I wrote some simple inline functions for managing GPIO (all the pins are GPIO at startup, so you don't need to mess with I/O multiplexing for GPIO use):

#include "samd20.h"

static inline int
pin_get_group(uint8_t pin)
{
   return pin / 32;
}

static inline int
pin_get_num(uint8_t pin)
{
   return pin % 32;
}

static inline void
pin_set_output(uint8_t pin)
{
   uint8_t group = pin_get_group(pin);
   uint8_t pinnum = pin_get_num(pin);
   PORT->Group[group].PINCFG[pinnum].reg = 0;
   PORT->Group[group].DIRSET.reg = (1 << pinnum);
}
static inline void
pin_set_output_level(uint8_t pin, uint8_t level)
{
   uint8_t group = pin_get_group(pin);
   uint8_t pinnum = pin_get_num(pin);
   if (level) PORT_IOBUS->Group[group].OUTSET.reg = (1 << pinnum);
   else       PORT_IOBUS->Group[group].OUTCLR.reg = (1 << pinnum);
}

static inline void
pin_set_input(uint8_t pin)
{
   uint8_t group = pin_get_group(pin);
   uint8_t pinnum = pin_get_num(pin);
   PORT->Group[group].PINCFG[pinnum].reg = PORT_PINCFG_INEN;
   PORT->Group[group].DIRCLR.reg = (1 << pinnum);
}
static inline void
pin_set_input_pullup(uint8_t pin)
{
   uint8_t group = pin_get_group(pin);
   uint8_t pinnum = pin_get_num(pin);
   PORT->Group[group].PINCFG[pinnum].reg = PORT_PINCFG_INEN | PORT_PINCFG_PULLEN;
   PORT->Group[group].OUTSET.reg = (1 << pinnum);      /* Imposta pull-up */
   PORT->Group[group].DIRCLR.reg = (1 << pinnum);
}
static inline void
pin_set_input_pulldown(uint8_t pin)
{
   uint8_t group = pin_get_group(pin);
   uint8_t pinnum = pin_get_num(pin);
   PORT->Group[group].PINCFG[pinnum].reg = PORT_PINCFG_INEN | PORT_PINCFG_PULLEN;
   PORT->Group[group].OUTCLR.reg = (1 << pinnum);      /* Imposta pull-down */
   PORT->Group[group].DIRCLR.reg = (1 << pinnum);
}
static inline uint8_t
pin_get_input_level(uint8_t pin)
{
   uint8_t group = pin_get_group(pin);
   uint8_t pinnum = pin_get_num(pin);
   return 0 != (PORT_IOBUS->Group[group].IN.reg & (1 << pinnum));
}

Remember to activate continuous input sampling on input pins, otherwise you can't read their state with IOBUS access (I usually enable continuous input sampling for all the pins at startup):

PORT->Group[0].CTRL.reg = 0xFFFFFFFF;
PORT->Group[1].CTRL.reg = 0xFFFFFFFF;

If you need to change the I/O multiplexing of a pin, I usually use the following:

/* First 16 pins (Px00-Px15) */
PORT->Group[0].WRCONFIG.reg = 
    PORT_WRCONFIG_WRPINCFG | 
    PORT_WRCONFIG_WRPMUX | 
    PORT_WRCONFIG_PMUXEN |
    PORT_WRCONFIG_PMUX(PORT_PMUX_PMUXE_D_Val) | (1 << <pin number>);

/* Last 16 pins (Px16-Px31) */
PORT->Group[<port>].WRCONFIG.reg = 
    PORT_WRCONFIG_HWSEL | 
    PORT_WRCONFIG_WRPINCFG | 
    PORT_WRCONFIG_WRPMUX | 
    PORT_WRCONFIG_PMUXEN |
    PORT_WRCONFIG_PMUX(PORT_PMUX_PMUXE_D_Val) | (1 << (<pin number> - 16));

<port> is the number of the port (PAxx is port 0, PBxx is port 1)

<pin number> is the number of the in the port (Px03 is 3, Px15 is 15)

Of course you need to change PORT_PMUX_PMUXE_D_Val with your multiplexing configuration.

 

There other methods to configure I/O multiplexing, for example to change the configuration at a group of pins at the same time. However I always use the previous code without any problems.

 

Now there are many many peripherals. I try to write simple drivers for my needs. For example for SERCOM/USART, DAC, ADC and so on. The callback drivers present in ASF are very very bad, in my opinion.

 

Even if I am usually able to avoid ASF at all, I still use Atmel Studio 7. I never tried, but I don't think it's difficult to compile and link the project with command line tools (or external IDE, such as CodeBlocks or Emacs or Eclipse). The Makefile used by Atmel Studio is present in the output directory, so you can copy and use it.

 

What stops me to abandon Atmel Studio is debugging. With the small monster MCUs you need a good debug support. It's very useful to see register contents, memory (Flash and RAM) contents, put breakpoints, run a single step and so on. How could you have the same things with an external tool that isn't made by the silicon manufacturers?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I got the UART working (with buffers and intterupts) through the EDGB on the demo board. Needed a bit of datasheet (1000+ pages!) and example reading. Some differences to Xmega how registers work and not all of them are clear by just reading the datasheet.

 

I edit with Emacs,  run make on CygWin command line, program the flash and dedug with AS7. Works nicely although I would prefer to skip AS7, which is so slow and big (1 GB RAM). Are there command line tools like avrdude for programing?

 

Continuous input sampling and IOBUS?? When is this necessary? This seems to work OK without it when you enable input (even for output like LED0)

if(REG_PORT_IN1&(LED0))

Is IOBUS a faster option?

 

I haven't quite understood how the generic clock control register works. Initialising timer I do this:

REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3;

Then initialising uart I do this:

REG_GCLK_CLKCTRL = GCLK_CLKCTRL_ID(SERCOM3_GCLK_ID_CORE) |
    GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

It works, but I can't see from the datasheet why it works. So the latter doesn't overwrite the former with zeros. So how do you know when you must use |= or give the full register value and when it just sets the new values and doesn't zero the rest. How can these settings be undone?

 

How are you using pin numbers? The function pin_get_group and pin_get_num suggested that you are using something not in the datasheet. E.g. for PB30 you would use 61?

 

It seems to be quite hard to use the ports and pins in an easy to read and understand manner. E.g. setting the RX pin for UART I used

  //RX as input
  REG_PORT_DIRCLR0 = PORT_PA23;
  //Enable reading input and multiplexing
  PORT->Group[0].PINCFG[23].reg = PORT_PINCFG_INEN | PORT_PINCFG_PMUXEN;

  //Choose SERCOM3 as PMUX for TX and RX. PMUX = 22/2 = 23/2;
  PORT->Group[0].PMUX[11].reg = PORT_PMUX_PMUXO_C | PORT_PMUX_PMUXE_C;
 

I could have named defined PORT_PA23 as RX_EDGB, but what's the use when you need to know it's in Group 0 and for PMUX you need to use 11?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jmaja1 wrote:
I edit with Emacs,  run make on CygWin command line, program the flash and dedug with AS7. Works nicely although I would prefer to skip AS7, which is so slow and big (1 GB RAM). Are there command line tools like avrdude for programing?
'atprogram.exe' in Atmel Studio.

In-lieu of atprogram is OpenOCD.

Akin to AVRDUDE is Atmel SAM-BA or its alternative in BOSSA.


Atmel Studio

Command line utility (CLI)

http://www.atmel.com/webdoc/GUID-ECD8A826-B1DA-44FC-BE0B-5A53418A47BD/index.html?GUID-7EFC7945-0589-4C6C-9F45-C40B07349FC4

http://docs.platformio.org/en/latest/platforms/atmelsam.html#packages

http://openocd.org/

http://www.atmel.com/tools/ATMELSAM-BAIN-SYSTEMPROGRAMMER.aspx

https://github.com/shumatech/BOSSA

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gchapman wrote:

atprogram.exe' in Atmel Studio.

 

Thanks! That was even easy to use. I had quite a few problems with AVRDUDE and used AS instead for first flashing of Xmega, since I never got AVRDUDE to work with JTAGICE3 + PDI. AVRDUDE works fine with serial bootloader.

 

So now I can use AS only for debugging, for which it is OK.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jmaja1 wrote:
I had quite a few problems with AVRDUDE and used AS instead for first flashing of Xmega, since I never got AVRDUDE to work with JTAGICE3 + PDI.
JTAGICE3 is in AVRDUDE 6.3

JTAGICE3 with version 3 firmware (via Atmel Studio or atfw.exe) has a USB HID capability which was added to AVRDUDE after 6.3


http://savannah.nongnu.org/forum/forum.php?forum_id=8461 (AVRDUDE 6.3 released)

http://www.atmel.com/webdoc/jtagice3/jtagice3.whats_new.html

http://svn.savannah.gnu.org/viewvc/avrdude/trunk/avrdude/ChangeLog-2016?revision=1393&view=markup

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Works nicely although I would prefer to skip AS7, which is so slow and big (1 GB RAM). Are there command line tools like avrdude for programing?

You can skip AS7 for programming, but you can't avoid it for debugging. I searched for an alternative debugger tool, but I couldn't set it.

 

Continuous input sampling and IOBUS?? When is this necessary? This seems to work OK without it when you enable input (even for output like LED0)

if(REG_PORT_IN1&(LED0))

Is IOBUS a faster option?

 Yes, IOBUS should be faster. When you set the level of an output pin high, you really want to see it immediately on the scope. I understood this couldn't happen in certain circumstances, because of a complex bus where a lot of peripherals could communicate. To avoid this, use IOBUS feature. I usually enable it for all the pins.

I haven't quite understood how the generic clock control register works.

 Some registers, such as GCLK->CLKCTRL, aren't normal registers. You see only one register, but you can configure many generic clocks with it. When you write to it, the ID field says which generic clock you are configuring (1 for WDT, 2 for RTC, and so on). So your second instruction doesn't really overwrite the previous value.

How are you using pin numbers? The function pin_get_group and pin_get_num suggested that you are using something not in the datasheet. E.g. for PB30 you would use 61?

In code you must use numbers to identify a single pin among many. I know datasheet uses PB30 and not 62 (it should be 62 and not 61), because of port/group aggregation. But in code is simpler to use integers. You can always defines pins as:

   #define PIN_PB30    62

and use PIN_PB30 in your functions. Anyway I didn't invent this method, I simple copied it from ASF.