Ho to reuse FullDuplexSerial from multiple COGs? [RESOLVED - use cserial]
Andrey Demenev
Posts: 377
I have 2 cogs running SPIN code, and need to write data to serial port from each. I have tried, the following, without success:
debug.spin
main.spin:
I receive "MAIN" twice, then nothing.
What is the correct way of doing this?
Post Edited (Andrey Demenev) : 5/5/2010 1:49:55 AM GMT
debug.spin
VAR LONG gLock OBJ fd : "FullDuplexSerial" PUB init gLock := lockNew fd.start(31, 30, 0, 115200) PUB str(s) repeat until not lockSet(gLock) result := fd.str(s) lockClr(gLock) PUB tx(b) repeat until not lockSet(gLock) result := fd.tx(b) lockClr(gLock) PUB dec(b) repeat until not lockSet(gLock) result := fd.dec(b) lockClr(gLock) PUB hex(b, n) repeat until not lockSet(gLock) result := fd.hex(b,n) lockClr(gLock)
main.spin:
CON _CLKMODE = XTAL1 + PLL8X _CLKFREQ = 96_000_000 OBJ debug: "debug" another: "another" PUB main debug.init another.start repeat debug.str(string("MAIN", $0D)) WAITCNT(CLKFREQ + CNT)
OBJ debug: "debug" var LONG stack[noparse][[/noparse]32] PUB start CogNew(main, @stack) PUB main repeat debug.str(string("ANOTHER", $0D)) WAITCNT(CLKFREQ + CNT)
I receive "MAIN" twice, then nothing.
What is the correct way of doing this?
Post Edited (Andrey Demenev) : 5/5/2010 1:49:55 AM GMT
Comments
What you would have to do is to write an object that can stuff data to the tx buffer of the (once) running fd object. Therefore you need to know the fd object's tx_head, tx_tail and tx_buffer pointers. You would then do the same as the fd.tx itself does: check if long[noparse]/noparse]tx_head_ptr]+1 == long[noparse][[/noparse]tx_tail], and wait if they are equal. Otherwise write byte[noparse][[/noparse]tx_buffer][noparse][[/noparse]long[noparse][[/noparse]tx_head := data and add 1 to the head with wrapping at the buffer size: long[noparse][[/noparse]tx_head_ptr] := (long[noparse][[/noparse]tx_head_ptr] + 1) & 15
In code - add this to FullDuplexSerial.spin
and in your debug.init code write:
The other methods of debug should then use chr(ch) to send bytes to the fd object.
From main you call fd.init() once and then debug.init(fd.get_tx_head, fd.get_tx_tail, fd.get_tx_buffer) to setup the pointers.
Every object that wants to use debug would then have to be passed the 3 pointers as well. You could set up an array of 3 longs and put the 3 pointers in there, then you'd have to pass just the address of that array to your objects, which would then call debug.init() with the 3 values from the array.
Locking is not strictly necessary, but if you want to add it, you would pass the lock handle as well and try to acquire the lock at the start of each function in debug.spin, then release it at the end of the function.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Pullmoll's Propeller Projects
Post Edited (pullmoll) : 5/4/2010 8:05:02 AM GMT
· fd.start(31, 30, %10000, 115200)
The·start method·should only be called once, normally from cog 0 in the top object.· Check out the test program in CLib.· I have several cogs waiting on the same flag, and then they all print at the same time.
You can download CLib from the OBEX at http://obex.parallax.com/objects/594/·.
Dave
main.spin
another.spin
I have also attached cserial.spin.
Dave