----------------------------------------
> From: [email protected]
> Date: Wed, 17 Feb 2016 16:29:41 +0000
> To: [email protected]
> Subject: [Amforth] Bit Banged serial on Arduino
>
> Hi,
>
> Has anybody created a 'soft uart' in amforth ? I need a second port on on
> arduino and would rather program it in forth than via the IDE.
>
What kind of speeds you are targeting? Do you want it to be interrupt driven or
blocking? How much you want it to be integrated?
Blocking is rather easy. I'm planning 6 channel soft serial.
Following code misses some data probably and isn't serial system. It is based
on timer and pin change. Further the protocol is time based, not voltage based.
However same ideas can be used with serial communication implementation.
Lot of ready code which is tangled to its self.
Hope this gives ideas.
Hannu Vuolasaho
I have two assembler words:
------------------- cfetchzero.asm --------------------
; Hannu Vuolasaho 2015
; Some words for efficient timer handling
; c@0 ( addr -- c, addr contents is zeroed )
VE_CFETCHZERO:
.dw $ff03
.db "c@0", 0
.dw VE_HEAD
.set VE_HEAD = VE_CFETCHZERO
XT_CFETCHZERO:
.dw PFA_CFETCHZERO
PFA_CFETCHZERO:
movw zl, tosl
clr tosh
ld tosl, Z
st Z, r2
jmp_ DO_NEXT
--------------------- questionoffsetpluspluscstore.asm ----------------
And the application
------------- stereocontroller.fs --------------------------------
\ Hannu Vuolasaho 2016
\ Kenwood SL16 protocol
\ |-------------------|
\ _| |____ Busy signal
\ |--| |-| |-| |-|
\ ___--| |--| |-| |--| |____ Data signal
\ | | Start:
\ Busy up 5ms later act up 5 ms later down.
\ | 1 | 0 | 1 |
\ 1: 5ms low 2.5ms high
\ 0: 2.5 ms low 2.5 high
\ MSB first 16 bits and after them busy comes down same time wtih data.
\ #include builds.frt
\ #include bitnames.frt
\ #include previous.frt
\ #include buffer.frt
\ #include marker.frt
\ #include definitions.frt
\ #include 2-fetch.frt
\ #include 2-store.frt
\ #include quotations.frt
\ #include avr-defers.frt
\ #include is.frt
\ #include ms.frt
marker --stereocontroller--
\ wordlist constant stereoprivate
\ get-order stereoprivate swap 1+ set-order definitions
PORTD sl16datapin portpin: sl16data
PORTD sl16busypin portpin: sl16busy
PORTD 1 sl16busypin lshift 1 sl16datapin lshift or bitmask: sl16bus
\ LCD back light control LED. Controlled with Timer 0 OCRB
PORTD 5 portpin: lcd-led
-2 constant sl16off
variable sl16word
variable sl16txindex
36 buffer: sl16rxvalues
variable lcd-backlight
\ #include sl16send.fs
\ #include sl16receive.fs
------------------- sl16send.fs -------------------------------------------
\ Hannu Vuolasaho 2016
\ Kenwood SL16 protocol
\ data sending words
\ Requires stereocontroller.fs
marker --sl16send--
: -sl16rx ( -- )
( Disable interrupst from SL16 bus )
0 [ PCMSK2 sl16bus drop ] literal literal pin!
sl16bus pin_output
[ sl16busy drop ] literal sl16bus pin!
0 TCNT0 c!
$ff OCR0A c!
sl16one OCR0B c!
;
: +sl16rx ( -- )
( Enable interupts for SL16 bus )
sl16bus low sl16bus pin_input
[ sl16bus drop ] literal
[ PCMSK2 sl16bus drop ] literal literal pin!
0 sl16word !
0 TCNT0 c!
#112 OCR0A c!
lcd-backlight @ dup 0= if
drop #127 lcd-led low
then
OCR0B c!
;
: sl16endtx ( -- OC0Bval )
lcd-led low
sl16off sl16txindex ! lcd-backlight @
+sl16rx
;
: sl16datatime ( index -- n )
sl16data pin_low?
if
drop sl16zero \ time for 2.5ms to stay up
else
dup 0 <
if
drop sl16endtx exit
then
1 swap lshift sl16word @ and ( bit )
if sl16one else sl16zero then ( countervalue )
-1 sl16txindex +!
then
sl16data toggle
;
: timer0OCA.isr ( -- )
lcd-backlight @ if lcd-led high then
;
: timer0OCB.isr ( -- )
sl16txindex @ dup sl16off =
if
drop
lcd-led low
exit
then
dup #16 <
if
sl16datatime
else
\ Not a valid index
drop #15 sl16txindex !
\ BTW we are starting.
sl16data high sl16one
then
OCR0B c!
0 TCNT0 c!
;
: sl16send ( n -- )
sl16busy pin_high? if
sl16rxvalues @ if
[ #75 #17 * #10 / ] literal
ms
then
then
-sl16rx
sl16word !
#42 sl16txindex ! \ 42 is good value as any other> 15
lcd-led high
[ #75 #17 * #10 / ] literal ms \ Wait it to be sent
+sl16rx
;
: display-backlight ( n -- )
dup #100> if drop #110 then dup lcd-backlight !
sl16txindex @ sl16off = if OCR0B c! else drop then
;
------------------- sl16receive.fs
------------------------------------------------
\ Hannu Vuolasaho 2016
\ Kenwood SL16 protocol
\ data receiving words
\ Requires stereocontroller.fs
marker --receiver--
: values. ( -- )
36 0 do sl16rxvalues i + c@0 . loop cr
;
: sl16printword ( n -- ) base @>r hex u. cr r> base ! ;
: sl16rxtimes>value ( -- )
sl16rxvalues 2 + \ Skip count and first low
#16 0 do dup i + c@0 ( baseaddr value )
[ sl16one sl16one 4 / 2dup + rot rot - ] literal literal
within if
1 #15 i - lshift sl16word +!
then loop drop
;
Edefer sl16print
' sl16printword is sl16print
: sl16endrx ( -- )
sl16rxvalues c@ dup 17> swap 0> 0= or ( flag )
if $ffff sl16word ! values. \ this should be removed when in proudction.
else
0 sl16word !
sl16rxtimes>value
then sl16word @ sl16print
0 sl16rxvalues !
+sl16rx
;
: PC2.isr ( -- )
sl16rxvalues TCNT0 c@0 sl16data pin_low? 0= and
?++offsetc! sl16busy pin_low? if sl16endrx then
;
------------------ init.fs --------------------------
\ Hannu Vuolasaho 2016
\ Initialization words.
\ Startup squence.
\ requires sl16send.fs and sl16receive.fs
marker --init--
' timer0OCA.isr TIMER0_COMPAAddr int!
' timer0OCB.isr TIMER0_COMPBAddr int!
: init-sl16sending ( -- )
sl16off sl16txindex !
$ff OCR0A c!
$0 OCR0B c!
$2 TCCR0A_WGM0 and
TCCR0A c!
TIMSK0_OCIE0A TIMSK0_OCIE0B or TIMSK0 c!
5 TCCR0B_CS0 and TCCR0B c!
;
' PC2.isr PCINT2Addr int!
: init-sl16reception ( -- )
0 sl16rxvalues !
\ Pin change interrupt configuration
sl16bus drop
sl16bus drop PCMSK2 pin!
$4 PCICR_PCIE and PCICR c!
;
: init-stereocontroller ( -- )
\ init varaibles
0 display-backlight
\ Init I/O
lcd-led pin_output
init-sl16sending
init-sl16reception
;
; Hannu Vuolasaho 2016
; ?offsetc! ( addr n -- )
; n 0 <> if addr @ 1+ addr ! addr @ addr + n swap c!
; else 2drop
VE_QUESTION_OFFSET_C_STORE:
.dw $ff0b
.db "?++offsetc!", 0
.dw VE_HEAD
.set VE_HEAD = VE_QUESTION_OFFSET_C_STORE
XT_QUESTION_OFFSET_C_STORE:
.dw PFA_QUESTION_OFFSET_C_STORE
PFA_QUESTION_OFFSET_C_STORE:
mov temp0, tosl ;value in temp0
loadtos
cpi temp0, 0
breq QUESTION_OFFSET_C_STORE_ZERO
movw zl, tosl ; addr in Z
clr tosh ; Clear highside
ld tosl, Z ;load offset
adiw tosl,1 ; increment
st Z, tosl ; write back
add zl, tosl ; add offset
adc zh, tosh
st Z, temp0 ; Write the value.
QUESTION_OFFSET_C_STORE_ZERO:
loadtos ; Drop the address.
jmp_ DO_NEXT
------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
Amforth-devel mailing list for http://amforth.sf.net/
[email protected]
https://lists.sourceforge.net/lists/listinfo/amforth-devel