;------------------------------------------------------------------------------------------------------------------- ; Keyboard.asm ; Written for the ATmega8 .nolist .include "m8def.inc" .list .listmac ; ; Written by Dave Brown ; Created: July 4, 2005 ; Last Modified: July 7, 2005 ; ;------------------------ ; pins ;------------------------ ; ; pc0 |midi channel select ; pc1 | inverted (pullups) ; pc1 | f=channel 0 ; pc2 | 0=channel f ; ; pd0 midi in ; pd1 midi out ; pd2 pedal-1 input (pullups) ; pd3 pedal-2 input (pullups) ; pd4 inverted pedal-1 output ; pd5 inverted pedal-2 output ; pd6 LED output (blinks on note down) ; ; timer0 25 mS interrupts ; timer1 not used ; timer2 not used ; ;------------------------ ; registers ;------------------------ ; ; r0 ; r1 ; r2 ; r3 ; r4 ; r5 ; r6 ; r7 ; r8 ; r9 ; r10 ; r11 ; r12 ; r13 ; r14 ; r15 LED blink count ; r16 temp ; r17 tx character count (0=empty) ; r18 tx put pointer (first empty) ; r19 tx get buffer pointer (first valid) ; r20 rx character count (0=empty) ; r21 rx put pointer (first empty) ; r22 rx get buffer pointer (first valid) ; r23 running status command ; r24 note offset ; r25 midi channel ; r26 xl rx temp address pointer ; r27 xh rx temp address pointer ; r28 yl tx temp address pointer ; r29 yh tx temp address pointer ; r30 zl ; r31 zh ; ;------------------------ ; ram ;------------------------ ; .dseg .org 0x0060 ; .equ rx_len =60 ;midi in buffer length (< 256) .equ tx_len =100 ;midi out buffer length (<256) rx_bfr: .byte rx_len ;midi in buffer tx_bfr: .byte tx_len ;midi out buffer ; ;------------------------ ; program ;------------------------ ; .cseg .org 0x0000 ; rjmp start ;0x000 reset rjmp irq_none ;0x001 int0 rjmp irq_none ;0x002 int1 rjmp irq_none ;0x003 timer2 comp rjmp irq_none ;0x004 timer2 ovf rjmp irq_none ;0x005 timer1 capt rjmp irq_none ;0x006 timer1 comp-a rjmp irq_none ;0x007 timer1 comp-b rjmp irq_none ;0x008 timer1 ovf rjmp tmr0_isr ;0x009 timer0 ovf rjmp irq_none ;0x00A spi stc rjmp rx_isr ;0x00B uart rx rjmp tx_isr ;0x00C uart udre rjmp irq_none ;0x00D uart tx rjmp irq_none ;0x00E adc rjmp irq_none ;0x00F ee ready rjmp irq_none ;0x010 ana comp ; ;------------------------ ; unused interrupt isr ;------------------------ irq_none: reti ; ;------------------------ ; serial in isr ;------------------------ ; ;serial in isr ;puts data into buffer ;decrements character count if not empty ;registers used ; r16=temp ; r20=character count ; r21=put pointer ; x=buffer address rx_isr: push xh push xl push r16 in r16,sreg push r16 in r16,udr ;read received byte cpi r16,0xfe ;check for running status breq rx_3 ;filter out ldi xh,high(rx_bfr) ;get input buffer address ldi xl,low(rx_bfr) add xl,r21 ;add put pointer brcc rx_1 ;check for carry inc xh ;correct high byte rx_1: st x,r16 ;store character inc r21 ;increment put pointer cpi r21,rx_len ;check if at end of buffer brne rx_2 ldi r21,0 ;wrap pointer rx_2: cpi r20,rx_len ;check if buffer full breq rx_3 ;overwrites first data if full inc r20 ;increment character count if not full rx_3: pop r16 out sreg,r16 pop r16 pop xl pop xh reti ; ;------------------------ ; serial out isr ;------------------------ ; ;serial out isr ;gets data from buffer ;decrements character count ;registers used ; r16=temp ; r17=character count ; r19=get pointer ; y=buffer address tx_isr: push yh push yl push r16 in r16,sreg push r16 ldi yh,high(tx_bfr) ;get input buffer address ldi yl,low(tx_bfr) add yl,r19 ;add put pointer brcc tx_1 ;check for carry inc yh ;correct high byte tx_1: ld r16,y ;get character out udr,r16 ;send to uart inc r19 ;increment put pointer cpi r19,tx_len ;check if at end of buffer brne tx_2 ldi r19,0 ;wrap pointer tx_2: dec r17 ;decrement character count brne tx_3 ;check for empty push r16 ;save data in r16,ucsrb ;get control register andi r16,0xdf ;set udrie=0 out ucsrb,r16 pop r16 tx_3: pop r16 out sreg,r16 pop r16 pop yl pop yh reti ; ;------------------------ ; timer0 isr ;------------------------ ; ;25 mS timer ;blinks LED ;registers used ; r16=temp tmr0_isr: push r16 in r16,sreg ;save sreg push r16 ldi r16,60 out tcnt0,r16 ;set tcnt0 for 25 mS interrupts and r15,r15 ;check for 0 breq tm_1 dec r15 brne tm_1 cbi portd,6 ;turn LED back on tm_1: pop r16 out sreg,r16 ;restore sreg pop r16 reti ; ;------------------------ ; program start ;------------------------ ; start: ;initialize direction ldi r16,0b11110000 ;0=input bits 0-3 out ddrc,r16 ;set port c directions ldi r16,0b00001111 ;1=pullup bits 0-3 out portc,r16 ;set port c pullups ldi r16,0b11110010 ;0=input bits 0 and 2-3 out ddrd,r16 ;set port d directions ldi r16,0b00001110 ;1=pullup bits 2-3 out portd,r16 ;set port d pullups, clear pedal outputs, turn on LED ;initialize stack: ldi r16,0x5f ;set stack pointer to 0x045f ldi r17,0x04 out spl,r16 out sph,r17 ;stop watchdog ldi r16,0x1f ;set wd to longest delay & set wdtoe high out wdtcr, r16 ldi r16,0x17 ;turn off wde out wdtcr,r16 ;initialize timer0 ; 8MHz / 1024 = 128 uS clock ; 32 uS x 256 = 32.768 mS ; set tcnt0 for 25 mS interrupts in r16,tccr0 ;read control register sbr r16,(1<