0

I have microprocessor at32uc3b0256 and I want turn on leds, (simple program from examples). To do this I use Atmel Studio. I found sample code:

#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock speed
#endif

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
  DDRC = 0xFF; //Makes PORTC as Output
  while(1) //infinite loop
  {
    PORTC = 0xFF; //Turns ON All LEDs
    _delay_ms(1000); //1 second delay
    PORTC= 0x00; //Turns OFF All LEDs
    _delay_ms(1000); //1 second delay
  }
}

But when i wrote it to Atmel Studio i got some errors, Atmel Studio dont see DDRC and PORTs as variable. How can I fix it? Screen form Atmel Studio

enter image description here

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
skajar
  • 99
  • 1
  • 7
  • 2
    Well, what are they called in io.h? Maybe there's some #define you need to set for the actual device? – Martin James Apr 12 '16 at 11:02
  • 1
    Avr32 io is more complicated then for normal avr's. Google for avr32 io examples. For one thing you need avr32/io.h – Unimportant Apr 12 '16 at 12:08
  • Some examples here: https://www.kth.se/social/upload/300/Writing%20your%20own%20program%20%28AVR32%20Studio%29_pm_20100910.pdf – Unimportant Apr 12 '16 at 17:28
  • I know it is a bit older question but still no answers so I added one. Also before writing code I recommend to download newest datasheet for your chip and check the chip bugs log against your version of chip to avoid problems. (Once I lost months on UC3L GPIO interrupts to workaround one problem only realizing each possibility I think of was another bug in a chip ended up with external HW workaround) – Spektre Jul 15 '16 at 09:02

1 Answers1

1

You are using GPIO example for AVR8 architecture. AVR32 architecture is completely different introducing GPIO module as separate HW block connected through PBA (I think). There are no registers like DDRC,...

You can look at AVR32 architecture as on network of subcomponents where MCU core is only one of the modules. There are 2 main buses PBA and PBB each connected to different modules.

To make AVR32 firmware work you need do this:

  1. configure and start main MCU core clock you want to use

    AVR32 MCU core is usually running at low 32KHz clock after reset. To achieve better performance you need higher clock up to 66MHz. I usually start PLL at some common frequency and divide all clocks (CPU,PBA,PBB,HSB) from it later. As a source for the PLL you need some clock for example internal RC or oscillator driven by external crystal. If you want also USB then you need to take in mind it needs specific frequency so compromise ... For more info check SCIF module in datasheet and or in examples.

  2. switch to it when started properly

    Either wait a bit (100ms) or check if clock is running directly (SCIF module has some capabilities for it I think).

  3. configure/start used HW modules

  4. now do your stuff

  5. Bootlaoder

    Another thing you need to take care of is the boot loader. I do not like JTAG as I have a bad experience with it (does not take much to fry it and the programing with it is really uncomfortable). With JTAG you can easily wipe out bootloader (each chip is shipped with it) and trust me getting it back to work is really nasty.

    Bootloader on the other hand is simple and elegant. For example I use FLIP and has simple comandline file for programing chip. Then I just open command prompt execute it. And on each rebuild/programming I just hit up arrow to repeat last command in the prompt and hit enter. In comparison to many clicks with JTAG is this much faster and simpler. Here example of the cmd:

    avr32-objcopy -O ihex AT32UC3L064.elf AT32UC3L064.hex
    Batchisp -device AT32UC3L064 -hardware RS232 -port COM1 -baudrate 115200 -operation onfail abort memory flash erase f blankcheck loadbuffer AT32UC3L064.hex program start reset 0
    

    The avr32-objcopy.exe is in the AVR studio bin directory.

    With Bootloader you need to tell the compiler your program is not starting at 0x0000 because that would be overlapping with bootloader. To do that see the trampoline examples.

This is how my AVR32 app usually looks like:

#include <avr32/io.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "intc.c"
#include "gpio.c"
#include "pm_uc3l.c"
#include "scif_uc3l.c"
#include "adcifb.c"
#include "flashcdw.c"
#include "pdca.c"
//#include "pwma.c"
#include "tc.c"
#include "usart.c"
#include "eic.c"

#include "genclk.h"
#include "osc.c"
#include "dfll.c"
#include "sysclk.c"

#include "status_codes.h"
#include "cycle_counter.h"
#include "sleep.h"
#include "delay.c"
#define cpu_clk 30000000

#define _LED AVR32_PIN_PA04


void system_init()
    {
    delay_init(115000);

    Disable_global_interrupt();
    INTC_init_interrupts();
    scif_start_rc120M();
    delay_ms(100);

    pm_set_clk_domain_div((pm_clk_domain_t)AVR32_PM_CLK_GRP_CPU,PM_CKSEL_DIVRATIO_4);
    pm_set_clk_domain_div((pm_clk_domain_t)AVR32_PM_CLK_GRP_PBA,PM_CKSEL_DIVRATIO_4);
    pm_set_clk_domain_div((pm_clk_domain_t)AVR32_PM_CLK_GRP_PBB,PM_CKSEL_DIVRATIO_4);
    pm_set_clk_domain_div((pm_clk_domain_t)AVR32_PM_CLK_GRP_HSB,PM_CKSEL_DIVRATIO_4);
    pm_set_all_cksel(SCIF_RC120M_FREQ_HZ,cpu_clk,cpu_clk,cpu_clk);
    flashcdw_set_flash_waitstate_and_readmode(cpu_clk);
    pm_set_mclk_source(PM_CLK_SRC_RC120M);

    delay_init(cpu_clk);
    }
//------------------------------------------------------------------------------------------------
void wait_ms(U32 dt)
    {
    U32 t0,t1;
    t0=Get_system_register(AVR32_COUNT);
    dt=((dt*cpu_clk)+999)/1000;
    t0&=RDTSC_mask;
    for (;;)
        {
        t1=Get_system_register(AVR32_COUNT);
        t1&=RDTSC_mask;
        if (t0>t1)  t1+=RDTSC_mask+1;
        if ((t1-t0)>=dt) break;
        }
    }
//------------------------------------------------------------------------------------------------
void wait_us(U32 dt)
    {
    U32 t0,t1;
    t0=Get_system_register(AVR32_COUNT);
    dt=((dt*cpu_clk)+999999)/1000000;
    t0&=RDTSC_mask;
    for (;;)
        {
        t1=Get_system_register(AVR32_COUNT);
        t1&=RDTSC_mask;
        if (t0>t1)  t1+=RDTSC_mask+1;
        if ((t1-t0)>=dt) break;
        }
    }
//------------------------------------------------------------------------------------------------
int main(void)
    {
    system_init();

    // here init what you need
    gpio_configure_pin(_LED,GPIO_DIR_OUTPUT|GPIO_INIT_HIGH);

    for (;;)
     {
     // here do your stuff
     gpio_tgl_gpio_pin(_LED);
     wait_ms(200);
     }
//------------------------------------------------------------------------------------------------

I do not use framework manager instead I include the stuff myself... and my framework is rewritten to avoid unnecessary includes and slowdowns of compilation. Also beware that framework updates are not always compatible so sometimes after update your code will not compile ... It is better to have one solid framework and not update it unless you really need to.

Select only the modules you need to (no need to include them all). For example you need intc,gpio,scif etc my includes are from bigger project so many of them are useless for you and also not all headers/modules are available for all of the AVR32 chips.

I got a bit off topic (I think was necessary) so back to GPIO

The API and architecture is completely changed. Do not be fooled by the pin names. For example pin PA35 does not mean port A pin 35 !!! There is no port PA It is just naming convention without any real meaning to the architecture which is a bit silly and took me a while to got along with it. There are as many ports as needed to cover all the pins. Each port support 32 pins and the pin number is the real thing you need to know.

Each pin is defined somewhere in avr32/io.h as a define like AVR32_PIN_PA04 and it contains numerical value of the pin position in chips GPIO. To obtain gpio port/mask you just do this:

port = pin>>5
mask = 1<<(pin&31)

Now to access GPIO registers directly I recommend to look at gpio.c. You can set,res,test,read 32 pins at a time to speed up (if they are at the same port). The speed is dependent mainly on the buss clock (usually PBA for GPIO) so if your clock for it is low do not expect high toggle rate. beware GPIO access is slow and if not used wisely can kill the performance of your code...

If HW pins selected for your App are done wisely you can have really fast speeds. For example I got toggle speeds around 2-5 MHz !!!

Here example of setting a pin from gpio.c

void gpio_set_gpio_pin(uint32_t pin)
{
  U32 bit= 1 << (pin & 0x1F);
  volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];
  gpio_port->ovrs  = bit; // Value to be driven on the I/O line: 1.
  gpio_port->oders = bit; // The GPIO output driver is enabled for that pin.
  gpio_port->gpers = bit; // The GPIO module controls that pin.
}

You can use this to set multiple pins at the same port simply by exchanging bit with the mask of all pins you want to set ...

If you are using Interrupts for GPIO beware that the interrupt controller INTC is also a separate module connected by buss and wrongly set clock or wait states can cause huge problems.

Spektre
  • 49,595
  • 11
  • 110
  • 380