;

;Atmel AVR Design Contest 2006 Registration Number AT3222

;


;***************************************************************************

; Source: attiny13.asm

; Application: Initialisation Template.

; Author: Andy Gayne.

; Date: 31/10/03.

; Version: 1.01 beta

; Assembler: AVR Studio 4.07.

; Target: Atmel ATtiny13.

; Platform: Any.

;***************************************************************************

;

; The purpose of this file is to provide an initialisation template for

; the Atmel ATtiny13 AVR microcontroller.

;

; This file is based on information provided by Atmel in preliminary data

; sheet Rev. 2535A AVR 06/03. No guarantee is given by the author that

; this file is complete or correct.

;

; Andy Gayne is a Field Applications Engineer for GD Technik Ltd, UK.

; www.gd-technik.com

;

;***************************************************************************

;   Modification History

;

;   31/10/03 1.01b Device directive removed (present in tn13def.inc)

; TCNT & OCR0 register initialisation relocated.

;

; 26/10/03 1.00b Initial draft.

;***************************************************************************



;***************************************************************************

;Interrupt Vectors

;***************************************************************************

; Convert 'reti' instructions to 'rjmp' instructions where an interrupt

; service routine is required.


.ORG $0000

rjmp RESET ; RESET service

reti ; EXT_INT0 service

rjmp ISR_PC ; PCINT0 service (pin change)

rjmp ISR_T0 ; TIM0_OVF service

reti ; EE_RDY service

reti ; ANA_COMP service

reti ; TIM0_COMPA service

reti ; TIM0_COMPB service

reti ; WATCHDOG service

reti ; ADC service





;***************************************************************************

; Device initialisations follow.

; Register default values are defined here, which means the code effectively

; does nothing when executed from a power-up reset. Modify the default 

; values to suit the application, unmodified code can be commented out to 

; save code memory space, if required.

; Zero shifts (for example (0<<CLKPS3)) do not actually do anything, but are

; included to improve clarity.

;***************************************************************************


RESET:

ldi tempa, low(RAMEND)

out SPL,tempa ; Set Stack Pointer to top of RAM


;***************************************************************************

;Clock Initialisation

;***************************************************************************

; Default for a new device is 9.6MHz internal RC oscillator with divide by 

; 8 prescaler (1.2MHz). The OSCAL register is automatically loaded at 

; power up to calibrate the internal RC oscillator.

;

; CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor

; 0 0  0  0  1

; 0 0  0  1  2

; 0 0  1  0  4

; 0 0 1 1 8 (default)

; 0 1 0 0 16

; 0 1 0 1 32

; 0 1 1 0 64

; 0 1 1 1 128

; 1 0 0 0 256

; All other CLKPS combinations are 'reserved'.


ldi tempa,(1<<CLKPCE)

ldi tempb,(0<<CLKPS3)|(0<<CLKPS2)|(0<<CLKPS1)|(0<<CLKPS0)

out CLKPR,tempa ;set CLKPCE bit

out CLKPR,tempb ;CLKPS bits must be written within 4 clock

;cycles of CLKPCE bit being set

;***************************************************************************

;MCU and General Interrupt Initialisation

;***************************************************************************


; PUD: 0(default)=Pull-ups enabled, 1=pull-ups disabled

; SE: 0(default)=sleep mode disabled, 1=sleep mode enabled

; Note: SE is normally set immediately before entering sleep mode, and not

; as part of initialisation.


; SM1 SM0 Sleep Mode

; 0 0 Idle (default)

; 0 1 ADC Noise Reduction

; 1 0 Power-down

; 1 1 Reserved


; ISC01 ISC00 Interrupt 0 Sense Control Description

; 0 0 The low level of INT0 generates an interrupt (default).

; 0 1 Any logical change on INT0 generates an interrupt.

; 1 0 The falling edge of INT0 generates an interrupt.

; 1 1 The rising edge of INT0 generates an interrupt.


ldi tempa,(0<<PUD)|(0<<SE)|(0<<SM1)|(0<<SM0)|(0<<ISC01)|(0<<ISC00)

out MCUCR,tempa


; INT0: 0(default)=External Interrupt Request 0 disabled, 1=enabled

; PCIE: 0(default)=Pin Change Interrupt disabled, 1=enabled


ldi tempa,(0<<INT0)|(1<<PCIE)

out GIMSK,tempa


; PCINT5->0: 0(default)=pin change interrupt disabled, 1=enabled

; Note: PCIE must be set to enable pin change interrupts, these bits are

; used to enable or mask individual pins.


ldi tempa,(0<<PCINT5)|(0<<PCINT4)|(1<<PCINT3)|(1<<PCINT2)|(0<<PCINT1)|(0<<PCINT0)

out PCMSK,tempa


;***************************************************************************

;I/O PORTB Initialisation

;***************************************************************************

; Note: pull-up function requires PUD in MCUCR to be zero (default value).

; PORTB(input):  1=pull-up on, 0=pull-up off

; PORTB(output): 1=output high (source), 0=output low (sink)

; DDRB: 1=output, 0=input


; PORTB and DDRB defaults are all bits zero.


ldi tempa,(0<<PORTB5)|(0<<PORTB4)|(1<<PORTB3)|(1<<PORTB2)|(0<<PORTB1)|(0<<PORTB0)

ldi tempb,(0<<DDB5)|(0<<DDB4)|(0<<DDB3)|(0<<DDB2)|(1<<DDB1)|(1<<DDB0)

out PORTB,tempa

out DDRB,tempb


; Pins used for analogue input should have their respective digital input

; buffer disabled by writing the appropiate bit in DIDR0 to 1.

; DIDR0 defaults are all bits zero.


ldi tempa,(0<<ADC3D)|(0<<ADC2D)|(0<<ADC1D)|(0<<ADC0D)|(0<<AIN1D)|(0<<AIN0D)

out DIDR0,tempa


;***************************************************************************

;Watchdog Initialisation

;***************************************************************************


; WDE: 0=watchdog disabled, 1=watchdog enabled

; WDIE: 0(default)=interrupt disabled, 1=interrupt enabled

; WDCE: Watchdog Change Enable, 1=start timed sequence


; WDE WDIE Watchdog Timer State Action on Time-out

; 0 0 Stopped None

; 0 1 Running Interrupt

; 1 0 Running Reset

; 1 1 Running Interrupt

; Note: Interaction of WDE and WDIE, and state of WDE, will be dependant

; on fuse setings for safety level. Consult data sheet for full details.


; WDP3 WDP2 WDP1 WDP0 WDT Osc Cycles Typical Time-out (@5.0V)

; 0 0 0 0 2K 16 ms (default)

; 0 0 0 1 4K 32 ms

; 0 0 1 0 8K  64 ms

; 0 0 1 1 16K  0.125 sec

; 0 1 0 0 32K  0.25 sec

; 0 1 0 1 64K 0.5 sec

; 0 1 1 0 128K 1.0 sec

; 0 1 1 1 256K 2.0 sec

; 1 0 0 0 512K 4.0 sec

; 1 0 0 1 1024K 8.0 sec


; Note: This default initialisation will attempt to disable the watchdog,

; if the safety fuse settings will allow. From the Atmel ATtiny13 data:


; "If the watchdog timer is not going to be used in the application, it

; is important to go through a watchdog disable procedure in the

; initialization of the device. If the Watchdog is accidentally enabled,

; for example by a runaway pointer or brown-out condition, the device

; will be reset, which in turn will lead to a new watchdog reset. To

; avoid this situation, the application software should always clear the

; WDRF flag and the WDE control bit in the initialization routine."


; in tempc,MCUSR ;make a copy of reset flags for application code

clr tempa

out MCUSR,tempa ;clear reset flags


ldi tempa,(1<<WDE)|(1<<WDCE)

ldi tempb,(0<<WDE)|(0<<WDTIE)|(0<<WDCE)|(0<<WDP3)|(0<<WDP2)|(0<<WDP1)|(0<<WDP0)

out WDTCR,tempa ;start the timed sequence

out WDTCR,tempb ;disable the watchdog


; Note: WDTIE is nomenclature used for WDIE in tn13def.inc version 1.00,

; this may be corrected in future versions.


;***************************************************************************

;Comparator Initialisation

;***************************************************************************

; ACD: 0(default)=comparator on, 1=comparator off

; ACBG: 0(default)=AIN0 to + input, 1=bandgap reference to + input

; ACIE: 0(default)=interrupt disabled, 1=interrupt enabled


; ACIS1 ACIS0 Interrupt Mode

; 0 0 Comparator Interrupt on Output Toggle (default).

; 0 1 Reserved

; 1 0 Comparator Interrupt on Falling Output Edge.

; 1 1 Comparator Interrupt on Rising Output Edge.

; Note: always disable interrupts before changing interrupt mode.


; Comparator negative input is dependant on ADC settings, see below.


ldi tempa,(0<<ACD)|(0<<ACBG)|(0<<ACIE)|(0<<ACIS1)|(0<<ACIS0)

out ACSR,tempa


;***************************************************************************

;ADC Initialisation

;***************************************************************************

; REFS0: 0(default)=Vcc reference, 1=internal 1.1V reference

; ADLAR: 0(default)=right adjusted, 1=left adjusted (result in ADCL/H).


; MUX1 MUX0 Single Ended Input

; 0 0 ADC0(default)

; 0 1 ADC1

; 1 0 ADC2

; 1 1 ADC3

; Note: if ADC is disabled and ACME bit is set in ADCSRB, MUX is used to 

; select comparator negative input.


ldi tempa,(0<<REFS0)|(0<<ADLAR)|(0<<MUX1)|(0<<MUX0)

out ADMUX,tempa


; ACME: 0=AIN1 to comparator negative input (default),

; 1=MUX output to neg input if ADEN=0, otherwise AIN1 to neg i/p.


; ADTS2 ADTS1 ADTS0 ADC Trigger Source

; 0 0 0 Free Running mode (default)

; 0 0 1 Analog Comparator

; 0 1 0 External Interrupt Request 0

; 0 1 1 Timer/Counter Compare Match A

; 1 0 0 Timer/Counter Overflow

; 1 0 1 Timer/Counter Compare Match B

; 1 1 0 Pin Change Interrupt Request


ldi tempa,(0<<ACME)|(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0)

out ADCSRB,tempa


; ADEN: 0(default)=ADC off, 1=ADC on

; ADSC: 0(default)=no effect, 1=start conversion (see note)

; ADATE: 0(default)=auto trigger off, 1=auto trigger enabled

; ADIE: 0(default)=interrupt disabled, 1=interrupt enabled


; ADPS2 ADPS1 ADPS0 Clock Prescaler Division Factor

; 0 0 0 2 (default)

; 0 0 1 2

; 0 1 0 4

; 0 1 1 8

; 1 0 0 16

; 1 0 1 32

; 1 1 0 64

; 1 1 1 128

; Note: ADC prescaler must be set to give 50-200kHz ADC clock


ldi tempa,(0<<ADEN)|(0<<ADSC)|(0<<ADATE)|(0<<ADIE)|(0<<ADPS2)|(0<<ADPS1)|(0<<ADPS0)

out ADCSRA,tempa


; Note:ADSC bit is not normally set as part of initialisation, unless

; ADC is enabled and free running mode is selected.


;***************************************************************************

;Timer Initialisation

;***************************************************************************

; Initialise Timer/Counter register and Output Compare Registers with a 

; value, if required. Default values are all zeroes.


ldi tempa,0x00

out TCNT0,tempa


ldi tempa,0x00

out OCR0A,tempa


ldi tempa,0x00

out OCR0B,tempa


; COM0A1/COM0A0: Compare match A output mode - see data sheet

; COM0B1/COM0B0: Compare match B output mode - see data sheet

; WGM02/WGM01/WGM00: Waveform generation mode - see data sheet

;

; TCCR0A defaults: all bits zero


ldi tempa,(1<<COM0A1)|(0<<COM0A0)|(1<<COM0B1)|(0<<COM0B0)|(0<<WGM01)|(1<<WGM00)

out TCCR0A,tempa


; FOC0A/FOC0B: Force output compare - see data sheet

;

; CS02 CS01 CS00 Description

; 0 0 0 No clock, timer stopped

; 0 0 1 CLKio - no prescaler

; 0 1 0 CLKio/8

; 0 1 1 CLKio/64

; 1 0 0 CLKio/256

; 1 0 1 CLKio/1024

; 1 1 0 External clock (T0 pin) falling edge

; 1 1 1 External clock (T0 pin) rising edge

;

; TCCR0B defaults: all bits zero


ldi tempa,(0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(0<<CS01)|(1<<CS00)

out TCCR0B,tempa


; OCIE0B/OCIE0A: output compare match interrupts, 1=enabled, 0 = disabled

; TOIEO: Timer0 overflow interrupt, 1=enabled, 0 = disabled

;

; TIMSK0 defaults: all bits zero


ldi tempa,(0<<OCIE0B)|(0<<OCIE0A)|(1<<TOIE0)

out TIMSK0,tempa