[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-gcc-list] 16 bit Timer Issue.
[avr-gcc-list] 16 bit Timer Issue.
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
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......
// Target : AT90CAN128
// Crystal: 8.0000Mhz
unsigned int data;
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%)
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
//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
//stop errant interrupts until set up
CLI(); //disable all interrupts
//XDIV = 0x00; //xtal divider
//XMCRA = 0x00; //external memory
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
[mailto:address@hidden On Behalf Of Spiro
Sent: Monday, January 05, 2009 4:16 PM
Subject: [avr-gcc-list] Re: Sharing code between a bootloader and an
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
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
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
E. Reprogram $1840-$187f, overwriting the "new" spm() (which is not
F. As last step, reprogram $1800-$183f. This will remove our RJMP $0
from $1800; instead, the reset vector will point back to the
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
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 ----
Spiro R. Trikaliotis http://opencbm.sf.net/
AVR-GCC-list mailing list