aboutsummaryrefslogtreecommitdiff
path: root/amforth-6.5/avr8/lib/hardware/i2c-twi-slave.frt
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-08-19 12:15:28 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-08-19 12:15:28 +0200
commit67d25d837ac55f28a366c0a3b262e439a6e75fc3 (patch)
treedf7715c7724c5935ab87c807f3b8b4ef529315e3 /amforth-6.5/avr8/lib/hardware/i2c-twi-slave.frt
parente0d6784e89dba33226c0edb815bb974486fa7c48 (diff)
Add AmForth
Diffstat (limited to 'amforth-6.5/avr8/lib/hardware/i2c-twi-slave.frt')
-rw-r--r--amforth-6.5/avr8/lib/hardware/i2c-twi-slave.frt89
1 files changed, 89 insertions, 0 deletions
diff --git a/amforth-6.5/avr8/lib/hardware/i2c-twi-slave.frt b/amforth-6.5/avr8/lib/hardware/i2c-twi-slave.frt
new file mode 100644
index 0000000..c045433
--- /dev/null
+++ b/amforth-6.5/avr8/lib/hardware/i2c-twi-slave.frt
@@ -0,0 +1,89 @@
+\ the following code is work in progress.
+\ debug output and other oddities are possible
+
+\ The slave provides a circular buffer of
+\ $10 bytes size. The variables i2c-in
+\ and i2c-out are pointers to the next
+\ byte in this buffer.
+\
+
+\ #require buffer.frt
+
+$10 constant i2c-bufsize
+
+i2c-bufsize buffer: i2c-buffer
+variable i2c-in
+variable i2c-out
+
+: ++wrap ( addr -- n )
+ dup @ ( -- addr n )
+ dup 0 [ i2c-bufsize 1- ] literal within
+ if 1+ else drop 0 then
+ dup rot !
+;
+
+: >i2c-buffer ( c -- )
+ i2c-buffer i2c-in ++wrap + c!
+;
+
+: i2c-buffer> ( -- c )
+ i2c-buffer i2c-out ++wrap + c@
+;
+
+
+TWCR_TWEN TWCR_TWIE TWCR_TWINT or or constant TWCR_TWENALL
+
+\ set the hw address and start the receiver
+: i2c.slave.init ( hwid -- )
+ 2* \ see datasheet
+ TWAR c!
+ [ TWCR_TWENALL TWCR_TWEA or ] literal TWCR c!
+;
+
+: i2c.slave.twcr.ack
+ [ TWCR_TWENALL TWCR_TWEA or ] literal TWCR c!
+;
+: i2c.slave.twcr.nack
+ [ TWCR_TWENALL ] literal TWCR c!
+;
+
+: i2c.slave.twcr.reset
+ [ TWCR_TWENALL TWCR_TWEA TWCR_TWSTO or or ] literal TWCR c!
+;
+
+\ own address received with ACK
+: i2c.addr.ack ( -- )
+ \ well, nothing to do
+ i2c.slave.twcr.ack
+;
+
+\ data received with NACK, probably the last one
+: i2c.data.nack ( -- )
+ TWDR c@ >i2c-buffer
+ i2c.slave.twcr.nack
+;
+\ data received with ACK, more to follow
+: i2c.data.ack ( -- )
+ TWDR c@ >i2c-buffer
+ i2c.slave.twcr.ack
+;
+
+: i2c.data.send ( -- )
+ i2c-buffer> TWDR c!
+ i2c.slave.twcr.ack
+;
+
+: i2c.slave.isr ( -- )
+ TWSR c@ $f8 and
+ \ receiving data
+ dup $60 = if drop i2c.addr.ack exit then \ TW_SR_SLA_ACK
+ dup $80 = if drop i2c.data.ack exit then \ TW_SR_SLA_ACK
+ dup $88 = if drop i2c.data.nack exit then \ TW_SR_SLA_NACK
+ \ sending data
+ dup $a8 = if drop i2c.data.send exit then \ TW_ST_SLA_ACK
+ dup $b8 = if drop i2c.data.send exit then \ TW_ST_DATA_ACK
+ drop i2c.slave.twcr.reset
+;
+
+' i2c.slave.isr decimal TWIAddr int!
+$42 i2c.slave.init