-
Notifications
You must be signed in to change notification settings - Fork 30
/
iic-serial-core.mu4
138 lines (108 loc) · 4.58 KB
/
iic-serial-core.mu4
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
| This file is part of muforth: https://muforth.dev/
|
| Copyright 2002-2024 David Frech. (Read the LICENSE for details.)
loading IIC over serial (core)
__meta
| Support for translating serial port commands into IIC commands
| using a serial-connected S08QE or QG as a master.
| The style of this code was inspired by chat3.mu4. It's really just an
| experiment to see if the style that I wrote the USB chat firmware in
| works in this context too. The main difference is that the original chat
| code was a big loop, where the USB "loop" was a subroutine - which meant
| that to return the "top" from any piece of code all you do is _return_. And
| using tail calls, it's easy to code in a Forth-like style that is very
| efficient.
hex
( Create a forward jump at the start of the flash sector.)
forward-jmp iic-loop
( Return a signature of who we are and what we're doing.)
label id
char I c, char I c, char C c, ( IIC)
char t c, ( test)
.ifdef in-ram
char X c, ( version X - testing)
.else
char 1 c, ( version 1)
.then
| QE and QG parts have been trimmed to run at 9.216M so they can
| accurately generate a 115200 bps UART clock. IIC clock rates are
| calculated assuming a bus clock of 9.216M.
label InitIIC
| 02 # ( mul=1, ICR=02: /24, sda hold 8~) IICF ) mov ( 384k IIC clock)
| 19 # ( mul=1, ICR=19: /96, sda hold 9~) IICF ) mov ( 96k IIC clock)
| 15 # ( mul=1, ICR=15: /88 sda hold 17~) IICF ) mov ( 104k IIC clock)
12 # ( mul=1, ICR=12: /64 sda hold 13~) IICF ) mov ( 144k IIC clock)
80 # IICC ) mov ( enable IIC module)
| ff # IICS ) mov ( clear all status bits)
%0000_1100 # lda PTADS ) sta ( high drive on SCL and SDA, A3, A2)
PTAPE ) sta ( pullup enable on SCL and SDA, A3, A2)
rts ;c
label get-serial ( returns char in A)
begin SCIS1 5 ( recvr full) bset? until
SCID ) lda rts ;c
label put-serial ( transmits char in A)
begin SCIS1 7 ( xmit empty) bset? until
SCID ) sta rts ;c
label signon
.h clr .x clr
begin id ,x lda put-serial c .x inc 5 # cpx 0= until
rts ;c
| The keys to the IIC status and control bits:
| reg IICC | IICEN IICIE MST TX TXAK RSTA 0 0
| reg IICS | TCF IAAS BUSY ARBL 0 SRW IICIF RXAK
label start-bit
IICC 5 ( MST) bset rts ;c
label stop-bit
IICC 5 ( MST) bclr rts ;c
label restart-bit
IICC 2 ( RSTA) bset rts ;c
label put-iic
get-serial c
IICC 4 ( TX) bset IICD ) sta
begin IICS 7 ( TCF) bset? until ( transfer complete)
| begin IICS 1 ( IICIF) bset? until ( transfer complete)
| IICS 1 bset
IICS ) lda ( RXAK is bit 0)
put-serial j ;c
( Return 0ff if got RXAK; 00 otherwise)
| .a clr IICS 0 ( RXAK) bclr? if .a com then put-serial j ;c
label start-iic-recv
IICC 4 ( TX) bclr IICD ) lda ( read last byte; start new recv)
begin IICS 7 ( TCF) bset? until ( transfer complete)
put-serial j ;c
label end-iic-recv
IICC 4 ( TX) bset IICD ) lda ( read last byte; don't start new recv)
begin IICS 7 ( TCF) bset? until ( transfer complete)
put-serial j ;c
label get-iic-ack
IICC 3 ( TXAK) bclr ( ACK slave) start-iic-recv j ;c
label get-iic-nack
IICC 3 ( TXAK) bset ( NACK slave) start-iic-recv j ;c
| Commands:
| 0-2f Bye - exit IIC code and return to HC08 chat loop
| 30 Start - send START bit
| 31 Restart - send RESTART bit
| 32 Stop - send STOP bit
| 33 Send - send data byte, return ACK/NACK
| 34 RecvAck - receive data byte, send ACK
| 35 RecvNack - receive data byte, send NACK
| 36 EndRecv - read last byte received
label process-serial
SCIS1 5 ( recvr full) bclr? if rts then ( nothing to do)
SCID ) lda ( command)
( NOTE: Command numbers are all given in HEX.)
30 # sub ( IIC commands start at 30 hex; anything below that, we exit)
u< if ( 00 - 2f Bye) 2 # ais ( skip return from process-serial) rts then
( 30 Start) start-bit 0!= until
( 31 Restart) restart-bit .a dec 0!= until
( 32 Stop) stop-bit .a dec 0!= until
( 33 SendByte) put-iic .a dec 0!= until
( 34 RecvAck) get-iic-ack .a dec 0!= until
( 35 RecvNack) get-iic-nack .a dec 0!= until
( 36 EndRecv) end-iic-recv .a dec 0!= until
( unknown command) rts ;c
\m iic-loop resolve>> ( jump at start of Flash points here)
label main-loop
InitIIC c ( setup IIC interface)
signon c ( tell who we are and what we're doing)
begin process-serial c again ;c