; flaneth - flash and ethernet
; Copyright (C) 2007-2012 Stefan Schuermans <stefan@schuermans.info>
; 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  0 = PC0



; output a data item with 62500 baud in 9N2 protocol
; extern void Ser62500Out9N2( unsigned short item );
.global Ser62500Out9N2
.func Ser62500Out9N2
Ser62500Out9N2:
	push	R16

	; parameters: R25:R24=value

	cli

	ldi	R16,0xFF			; PORTC := output
	sts	DDRC,R16

	ldi	R16,0x00			; start bit
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 0
	sbrc	R24,0
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 1
	sbrc	R24,1
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 2
	sbrc	R24,2
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 3
	sbrc	R24,3
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 4
	sbrc	R24,4
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 5
	sbrc	R24,5
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 6
	sbrc	R24,6
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 7
	sbrc	R24,7
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait251

	ldi	R16,0x00			; bit 8
	sbrc	R25,0
	ldi	R16,0xFF
	sts	PORTC,R16

	rcall	wait253

	ldi	R16,0xFF			; 2 stop bits
	sts	PORTC,R16

	rcall	wait256
	rcall	wait256

	sei

	pop	R16
	ret
.endfunc



; wait 256/253/251 cycles (including rcall and ret)
wait256:
	nop					; 3 cycles
	nop
	nop
wait253:
	nop					; 2 cycles
	nop
wait251:
	ldi	R16, 81				; 1 cycle, N := 81
wait_loop:
	dec	R16				; N cycles
	brne	wait_loop			; 2N-1 cycles
	nop					; 1 cycle
	ret					; 7 cycles (including rcall)

