---------------------------------------- > 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