console.s
author Tero Marttila <terom@fixme.fi>
Fri, 07 May 2010 01:46:31 +0300
changeset 9 30c3807baac1
child 11 49c5eeee4cb7
permissions -rw-r--r--
serial console
.nolist
.include "m168def.inc"      ; Same family as 328P
.list

.macro poke
		.message	"No parameters"
.endm

.macro poke_i_8_i
		ldi			@1, @2
		sts			@0, @1
.endm

.macro poke_i_16_i
		ldi			@1, low(@3)
		sts			@0+0, @1
		
		ldi			@2, high(@3)
		sts			@0+1, @2
.endm

;; Load a 16-bit *word* address into the given register a a byte address
.macro loadp_16_i
		ldi			@0, high(2 * @2)
		ldi			@1, low(2 * @2)
.endm

.macro load_16_i
		ldi			@0, high(@2)
		ldi			@1, low(@2)
.endm

;; Interrupt Vector
.org 0x00
        rjmp        Main

;; Serial
.set SERIAL_BAUD = 103		; 9.6k @ 16Mhz

;; Initialize the UART for 
Serial_Init:
	; Set up control registers
		; Single-speed
		poke		[UCSR0A, r16, (0 << U2X0)]

		; Async
		; n parity
		; 1 stop
		; 8 bits
		poke		[UCSR0C, r16, (0b00 << UMSEL00) | (0b00 << UPM00) | (0 << USBS0) | (0b11 << UCSZ00)]

		; Baud rate
		poke		[UBRR0L, r16:r17, SERIAL_BAUD]
		
		; Enable RX
		; Enable TX
		; 8 bits
		poke		[UCSR0B, r16, (0 << RXEN0) | (1 << TXEN0) | (0 << UCSZ02)]
		
	; Done
		ret

;; Send a single byte on serial port
; Input byte in r16
Serial_Send:
	; Wait for idle
		lds			r0, UCSR0A
		sbrs		r0, UDRE0
		rjmp		Serial_Send

	; Copy byte to buffer
		sts			UDR0, r16

	; Done
		ret

;; Write nul-terminated string to serial port
; Input string in Z
Serial_Write:
	; Load byte to r16
		lpm			r16, Z+

	; Quit if nul
		tst			r16
		breq		_serial_write_end

	; Write it
		rcall		Serial_Send

	; Continue
		rjmp		Serial_Write

_serial_write_end:
		ret

;; Program
message:	.db "Hello World", 13, 10, 0

Main:
; Initialization
	; Stack
		poke		[SPL, r16:r17, RAMEND]

    ; Enable interrupts
        sei

	; Init
		rcall		Serial_Init

loop:
; Main program
		ldi			ZH, high(message * 2)
		ldi			ZL, low(message * 2)
		
		rcall		Serial_Write
		
		; repeat
		rjmp		loop