AtMega164P run-away UART 0 Tx

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just started working with the 164P. Ending reset init with sleep mode, waiting on RTC interrupt (T2_Overflow). Instead, I get vector 23. This should be UART 0 Tx. I've actively disabled it, and the interrupt it rode in on. Still, it is triggering, and on two chips - so it's not the device. I haven't found any other interrupts triggering. I've verified the WDT vector matches, so I'm left believing that U0_Tx is really happening. I'm running external at 16MHz - 0.067µsec, and the rate of interrupt is ~7.8125msec. That's a count of 117k at system clock rate. My RTC is 32.768kHz on OSC2 and I'm running async. I've just noticed that at 32kHz the 7.8msec is a count around 244. This is pretty close to 256, so I may have a new course to follow. Please, somebody point me in the right direction before I grab me a shopping cart and start touring the county. :?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Show some code, say which tools (compiler) you are using, and make sure you are really building for your desired target. Find the interrupt vector table in the compiler output, and examine/post that.

If I had to guess, I'd wager on wrong target. I plopped a Mega16 app into a Mega644 and a Mega164P without any problems. Is this a fresh '164 app, or ported from a different chip? There >>are<< things that need to change when you port.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here you go, Lee
; ************************************************************************
.include "AC03-102 reg.asm"
.include "Mega164.asm"
;.include "AC03-102 mac.asm"
; ************************************************************************
.ORG 0
; Vector No. AtMega164
rjmp Reset_Int ; 1
reti ;rjmp Ext_Int0 ; 2
reti ;rjmp Ext_Int1 ; 3
reti ;rjmp Ext_Int2 ; 4
reti ;rjmp PC_Int0 ; 5
reti ;rjmp PC_Int1 ; 6
reti ;rjmp PC_Int2 ; 7
reti ;rjmp PC_Int3 ; 8
rjmp Reset_Int ;reti ;rjmp WDT_Int ; 9
reti ;rjmp T2_CompA ; 10
reti ;rjmp T2_CompB ; 11
rjmp T2_Ovfl ; 12
reti ;rjmp T1_Capt ; 13
reti ;rjmp T1_CompA ; 14
reti ;rjmp T1_CompB ; 15
reti ;rjmp T1_Ovfl ; 16
reti ;rjmp T0_CompA ; 17
reti ;rjmp T0_CompB ; 18
reti ;rjmp T0_Ovfl ; 19
reti ;rjmp SPI_STC ; 20
reti ;rjmp U0_Rx ; 21
reti ;rjmp U0_Empty ; 22
rjmp Reset_Int ;reti ;rjmp U0_Tx ; 23
reti ;rjmp AC_Comp ; 24
reti ;rjmp A2D_Done ; 25
reti ;rjmp EE_Rdy ; 26
reti ;rjmp TWI_Int ; 27
reti ;rjmp SPM_Rdy ; 28
reti ;rjmp U1_Rx ; 29
reti ;rjmp U1_Empty ; 30
reti ;rjmp U1_Tx ; 31
/* ; Vector No. AtMega16
rjmp Reset_Int ; 1
reti ;rjmp Ext_Int0 ; 2
reti ;rjmp Ext_Int1 ; 3
reti ;rjmp T2_Comp ; 4
reti ;rjmp T2_Ovfl ; 5
reti ;rjmp T1_Capt ; 6
reti ;rjmp T1_CompA ; 7
reti ;rjmp T1_CompB ; 8
reti ;rjmp T1_Ovfl ; 9
rjmp T0_Ovfl ; 10
reti ;rjmp SPI_STC ; 11
reti ;rjmp U0_Rx ; 12
reti ;rjmp U0_Empty ; 13
reti ;rjmp U0_Tx ; 14
reti ;rjmp A2D_Done ; 15
reti ;rjmp EE_Rdy ; 16
reti ;rjmp AC_Comp ; 17
reti ;rjmp TWI_Int ; 18
reti ;rjmp Ext_Int2 ; 19
reti ;rjmp To_Comp ; 20
reti ;rjmp SPM_Rdy ; 21*/
; ************************************************************************
; Reset Int
Reset_Int:
CLI
clr ZeroReg

ldi Temp,0x00 ; 0 0 0 0 , 0 0 0 0
out PortA,Temp ; Esnd Esns A5 K60, Tst S30 Tnk Rm
ldi Temp,0x80 ; 1 0 0 0 , 0 0 0 0
out DDRA,Temp ; o i i i , i i i i

ldi Temp,0x00 ; 0 0 0 0 , 0 0 0 0
out PortB,Temp ; SClk Mi Mo Prg, Shft Data Frm XCl
ldi Temp,0xde ; 1 0 1 1 , 1 1 1 0
out DDRB,Temp ; o i o o , o o o i

ldi Temp,0x10 ; 0 0 0 1 , 0 0 0 0
out PortC,Temp ; Osc1 Osc2 - S30, WS Sda Scl -
ldi Temp,0x40 ; 0 1 0 0 , 0 0 0 0
out DDRC,Temp ; i o i i , i i i i

ldi Temp,0x00 ; 0 0 0 0 , 0 0 0 0
out PortD,Temp ; - 60R 60Cl 60Ce, 60D - Do Di
ldi Temp,0x7a ; 0 1 1 1 , 1 0 1 0
out DDRD,Temp ; i o o o , o i o i

; ldi Temp,0xff ; Put the stack at the end of RAM
; sts SPL,Temp
; ldi Temp,0x03 ; Put the stack at the end of RAM
; sts SPH,Temp
ldi Temp,0x80
sts ACSR,Temp ; Disable analog comparator
sts UCSR0B,ZeroReg
sts UCSR1B,ZeroReg
sts PCICR,ZeroReg

ldi Temp,0x58
sts WDTCSR,Temp
ldi Temp,0x4f
sts WDTCSR,Temp ; Set watchdog for four seconds

; ldi Temp,0x20
; sts ASSR,Temp ; Select async external ops for T2
; ldi Temp,0x01 ;
; sts TCCR2B,Temp ; Start Timer 2
;Set_TCCR2B:
; lds Temp,ASSR ; Wait for timer to start
; sbrc Temp,0
; rjmp Set_TCCR2B
; ldi Temp,0x01 ;
; sts TIMSK2,Temp ; Enable overflow interrupt

ldi Temp,0x01
sts SMCR,Temp ; Enable sleep
SEI
sbi PortD,DeBug ; $$$$$$$$$$$$$$$$$$$$$$$$$$$
sleep
rjmp Los_Entry

End Code

Note that I have vectors for the 16 built, but commented out. My Mega164 include file has IO starting at 0x00, but I start adding 0x20 at TIFR0 (0x35 versus 0x15), so STS is required instead of OUT.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The interrupt vectors in the mega162 are 4 bytes each, not 2 bytes. You need to use jump instead of rjmp (or put a nop or whatever in to take up the space).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The interrupt vectors in the mega162 are 4 bytes each, ...

...as they are in the Mega164. ;)

Off-Earth, you might consider making a full vector table with an .ORG for each, using the chip-include defines. Hmmm--I was looking for an example to save you typing time. The datasheet vector table example doesn't use a .ORG for each, but you can see that they are two words wide.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

All better - thanks for the effort.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Back in the day we jumped to spurious interrupt. I got lazy putting reti at each unused vector with the Tiny series, so now I'll jump to No_Int instead.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Back in the day I was more familiar with AVR assembly instruction set, it was stated somewhere in the documentation, that no real code should be placed in the interrupt vector table, just RJMPs. This was because then they could reserve the right not to execute the RJMP xxxx code, but to read the address where to jump directly from the address part of the RJMP xxxx instruction.

So nowadays there are also these AVRs which need two word JUMPs, which propably just run the instruction like before, but still I would be paranoid and avoid the use of RETI in the interrupt table.

But hey, my info is like 5 years old, so please correct me if I am wrong. And since it works, why not use it.. And when it does not work on the next generation AVRs, it can be fixed when porting. So I think I'll just go back to sulk in the darkness now and forget these pointless details :)

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Back in the day I was more familiar with AVR assembly instruction set, it was stated somewhere in the documentation, that no real code should be placed in the interrupt vector table, just RJMPs. This was because then they could reserve the right not to execute the RJMP xxxx code, but to read the address where to jump directly from the address part of the RJMP xxxx instruction.

That continues to sound like an urban legend.

A cold one to the first 5 responders with "proof" of this documentation.

[Weird--this is about the 3rd time this has come up in the past month.]

[Jani--remember that Mega103 was one of the first AVRs. ]

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It might be a tie. Old datasheets have wording such as

Quote:
During reset, all I/O registers are set to their initial values and the program starts execution from address $000. The instruction placed in address $000 must be an RJMP (relative jump) instruction to the reset handling routine. If the program never enables an interrupt source, the interrupt vectors are not used and regular program code can be placed at these locations.

Note the "starts execution", and the last part about using unused space.

Now, the middle part can certainly be interpreted as you remembered. I think, however, that it was a backwards warning that you just cannot put any old code there, and must remember a reset is going to end up there.

Pull up any old app note and its sample program. They start right off at address 0:

;**** A P P L I C A T I O N   N O T E   A V R 2 0 2 ************************
;*
;* Title:		16-bit Arithmetics
;* Version:		1.1
;* Last updated:	97.07.04
;* Target:		AT90Sxxxx (All AVR Devices)
;* ...
;***************************************************************************

.cseg
	ldi	r16,0x12	;Set up some registers to show usage of
	ldi	r17,0x34	;the subroutines below.
	ldi	r18,0x56	;All expected results are presented as 
	ldi	r19,0x78	;comments
...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I simply copy the info off the data sheets and turn them into a file to keep for ever. Attaching both the vector and interrupt service routine files.

Attachment(s): 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly