ucl 2.0 # Copyright (c) 2005-2006 by Wayne C. Gramlich # All rights reserved. library $pic16f688 library clock20mhz library $uart constant $eusart_clock = clock_rate constant $eusart_factor = 4 library $eusart configure fosc=hs package pdip pin 1 = power_supply pin 2 = osc1 pin 3 = osc2 pin 4 = ra3_in, name=p6 pin 5 = rx, name=rx pin 6 = tx, name=tx pin 7 = rc3_in, name=p3 pin 8 = rc2_in, name=p2 pin 9 = rc1_out, name=p1 pin 10 = rc0_out, name=p0 pin 11 = ra2_out, name=reset pin 12 = ra1_out, name=p5 pin 13 = ra0_in, name=p4 pin 14 = ground origin 0 constant microsecond = clocks_per_instruction / 1000000 constant buffer_power = 5 constant buffer_size = 1 << buffer_power constant buffer_mask = buffer_size - 1 global lows[buffer_size] array[byte] global highs[buffer_size] array[byte] global buffer_in byte global buffer_out byte global buffer_amount byte global command byte global response byte procedure main arguments_none returns_nothing p0 := $false p1 := $false p5 := $false command := 0 response := 0 buffer_in := 0 buffer_out := 0 buffer_amount := 0 # Warm up the UART: $trisc@5 := $true $trisc@4 := $true $txsta := 0 $tx9 := $true #$tx9 := $false $txen := $true $brgh := $true $rcsta := 0 $spen := $true $rx9 := $true #$rx9 := $false $cren := $true #$adden := $true $adden := $false $baudctl := 0 $brg16 := $true #$spbrg := $eusart_19200_low #$spbrgh := $eusart_19200_high #$spbrg := $eusart_115200_low #$spbrgh := $eusart_115200_high #$spbrg := $eusart_230400_low #$spbrgh := $eusart_230400_high #$spbrg := $eusart_406800_low #$spbrgh := $eusart_406800_high $spbrg := $eusart_625000_low $spbrgh := $eusart_625000_high #$spbrg := $eusart_833333_low #$spbrgh := $eusart_833333_high # For debugging only -- Just output pulses on {reset}: #loop_forever # reset := $false # reset := $true # For debugging only -- Just output pulses on {reset}: #loop_forever # p5 := $false # p5 := $true #loop_forever # if p6 # p5 := $true # reset := $true # else # p5 := $false # reset := $false loop_forever if p6 # P6=1; wait for it to go low: while p6 if $rcif call byte_receive() call process() p5 := $false else # P6=0; wait for it to go high: while !p6 if $rcif call byte_receive() call process() p5 := $true # # Process commands: # loop_forever # # Wait for some data from the host: # while !p6 # if $rcif # call byte_receive() # call process() # # # Wait for some data from the host: # while p6 # if $rcif # call byte_receive() # call process() procedure process arguments_none returns_nothing # This procedure will process the bits coming in on P4:2 and # respond with two bits on P1:0. local low byte local high byte p1 := $false p0 := $false if p4 # We have a command to process: if p3 # Command 1x: if p2 # Command 11 (Reset): reset := $false delay 10 * microsecond do_nothing reset := $true else # Command 10 (Receive Byte): if buffer_amount = 0 # Empty buffer: p1 := $true else # We've got one: high := highs[buffer_out & buffer_mask] if high@0 p0 := $true response := lows[buffer_out & buffer_mask] buffer_out := buffer_out + 1 buffer_amount := buffer_amount - 1 else # Command 0x (Send a byte): $tx9d := $false if p2 $tx9d := $true $txreg := command p1 := $true else # We just need to shift command data in and the response data out: command := command >> 2 if p3 command@7 := $true if p2 command@6 := $true if response@7 p1 := $true if response@6 p0 := $true response := response << 2 procedure byte_receive arguments_none returns_nothing # This procedure will receive a 9-bit "byte" from the UART # and store the result into the {highs} and {lows} buffers. local high byte local low byte high := 0 if $rx9 high := high + 1 highs[buffer_in & buffer_mask] := high lows[buffer_in & buffer_mask] := $rcreg buffer_in := buffer_in + 1 buffer_amount := buffer_amount + 1