Pass 6 digit ascII from spin obj to asm ?

I have never wrote any code in spin yet, I'm pretty good at pasm.
I understand when you start a new cog, you can pass one value that is an single address in hub ram.
PUB LedDisplay (text)
cognew(@asm_entry, text) 'launch assembly program in a COG
And to access it you would use something like rdlong mytext,par
You could only squeeze in four bytes (letters) in an long.
So the par would instead need to point to the first hub address of a 6 bytes/longs table?
And how do you use LedDisplay("HELLO9") to be broken up in 6 bytes/longs in spin?
not using "H","E"... as it need to support to.string(value) for temprature etc
Later it should also support a dot and then have 7 letters as a dot does not use up a digit.
I understand when you start a new cog, you can pass one value that is an single address in hub ram.
PUB LedDisplay (text)
cognew(@asm_entry, text) 'launch assembly program in a COG
And to access it you would use something like rdlong mytext,par
You could only squeeze in four bytes (letters) in an long.
So the par would instead need to point to the first hub address of a 6 bytes/longs table?
And how do you use LedDisplay("HELLO9") to be broken up in 6 bytes/longs in spin?
not using "H","E"... as it need to support to.string(value) for temprature etc
Later it should also support a dot and then have 7 letters as a dot does not use up a digit.
Comments
Lately I've been spending a lot of time with Tim Moore's four port serial driver. I've modified it to increase the buffers size, to set end of message flags and detect wireless tx acknowledgments.
I'm hoping of using the same starting point (Tim's driver) but make one the serial ports drive the LED display. The display wouldn't need to run faster than 80 bps and wouldn't require checking for any rx signal. It would probably end up slowing the serial driver but most of my serial devices aren't very fast.
I'm not sure if this is possible (especially for me) but it would be nice if the LED driver didn't take up a whole cog. I think it would be great if the cog could also drive a few serial lines.
The led driver needs to move on the next digit on a regulary time interval and do so at least 200 times/sec.
But if you look at driver v0.6 you see a 4000 cycle delay (will use waitcnt later)
so you could squeeze in your program there and not waste a cog.
as long you don't use waitpne etc that wait for long periods.
And I may even write a driver made in spin,
so you could squeeze in your spin code and not waste a cog.
But now back the original question.
PUB Display (text)
cognew(@asm_entry, @text) 'launch assembly program in a COG
added these lines of code
mov buffer,par
rdlong mytext,buffer
created a new spin program
OBJ
LED : "LED17"
PUB DisplayText
LED.Display("W")
And it will change the first letter H to W.
But how do I change the spin program so it will accept 6 numbers inside LED.Display(1,2,3,4,5,6)?
LED.Display("W")
I think you'll want
LED.Display(@textBuffer) DAT textBuffer byte "World1", 0 ' add a zero in case you want to treat it as a string.
I think you'd be better off using bytes instead of longs. You could read one byte in at a time and place it in the appropriate place inside the cog.
I'd add an incrementing pointers "t1" and "t2".
EDIT: I think I did this wrong. I'm fixing it now. Fixed, I think. I needed the movd instructions. It's harder to use pointers in PASM.
mov buffer,par mov t1, buffer mov t2, #mytext movd modify1, t2 rdbyte t3,t1 modify1 mov 0-0, t3 add t1, #1 add t2, #1 movd modify2, t2 rdbyte t3,t1 modify2 mov 0-0, t3 add t1, #1 add t2, #1 movd modify3, t2 rdbyte t3,t1 modify3 mov 0-0, t3 add t1, #1 add t2, #1 movd modify4, t2 rdbyte t3,t1 modify4 mov 0-0, t3 add t1, #1 add t2, #1 movd modify5, t2 rdbyte t3,t1 modify6 mov 0-0, t3 add t1, #1 add t2, #1 movd modify7, t2 rdbyte t3,t1 modify7 mov 0-0, t3
I think that would get the six characters into the cog.I think it would work if you left mytext as longs. I'm not sure how to deal with bytes vs longs within the cog.
In hub RAM you increment by one for each byte and by four for each long. Inside a cog you increment longs by one. I'm not sure how one increments by bytes inside the cog.
Edit: I think I've fixed it.
{{ *************************************** * LED17Demo, needs LED17.spin * *************************************** }} OBJ LED : "LED17" PUB DisplayText LED.Display("W","O","R","K","I","T") DAT {{ }}
{{ ***************************************** * LED driver v0.7 * * Author: Tony Philipsson * * Copyright 2011 Electrons Engineering * ***************************************** }} CON CLK = 4 'pin for clock (P2) LAT = 2 'pin for latc (P1) SER = 1 'pin for serial (P0) A1= %1<<19 'LED Segments A2= %1<<20 B= %1<<21 C= %1<<22 D1= %1<<23 D2= %1<<10 E= %1<<11 F= %1<<12 G1= %1<<6 G2= %1<<2 H= %1<<13 I= %1<<14 J= %1<<15 K= %1<<3 L= %1<<4 M= %1<<5 DP= %1<<7 PUB Display (text,tx2,tx3,tx4,tx5,tx6) cognew(@asm_entry, @text) 'launch assembly program in a COG DAT org asm_entry mov dira,#7 'make pin 0, 1, 2 pin an output mov outa,#0 'set all pins to off main mov digit,#6 'we have 6 digits to multiplex mov buffer,par 'reset buffer (par=hub address of first letter) movs sinkpnt,#sink 'reset transistor sink table loop1 rdlong mytext,buffer 'get ascII char from hub ram. movs fontpnt,#font 'reset font pointer add fontpnt,mytext 'add ascii code that mytext have, to font pointer sub fontpnt,#48 'subtract as our ascii table start at char(48) nop 'needed as above code mod code below fontpnt mov serial,0-0 'start a new serial data sinkpnt add serial,0-0 'fuse in the transistor sink bit. mov bit_test,#1 'reset bit mask shl bit_test,#24 'we have 24 bits to shift out loop2 test serial,bit_test wz 'test serial data bitwize muxnz outa,#SER 'answer in z, use it to set Serial pin or outa,#CLK 'turn pin on (clock) andn outa,#CLK 'turn pin off (clock) sar bit_test,#1 wz 'shift right if_nz jmp #loop2 'if not zero, jmp or outa,#LAT 'turn pin on (latch) andn outa,#LAT 'turn pin off (latch) mov delay, #500 'delay cycles shl delay, #3 'make it a 8 times bigger value(use #10 for slowmotion) loop3 djnz delay,#loop3 'a slight delay could not hurt before next digit. add sinkpnt,#1 'next digit add buffer,#4 'next text char djnz digit, #loop1 'have we done 6 digits? jmp #main 'restart font long A1+A2+B+C+D1+D2+E+F+J+M '0 long B+C '1 long A1+A2+B+D1+D2+E+G1+G2 '2 long A1+A2+B+C+D1+D2+G2 '3 long B+C+F+G1+G2 '4 long A1+A2+D1+D2+F+G1+K '5 long A1+A2+C+D1+D2+E+F+G1+G2 '6 long A1+A2+B+C '7 long A1+A2+B+C+D1+D2+E+F+G1+G2 '8 long A1+A2+B+C+D1+D2+F+G1+G2 '9 long 0,0,0,0,0,0,0 'unused long A1+A2+B+C+E+F+G1+G2 'A long A1+A2+B+C+D1+D2+G2+I+L 'B long A1+A2+D1+D2+E+F 'C long A1+A2+B+C+D1+D2+I+L 'D long A1+A2+D1+D2+E+F+G1+G2 'E long A1+A2+E+F+G1 'F long A1+A2+C+D1+D2+E+F+G2 'G long B+C+E+F+G1+G2 'H long I+L 'I long B+C+D1+D2+E 'J long E+F+G1+J+K 'K long D1+D2+E+F 'L long B+C+E+F+H+J 'M long B+C+E+F+H+K 'N long A1+A2+B+C+D1+D2+E+F 'O long A1+A2+B+E+F+G1+G2 'P long A1+A2+B+C+D1+D2+E+F+K 'Q long A1+A2+B+E+F+G1+G2+K 'R long A1+A2+C+D1+D2+F+G1+G2 'S long A1+A2+I+L 'T long B+C+D1+D2+E+F 'U long E+F+J+M 'V long B+C+E+F+K+M 'W long H+J+K+M 'X long H+J+L 'Y long A1+A2+D1+D2+J+M 'Z sink long %10,%01,%10<<8,%01<<8,%10<<16,%01<<16 'what transistor to sink. mytext res 1 buffer res 1 bit_test res 1 serial res 1 digit res 1 delay res 1
I tried this flashing text, but it's gets garbled when it tries to update to LUCKY7
Repeat
LED.Display("W","O","R","K","I","T")
waitcnt(15000000+cnt)
LED.Display("L","U","C","K","Y","7")
waitcnt(15000000+cnt)
add sinkpnt,#1 'next digit
I'm guessing it's the same as incrementing the source by one. Interesting.
I suppose one could add an appropriate number to increment the destination field as well. This self modifying code stuff is a trip.
if you add %1000000000 to it and that would be the same as +1 without effecting the sourcefield.
lable mov 0-0,#255
add lable,destfield
destfield long %1<<9 'declaring needed as highest number inline is 511
I think the driver should read the characters in from the hub in a similar way to many of the serial drivers.
So every time I use LED.Display in the spin cog it starts a new cog.
This works:
OBJ LED : "LED17" PUB DisplayText Repeat LED.Display("W","O","R","K","I","T") waitcnt(15000000+cnt) cogstop(1) LED.Display("L","U","C","K","Y","7") waitcnt(15000000+cnt) cogstop(1)
But how do I create a spin method of updating the text on the fly?
I guess I need to create seperate LED.Start and LED.Display
In the PASM COG you simply loop checking a memory address, and if it changes you jump to a dedicated code.
Moreover, consider a string as an array. You pass the address of the first char. If you had an array (say array[10]) you would pass to the COG the address of the array as @array[0]. Then you iteratively add 1, 2 or 4 (byte, word, long) to have the address of the next one.
With a string you pass the string address, so part of the job is done.
With a formatted string the last byte is 0, so you can check for it for ending the routine.
Massimo
{{ *************************************** * LED17Demo, needs LED17.spin * *************************************** }} OBJ LED : "LED17" PUB DisplayText LED.Display(@textBuffer) repeat waitcnt($FF0000+cnt) bytemove(@textBuffer,@text1,7) waitcnt($FF0000+cnt) bytemove(@textBuffer,@text2,7) DAT textBuffer byte "1 1 1 ",0 ' added a zero to treat it as a string. text1 byte "OH MY",0 text2 byte "WORKIT",0
needs LED17.spin (version 0.72 or higher.) attached to this post.Supports zero terminated text of any lenght and also space char.