; $Id$
;
+#ifdef __ATmega8__
+ #error "ATmega8 is not supported (yet)! Please update this driver, or buy an ATmega88."
+#endif
+
#define SSER_BIT_TC (F_CPU+BAUD/2) / BAUD
+#define SSER_CHAR_TC (10 * 1000 / BAUD) + 2
#define RXBUFMASK RXBUFSIZE-1
#define TXBUFMASK TXBUFSIZE-1
.byte 1
srx_char_to:
.byte 1
+srx_char_time:
+ .byte 1
srx_dr:
.byte 1
-;srx_lastedge:
-; .byte 2
+srx_lastedge:
+ .byte 2
stx_bitcount:
.byte 1
stx_dr:
; - Soft UART RX (ICP1/ICR1).
; - 1ms System timer is already configured at this point.
+
+ cbi P_TXD-1,TXD ;TXD pin as input
ldi temp,(1<<COM1A1)|(1<<COM1A0) ;OC1A high on compare match (UART TX)
+ ldi temp2,(1<<FOC1A) ;force compare match
outm8 TCCR1A,temp
+ outm8 TCCR1C,temp2
+ sbi P_TXD-1,TXD ;TXD pin now output (OC1A)
- ldi temp,(1<<ICF1) ;clear pending int
- out TIFR1,temp
- inm8 temp,TIMSK1
+ ldi temp,(1<<ICF1) ;clear pending input capture int
+ out TIFR1,temp ;
+ inm8 temp,TIMSK1 ;
ori temp,(1<<ICIE1) ;Enable input capture int. (UART RX)
- outm8 TIMSK1,temp
+ outm8 TIMSK1,temp ;
+
+ ldi temp,SSER_CHAR_TC ;Character TO
+ sts srx_char_time,temp
+
ret
;------------------------------------------------------------------
; State 0: Wait for start bit
-; sts srx_lastedge,zl ;save beginning of start bit
-; sts srx_lastedge+1,zh
- movw srx_lastedgel,zl
+ sts srx_lastedge,zl ;save beginning of start bit
+ sts srx_lastedge+1,zh
+; movw srx_lastedgel,zl
sts srx_dr,_0
ldi temp,1
sts srx_state,temp
- ldi temp,2
+ lds temp,srx_char_time
sts srx_char_to,temp
sbis P_RXD-2,RXD ;RXD still low?
- rjmp srxi_end2
+ rjmp srxi_end
ldi zl,(1<<ICNC1)|(1<<CS10) ;next edge is falling edge
outm8 TCCR1B,zl
ldi zh,(1<<ICF1) ;clear pending int
out TIFR1,zh
sts srx_state,_0
sts srx_char_to,_0
- rjmp srxi_end2
+ rjmp srxi_end
srxi_S1:
cpi temp,1
; State 1: Check start bit (and collect 0-bits)
-; lds temp,srx_lastedge
-; lds temp2,srx_lastedge+1
-; sts srx_lastedge,zl
-; sts srx_lastedge+1,zh
+ lds temp,srx_lastedge
+ lds temp2,srx_lastedge+1
+ sts srx_lastedge,zl
+ sts srx_lastedge+1,zh
- movw temp,srx_lastedgel
- movw srx_lastedgel,zl
+; movw temp,srx_lastedgel
+; movw srx_lastedgel,zl
sub zl,temp
sbc zh,temp2
sts rxidx_w,_0
sts rxidx_r,_0
- rjmp srxi_end2
+ rjmp srxi_end
srxi_1be:
sts srx_dr,temp
ldi temp,2
sts srx_state,temp
- rjmp srxi_end2
+ rjmp srxi_end
srxi_sberr:
ldi temp,(1<<ICNC1)|(1<<CS10) ;next edge is falling edge
mov temp,zl
rcall printhex
#endif
- rjmp srxi_end2
+ rjmp srxi_end
srxi_S2:
cpi temp,2
; State 2: collect 1-bits
-; lds temp,srx_lastedge
-; lds temp2,srx_lastedge+1
-; sts srx_lastedge,zl
-; sts srx_lastedge+1,zh
+ lds temp,srx_lastedge
+ lds temp2,srx_lastedge+1
+ sts srx_lastedge,zl
+ sts srx_lastedge+1,zh
- movw temp,srx_lastedgel
- movw srx_lastedgel,zl
+; movw temp,srx_lastedgel
+; movw srx_lastedgel,zl
sub zl,temp
sbc zh,temp2
sts srx_dr,temp
ldi temp,3
sts srx_state,temp
- rjmp srxi_end2
+ rjmp srxi_end
srxi_complete1:
ldi temp2,1 ;We are in start bit now.
sts srx_state,temp2
- ldi temp2,2
+ lds temp2,srx_char_time
sts srx_char_to,temp2
rjmp srxi_complete
; State 3: collect 0-bits
-; lds temp,srx_lastedge
-; lds temp2,srx_lastedge+1
-; sts srx_lastedge,zl
-; sts srx_lastedge+1,zh
+ lds temp,srx_lastedge
+ lds temp2,srx_lastedge+1
+ sts srx_lastedge,zl
+ sts srx_lastedge+1,zh
- movw temp,srx_lastedgel
- movw srx_lastedgel,zl
+; movw temp,srx_lastedgel
+; movw srx_lastedgel,zl
sub zl,temp
sbc zh,temp2
sts srx_dr,temp
ldi temp,2
sts srx_state,temp
- rjmp srxi_end2
+ rjmp srxi_end
srxi_S4:
ldi zl,(1<<ICNC1)|(1<<CS10) ;next edge is falling edge
outm8 TCCR1B,zl
ldi zl,(1<<ICF1) ;clear pending int
sts srx_state,_0 ;next state
- rjmp srxi_end2
+ rjmp srxi_end
srxi_complete0:
sts srx_char_to,_0 ;clear timeout
; Save received character in a circular buffer. Do nothing if buffer overflows.
- lds zh,rxcount ;if rxcount < RXBUFSIZE
- cpi zh,RXBUFSIZE ; (room for at least 1 char?)
- brsh srxi_ov ;
- inc zh ;
- sts rxcount,zh ; rxcount++
-
- ldi zl,low(rxfifo) ;
- lds zh,rxidx_w ;
- add zl,zh ;
- inc zh ;
- andi zh,RXBUFMASK ;
- sts rxidx_w,zh ; rxidx_w = ++rxidx_w % RXBUFSIZE
- ldi zh,high(rxfifo) ;
- brcc PC+2 ;
- inc zh ;
- st z,temp ; rxfifo[rxidx_w] = char
-srxi_ov: ;endif
-
-srxi_end2:
+ lds zh,rxcount ;2 if rxcount < RXBUFSIZE
+ cpi zh,RXBUFSIZE ;1 (room for at least 1 char?)
+ brsh srxi_ov ;1
+ inc zh ;1
+ sts rxcount,zh ;2 rxcount++
+
+ ldi zl,low(rxfifo) ;1
+ lds zh,rxidx_w ;2
+ add zl,zh ;1
+ inc zh ;1
+ andi zh,RXBUFMASK ;1
+ sts rxidx_w,zh ;2 rxidx_w = ++rxidx_w % RXBUFSIZE
+ ldi zh,high(rxfifo) ;1
+ adc zh,_0 ;1
+ st z,temp ;2 rxfifo[rxidx_w] = char
+srxi_ov: ;=19 endif
+
+srxi_end:
pop temp2
-srxi_end:
pop zl
pop zh
pop temp
INTERRUPT OC1Aaddr
- push temp
- in temp,sreg
- push temp
+ push zl
+ in zl,sreg
+ push zl
push zh
- inm8 temp,OCR1AL
+ inm8 zl,OCR1AL
inm8 zh,OCR1AH
- subi temp,low(-SSER_BIT_TC)
+ subi zl,low(-SSER_BIT_TC)
sbci zh,high(-SSER_BIT_TC)
outm8 OCR1AH,zh
- outm8 OCR1AL,temp
- lds temp,stx_bitcount
- tst temp
- breq stxi_nxtchar
+ outm8 OCR1AL,zl
+
+ lds zl,stx_bitcount
+ dec zl
+ brpl stxi_nextbit
- dec temp
- sts stx_bitcount,temp
- ldi zh,9 ;Start bit?
- cp temp,zh
- ldi zh,(1<<COM1A1)
- breq stxi_0
- lds temp,stx_dr
- sbrs temp,0
- ldi zh,(1<<COM1A1)|(1<<COM1A0)
- lsr temp
- sts stx_dr,temp
-stxi_0:
- outm8 TCCR1A,zh
- pop zh
- pop temp
- out sreg,temp
- pop temp
- reti
+; bit counter was 0, more characters?
-; more characters?
stxi_nxtchar:
- lds temp,txcount ;if txcount != 0
- tst temp ;
- breq stxi_dis
+ lds zl,txcount ;if txcount != 0
+ dec zl
+ brmi stxi_dis
+
; get next char
- push zl
- dec temp ;
- sts txcount,temp ; --txcount
+ sts txcount,zl ; --txcount
+ push temp ;
ldi zl,low(txfifo) ;
ldi zh,high(txfifo) ;
lds temp,txidx_r ;
add zl,temp ;
- brcc PC+2 ;
- inc zh ;
+ adc zh,_0
inc temp ;
andi temp,TXBUFMASK ;
sts txidx_r,temp ;
ld temp,z
com temp
sts stx_dr,temp
- ldi temp,10
+ ldi temp,9
sts stx_bitcount,temp
- pop zl
- pop zh
pop temp
- out sreg,temp
- pop temp
- reti
+
+ ldi zh,(1<<COM1A1)
+ rjmp stxi_ex
; disable transmitter
stxi_dis:
- ldi temp,(1<<COM1A1)|(1<<COM1A0)
- outm8 TCCR1A,temp
- inm8 temp,TIMSK1
- andi temp,~(1<<OCIE1A)
- outm8 TIMSK1,temp
+ inm8 zl,TIMSK1
+ andi zl,~(1<<OCIE1A)
+ outm8 TIMSK1,zl
+
+ ldi zh,(1<<COM1A1)|(1<<COM1A0)
+ rjmp stxi_ex
+
+stxi_nextbit:
+ sts stx_bitcount,zl
+
+ ldi zh,(1<<COM1A1)
+ lds zl,stx_dr
+ sbrs zl,0
+ ldi zh,(1<<COM1A1)|(1<<COM1A0)
+ lsr zl
+ sts stx_dr,zl
+stxi_ex:
+ outm8 TCCR1A,zh
pop zh
- pop temp
- out sreg,temp
- pop temp
+ pop zl
+ out sreg,zl
+ pop zl
reti
+
;------------------------------------------------------------------
srx_to:
lds zh,txcount
inc zh
sts txcount,zh
- dec zh
+ cpi zh,1
brne sputc_e
; Enable transmitter
inm8 zh,TIMSK1
+ sbrc zh,OCIE1A
+ rjmp sputc_e
ori zh,(1<<OCIE1A)
outm8 TIMSK1,zh
+
+ inm8 zl,TCNT1L ;
+ inm8 zh,TCNT1H ;
+ adiw zl,30 ;
+ outm8 OCR1AH,zh ;
+ outm8 OCR1AL,zl ;
+ ldi zl,(1<<OCF1A)
+ outm8 TIFR1,zl
+
sputc_e:
pop zl
out sreg,zl