2 #define CAL_MAGIC 0x91 // attiny4 flex-lowpass 1
3 //#define CAL_MAGIC 0x9e // attiny4 handwired
4 //#define CAL_MAGIC 0x8d // attiny4 devboard
5 //#define CAL_MAGIC 0xa9 // attiny9 devboard
16 #define x r23 //==a1==Mh
26 #define Ml t //mod3 vars
51 .org 0x0000 ; RESET interrupt
53 .org 0x0002 ; INT0 interrupt
54 CBI EIMSK, 0 ; disable interrupt
56 .org 0x0008 ; TIM0_OVF interrupt
60 .byte 0x84, 0x9d, 0xb0, 0x69, 0x9d, 0x84, 0x69, 0x58
61 .byte 0x75, 0x8c, 0xb0, 0x69, 0x8c, 0x75, 0x69, 0x58
63 mod3: ; mod3(Mh.Ml) -> t
67 ADC Mh, Mh ; store carry in Mh
113 ; begin of mulitiplication:
122 ; BRCC skip2 -- this bit is always zero
165 MOV t, a1 ;;TODO: use a1 in loop: directly
170 main: ; setup routine
174 CLR acc ; we output a dummy sample before the actual first one
175 LDI Xhi, hi8(FLASHM + notes) ; never changes
176 LDI one, 1 ; mostly for clearing TIM0_OVF bit
180 OUT SPL, x ; init stack ptr
182 OUT PUEB, zero ; disable pullups
184 OUT DDRB, x ; PORTB0:pwm, PORTB1:debug (PORTB2:wakeup-input)
186 OUT CCP, x ; change protected ioregs
187 OUT CLKPSR, one ; clock prescaler 1/2 (4Mhz)
188 LDI x, CAL_MAGIC ; determined by trial-and-error (->PORTB1)
189 OUT OSCCAL, x ; set oscillator calibration
190 OUT WDTCSR, zero; turn off watchdog
192 ;set timer/counter0 to 8bit fastpwm, non-inverting, no prescaler
197 OUT TIMSK0, one ; enable tim0_ovf
202 CPI i2, 0x78 ; 16m23 -- one loop
208 //we use an external pullup(>= 1kohm), as line-input usually has an impedance
209 //between 20-100kohm, while the attiny's internal pullups are "only" 20-50kohm
210 //(which is too strong)
212 ;stop the music, and check whether PINB0 is plugged into an audio
213 ;sink. Until then, conserve as much battery as possible.
214 CLR i2 ; clear halt condition
217 ; disable timer to free audio pin for wakeup function:
224 ;assert high level on pullup pins to avoid accidentally triggering INT0:
227 OUT DDRB, zero ; set all pins as input
229 ;set up INT0 to wake up when a audio sink is connected
230 SBI EIMSK, 0 ; set-bit-0 high => enable interrupt
231 OUT EICRA, zero ; logical low generates INT0
233 ;enter power-down-mode
234 OUT SMCR, five ; sleep mode: power-down, enabled
236 ;OUT SMCR, one ; sleep mode: idle, enabled
237 OUT SMCR, zero ; sleep mode: disabled
243 LDI x, 0x03 ; restore output pins
246 OUT TCCR0A, x ; reenable COMA bits
248 OUT TCCR0B, x ; reenable timer0
253 OUT OCR0AL, acc ; start by outputting a sample, because routine has variable runtime
255 SBI PORTB, 1 ; to measure runtime
380 SWAP acc ; acc<<4, to be passed to OCR0AL
387 CBI PORTB, 1 ; end runtime measurement
389 OUT TIFR0, one ; clear pending interrupt (routine takes two intr.cycles)
390 RETI ; reenables interrupts