; putsclick.asm
; Stacy DeRuiter, 12/05
; send clicks for capacitative sensing by other i0 chip
;
; based on:
; i0.6.thtp.asm
;
; Neil Gershenfeld CBA MIT 11/27/05
; (c) Massachusetts Institute of Technology 2005
; Permission granted for experimental and personal use;
; license for commercial use available from MIT
;
; transmit a SLIP UDP HTTP (THTP) packet when the button is pushed
; blink the LED when the button is pushed or a click is received
;
.include "tn13def.inc"
.equ ledpin = PB1; LED pin
.equ buttonbit = 2; pushbutton bit
.equ buttonpin = PB2; pushbutton pin
.equ chargepin1 = PB3; charged or grounded to change capacitance between 2 i0 chips
.equ chargepin2 = PB4; " (both should be set(on or ground) at same times)
.def bitcnt = R16; bit counter
.def txbyte = R17; bit counter
.def temp = R18; temporary storage
.def temp1 = R19; temporary storage
.def count = R20; loop counter
.def check_lo = R21; lo checksum accumulator
.def check_hi = R22; hi checksum accumulator
.def check_carry = R23; checksum carry accumulator
.def zero = R24; 0
.equ END = 192
.equ ESC = 219
.equ ESC_END = 220
.equ ESC_ESC = 221
.macro putslip
;
; putslip
; outputs char in txbyte, with SLIP mapping
;
ldi temp, END
cpse txbyte, temp
rjmp putslipchar
mov temp, txbyte
ldi txbyte, ESC
rcall putclick
rcall chardelay
ldi txbyte, ESC_END
rcall putclick
rcall chardelay
mov txbyte, temp
rjmp endputslip
ldi temp, ESC
cpse txbyte, temp
rjmp putslipchar
mov temp, txbyte
ldi txbyte, ESC
rcall putclick
rcall chardelay
ldi txbyte, ESC_ESC
rcall putclick
rcall chardelay
mov txbyte, temp
rjmp endputslip
putslipchar:
rcall putclick
rcall chardelay
endputslip:
.endmacro
.cseg
.org 0
rjmp reset
;
; the packet
;
.equ ip_header_size = 20
.equ ip_header_size_before_checksum = 10
.equ ip_header_size_after_checksum = 8
.equ udp_header_size = 8
.equ data_size = 72
ip:
.db 0x45, 0
; version = 4 (4 bits)
; header length = 5 32-bit words (4 bits)
; type of service
.db 0, ip_header_size + udp_header_size + data_size
; total length
.db 0, 0
; identification
.db 0, 0
; flag (3 bits)
; fragment offset (13 bits)
.db 255, 17
; time to live
; protocol = 17 for UDP
.db 0, 0
; header checksum (to be calculated)
; .db 192, 168, 1, 101
.db 192, 168, 1, 102
; source address
.db 127, 0, 0, 1
; destination address
udp:
.db 0, 0
; source port = 0
.db 0x10, 0
; destination port = 4096
.db 0, udp_header_size + data_size
; length
.db 0, 0
; packet checksum
data:
.db "HTTP/1.1 200 OK",13,10,"Content-Type: text/html",13,10,13,10,"
button pushed ",13,10 ; 44 bytes HTTP header + 14 bytes HTML + text string = data_size
; .db "HTTP/1.1 200 OK",13,10,"Content-Type: text/html",13,10,13,10,"Internet 0 ",13,10 ; 44 bytes HTTP header + 14 bytes HTML + text string = data_size
;
; putclick
; send char in txbyte clicks
;
putclick:
ldi bitcnt, 8
sec; set start bit
;
; send start clicks
;
; first half
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
cbi PORTB, chargepin1
cbi PORTB, chargepin2
rcall ondelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
;
;second half
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
cbi PORTB, chargepin1
cbi PORTB, chargepin2
rcall ondelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
;
; send data clicks
;
putclick0:
lsr txbyte; get next bit
brcc putclick1; if carry set, send a 1 click
; first half
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
cbi PORTB, chargepin1
cbi PORTB, chargepin2
rcall ondelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
;
;second half
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall ondelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
rjmp putclick2; otherwise ...
putclick1: ; send a zero click
; first half
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall ondelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
;
;second half
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
cbi PORTB, chargepin1
cbi PORTB, chargepin2
rcall ondelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
putclick2:
dec bitcnt; if not all bits sent
brne putclick0; send next bit
;
; send stop clicks
;
; first half
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
cbi PORTB, chargepin1
cbi PORTB, chargepin2
rcall ondelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
;
;second half
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
cbi PORTB, chargepin1
cbi PORTB, chargepin2
rcall ondelay
sbi PORTB, chargepin1
sbi PORTB, chargepin2
rcall clickdelay
ret;
;
; clickdelay
; delay between clicks
;
clickdelay:
ldi temp, 10
clickdelayloop:
dec temp
brne clickdelayloop
ret
;
; ondelay
; delay while pins are grounded
ondelay:
ldi temp, 30
ondelayloop:
dec temp
brne ondelayloop
ret
;
; chardelay
; delay between characters
;
chardelay:
ldi temp, 100
chardelayloop:
ldi temp1, 10
chardelayloop1:
dec temp1
brne chardelayloop1
dec temp
brne chardelayloop
ret
;
; packet_delay
; delay between packets
;
packet_delay:
ldi temp, 255
packet_delayloop:
ldi temp1, 255
packet_delayloop1:
dec temp1
brne packet_delayloop1
dec temp
brne packet_delayloop
ret
;
; print_packet
; send a packet, calculating checksums and doing SLIP encoding
;
print_packet:
;
; find the header checksum
;
ldi zl, low(ip*2)
ldi zh, high(ip*2)
ldi count, ip_header_size
clr check_lo
clr check_hi
clr check_carry
ip_checksum_loop:
inc zl
lpm
add check_lo, R0
dec count
dec zl
lpm
adc check_hi, R0
adc check_carry, zero
inc zl
inc zl
dec count
brne ip_checksum_loop
add check_lo, check_carry
adc check_hi, zero
com check_lo
com check_hi
;
; send the packet
;
ldi txbyte, END ; SLIP start
rcall putclick
rcall chardelay
ldi zl, low(ip*2)
ldi zh, high(ip*2)
ldi count, ip_header_size_before_checksum
print_loop: ; start of IP header
lpm
mov txbyte, R0
putslip
inc zl
dec count
brne print_loop
mov txbyte, check_hi ; IP header checksum
putslip
inc zl
mov txbyte, check_lo
putslip
inc zl
ldi count, (ip_header_size_after_checksum + udp_header_size + data_size)
print_loop1: ; rest of IP header
lpm
mov txbyte, R0
putslip
inc zl
dec count
brne print_loop1
ldi txbyte, END ; SLIP end
rcall putclick
rcall chardelay
ret
;
; main program
;
reset:
ldi temp, low(RAMEND) ; set stack pointer to top of RAM
out SPL, temp ;
clr zero
sbi PORTB, ledpin ; init LED pin for output
sbi DDRB, ledpin ;
sbi PORTB, buttonpin ; init pushbutton pin for input with pull-up
cbi DDRB, buttonpin ;
sbi PORTB, chargepin1 ; init charge pin for output
sbi DDRB, chargepin1 ;
sbi PORTB, chargepin2 ; init charge pin for output
sbi DDRB, chargepin2 ;
;cbi ACSR, ACIS1 ; setup comparator to output on state change
;cbi ACSR, ACIS0 ;
;sbi ADCSRB, ACME ; setup comparator to use ADC multiplexer
;cbi ADCSRA, ADEN ;
;sbi ADMUX, MUX1 ; set channel to ADC3
;sbi ADMUX, MUX0 ;
loop:
;
; wait for the button to be pressed or a click to arrive
;
;sbi ACSR, ACI ; reset comparator
waitloop:
; sbic ACSR, ACI ; check for click
; rjmp click
sbic PINB, buttonbit ; check for button
rjmp waitloop
button:
;
; send the string and blink the LED
;
cbi PORTB, ledpin
rcall print_packet
sbi PORTB, ledpin
rjmp loop
click:
;
; blink the LED
;
cbi PORTB, ledpin
rcall packet_delay
sbi PORTB, ledpin
rjmp loop