; flaneth - flash and ethernet
; Copyright (C) 2007-2012 Stefan Schuermans <stefan@blinkenarea.org>
; Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
; a BlinkenArea project - http://www.blinkenarea.org/ */


#include <avr/io.h>

.section .text



; output = PD3



; output a byte item with 115200 baud in 8N1 protocol
; extern void Ser115200Out(unsigned char val);
.global Ser115200Out
.func Ser115200Out
Ser115200Out:
	push	R17
	push	R16

	; parameters: R24=val

	in	R17,SREG-0x20			; interrupts off
	cli

	clt					; start bit
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	bst	R24,0				; bit 0
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	bst	R24,1				; bit 1
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	bst	R24,2				; bit 2
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	bst	R24,3				; bit 3
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	bst	R24,4				; bit 4
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	bst	R24,5				; bit 5
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	bst	R24,6				; bit 6
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	bst	R24,7				; bit 7
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	set					; stop bit
	in	R16,PORTD-0x20
	bld	R16,3
	out	PORTD-0x20,R16

	rcall	wait135

	out	SREG-0x20,R17			; restore interrupt state

	pop	R16
	pop	R17
	ret
.endfunc



; wait 135 cycles (including rcall and ret)
wait135:
	nop					; 2 cycles
	nop
	ldi	R16, 42				; 1 cycle, N := 42
wait_loop:
	dec	R16				; N cycles
	brne	wait_loop			; 2N-1 cycles
	ret					; 7 cycles (including rcall)

