Hello Christian,
On 01/17/2012 10:15 PM, Christian Kellermann wrote:
>
> I am interested in an example for bit banging, communicating with
> a serial device on a digital port. Do you have an example for such
> code?
yes and no.
please find below the code I used to demonstrate a connection
to a i2c (twi) device. The device was connected to PortB 3 and 4.
This is a *very* simplistic approach, but it does work nicely for
i2c devices. No error checking, whatsoever.
You can see in the code, a few low level words are needed
(sda0, sda1, scl0, scl1, wait) from which the pulse trains for
one byte data exchange are constructed (bit>i2c, byte>i2c). Add
generating start and stop conditions, and you are pretty much done.
This does not implement clock slowing by the addressed device or
multi master collision detection. But it's good for some scenarios.
That is an example of bit-banging.
---
No, I have not tried to build a soft uart or 1-wire in software.
How would I go about it? Well, say I want a connection with
9600 baud. Then I need a feeling, of how many forth commands
can I run within one Bit transfer time: 1/9600 * 1105920 (crystal)
gives 1152 AVR cycles per bit. The idle command loop needs approx.
40 cycles for one round, so we are near 29 rounds per bit. This
does not sound too bad. A few commands (assert the current bit,
get the next bit, then wait some) seems possible to fit in.
*However*, I would try to measure the resulting pulse times
and fine tune the words sending one bit with with additional
noop commands.
IF that does not work, or if busy waiting is not an option, then
the next idea would be to use a timer and put the handling of
one Bit into the timer overflow isr. I have done this with
receiving single bits from a rfm12 434MHz receiver and rotating
them into a temporary variable.
If you seach the web, I'm sure, something more sophisticated will
come up. If you give it a try, be sure to share the code on the
list.
Cheers,
Erich
------------------------------------------------------------------
\ 2011-01-23 EW fosdem i2c bitbang demo
\ purely didactic thing.
\ for production code use lib/twi.frt
marker --start--
decimal
PORTB 0 portpin: blue \ sda
PORTB 1 portpin: green
PORTB 2 portpin: red \ scl
PORTB 3 portpin: sda
PORTB 4 portpin: scl
: sda0 sda low blue high ;
: sda1 sda high blue low ;
: scl0 scl low red high ;
: scl1 scl high red low ;
: wait-long &500 0 do 1ms loop ;
: wait-short &50 0 do 1ms loop ;
\ "function pointer" wait
Rdefer wait
: slow ['] wait-long is wait ;
: fast ['] wait-short is wait ;
slow
: pulses ( n -- )
0 ?do
red low wait red high wait
loop
;
\ test "function pointer"
: test-wait
slow &5 pulses
fast &25 pulses
;
\ clock a given data bit out
: bit>i2c ( bit -- )
if sda1 else sda0 then \ set data
scl1 wait scl0 wait \ clock it out
;
\ see if bit at pos is set
: get.bit ( byte pos -- bit )
1 swap lshift \ -- byte bitmask
and \ -- bit
;
\ clock one byte out, MSB first!
: byte>i2c ( byte -- )
8 0 do
dup 7 i - \ 7 6 5 ... 0: MSB first!
get.bit
bit>i2c
loop
drop
;
\ create start, stop conditions
: i2c.start sda0 wait scl0 wait ;
: i2c.stop scl1 wait sda1 wait ;
\ read ack|nack from bus
: ack<i2c ( -- t/f )
sda pin_input
scl1 wait
sda pin_low?
sda pin_output
scl0 wait
;
\ make it really fast!
' noop is wait
\ send a byte to pcf8574
: >8io ( x -- )
$40 \ addr
i2c.start
byte>i2c ack<i2c drop
byte>i2c ack<i2c drop
i2c.stop
;
: i2c.scan
$FF 0 do
i2c.start
i byte>i2c
ack<i2c \ -- ack|nack
i2c.stop
if
i . cr
then
2 +loop
;
: init
blue pin_output blue high
red pin_output red high
sda pin_output sda high
scl pin_output scl high
\ alternatively
\ $ff DDRB c! $ff PORTB c!
['] noop is wait
;
: ms 0 ?do 1ms loop ;
variable N 0 N !
: run
init
$00 >8io
&1000 ms
begin
N @ invert >8io
1 N +!
&1000 ms
key? until
key drop
;
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
Amforth-devel mailing list for http://amforth.sf.net/
[email protected]
https://lists.sourceforge.net/lists/listinfo/amforth-devel