----------------------------------------
> From: andrewthol...@gmail.com
> Date: Wed, 17 Feb 2016 16:29:41 +0000
> To: amforth-devel@lists.sourceforge.net
> 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/
Amforth-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/amforth-devel

Reply via email to