UC3B @ High Speed

From time to time I forget how to set the UC3B CPU to run at full speed. The EVK1101 comes with a 12MHz crystal, and I use the same crystal for my board because it is a nice number that let me easily reach the 48Mhz needed for driving the USB port correctly. So I will not change it, but I will try to get the most of the CPU.
The UC3B comes with the following oscilators:

  • 2 PLL [80MHz – 240MHz]
  • Crystal Osc. [0.4MHz – 20MHz] (but I will let it fixed at 12MHz)
  • Crystal Osc. [32KHz] (The RTC clock)
  • RC Osc. [115KHz] (May be useful for low power consumption apps, but not this case.)

The Power Management unit handles all clock generators. A close look at the part of the unit responsible for driving CPU, HSB, PBA and PBB clocks is shown here:

So if we want to run our UC3B as fast as cars do in “The Fast & The Furious” (but without Nitro), we have to use PLL. The rules for setting PLL propertly are:

  1. Crystal must be between 0.4MHz and 16MHz
  2. PLL multiplication factor goes from 3 to 15
  3. PLL frequency must go from 80MHz to 240MHz

PLL output frecuency is the result of  ((Crystal frequency/ OSC_DIVIDE) *  PLL_MUL_FACTOR). As the datasheet states the maximum frequency for the UC3B is 60MHz. So the following should configuration can be applied in order to get 60MHz for CPU and 30MHz for PBA (USB will use PBB and PLL1 in order to get 48Mhz from the 12Mhz source)

Crystal Osc: 12MHz
PLL multiplication factor: 9
PLL divisor: 1
PLL0 = (12MHZ / 1) * (9+1) = 120MHz (and we are safe at this frequency)
PLL0 output divided by two = 1 (yes)
CPU frequency = PLL0 output /2 = 60MHz
PBA frequency = 30MHz (Pheriperial Bus A clock)

 
In order to get this configuration we have to choices. We can do it manually, or we can tell ASF (AVR Software Framework) to set the registers based on our needs.
The old way:

And the simplest way of configuring the frequency we want is by doing the following.

 
 
 
 
 
 
 
Of course, both ways do the same thing. But this lastest one, lets the ASF do the maths and the configuration for you.
It is important not to forget to set the CPU frequency for NewLib and to initialize the USB clock after setting the main clock source.
 

First contact with AVR Studio 5 (beta)

After years of being the lastest (and only) official IDE for AVR microcontrollers, Atmel decided to launch a new version of the famous AVR Studio. Of course between this AVR Studio 5 release (which is still beta) and AVR Studio 4, Atmel tried a new IDE for AVR32 based on Eclipse.
From my point of view the AVR32 Studio based on Eclipse was the best decision Atmel did. It brought something new all the developers that love and use AVR products. The fact is that having an IDE based on Eclipse (which is based on Java) let users run the IDE in several platforms and not only Windows (as AVR Studio 4 did). Moreover, Atmel delivered an AVR32 Toolchain for Windows and Linux, and the lastest one was easily ported to OS X.
The new version of AVR Studio (5) is based on…. Visual Studio! Yes… it can only runs on Windows (don’t try Wine, it’s like trying to drive a new BMW X5 with an old FIAT 600 engine, you will not go very far). But, let’s judge it by  how it works, and not how it was constructed.

As you might image when listening that it was based on Visual Studio, the ASM/C/C++ compiler is integrated with the instaler. And also the software framework, even though this last one is only available for AVR32 and the XMega series. There is no ASF for the 8bit family (yet).

Once the project is created, everything is very similar to AVR Studio 4. May be this is one of the reason why Atmel choose Visual Studio instead of Eclipse for the new IDE.

At a glance there are a few interesting things that were necessary to have. For example, you can import an AVR Studio 4 project into this new IDE.

As it happens with AVR32 Studio (based on Eclipse) you have a few predefined code snippets, and can add yours.

The project properties panel is more complete, you can choose different microcontrollers, and configure the toolchain in the same way you do it with Eclipse (for AVR32)

To sum up, AVR Studio 5 it’s a better IDE than Studio 4, it’s not perfect or portable to other platforms, but it gives me a good impression.

Software Framework comes to rescue: FAT32

Embedded applications make intense use of information these days, both for reading configurations and writing logs and process’ results. Developers tend to use built-in FLASH or small EEPROM memories to archive these tasks but as information gets complex, systems’ features grow and programming is done in high level languages, the need of a reliable and flexible solution takes more importance.
Is in this situation when embedded systems designers incorporates technologies available in personal computers, servers and mobile devices. Using mass storage devices like USB keys, USB-SATA disks and memory cards is a great solution for several problems including portability, capacity and reliability.
The Atmel’s AVR32 Software Framework incorporates low level drivers for SD/MMC cards, AT45DB memories and a USB mini Host driver capable of communicating with USB keys and disks. Moreover FAT12/16/32 is present as a high level API that can be connected to any low level driver.
Creating a file inside a directory, and writing something inside is as simple as this

For making use of these drivers and components the project must be configured with the following features:

  • Drivers
    • PM
    • SPI
    • USART
    • GPIO
    • INTC
  • Components
    • SD/MMC Memory Card
  • Services
    • FAT File System
    • Memory Control Access Services

Then it is necessary to set CONFIG/conf_access.h properly to activate the SD/MMC logic unit.

/*! name Activation of Logical Unit Numbers
*/
//! @{
#define LUN_0 DISABLE //!< On-Chip Virtual Memory.
#define LUN_1 DISABLE //!< AT45DBX Data Flash.
#define LUN_2 ENABLE //!< SD/MMC Card over SPI.
#define LUN_3 DISABLE
#define LUN_4 DISABLE
#define LUN_5 DISABLE
#define LUN_6 DISABLE
#define LUN_7 DISABLE
#define LUN_USB DISABLE //!< Host Mass-Storage Memory.
//! @}


/*! name Activation of Interface Features
*/
//! @{
#define ACCESS_USB DISABLED //!< MEM <-> USB interface.
#define ACCESS_MEM_TO_RAM ENABLED //!< MEM <-> RAM interface.
#define ACCESS_STREAM DISABLED //!< Streaming MEM <-> MEM interface.
#define ACCESS_STREAM_RECORD DISABLED //!< Streaming MEM <-> MEM interface in record mode.
#define ACCESS_MEM_TO_MEM DISABLED //!< MEM <-> MEM interface.
#define ACCESS_CODEC DISABLED //!< Codec interface.
//! @}

And then call this SPI initialization code from your main code:

/*! brief Initializes SD/MMC resources: GPIO, SPI and SD/MMC.
*/
static void sd_mmc_resources_init(void) {
// GPIO pins used for SD/MMC interface
static const gpio_map_t SD_MMC_SPI_GPIO_MAP = { { SD_MMC_SPI_SCK_PIN,
SD_MMC_SPI_SCK_FUNCTION }, // SPI Clock.
{ SD_MMC_SPI_MISO_PIN, SD_MMC_SPI_MISO_FUNCTION }, // MISO.
{ SD_MMC_SPI_MOSI_PIN, SD_MMC_SPI_MOSI_FUNCTION }, // MOSI.
{ SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION } // Chip Select NPCS.
};
// SPI options.
spi_options_t spiOptions = {
.reg = SD_MMC_SPI_NPCS,
.baudrate = SD_MMC_SPI_MASTER_SPEED, // Defined in conf_sd_mmc_spi.h.
.bits = SD_MMC_SPI_BITS, // Defined in conf_sd_mmc_spi.h.
.spck_delay = 0, .trans_delay = 0, .stay_act = 1, .spi_mode = 0,
.modfdis = 1 };
// Assign I/Os to SPI.
gpio_enable_module(SD_MMC_SPI_GPIO_MAP, sizeof(SD_MMC_SPI_GPIO_MAP)
/ sizeof(SD_MMC_SPI_GPIO_MAP[0]));
// Initialize as master.
spi_initMaster(SD_MMC_SPI, &spiOptions);
// Set SPI selection mode: variable_ps, pcs_decode, delay.
spi_selectionMode(SD_MMC_SPI, 0, 0, 0);
// Enable SPI module.
spi_enable(SD_MMC_SPI);
// Initialize SD/MMC driver with SPI clock (PBA).
sd_mmc_spi_init(spiOptions, PBA_HZ);
}

AVR32 Software Framework Drivers: USART

As we get into AVR32 programming it’s unavoidable to use drivers from the software framework. First because we are not going to reinvent the wheel every time we want to start a new project, then because they are fully tested and documented. Moreover, they provide code-compatibility between several AVR32 families (UC3A, UC3B, UC3L, AP7…)
I thought that a good first approach to AVR32 software framework was using and understanding the USART. The USART is essential for those who don´t have a JTAG for debugging (I know, it’s not too expensive, but may be for a student or somebody that just want to test the platform) because you can send debug content to your Mac/PC using the serial port (this means using the USART in UART mode).
Our first program will be an UART echo program. This means that it will echo every character sent from the PC. We will learn a few things about AVR32 and how to code with this example, more than be can imagine at first.
First of all, ensure you have the lastest version of AVR32Studio and AVR32 Software Framework. Both available and for free at http://www.atmel.com/products/AVR/. Inside AVR32Studio create a “New AVR32 C project from template”.

In the template you will choose your board/mcu configuration. In this case, I will use EVK1101 as the board, and AT32UC3B0256 ad the MCU.

Once the project is configured we will select the Software Framework drivers that we will use.

Once the Software Framework drivers are selected, replace your main.c with main.c (USART)
Let’s take a close look to the code:
First of all we will include the header files from the framework that we will use, this includes the AVR32 IO definition, GPIO, USART and Power Manager.

// Include Files
#include <avr32/io.h>
// EVK1101
#include "board.h"
// Drivers
#include "power_clocks_lib.h"
#include "gpio.h"
#include "usart.h"

then we will define the frequency for the PBA, which USART we will use, and which GPIO pins we will be connected to that UART

#define TARGET_PBACLK_FREQ_HZ FOSC0  // PBA clock target frequency, in Hz
// Usart Pins compatible with EVK1101
#define MY_USART               (&AVR32_USART1)
#define MY_USART_RX_PIN        AVR32_USART1_RXD_0_0_PIN
#define MY_USART_RX_FUNCTION   AVR32_USART1_RXD_0_0_FUNCTION
#define MY_USART_TX_PIN        AVR32_USART1_TXD_0_0_PIN
#define MY_USART_TX_FUNCTION   AVR32_USART1_TXD_0_0_FUNCTION
#define MY_USART_CLOCK_MASK    AVR32_USART1_CLK_PBA
#define MY_PDCA_CLOCK_HSB      AVR32_PDCA_CLK_HSB
#define MY_PDCA_CLOCK_PB       AVR32_PDCA_CLK_PBA

in the main function we will configure the GPIO pins. this is done by creating a variable of type gpio_map_t which includes the pin and its function.

	static const gpio_map_t MY_USART_GPIO_MAP = {
			{MY_USART_RX_PIN, MY_USART_RX_FUNCTION},
			{MY_USART_TX_PIN, MY_USART_TX_FUNCTION} };

then we set up the UART parameters, this includes the baudrate, parity and stop among others.

	static const usart_options_t MY_USART_OPTIONS = { .baudrate= 57600, .charlength= 8,
			.paritytype= USART_NO_PARITY, .stopbits = USART_1_STOPBIT,
			.channelmode = USART_NORMAL_CHMODE };

next we configure the Power Clock in order to use the crystal connected to OSC0.

	pcl_switch_to_osc(PCL_OSC0, FOSC0, OSC0_STARTUP);

We need to tell the GPIO module that it must assign the GPIO pins to the USART

	gpio_enable_module(MY_USART_GPIO_MAP,sizeof(MY_USART_GPIO_MAP)/sizeof(MY_USART_GPIO_MAP[0]));

For enabling the UART the framework provides a function for initializing in RS232 mode

	usart_init_rs232(MY_USART,&MY_USART_OPTIONS,TARGET_PBACLK_FREQ_HZ);

And last, but not least, you can see in this few lines of code how to write and read from the UART

	usart_write_line(MY_USART, "This is an echo program)n");
	while(1) {
		c = usart_getchar(MY_USART);
		usart_putchar(MY_USART,c);
	}

AVR32 UC3B Hello World!

Inside AVR32 Studio I’ll create a new project (File -> New -> AVR32 Example). As I’m going to use the EVK1101 as my base development it may be a good idea to build my first app over a test program like “an example project”.  I have choosen the USART Example, which includes the necessary startup files for the MCU plus a small echo client, and modified it to only show “Hello World”.

The good thing about developing over the AVR32 Software Framework is that is fully documented and you will find comments everywhere, what makes the learning curve smooth.

After building this project, you can deploy it either by using an AVR32 Target configured inside AVR32Studio, or by calling the external tool BatchISP which cames with FLIP.
This is a call to BatchISP for programming the “Hello World” example:

batchisp -hardware usb -device at32uc3b0256 -operation erase f memory flash blankcheck loadbuffer HelloWorld.elf program verify start reset 0

Running batchisp 1.2.4 on Mon Mar 29 22:56:02 2010
AT32UC3B0256 - USB - USB/DFU
Device selection....................... PASS
Hardware selection..................... PASS
Opening port........................... PASS
Reading Bootloader version............. PASS    1.0.2
Erasing................................ PASS
Selecting FLASH........................ PASS
Blank checking......................... PASS    0x00000 0x3ffff
Parsing ELF file....................... PASS    HelloWorld.elf
Programming memory..................... PASS    0x00000 0x02e9f
Verifying memory....................... PASS    0x00000 0x02e9f
Starting Application................... PASS    RESET   0
Summary:  Total 11   Passed 11   Failed 0

The AVR32 UC3B Platform

The AVR32 is not only a microcontroller, it’s a complete development platform that works smoothly on Linux and Windows, and may be OSX without too much pain. By development platform I mean having an IDE not only for building projects, but also for managing them (version control, plugins that support development, built-in programmer and debugger), a programmer that requires few external components, and a good compiler (if possible in C/C++).  If you found a platform with all these positive points, for free, and all the tools provided by the  manufacturer, then you will enjoy programming on this platform. Atmel provides all these things and a software framework that let you reach your time to market faster.
Basically the fact that Eclipse was the IDE choosen by Atmel for developening over AVR32 plus the software framework where the things that motivated me to start learning about this new version of AVR. Moreover, the microcontroller is not a mid-range AVR, but a full 32bit MCU capable of running Linux, or a small RTOS, delivering nearly 83DMIPS at 60MHz using 3.3V and 23mA.
My starting MCU is the AT32UC3B0256 which has the following features:

  • 256Kbytes of Flash
  • 32Kbytes of SRAM
  • 83 Dhrystone MIPS at 60MHz
  • 44 I/O pins in a 64 pins TQFT package
  • USB 2.0 Full Speed and On The Go

A very basic diagram shows how things are connected in the AVR32 UC3B.

Recently Atmel annouced a new member of the UC3B family, the AT32UC3B0512, which has 96Kbytes of SRAM and 512Kbytes of Flash in the same TFQF64 package.
My first steps in this platform are guided by the ATEVK1101 which is an evalutation kit for the AT32UC3B. This kit allows a rapid and friendly development without the need of dealing with a SMD component and a custom PCB.

The AVR32 Studio IDE can be found at: http://www.atmel.com/dyn/products/tools_card_mcu.asp?tool_id=4116
For programming the AVR32 using the USB DFU (we need Flip: http://www.atmel.com/dyn/products/tools_card_mcu.asp?tool_id=3886
And last but not least, Atmel provides a toolchain of GCC for compiling apps: http://www.atmel.com/dyn/products/tools_card_mcu.asp?tool_id=4118
So let’s get started with a simple Hello World project…