console.s
changeset 89 1b3cea759eff
parent 88 c923295ee520
child 90 13c2deb919d1
equal deleted inserted replaced
88:c923295ee520 89:1b3cea759eff
     1 .nolist
       
     2 .include "m168def.inc"      ; Same family as 328P
       
     3 .list
       
     4 
       
     5 .include "macros.inc"
       
     6 
       
     7 ;; Load a 16-bit *word* address into the given register a a byte address
       
     8 .macro loadp_16_i
       
     9 		ldi			@0, high(2 * @2)
       
    10 		ldi			@1, low(2 * @2)
       
    11 .endm
       
    12 
       
    13 .macro load_16_i
       
    14 		ldi			@0, high(@2)
       
    15 		ldi			@1, low(@2)
       
    16 .endm
       
    17 
       
    18 ;; Data
       
    19 .dseg
       
    20 buffer:	.byte 0
       
    21 
       
    22 ;; Interrupt Vector
       
    23 .cseg
       
    24 .org 0x0000
       
    25         rjmp        Main
       
    26 
       
    27 ;; Libraries
       
    28 .include "div.inc"			; Division routines
       
    29 
       
    30 ;; Serial
       
    31 .set SERIAL_BAUD = 103		; 9.6k @ 16Mhz
       
    32 
       
    33 ;; Initialize the UART for 
       
    34 Serial_Init:
       
    35 	; Set up control registers
       
    36 		; Single-speed
       
    37 		poke		[UCSR0A, r16, (0 << U2X0)]
       
    38 
       
    39 		; Async
       
    40 		; n parity
       
    41 		; 1 stop
       
    42 		; 8 bits
       
    43 		poke		[UCSR0C, r16, (0b00 << UMSEL00) | (0b00 << UPM00) | (0 << USBS0) | (0b11 << UCSZ00)]
       
    44 
       
    45 		; Baud rate
       
    46 		poke		[UBRR0L, r16:r17, SERIAL_BAUD]
       
    47 		
       
    48 		; Enable RX
       
    49 		; Enable TX
       
    50 		; 8 bits
       
    51 		poke		[UCSR0B, r16, (1 << RXEN0) | (1 << TXEN0) | (0 << UCSZ02)]
       
    52 		
       
    53 	; Done
       
    54 		ret
       
    55 
       
    56 ;; Send a single byte on serial port
       
    57 ; Input byte in r16
       
    58 Serial_Send:
       
    59 	; Wait for idle
       
    60 		lds			r0, UCSR0A
       
    61 		sbrs		r0, UDRE0
       
    62 		rjmp		Serial_Send
       
    63 
       
    64 	; Copy byte to buffer
       
    65 		sts			UDR0, r16
       
    66 
       
    67 	; Done
       
    68 		ret
       
    69 
       
    70 ;; Read a single byte from serial port
       
    71 ; Output byte in r16
       
    72 Serial_Recv:
       
    73 	; Wait for recv
       
    74 		lds			r0, UCSR0A
       
    75 		sbrs		r0, RXC0
       
    76 		rjmp		Serial_Recv
       
    77 
       
    78 	; Copy byte from buffer
       
    79 		lds			r16, UDR0
       
    80 
       
    81 	; Done
       
    82 		ret
       
    83 
       
    84 ;; Write nul-terminated string from program mem to serial port
       
    85 ; Input string in Z
       
    86 Serial_pprint:
       
    87 	; Load byte to r16
       
    88 		lpm			r16, Z+
       
    89 
       
    90 	; Quit if nul
       
    91 		tst			r16
       
    92 		breq		_serial_pprint_end
       
    93 
       
    94 	; Write it
       
    95 		rcall		Serial_Send
       
    96 
       
    97 	; Continue
       
    98 		rjmp		Serial_pprint
       
    99 
       
   100 _serial_pprint_end:
       
   101 		ret
       
   102 
       
   103 ;; Write nul-terminated string from sram and \r\n to serial port
       
   104 ; Input string in Z
       
   105 Serial_sprintln:
       
   106 	; Load byte to r16
       
   107 		ld			r16, Z+
       
   108 
       
   109 	; Quit if nul
       
   110 		tst			r16
       
   111 		breq		_serial_sprintln_end
       
   112 
       
   113 	; Write it
       
   114 		rcall		Serial_Send
       
   115 
       
   116 	; Continue
       
   117 		rjmp		Serial_sprintln
       
   118 
       
   119 _serial_sprintln_end:
       
   120 	; \r\n
       
   121 		ldi			r16, 13
       
   122 		rcall		Serial_Send
       
   123 		ldi			r16, 10
       
   124 		rcall		Serial_Send
       
   125 
       
   126 	; Done
       
   127 		ret
       
   128 
       
   129 ;; Write char to serial port
       
   130 ; Input byte in r16
       
   131 Serial_bprint:
       
   132 		; ASCII offset for '0'
       
   133 		ldi			r17, 48
       
   134 		mov			r4, r17	
       
   135 	
       
   136 	; Convert
       
   137 		ldi			r17, 100
       
   138 		call		div8u
       
   139 		add			r16, r4
       
   140 		rcall		Serial_Send
       
   141 		mov			r16, r15
       
   142 
       
   143 		ldi			r17, 10
       
   144 		call		div8u
       
   145 		add			r16, r4
       
   146 		rcall		Serial_Send
       
   147 		mov			r16, r15
       
   148 
       
   149 		add			r16, r4
       
   150 		rcall		Serial_Send
       
   151 		
       
   152 	ret
       
   153 
       
   154 ;; Program
       
   155 message:	.db "Hello World", 13, 10, 0
       
   156 
       
   157 Main:
       
   158 ; Initialization
       
   159 	; Stack
       
   160 		poke		[SPL, r16:r17, RAMEND]
       
   161 
       
   162     ; Enable interrupts
       
   163         sei
       
   164 
       
   165 	; Init
       
   166 		rcall		Serial_Init
       
   167 
       
   168 ; Main program
       
   169 		ldi			ZH, high(message * 2)
       
   170 		ldi			ZL, low(message * 2)
       
   171 		
       
   172 		rcall		Serial_pprint
       
   173 
       
   174 ; Echo out
       
   175 		sbi			DDRB, PORTB5
       
   176 		ldi			r20, 0
       
   177 		ldi			r21, 0
       
   178 		ldi			r22, 0
       
   179 		
       
   180 		; pointer to memory buffer
       
   181 		ldi			XH, high(buffer)
       
   182 		ldi			XL, low(buffer)
       
   183 
       
   184 		st			X, r22		; '\0'
       
   185 
       
   186 Main_Echo:
       
   187 		; blink LED
       
   188 		out			PORTB, r20
       
   189 		
       
   190 		; read
       
   191 		rcall		Serial_Recv
       
   192 		push		r16
       
   193 		
       
   194 		; display
       
   195 		rcall		Serial_bprint
       
   196 		ldi			r16, 32
       
   197 		rcall		Serial_Send
       
   198 
       
   199 		pop			r16
       
   200 
       
   201 		; test for control chars
       
   202 		cpi			r16, 127	; DEL
       
   203 		breq		backspace
       
   204 
       
   205 		cpi			r16, 13		; '\r'
       
   206 		breq		cr
       
   207 
       
   208 		cpi			r16, 10		; '\n'
       
   209 		breq		Main_Echo	; ignore
       
   210 
       
   211 		rjmp		char		; buffer char
       
   212 
       
   213 ; Erase last char
       
   214 backspace:
       
   215 		; ignore if already at zero
       
   216 		cpi			XL, low(buffer)
       
   217 		ldi			r23, high(buffer)
       
   218 		cpc			XH, r23
       
   219 		breq		echo
       
   220 
       
   221 		; use pre-decrement to store nul
       
   222 		st			-X, r22		; '\0'
       
   223 
       
   224 		rjmp		echo
       
   225 
       
   226 ; Erase line
       
   227 cr:
       
   228 		; seek to start
       
   229 		ldi			XH, high(buffer)
       
   230 		ldi			XL, low(buffer)
       
   231 		
       
   232 		; store nul
       
   233 		st			X, r22		; '\0'
       
   234 
       
   235 		rjmp 		echo
       
   236 
       
   237 char:
       
   238 		; buffer char
       
   239 		st			X+, r16
       
   240 		st			X, r22		; '\0'
       
   241 
       
   242 echo:		
       
   243 		; running counter
       
   244 		inc			r21
       
   245 		mov			r16, r21
       
   246 		rcall		Serial_bprint
       
   247 		
       
   248 		; ' '
       
   249 		ldi			r16, 32
       
   250 		rcall		Serial_Send
       
   251 
       
   252 		; length
       
   253 		mov			r16, XL
       
   254 		rcall		Serial_bprint
       
   255 
       
   256 		; ' '
       
   257 		ldi			r16, 32
       
   258 		rcall		Serial_Send
       
   259 		
       
   260 		; output buffer
       
   261 		ldi			ZH, high(buffer)
       
   262 		ldi			ZL, low(buffer)
       
   263 		rcall		Serial_sprintln
       
   264 		
       
   265 		; toggle
       
   266 		com			r20
       
   267 		
       
   268 		; continue
       
   269 		rjmp		Main_Echo
       
   270