avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] 16 bit Timer Issue.


From: prabu
Subject: [avr-gcc-list] 16 bit Timer Issue.
Date: Mon, 5 Jan 2009 17:36:31 +0530

Hello Every Body

                Can Anyone help me to clear my Timer Issue. 
Am very new to this ....

Controller  : AT90CAN128
Extn crystal: 8MHz
Tool:ICCAVR

I am using timer1 for the delay of 1 second.

So the value for the timer TCNT1 (0x1E84).( Clk/1024 prescale).

My intention is I have to generate  1 sec periodic delay.


AT every one sec the portc PC6 will be toggled ......(LED connected to this
pin).The LED was not toggling ..

Can anyone find verify my code......That would be more helpful for me......

MY code:



#include <ioCAN128v.h>
#include <macros.h>
#inclue<stdio.h>     
// Target : AT90CAN128
// Crystal: 8.0000Mhz
  

unsigned int data;


void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = 0x00;
 DDRB  = 0x00;
 PORTC = 0x00; //m103 output only
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00;
 PORTE = 0x00;
 DDRE  = 0x00;
 PORTF = 0x00;
 DDRF  = 0x00;
 PORTG = 0x00;
 DDRG  = 0x00;
}

//TIMER1 initialize - prescale:1024
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1Sec
// actual value:  1.000Sec (0.0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xE1; //setup
 TCNT1L = 0x7C;
 OCR1AH = 0x1E;
 OCR1AL = 0x84;
 OCR1BH = 0x1E;
 OCR1BL = 0x84;
 OCR1CH = 0x1E;
 OCR1CL = 0x84;
 ICR1H  = 0x1E;
 ICR1L  = 0x84;
 TCCR1A = 0x00;
 TCCR1B = 0x05; //start Timer
}

#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
 //TIMER1 has overflowed
 TCNT1H = 0xE1; //reload counter high value
 TCNT1L = 0x7C; //reload counter low value
 PORTC  = ~(1<<PC6);
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 //XDIV  = 0x00; //xtal divider
 //XMCRA = 0x00; //external memory
 port_init();
 timer1_init();

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EICRB = 0x00; //extended ext ints
 EIMSK = 0x00;
 TIMSK1 = 0x01; //timer interrupt sources
 //ETIMSK = 0x00; //extended timer interrupt sources
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

//
void main(void)
{
 init_devices();
 while(1);
 
}








          

-----Original Message-----
From: address@hidden
[mailto:address@hidden On Behalf Of Spiro
Trikaliotis
Sent: Monday, January 05, 2009 4:16 PM
To: address@hidden
Subject: [avr-gcc-list] Re: Sharing code between a bootloader and an
application.

Hello Jim,

Jim Brain wrote:
> Spiro Trikaliotis wrote:
>> There is also a specific firmware available which can update the
>> bootloader itself.
>>   
> I'm looking at the /xu1541/update-bootloader/ area on SF, but I don't 
> understand what I am looking at:
>
>     * Are you stating that this code will allow a firmware image to
>       update a bootloader?  Can you clarify how it does this?

Yes, I am stating this.

Of course, the firmware image needs some help of the bootloader in order
to be able to do it. And: I am clearly aware that this is not very good
documented yet.

Here is some text I wrote in July 2007 on the OpenCBM mailing list
(aren't you there, too?) about this approach: 

Note0: I use the names BIOS and bootloader unterchangeable.

Note1: When speaking about addresses, I am counting the
       addresses in octets, not in the 16-bit-numbering scheme as seen
       by the processor itself

Note2: There is a jumptable in the bootloader code at $1FF0 (cf.
       bootloader/biostable.S, called "biosdata")

Note3: The spm() subroutine which gives a SPM command from the
       bootloader area must reside somewhere in $1880-$1FFF; its address
       is part of the jumptable at $1FF0 (cf. note 2)
        
Note4: My Bootloader region is too small. Thus, I have some additional
       data in the area $1700-$17FF which I consider to be part of the
       bootloader, although technically, it is not.

Note5: The bootloader determines if a firmware is available by checking
       $0000-$0001. If there is $FFFF (like after clearing the flash
       page), then no firmware is available, and the bootloader will not
       call the firmware. If there is anything but $FFFF, the bootloader
       will call the firmware, unless a special input pin is low.

------- begin description from July 2007 ----

How is the update done? From the ATMega8 data sheet, one finds out that
the command SPM is needed for programming. That program is only valid
from the bootloader region ($1800-$1fff).

Thus, there is a subroutine in that region for every bootloader. When I
want to update the bootloader, the following steps are performed:

A. Program $1800 (the reset "vector") to contain JMP $0; that is, if
   we crash in this procedure, the updater will be started again.
   This programming is done with the help of the spm() subroutine in the
   bootloader.

B. Now, program a *new* spm() subroutine into $1840-$187f.

C. From now on, use the *new* spm() subroutine in the bootloader to:

   C1. reprogram $1880-$1FFF. This will also reprogram the "old" spm()
       subroutine, which is somewhere in that region.
   C2. reprogram $1700-$17ff.

D. Now, switch back to the spm() subroutine of the bootloader again.
   Remember, the bootloader is "almost" completely rewritten, only
   $1800-$187F is missing. If the spm() subroutine is not in that area,
   it will be available again.
   Thus, we have to make sure that spm() is *never* placed into the
   $1800-$187f area!

E. Reprogram $1840-$187f, overwriting the "new" spm() (which is not
   needed anymore)

F. As last step, reprogram $1800-$183f. This will remove our RJMP $0
   from $1800; instead, the reset vector will point back to the
   bootloader.

G. Delete the first page ($0000-$003F). This makes sure the updater will
   not be called anymore.

H. Restart the bootloader by resetting the ATMega8.

This routine is "almost" secure against power failure. It is criticial
against a power failure while in step A. or F.; if this happens, the
RESET vector might end being corrupt. There is nothing we can do against
this!

Note that step B. first checks if the new spm() is already available.
For this, a byte-by-byte compare is performed. If the new spm() is
identical to what would have been written, spm() is not written! This
way, we prevent a problem in case the new spm() had already been written
and some other pages, too, and then a power failure occurred. In this
case, the "original" spm() might be corrupt, so, we would not be able to
write the new spm(), but crash.

Additionally, note that after each flash of a page, the system checks if
everything was written correctly. This way, I want to prevent problems
because of low power as much as possible. After three tries, the system
will stop with a continuously flashing LED. Most probably, this will
occur when the system power is low.


The approach works perfectly here, and I think I do not have any races
against power failure anymore (but  A. and F.; but, as I told, these are
the only problematic steps, and I fear I cannot prevent this).

Any thoughts, comments, any races I did not think about?

------- end description from July 2007 ----

Regards,
Spiro.

-- 
Spiro R. Trikaliotis                              http://opencbm.sf.net/
http://www.trikaliotis.net/                     http://www.viceteam.org/



_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list






reply via email to

[Prev in Thread] Current Thread [Next in Thread]