-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathcontroller.fs
110 lines (91 loc) · 2.72 KB
/
controller.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
\
\ This code controls 6 inputs and 8 outputs using a serial port. The
\ device accepts commands at 9600bps with the format !xy where x and y
\ are hexadecimal digits (case does not matter). The device sends the
\ state of the input once every 5 seconds or when they change, using the
\ format !xy<cr>.
\
\ Inputs are on port A, outputs on port B. A led on port C0 blinks every 5
\ seconds so that humans trust that the system is running.
\
pic16f87x
include multitasker.fs
include libnibble.fs
0 pin-c led
macro
: transmit-byte ( byte -- )
begin txif bit-clr? while yield repeat
txreg !
;
: transmit-nibble ( nibble -- ) nibble>hex transmit-byte ;
target
variable input
variable send?
\ Send content of variable input
task : send-input ( -- )
begin
\ Wait until we are asked to send data
begin send? @ 0= while yield repeat 0 send? !
\ Transmit the frame !XX<cr>
[char] ! transmit-byte
input @ dup 4 rshift transmit-nibble 0f and transmit-nibble
$d transmit-byte
again
;
task : check-input ( -- )
begin
\ If input state has changed, record it and send it
input @ porta @ dup input ! xor if 1 send? +! then
yield
again
;
variable post-count
\ Every 5 seconds, send the data
task : timer ( -- )
begin
\ Toggle led and send data
led toggle 1 send? +!
\ Wait for 152*256*128µs
98 post-count v-for
begin yield t0if bit-set? until
t0if bit-clr
v-next
again
;
variable recv-state
variable recv-char
task : receive-command ( -- )
begin
begin rcif bit-clr? while yield repeat
\ '!' indicates a command start
rcreg @ dup [char] ! = if drop 1 recv-state ! recurse exit then
\ Decode nibble
hex>nibble
\ If this is the first nibble, store it in position
recv-state @ 1 = if
swapf-tos recv-char ! 1 recv-state +!
\ If this is the second nibble, build the byte and set it on the port
else recv-state @ 2 = if
recv-char @ or portb ! 0 recv-state !
else
\ Other states are impossible
drop
then then
again
;
\ Initialization and main program
: init ( -- )
$06 adcon1 ! \ Disable A/C converter
$ff trisa ! \ All pins of porta as inputs
0 trisb ! \ All pints of portb as outputs
0 portb ! \ Initial state is everything low
$90 rcsta ! \ serial-enable 8bits-rx continuous-receive
$24 txsta ! \ asynchronous transmit high-speed generator
$19 spbrg ! \ 9600 bauds with BGRH high at 4MhZ
$be trisc ! \ Port C6 is TX, port C0 is control led
$07 option_reg ! \ 128 prescaler
0 recv-state ! \ Initial state
;
main : main ( -- ) init multitasker ;
\ Configuration
fosc-hs set-fosc