; ; i0.3.IO.44.thtp.asm ; i0 three-wire IPv4 I/O node demonstration code ; ; Neil Gershenfeld ; CBA MIT 11/30/08 ; ; (c) Massachusetts Institute of Technology 2008 ; Permission granted for experimental and personal use; ; license for commercial sale available from MIT. ; .include "tn44def.inc" ; ; definitions ; .equ Web_port = 80 ; Web server port .equ set_source_address_port = 1000 ; port to set board's source address .equ set_destination_address_port = 1001 ; port to set board's destination address .equ toggle_port = 1002 ; port to toggle the light .equ set_destination_flag = 1 ; status flag for setting destination address .equ set_source_flag = 2 ; status flag for setting source address .equ click_pin = PA0 ; i0 click pin .equ click_count = 5 ; loop count to wait during click .equ settle_count = 10 ; loop count to wait for click to settle .equ delay_count = 15 ; loop count to wait between clicks .equ button_bit = 5 ; button bit .equ button_pin = PA5 ; button pin .equ button_gnd = PA4 ; button ground .equ mosfet_pin = PA7 ; MOSFET pin .equ LED_pin = PA2 ; LED pin .equ LED_gnd = PA1 ; LED ground .equ END = 192 ; SLIP definitions .equ ESC = 219 ; " .equ ESC_END = 220 ; " .equ ESC_ESC = 221 ; " .equ eeprom_source_address = 0 ; EEPROM addresses .equ eeprom_destination_address = eeprom_source_address + 4 ; " ; ; registers ; .def zero = R1 ; 0 .def one = R2 ; 1 .def double_count = R3 ; double loop count .def triple_space = R4 ; triple click spacing .def check_lo = R5 ; lo checksum accumulator .def check_hi = R6 ; hi checksum accumulator .def check_carry = R7 ; checksum carry accumulator .def bit_count = R16 ; bit counter .def byte_count = R17 ; byte counter .def txbyte = R18 ; transmit byte .def rxbyte = R19 ; receive byte .def temp = R20 ; temporary storage .def temp1 = R21 ; temporary storage .def temp2 = R22 ; temporary storage .def temp3 = R23 ; temporary storage .def flags = R24 ; status flags .def click_space = R25 ; click spacing .def count = R26 ; loop counter (X low) .def count_hi = R27 ; loop counter (X high) ; R28, 29 used for Y pointer ; R30, 31 used for Z pointer ; ; macros ; ; copy ; .macro copy ; ; copy bytes between two memory locations ; copy destination, source ; ldi zh, high(@1) ldi zl, low(@1) ld temp, z ldi zh, high(@0) ldi zl, low(@0) st z, temp .endmacro ; ; compare ; .macro compare ; ; compare two memory locations ; ldi zh, high(@1) ldi zl, low(@1) ld temp, z ldi zh, high(@0) ldi zl, low(@0) ld temp1, z cp temp, temp1 .endmacro ; ; compare_immediate ; .macro compare_immediate ; ; compare memory location with a constant ; ldi zh, high(@0) ldi zl, low(@0) ld temp, z cpi temp, @1 .endmacro ; ; store_immediate ; .macro store_immediate ; ; store immediate constant to memory ; ldi temp, @1 sts @0, temp .endmacro ; ; set_data ; .macro set_data ; ; set Y registers to point to data ; ldi yh, high(@0*2) ldi yl, low(@0*2) .endmacro ; ; putslip ; .macro putslip ; ; putslip ; click char in txbyte, with SLIP mapping ; ldi temp, END cpse txbyte, temp rjmp putslipchar ; ; END char ; mov temp, txbyte ldi txbyte, ESC rcall putclick rcall char_delay ldi txbyte, ESC_END rcall putclick rcall char_delay mov txbyte, temp rjmp endputslip ldi temp, ESC cpse txbyte, temp rjmp putslipchar ; ; ESC char ; mov temp, txbyte ldi txbyte, ESC rcall putclick rcall char_delay ldi txbyte, ESC_ESC rcall putclick rcall char_delay mov txbyte, temp rjmp endputslip putslipchar: ; ; ordinary char, no escape needed ; rcall putclick rcall char_delay endputslip: .endmacro ; ; read_eeprom ; .macro read_eeprom ; ; read EEPROM location to register ; read_eeprom_loop: ; make sure EEPROM is ready for writing sbic EECR, EEPE rjmp read_eeprom_loop ldi temp, high(@1) out EEARH, temp ldi temp, low(@1) out EEARL, temp sbi EECR, EERE in @0, EEDR .endmacro ; ; write_eeprom ; .macro write_eeprom ; ; write register to EEPROM ; write_eeprom_loop: ; make sure EEPROM is ready for writing sbic EECR, EEPE rjmp write_eeprom_loop cbi EECR, EEPM1 cbi EECR, EEPM0 ldi temp, high(@0) out EEARH, temp ldi temp, low(@0) out EEARL, temp out EEDR, @1 sbi EECR, EEMPE sbi EECR, EEPE .endmacro ; ; write_sram_to_eeprom ; .macro write_sram_to_eeprom ; ; write SRAM location to EEPROM ; write_sram_to_eeprom_loop: ; make sure EEPROM is ready for writing sbic EECR, EEPE rjmp write_sram_to_eeprom_loop cbi EECR, EEPM1 cbi EECR, EEPM0 ldi temp, high(@0) out EEARH, temp ldi temp, low(@0) out EEARL, temp ldi zh, high(@1) ldi zl, low(@1) ld temp, z out EEDR, temp sbi EECR, EEMPE sbi EECR, EEPE .endmacro ; ; code segment ; .cseg .org 0 rjmp reset ; ; init_packet ; initialize outgoing packet in SRAM ; init_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 outgoing_ip_start = SRAM_START; .equ outgoing_ip_length = outgoing_ip_start + 2 .equ outgoing_ip_checksum = outgoing_ip_start + 10 .equ outgoing_source_address = outgoing_ip_start + 12 .equ outgoing_destination_address = outgoing_ip_start + 16 .equ outgoing_udp_start = outgoing_ip_start + 20 .equ outgoing_source_port = outgoing_udp_start .equ outgoing_destination_port = outgoing_udp_start + 2 .equ outgoing_udp_length = outgoing_udp_start + 4 ldi zl, low(outgoing_ip_start) ldi zh, high(outgoing_ip_start) ; ; IP ; ldi temp, 0x45 ; version = 4 (4 bits), header length = 5 32-bit words (4 bits) st z+, temp ldi temp, 0 ; type of service st z+, temp ldi temp, 0 ; packet length high byte (to be calculated) st z+, temp ldi temp, 0 ; packet length low byte (to be calculated) st z+, temp ldi temp, 0 ; identification (high byte) st z+, temp ldi temp, 0 ; identification (low byte) st z+, temp ldi temp, 0 ; flag (3 bits), fragment offset (13 bits) (high byte) st z+, temp ldi temp, 0 ; flag (3 bits), fragment offset (13 bits) (low byte) st z+, temp ldi temp, 255 ; time to live st z+, temp ldi temp, 17 ; protocol = 17 for UDP st z+, temp ldi temp, 0 ; header checksum (to be calculated) st z+, temp ldi temp, 0 ; header checksum (to be calculated) st z+, temp read_eeprom temp, eeprom_source_address ; source address byte 1 st z+, temp read_eeprom temp, eeprom_source_address+1 ; source address byte 2 st z+, temp read_eeprom temp, eeprom_source_address+2 ; source address byte 3 st z+, temp read_eeprom temp, eeprom_source_address+3 ; source address byte 4 st z+, temp read_eeprom temp, eeprom_destination_address ; destination address byte 1 st z+, temp read_eeprom temp, eeprom_destination_address+1 ; destination address byte 2 st z+, temp read_eeprom temp, eeprom_destination_address+2 ; destination address byte 3 st z+, temp read_eeprom temp, eeprom_destination_address+3 ; destination address byte 4 st z+, temp ; ; UDP ; ldi temp, 0 ; source port st z+, temp ldi temp, 0 ; source port st z+, temp ldi temp, 0 ; destination port st z+, temp ldi temp, 0 ; destination port st z+, temp ldi temp, 0 ; payload length high byte (to be calculated) st z+, temp ldi temp, 0 ; payload length low byte (to be calculated) st z+, temp ldi temp, 0 ; payload checksum (not used) st z+, temp ldi temp, 0 ; payload checksum (not used) st z+, temp ; ; null-terminated data messages ; empty_message: .db 0 off_message: .db "HTTP/1.1 200 OK",13,10,"Content-Type: text/html",13,10,13,10,"