; ; getsclick.asm ; gets click - capacitative wireless i0 sensing ; bridge bytes between I0 and RS-232 ; ; Stacy DeRuiter, 12/05 ; based on i0.bridge.asm and hello3.asm by Neil Gershenfeld CBA MIT 9/8/05 ; (c) Massachusetts Institute of Technology 2005 ; Permission granted for experimental and personal use; ; license for commercial use available from MIT ; .include "tn13def.inc" .equ rxpin = PB0; receive pin .equ txpin = PB2; transmit pin .equ clickin = PB4 ; I0 input pin .equ chargepin = PB3 ; charging pin .def bitcount = R16; bit counter .def byte = R17; tx/rx byte .def clickdelay = R18; click spacing .def tripledelay = R19; triple click spacing .def count = R20; loop counter .def doublecount = R21; double loop count .def temp = R22; temporary storage .def temp1 = R23; temporary storage .cseg .org 0 rjmp reset ; ; getchar ; input a serial byte following first transition ; getchar: ldi bitcount, 9 ; 8 data bit + 1 stop bit rcall bitdelay ; 0.5 bit delay getcharloop: rcall bitdelay ; 1 bit delay rcall bitdelay ; clc ; clear carry sbis PINB, rxpin ; if RX pin high skip sec ; otherwise set carry dec bitcount breq getcharend ; return if all bytes read ror byte ; otherwise shift bit into receive byte rjmp getcharloop ; get next bit getcharend: ret ; ; putchar ; output a serial byte ; putchar: .equ sb = 1 ; number of stop bits ldi bitcount, 9+sb; 1+8+sb com byte ; invert everything sec ; set start bit putchar0: brcc putchar1 ; if carry set sbi PORTB, txpin ; send a '0' rjmp putchar2 ; else putchar1: cbi PORTB, txpin ; send a '1' nop ; even out timing putchar2: rcall bitdelay ; one bit delay rcall bitdelay lsr byte ; get next bit dec bitcount ; if not all bits sent brne putchar0 ; send next bit ret ; ; getclick ; input an I0 byte following first click ; getclick: clr clickdelay sbi ACSR, ACI ; reset comparator ; ; find click delay from arrival of second start click ; start2: inc clickdelay breq getclicktimeout ; time-out if count overflows sbis ACSR, ACI rjmp start2 mov tripledelay, clickdelay add tripledelay, clickdelay add tripledelay, clickdelay ; ; decode data clicks ; clr byte ldi bitcount, 8 bitloop: ; ; time arrival of next click ; clr count sbi ACSR, ACI ; reset comparator bitclickloop: inc count breq getclicktimeout ; time-out if count overflows sbis ACSR, ACI rjmp bitclickloop ; ; determine bit delay ; mov doublecount, count add doublecount, count cp doublecount, tripledelay brsh zero ; ; one bit ; sec ; set carry ror byte ; shift in carry ; ; even out timing with click delay ; mov count, clickdelay onedelay: nop ; time for breq nop ; time for sbis dec count brne onedelay dec bitcount brne bitloop ; output if byte received rjmp getclickend zero: ; ; zero bit ; clc ; clear carry ror byte ; shift in carry dec bitcount brne bitloop ; output if byte received getclickend: ret getclicktimeout: mov byte, clickdelay ret ; ;; putclick ;; output an I0 byte ;; ;putclick: ; ldi bitcount, 8 ; sec; set start bit ; ; ; ; send start clicks ; ; ; cbi PORTB, clickout ; sbi PORTB, clickout ; rcall clickdelay ; cbi PORTB, clickout ; sbi PORTB, clickout ; rcall clickdelay ; ; ; ; send data clicks ; ; ; putclick0: ; lsr byte; get next bit ; brcc putclick1; if carry set, send a 1 click ; cbi PORTB, clickout ; sbi PORTB, clickout ; rcall clickdelay ; sbi PORTB, clickout ; sbi PORTB, clickout ; rcall clickdelay ; rjmp putclick2; otherwise ... ; putclick1: ; sbi PORTB, clickout; ... send a 0 click ; sbi PORTB, clickout ; rcall clickdelay ; cbi PORTB, clickout ; sbi PORTB, clickout ; rcall clickdelay ; putclick2: ; dec bitcount; if not all bits sent ; brne putclick0; send next bit ; ; ; ; send stop clicks ; ; ; cbi PORTB, clickout ; sbi PORTB, clickout ; rcall clickdelay ; cbi PORTB, clickout ; sbi PORTB, clickout ; rcall clickdelay ; ; ; ; return ; ; ; ret ; ; routine to wait for sample to settle ; ;.equ delay = 255 ;settle: ; ldi temp, delay ; settleloop: ; dec temp ; brne settleloop ; ret ; ; bitdelay ; serial bit delay ; .equ b = 17 bitdelay: ldi temp, b bitdelayloop: dec temp brne bitdelayloop ret ; ; clickdelay ; delay between I0 clicks ; clickdelay: ldi temp, 100 clickdelayloop: dec temp brne clickdelayloop ret ; ; main program ; reset: ldi temp, low(RAMEND) ; set stack pointer to top of RAM out SPL, temp ; cbi PORTB, txpin; init comm pin for output sbi DDRB, txpin cbi PORTB, chargepin ; not charging sbi DDRB, chargepin ; " sbi ACSR, ACIS1 ; setup comparator to output on falling edge of signal cbi ACSR, ACIS0 ; sbi ADCSRB, ACME ; setup comparator to use ADC multiplexer cbi ADCSRA, ADEN ; sbi ADMUX, MUX1 ; set channel to ADC2 cbi ADMUX, MUX0 ; ; ;ldi delaycnt, 100; delay between sending charge and measuring response is 100 ; loop: ; ; settle sample and start upward step response ; ;cbi PORTB, chargepin ;rcall settle ;mov temp, delaycnt sbi PORTB, chargepin ; ; wait for delay ; ;delay: ; dec temp ; brne delay ; ; read response ; ; wait for a click or a bit ; sbi ACSR, ACI ; reset comparator waitloop: sbic ACSR, ACI ; check comparator for click rjmp I0_to_serial ; sbis PINB, rxpin ; check serial pin for bit rjmp waitloop serial_to_I0: ldi byte, 'b' rcall putchar rcall getchar ;rcall putclick rjmp loop I0_to_serial: rcall getclick rcall putchar rjmp loop