;
;Atmel AVR Design Contest 2006 Registration Number AT3223
;
;***************************************************************************
; 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
;
; Jun 2006 Modified for Atmel AVR Design Contest 2006
;
; 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:
clr zeroReg
; ldi tempa, low(RAMEND)
; out SPL,tempa ; Set Stack Pointer to top of RAM
; this has been commented out as it is called later in MAIN:
;***************************************************************************
;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)|(0<<PCINT3)|(0<<PCINT2)|(1<<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)|(0<<PORTB3)|(0<<PORTB2)|(1<<PORTB1)|(0<<PORTB0)
ldi tempb,(0<<DDB5)|(0<<DDB4)|(0<<DDB3)|(0<<DDB2)|(0<<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,(1<<ADC3D)|(1<<ADC2D)|(1<<ADC1D)|(1<<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,(1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(0<<ADIE)|(1<<ADPS2)|(1<<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)|(0<<COM0B1)|(0<<COM0B0)|(0<<WGM02)|(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)|(1<<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