; ; 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 ledpin1 = PB1; LED pin .equ buttonbit = 2; pushbutton bit .equ buttonpin = PB2; pushbutton pin .equ clickpin = PB3; click input pin .equ ledpin2 = PB4; mosfet output pin .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 .def temp1 = R25; .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 ; cbi PORTB, ledpin2 sbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 rcall clickdelay sbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 cbi PORTB, ledpin2 rcall clickdelay ; ; send data clicks ; putclick0: lsr txbyte; get next bit brcc putclick1; if carry set, send a 1 click cbi PORTB, ledpin2 sbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 cbi PORTB, ledpin2 rcall clickdelay rjmp putclick2; otherwise ... putclick1: cbi PORTB, ledpin2; ... send a 0 click cbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 rcall clickdelay sbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 cbi PORTB, ledpin2 rcall clickdelay putclick2: dec bitcnt; if not all bits sent brne putclick0; send next bit ; ; send stop clicks ; cbi PORTB, ledpin2 sbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 rcall clickdelay sbi PORTB, ledpin2 rcall clickdelay cbi PORTB, ledpin2 cbi PORTB, ledpin2 rcall clickdelay ret; ; ; clickdelay ; delay between clicks ; clickdelay: ldi temp, 200 clickdelayloop: ldi temp1, 200 clickdelayloop2: dec temp1 brne clickdelayloop2 dec temp brne clickdelayloop 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, ledpin1 ; init LED pin for output sbi DDRB, ledpin1 ; sbi PORTB, buttonpin ; init pushbutton pin for input with pull-up cbi DDRB, buttonpin ; sbi PORTB, ledpin2 ; init mosfet control pin for output sbi DDRB, ledpin2 ; 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, ledpin1 ;sbi PORTB, ledpin2 ldi txbyte, 2 rcall putclick sbi PORTB, ledpin1 ;cbi PORTB, ledpin2 rjmp loop click: ; ; blink the LED ; cbi PORTB, ledpin1 rcall packet_delay sbi PORTB, ledpin1 rjmp loop