Serial

The eZ8 can have up to two UART's built in. It can be used to send midi notes to a keyboard or text to a terminal program running on your computer.

Setting it up

To set up serial you need to specify the baudrate and set the pinmodes for the serial pins.

Calculating the frequency for the baudrate generator.

;Change this to the crystal frequency you are using.
SYSFREQ    EQU 2000000

; UART baudrate selection
UART_BAUD   EQU 115200
UART_BRG    EQU ((SYSFREQ + (UART_BAUD * 8)) / (UART_BAUD * 16))

Macro to turn on uart interrupts

EI_U: MACRO
    orx IRQ0ENH, #%10
    orx IRQ0ENL, #%10
ENDMAC

If you want to be able to receive data via serial as well add this line:

VECTOR UART0_RX = isr_uart_rx

...and next: set up the pinmodes and interrupts.

init_uart:
    ldx PAADDR,#DDR                ;Set RX to input
    orx PACTL,#(16)
    andx PACTL,#~(32)            ;Set TX to output
    ldx PAADDR,#AF
    orx PACTL,#((16)|(32))

    ldx U_BRH, #HIGH(UART_BRG)
    ldx U_BRL, #LOW(UART_BRG)
    ldx U_CTL1, #%00     ; clear for normal non-Multiprocessor operation
    ldx U_CTL0, #%C0     ; Transmit enable, Receive Enable, No Parity, 1 Stop
    EI_U
    ret

Send bytes

To send a byte simply do this:

    ldx U_D, #42    ; Write 42 to serial data register.

If you want to make sure it works every time make sure to wait for the uart to finish sending the last byte. You can do this by checking the uart status register. In a routine it looks like this:

putc:
    push R1
$$:
    ldx R1, U_STAT0 ;Loop until serial is ready.
    and R1, #%04
    jr Z, $B

    ldx U_D, R0    ; Write R0 to serial data register. It gets sent automatically!
    pop R1
    ret

Receive bytes

Using interrupts for receiving bytes is really helpful. You don't have to worry about continuously polling for data. Just have an interrupt service routine for it. Make sure your interrupts are globally enabled using the EI instruction. Also make sure you set the isr vector. VECTOR UART0_RX = isr_uart_rx

isr_uart_rx:
	ldx R0,U0RXD ;Load data from uart rx data register in R0
	;put your code here
	iret

Final Sourcecode:

This is simpleserial.inc revision 1.

; simpleserial.inc
; by Koen van Vliet
; CC0 - Public Domain
; blog: 
;   http://8times8.host56.com
; programmers reference: 
;   http://ez8tut.sourceforge.com

VECTOR UART0_RX = isr_uart_rx

;Change this to the crystal frequency you are using.
SYSFREQ    EQU 2000000
;------------------------------------------------------------------------------
; UART baudrate selection
UART_BAUD   EQU 115200
UART_BRG    EQU ((SYSFREQ + (UART_BAUD * 8)) / (UART_BAUD * 16))

; UART control, status and data register mnemonics
U_BRH       EQU U0BRH
U_BRL       EQU U0BRL
U_CTL0      EQU U0CTL0
U_CTL1      EQU U0CTL1
U_STAT0     EQU U0STAT0
U_D         EQU U0D
EI_U: MACRO
    orx IRQ0ENH, #%10
    orx IRQ0ENL, #%10
ENDMAC


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output a character to UART
; R0: holds the character to send
putc:
    push R1
$$:
    ldx R1, U_STAT0
    and R1, #%04
    jr Z, $B
    ldx U_D, R0
    pop R1
    ret


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output a string to UART
; RR0: holds the address of the string
puts:
    push R2
    push R3
    ld R2, R0
    ld R3, R1
$$:
    ldc R0, @RR2
    cp R0, #0
    jr Z, $F
    call putc
    incw RR2
    jr $B
$$:
    pop R3
    pop R2
    ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output a string to UART from register file instead of flash
; RR0: holds the address of the string
puts_r:
    push R2
    push R3
    ld R2, R0
    ld R3, R1
$$:
    ldx R0, @RR2
    cp R0, #0
    jr Z, $F
    call putc
    incw RR2
    jr $B
$$:
    pop R3
    pop R2
    ret
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output data from Flash of SIZE bytes long
; RR0: holds the address of the data
; R4: The size
putFd:
    push R2
    push R3
	ld R2,R0
	ld R3,R1
$$:
    ldc R0, @RR2
    call putc
    incw RR2
    djnz R4,$B

    pop R3
    pop R2
    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Intialize UART
init_uart:
    ldx U_BRH, #HIGH(UART_BRG)
    ldx U_BRL, #LOW(UART_BRG)
    ldx U_CTL1, #%00     ; clear for normal non-Multiprocessor operation
    ldx U_CTL0, #%C0     ; Transmit enable, Receive Enable, No Parity, 1 Stop
    EI_U
    ret




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output an integer to UART formatted as a string
; RR0: holds the integer
puti:
	cp	R1,#0
	cpc R0,#0
	jr nz,$F
	
	ld	R0,#30h
	call putc
	ret
$$:
	
	ld  R5,#00h
	
	ld	R2,#high(-10000)
	ld	R3, #low(-10000)
	call	Num1
	ld	R2,#high(-1000)
	ld	R3, #low(-1000)
	call	Num1
	ld	R2,#high(-100)
	ld	R3, #low(-100)
	call	Num1
	ld	R2,#high(-10)
	ld	R3, #low(-10)
	call	Num1
	ld	R3,R2
Num1:	
	ld	R4,#('0'-1)
Num2:
	inc	R4
	
	add R1,R3
	adc R0,R2
	
	jr	c,Num2
	
	sub R1,R3
	sbc R0,R2
	
	cp R5,1
	jr z,Num3
	
	cp R4,#('0')
	jr z,Num4
Num3:	
	ld R5,1
	push R0
	ld	R0,R4
	call	putc
	pop R0
Num4:	
	ret

SCOPE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Interrupt Service Routine for UART
isr_uart_rx:
	ldx R0,U0RXD ;Load data from uart rx data register in R0
	;put your code here
	iret
	
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;  Routine: puth
;;;;;  Print byte as hexadecimal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
puth:
	push R0
	;Upper nibble
	srl R0 ;>>4
	srl R0
	srl R0
	srl R0
	add R0,#30h
	cp R0,#(30h + 9) ;0-9
	jr ule,$F
	add R0,#(10h - 9);A-F
$$:
	call putc
	pop R0
	;Lower nibble
	and R0,#0Fh
	add R0,#30h
	cp R0,#(30h + 9) ;0-9
	jr ule,$F
	add R0,#(10h - 9);A-F
$$:
	call putc
	ret

Please submit corrections, suggestions, and new documentation here: Submit a ticket
← Return to Reference Index
This is not an official Zilog website. Zilog nor 8times8 are liable for any damage done to equipment. Tutorial and reference copyright ©8times8 Creative Commons CC-0 License (public domain.) This reference uses content from Zilog's technical datasheets. Fair use only. Datasheets copyright © 2013 Zilog®, Inc. Z8, Z8 Encore!, Z8 Encore! XP and Z8 Encore! MC are trademarks or registered trademarks of Zilog, Inc. Read Zilog's terms at zilog.com

Website design by Koen van Vliet. Hosted by sourceforge.net