2 #define CAL_MAGIC 0x9e // attiny4 handwired
3 //#define CAL_MAGIC 0x8d // attiny4 devboard
4 //#define CAL_MAGIC 0xa7 // attiny9 devboard
12 ; XXX: move registers down!
16 #define x r24 //==a1==Mh
25 #define Ml t //mod3 vars
27 #define a1 x //mul_ vars
52 .org 0x0000 ; RESET interrupt
54 .org 0x0002 ; INT0 interrupt
55 CBI EIMSK, 0 ; disable interrupt
57 .org 0x0008 ; TIM0_OVF interrupt
61 .byte 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58
62 .byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
64 mod3: ; mod3(Mh.Ml) -> t
68 ADC Mh, Mh ; store carry in Mh
112 ; begin of mulitiplication:
121 ; BRCC skip2 -- this bit is always zero
164 MOV t, a1 ;;TODO: use a1 in loop: directly
167 main: ; setup routine
171 CLR acc ; we output a dummy sample before the actual first one
172 LDI Xhi, hi8(FLASHM + notes) ; never changes
173 LDI one, 1 ; mostly for clearing TIM0_OVF bit
177 OUT SPL, x ; init stack ptr
179 OUT PUEB, zero ; disable pullups
181 OUT DDRB, x ; PORTB0:pwm, PORTB1:debug (PORTB2:wakeup-input)
183 OUT CCP, x ; change protected ioregs
184 OUT CLKPSR, one ; clock prescaler 1/2 (4Mhz)
185 LDI x, CAL_MAGIC ; determined by trial-and-error (->PORTB1)
186 OUT OSCCAL, x ; set oscillator calibration
187 OUT WDTCSR, zero; turn off watchdog
189 ;set timer/counter0 to 8bit fastpwm, non-inverting, no prescaler
194 OUT TIMSK0, one ; enable tim0_ovf
199 CPI i2, 0x78 ; 16m23 -- one loop
205 //we use an external pullup(>= 1kohm), as line-input usually has an impedance
206 //between 20-100kohm, while the attiny's internal pullups are "only" 20-50kohm
207 //(which is too strong)
209 ;stop the music, and check whether PINB0 is plugged into an audio
210 ;sink. Until then, conserve as much battery as possible.
211 CLR i2 ; clear halt condition
214 ; disable timer to free audio pin for wakeup function:
221 ;assert high level on pullup pins to avoid accidentally triggering INT0:
224 OUT DDRB, zero ; set all pins as input
226 ;set up INT0 to wake up when a audio sink is connected
227 SBI EIMSK, 0 ; set-bit-0 high => enable interrupt
228 OUT EICRA, zero ; logical low generates INT0
230 ;enter power-down-mode
231 OUT SMCR, five ; sleep mode: power-down, enabled
233 ;OUT SMCR, one ; sleep mode: idle, enabled
234 OUT SMCR, zero ; sleep mode: disabled
240 LDI x, 0x03 ; restore output pins
243 OUT TCCR0A, x ; reenable COMA bits
245 OUT TCCR0B, x ; reenable timer0
250 OUT OCR0AL, acc ; start by outputting a sample, because routine has variable runtime
252 SBI PORTB, 1 ; to measure runtime
377 SWAP acc ; acc<<4, to be passed to OCR0AL
384 CBI PORTB, 1 ; end runtime measurement
386 OUT TIFR0, one ; clear pending interrupt (routine takes two intr.cycles)
387 RETI ; reenables interrupts