
;; atmel_rs232 - Copyright 2007 by Michael Kohn
;; Email: mike ta mikekohn.net
;;   Web: http://www.mikekohn.net/
;;
;; Simple example of how to use the UART of an Atmel ATmega168
;; Tx/Rx on the ATmega168 are connected to a DS275 to convert
;; TTL serial values to rs232

.include "m168def.inc"

; note: CLKSEL 0010

.dseg

.cseg
  ;; Set up stack ptr
  ldi r16, RAMEND>>8
  out SPH, r16
  ldi r16, RAMEND&255
  out SPL, r16

  ;; Set up LED default
  ldi r18, 2
  out PORTB, r18            ; turn on bit 1
  ser r17
  out DDRB, r17             ; entire port B is output

  ;; Set up rs232 baud rate
  ldi r16, 25               ; 25 @ 4MHz = 9600 baud
  sts UBRR0L, r16           ; 25 @ 8MHz = 19200 baud
  eor r16, r16
  sts UBRR0H, r16

  ;; Set up rs232 options
  ldi r16, (1<<UCSZ00)+(1<<UCSZ01)    ; sets up data as 8N1
  sts UCSR0C, r16
  ldi r17, (1<<TXEN0)+(1<<RXEN0)      ; enables send/receive
  sts UCSR0B, r17
  eor r17, r17
  sts UCSR0A, r17

  ;; Send copyright message
  ldi r30, (copyright*2)&255
  ldi r31, (copyright*2)>>8
  call send_string

  ldi r19, (1<<PINB1)

main_loop:
  lds r20, UCSR0A         ; poll uart to see if there is a data waiting
  sbrs r20, RXC0
  rjmp main_loop          ; if no data, loop around

  lds r17, UDR0           ; read char from uart
  call send_char          ; echo char back to source

  eor r18, r19
  out PORTB, r18          ; toggle LED for fun :)
  rjmp main_loop

  sleep

send_char:
  lds r14, UCSR0A     ; check to see if it's okay to send a char
  sbrs r14, UDRE0
  rjmp send_char      ; if it's not okay, loop around :)
  sts UDR0, r17       ; output a char over rs232
  ret

send_string:
  lpm r17, Z+              ; read next char in string buffer (from flash)
  tst r17                  ; check for null termination
  breq exit_send_string
  rcall send_char
  rjmp send_string
exit_send_string:
  ret

copyright:
.db "atmel_rs232 for Atmel ATMega168\r\nCopyright 2007 - Michael Kohn\r\nVersion 0.18\r\n",0




