; ; hello.echo.44.asm ; ; 115200 baud serial echo and LED hello-world program ; ; Neil Gershenfeld ; CBA MIT 10/12/09 ; ; (c) Massachusetts Institute of Technology 2009 ; Permission granted for experimental and personal use; ; license for commercial sale available from MIT. ; .include "tn44def.inc" .equ led_pin = PB2; LED pin .equ led_port = PORTB; LED port .equ led_dir = DDRB; LED dir .equ txpin = PA6; transmit pin .equ rxpin = PA7; receive pin .equ comm_port = PORTA; comm port .equ comm_dir = DDRA; comm direction .equ comm_pins = PINA; comm pins .def bitcnt = R16; bit counter .def temp = R17; temporary storage .def temp1 = R18; temporary storage .def txbyte = R19; transmit byte .def rxbyte = R20; receive byte ; Ryan's additions .equ button_pin = PA2; button pin ;.equ button_press = PCINT0; button interrupt .def temp2 = R21; temporary storage ; ; print ; .macro print ldi zl,low(@0*2) ldi zh,high(@0*2) rcall print_db .endmacro .cseg .org 0 rjmp reset // set the PCINT0 interrupt to call my button_status method .org 2 rjmp button_status ; ; half_bit_delay ; serial half bit delay ; half_bit_delay: ldi temp, 25; 115200 baud (20 MHz clock /1) half_bit_delay_loop: dec temp brne half_bit_delay_loop ret ; ; putchar ; assumes no line driver (doesn't invert bits) ; putchar: ldi bitcnt, 10; 1 start + 8 data + 1 stop bit com txbyte; invert everything sec; set start bit putchar0: brcc putchar1; if carry set sbi comm_port, txpin; send a '0' rjmp putchar2; else putchar1: cbi comm_port, txpin ; send a '1' nop; even out timing putchar2: rcall half_bit_delay; bit delay rcall half_bit_delay; " lsr txbyte; get next bit dec bitcnt; if not all bits sent brne putchar0; send next bit ret; ; ; getchar ; assumes no line driver (doesn't invert bits) ; getchar: ldi bitcnt, 9; 8 data + 1 stop bit getchar1: sbis comm_pins, rxpin; wait for start bit rjmp getchar1 rcall half_bit_delay; delay to middle of bit getchar2: rcall half_bit_delay; bit delay rcall half_bit_delay; " clc; clear carry sbis comm_pins, rxpin; if RX pin high skip sec; otherwise set carry dec bitcnt breq getchar3; return if all bits read ror rxbyte; otherwise shift bit into receive byte rjmp getchar2; go get next bit getchar3: ret ; ; blink_delay ; LED blink delay ; blink_delay: ldi temp, 255 blink_delay_loop: ldi temp1, 255 blink_delay_loop1: dec temp1 brne blink_delay_loop1 dec temp brne blink_delay_loop ret ; ; blink ; blink the LED ; blink: sbi led_port, led_pin rcall blink_delay cbi led_port, led_pin ret ; ; print_db ; prints a null-terminated .db string ; print_db: print_loop: lpm mov txbyte,R0 cpi txbyte,0 breq return rcall putchar adiw zl, 1 rjmp print_loop return: ret button_status: print message1 message1: .db "Button Status Changed! ",0 rcall blink reti ; ; main program ; reset: ; ; set fuse low byte to 0x7E for 20 MHz resonator ; ; set clock divider to /1 ; ldi temp, (1 << CLKPCE) ldi temp1, (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0) out CLKPR, temp out CLKPR, temp1 ; ; set stack pointer to top of RAM ; ldi temp, high(RAMEND) out SPH, temp ldi temp, low(RAMEND) out SPL, temp ; ; init comm pin ; sbi comm_port, txpin sbi comm_dir, txpin ; ; init LED pins ; cbi led_port, led_pin sbi led_dir, led_pin ; ;enable button interrupt sei ldi temp2, (1 << PCIE0) out GIMSK, temp2 ldi temp2, (1 << PCINT2) out PCMSK0, temp2 ; init button pin cbi comm_dir, button_pin ; turn on pull-up resistor sbi comm_port, button_pin ; ; start main loop ; loop: rcall getchar print message2 message2: .db "Ryan's board says: ",0 mov txbyte, rxbyte rcall putchar ldi txbyte,10 rcall putchar rcall blink rjmp loop