Posted on: 2009-12-29 04:22
Hi all, I just finished writing a simple blinky code (my first code) for AT91SAM9 and it compiled fine. Anyone mind looking at it to see if overall I have used the correct registers? I dont have the device yet so I can not test it. Thanks!
#include <../inc/AT91SAM9G45.h> //anything else I should include as a standard? #define F_CPU 12000000UL //12MHz int main(void) { AT91C_BASE_PIOA->PIO_PER = 1; //enables the Parallel IO; disables peripheral //can I use P0 like PAx in AVR? applicable to ARM programming for setting bits? AT91C_BASE_PIOA->PIO_OER = 1; //enables output while(1) { AT91C_BASE_PIOA->PIO_CODR = 1; //clears output; LED on (LED connected to Vcc) //delay function, which I have no idea if there is a library for this AT91C_BASE_PIOA->PIO_SODR = 1; //set output data to 1; LED off //delay function } } |
Posted on: 2009-12-29 18:44
Hi, it is correct to enable the PIO controller and to switch it to output state, but what you should know is, that you can control each single pin independently. The registers are 32bit and when you are writing 1 to this register, you enable pin 1. Is that your intention? If you instead want to enable or control another pin, for example pin number 14, you have to write a number to the register which equals 10000000000000 to the basis 2. better to write is (1 << 14) where 1 is shifted 14 bits left. AT91C_BASE_PIOA->PIO_PER = 1 << 14; The same procedure for the other registers. For the delay you can use one of the timer of your microcontroller. there is probably a software package from atmel available which covers this issue. so you don't need to write your own driver for the timer.
Posted on: 2009-12-29 19:49
Daniel G. (motello), Thank you so much for your descriptive response! I looked over the datasheet again and didn't see any settings for fuse bits. Perhaps ARM9s don't have fuse bits to set security settings and clock selection? I am also quite confused about the internal & external clocks (including the usage of PLL) from the AT91SAM9G45 datasheet. Would you please shine some light? Thank you very much!
Posted on: 2009-12-30 06:09
Hi, I have experience especially in ARM9 and Atmel MCU. There are no fuse bits or security settings for the PIO controller. You only have to enable the PIOC clock in the Power Management Controller (PMC). This feature is useful to save energy. You surely have a crystal on your board of around 15-20MHz. This frequency is of course to low for a appropriate processor clock for an ARM9. You have to configure the divider and PLL block to divide and then to multiply (PLL) the clock to the desired frequency. This part is done by the clock generator. The generated clock signal can be connected to the CPU. But for the peripherals, you will need the so called master clock. It is configured by the PMC. I recommend to use the AT91Bootstrap framework, which does all the clock initialization, so that you don't need to bother about these things in your program. Which board you want to use finally? Potentially, the manufacturer provides a adapted version of the framework which is already configured. I hope I could help you! Cheers, Daniel
Posted on: 2009-12-30 22:19
Daniel, So in order for the PIO/the above blinky to work, the PMC would have to be configured first? This means I would have to either use its internal RC oscillator or supply an external one. I am reading the "Device Initialization" section of the datasheet, and it seems to me that the initialization sequence is automatically executed (the device first uses a slow clock, then automically switches to an external main oscillator if one is present and detected), is this correct? I will be designing my own board and booting the device from a SD card. Thanks! John
Posted on: 2009-12-31 07:42
Hi, the slow clock is clocked either by an internal RC-oscillator or by an external crystal. The processor is clocked with this clock first but to increase the operation speed, it is worth to initialize the clock generator in an early state. I only know the AT91SAM9260 and there, the clock initialization is not automatically done. I thought it is the same for similar devices. which device you are exactly going to use? To use any of the peripherals, you need to initialize the master clock and to switch on this clock for your PIOC. You are going to design your own board!? Thats a very ambitious effort since you will surely encounter problems with your design and have to debug it. It is very hard to find a hardware bug when you cannot surely say that your software is bugfree and vice versa. There are so many good evaluation boards available. I use Olimex, for example. Or are you an experienced hardware designer? There is an important application note provided by atmel, dealing with signal integrity. It may be worth for you to read it: http://www.atmel.com/dyn/products/app_notes.asp?part_id=3870 http://www.atmel.com/dyn/resources/prod_documents/... Cheers, Daniel
Posted on: 2009-12-31 17:38
Daniel, Thanks for the links! It is very helpful! I've also taken a look at the AT91SAM9260 datasheet to see its similarities with the 9G45 device. Here's its device initialization (9260): Initialization follows the steps described below: 1. FIQ Initialization 2. Stack setup for ARM supervisor mode 3. External Clock Detection 4. Switch Master Clock on Main Oscillator 5. C variable initialization 6. Main osc freq detection if no external clock detected 7. PLL setup 8. Initialization of the DBGU serial port... 9. Jump to DataFlash Boot sequence. ...more boot sequences... I noticed that the actual blinky code doesn't execute until (or after) step 9, when it boots off an external memory. This means all the steps before 9 are executed from ROM, where the code is already written from Atmel (correct me if I'm wrong), so I wouldn't have to bother with the ROM code? On step 4 the device automatically switches to the main oscillator from the slow clock. The only clock configuration left for the developer is to set the Master Clock, and the PLL if one is needed. That's my understanding for now :) Thanks! John
Posted on: 2010-01-08 15:20
Daniel, Are the initialization steps automatically done? or does the programmer have to write code for it? Thanks, John
Posted on: 2010-01-09 05:15
Attached files:John wrote: > Thanks for the links! It is very helpful! I've also taken a look at the > AT91SAM9260 datasheet to see its similarities with the 9G45 device. > Here's its device initialization (9260): > > Initialization follows the steps described below: > 1. FIQ Initialization > 2. Stack setup for ARM supervisor mode > 3. External Clock Detection > 4. Switch Master Clock on Main Oscillator > 5. C variable initialization > 6. Main osc freq detection if no external clock detected > 7. PLL setup > 8. Initialization of the DBGU serial port... > 9. Jump to DataFlash Boot sequence. > ...more boot sequences... Hi John, if you are going to use the AT91bootstrap, you don't have to deal with some of the steps below. The AT91bootstrap doc gives you more information: http://www.atmel.com/dyn/resources/prod_documents/... http://www.atmel.com/dyn/products/tools_card.asp?t... The framework will load your program image from dataflash or Nandflash to SDRAM for example and runs it. But you cannot start with C-code before you haven't executet the so called startup or c-runtime code. This code does some of the above listed steps. Here is what the code has to be done: 1. Build a valid vector table (actually not a step but this table has to lie at the beginning of your image for that the framework will regard your image as valid). 2. initialize ALL stackpointer (C-code depend of the stack) 3. zero all global uninitialized variables (bss section) (it's better not to load the variables into your image (NOLOAD - instruction for the linker) to keep the file size low. 4. enable irq and fiq if needed. 5. branch to your c-code. So what you have to do is, if you are using the AT91bootstrap-framework: 1. compile your c-code with your startup code 2. link everything 3. strip all additional information in the object file (your MCU only expects instructions rather than object file header) 4. load your image to the address in ROM, which you have registered in the framework 5. load the framework to address 0x0 in your ROM. 6. reset - and your program will hopefully run :-) here is a good introduction in building bare-metal systems (w/o OS): http://www.state-machine.com/arm/Building_bare-met... Attached you will find my startup code. I hope, I haven't forgotten something. Cheers, Daniel
Posted on: 2010-01-09 05:17
John wrote: > Are the initialization steps automatically done? or does the programmer > have to write code for it? Everything has to be done by software (either by yourself or by the bootstrap framework, for example).
Posted on: 2010-01-21 15:25
Daniel, Thanks! I have re-read the datasheet (again) and it seems like the device ships with an initialization startup code already: "The Boot Program is contained in the embedded ROM. It is also called: “Rom Code” or “First level bootloader”. At power on, if the BMS pin is detected at 1, the boot memory is the embedded ROM and the Boot Program is executed." That's pretty nice! I wouldn't need to fiddle with the ROM code, at least as of yet that is :) Thanks again, John