Evanh, the 'a' bit is working fine. I have problem with $FFFF (that is supposed to run perpetually).
@cgracey , Please can you check if the streamer documentation is correct/accurate/complete? Could it be improved to include a step by step guide for idiots like me?
By setting the D[15:0] count to its maximal value of $FFFF, a streamer command will run perpetually.
I am testing with the following code, and the streamer stops after the initial command.
CON_clkfreq = 4_000_000
DOWNLOAD_BAUD = 115_200
rx_pin = 63
tx_pin = 62
baud = 115_200
OUTPIN = 36OBJ
ser: "spin/SmartSerial"PUBmain() | md, i
ser.start(rx_pin, tx_pin, 0, baud)
md := %0100_0000_1<<23 + OUTPIN<<17 + $FFFF'streamer mode: imm 32x1, 32 bits, run perpetually
ser.printf("md: %x The streamer is supposed to run perpetually\n", md)
orgsetxfrq ##3216'streamer freq: 3 Hzdrvl #OUTPIN 'pin = output, lowxinit md, ##%1010_1010_1010_1010_1010_1010_1010_1010' It starts sending '0', ... and send '1' lastendwaitms(9000)
ser.printf("But it is not runnning perpetually!\n", md)
'
md := %0100_0000_1<<23 + OUTPIN<<17 + 1<<16 + $FFFF'streamer mode: imm 32x1, 32 bits, set bit 'a' (bit-16) to reverse MSB, run perpetually
ser.printf("md: %x The streamer is supposed to run perpetually in reverse order\n", md)
orgsetxfrq ##3216'streamer freq: 3 Hzdrvl #OUTPIN 'pin = output, lowxinit md, ##%1010_1010_1010_1010_1010_1010_1010_1010' It should start sending '1', ... and send '0' lastendrepeatorgnopend
It's very easy to know if it has stopped or not. The frequency is set to 3 Hz, so I am staring my eyes to an LED on pin 36
If you have the opportunity to run the example code you can see how the first xinit sends the bits from right to left, and stops on a 'HIGH' (rightmost '1' bit near ##%1010 .....). So the led keeps turned ON, only during the 9 seconds delay I have hardcoded
before it starts the second XINIT. (waitms(9000))
The second XINIT has the 'a' bit set (bit 16) and then it starts sending a one (HIGH) reading the bits in the same order as an english reader will read the code (##%1010_ ... and _1010 last). So in the last bit will turn the led OFF.
I don't need to feed more data as the whole purpose of $FFFF in D(15:0) bits is to just to run perpetually. Or did I misread the docs?
@Ramon said:
I don't need to feed more data as the whole purpose of $FFFF in D(15:0) bits is to just to run perpetually. Or did I misread the docs?
If you don't keep feeding the streamer with data in immediate mode the last value will be output perpetually (after the previous ones).
Immediate -> Pins/DACs
S/# supplies 32 bits of data which form a set of 1/2/4/8/16-bit values that are shifted by 1/2/4/8/16/32 bits on each subsequent NCO rollover, with the last value repeating. Each value is output in sequence.
So confusing. We are talking about the streamer. (what is that? something that sends a stream of bits??).
My mother tongue is not English, but I would have not chosen 'Run perpetually' and just I would said instead that "It will latch the pin(s) to the last value(s) sent."
That said, now please test the following code and tell me what you see.
CON_clkfreq = 4_000_000
DOWNLOAD_BAUD = 115_200
OUTPIN = 36PUBmain() | md, i
md := %0100_0000_1<<23 + OUTPIN<<17 + %1<<16 + $FFFF'streamer mode: imm 32x1, 32 bits, a-bit set, run perpetuallyorgsetxfrq ##3216'streamer freq: 3 Hzdrvl #OUTPIN 'pin = output, lowxinit md, ##%1010_1010_1010_1010_1010_1010_1010_1011' It starts sending '1010', ... and send '1011' last ... and 'Run perpetually'endrepeatorgnopend
In your examples the streamer will output the last bit perpetually after the earlier 31 bits. It is running perpetually but you give it only enough data for 32 bits. To repeat the 32-bit pattern perpetually you can do one of two things:
1. Give the streamer an immediate data long before the end of every 32-bit time period, e.g. using XCONT.
2. Use RDFAST -> Pins/DACs mode. Write 16 identical longs to hub RAM, say to address ptra, then do RDFAST #1,ptra before XINIT to output the block of 16 longs / 64 bytes / 512 bits perpetually. However you will not be able to use the FIFO for anything else while the streamer is running a RDFAST mode.
I changed OUTPIN from 36 to 56 for Eval board and changed bit frequency from 6 Hz to 2 Hz with setxfrq ##1074 which makes it much easier to count the LED flashes. I also increased the wait to 18000 milliseconds.
In "perpetual immediate mode" there is no very little XCONT buffering and a new immediate value takes effect immediately after first NCO rollover probably. Therefore a wait longer than 32 bits is necessary to see all the flashes due to the first XINIT and I have edited my previous post because point 1. was wrong.
I use imm->LUT in my video driver (nostalgic, usable beta, and displaylisted, in constuction - displaylist works and it is fun to have text line upside down , zoomed, or interleaved by blank or color lines)
While doing this I learned, that If the streamer don't get its data on time, it outputs the last bit. In HDMI mode it means instant picture loss.
You have to feed it continuously either as I did, by a timed loop, or via interrupts.
It is important that the streamer gets its LUT data when it needs it, and not when xcont is executed, so you may execute xcont, and after this update the LUT with new values while the previous xcont is still working, I thought it reads LUT at the time it is executed and I didn't understand why my colors are shifted.
Better not use the same LUT entries for every xcont if you want to change their value in the real time,.or miracles happen (colors not at the places where they are supposed to be). I use 2 LUT banks separated by 32 longs (the least possible amount) and update them while they are not used for displaying pixels..
@pik33 said:
It is important that the streamer gets its LUT data when it needs it, and not when xcont is executed, so you may execute xcont, and after this update the LUT with new values while the previous xcont is still working, I thought it reads LUT at the time it is executed and I didn't understand why my colors are shifted.
Yes, the timing is deceptive. Both in the streamer command buffer delaying the start of a particular command until the prior one is completed, and also in the pacing of the active command.
@pik33 said:
It is important that the streamer gets its LUT data when it needs it, and not when xcont is executed, so you may execute xcont, and after this update the LUT with new values while the previous xcont is still working, I thought it reads LUT at the time it is executed and I didn't understand why my colors are shifted.
Yes, the timing is deceptive. Both in the streamer command buffer delaying the start of a particular command until the prior one is completed, and also in the pacing of the active command.
The current discussion is mainly about "perpetual immediate mode" which has little or no command buffering.
Try this prog which flashes an LED. 4th stream is repeated after 1st, 2nd & 3rd.
Without a-bit:
313029282726252423222120191817161514131211109876543210
With a-bit:
765432101514131211109823222120191817163130292827262524
I am re-reading the docs again "Modes which shift data use bits bottom-first, by default. Some of these modes have the %a bit in D[16] to reorder the data sequence within the individual bytes to top-first when %a = 1."
Several things doesn't make any sense (what was the purpose? I have no idea):
Repeat means : that the last bit is latched instead of repeating the stream (and good luck finding which one is the last bit when you set the a-bit)
%a bit reversal means that you reverse each one of the four bytes, instead of reversing the whole 32 bit stream.
Without a-bit:
313029282726252423222120191817161514131211109876543210
With a-bit:
765432101514131211109823222120191817163130292827262524
I am re-reading the docs again "Modes which shift data use bits bottom-first, by default. Some of these modes have the %a bit in D[16] to reorder the data sequence within the individual bytes to top-first when %a = 1."
Several things doesn't make any sense (what was the purpose? I have no idea):
- Repeat means : that the last bit is latched instead of repeating the stream (and good luck finding which one is the last bit when you set the a-bit)
- %a bit reversal means that you reverse each one of the four bytes, instead of reversing the whole 32 bit stream.
It's not the always the last bit that is repeated, but whatever the last datum is, which could be 1, 2, 4, 8, 16, or 32 bits.
The %a reorders data within each byte. It doesn't reorder the bytes. It's just for sub-byte data. For nibbles, it swaps the nibbles. For two-bit data, it reorders them from top to bottom of the byte. For one-bit data, it reverses all the bits.
@cgracey said:
The %a reorders data within each byte. It doesn't reorder the bytes. It's just for sub-byte data. For nibbles, it swaps the nibbles. For two-bit data, it reorders them from top to bottom of the byte. For one-bit data, it reverses all the bits.
My attempt to get immediate streamer mode to do that didn't have any affect. The bit order didn't change at all. I tried as 32 x 1-bit, and as 16 x 2-bit.
Of note is these "immediate" modes aren't "byte" based. Is that a factor?
@TonyB_ said:
The current discussion is mainly about "perpetual immediate mode" which has no command buffering.
The command buffer is always there. But obviously, when those commands run out then any fresh command will be actioned much quicker. Presumably on the next NCO trigger for XCONT.
@cgracey said:
The %a reorders data within each byte. It doesn't reorder the bytes. It's just for sub-byte data. For nibbles, it swaps the nibbles. For two-bit data, it reorders them from top to bottom of the byte. For one-bit data, it reverses all the bits.
My attempt to get immediate streamer mode to do that didn't have any affect. The bit order didn't change at all. I tried as 32 x 1-bit, and as 16 x 2-bit.
Of note is these "immediate" modes aren't "byte" based. Is that a factor?
Evan, setting %a does work in immediate mode, try my stream1.spin2 program.
@TonyB_ said:
Try this prog and count the flashes (frequency should be 1 Hz). 4th stream of 15 flashes is repeated after 1st, 2nd & 3rd. What do you see?
I haven't yet. As a quick read, I'm guessing the very first $FFFF length is holding the first command in action indefinitely. All the others never run.
@TonyB_ said:
Try this prog and count the flashes (frequency should be 1 Hz). 4th stream of 15 flashes is repeated after 1st, 2nd & 3rd. What do you see?
I haven't yet. As a quick read, I'm guessing the very first $FFFF length is holding the first command in action indefinitely. All the others never run.
Evan, you'll need to edit at least two posts once you have tried the prog.
Lol, I'll leave the posts there. Amusingly, I've got the "a" bit working now in my old program. Dunno what I'd done wrong last time. Maybe was too tired and not remembering the polarity correctly.
EDIT: Ah-ha! Got it! I'd got side tracked on trying to identify whether "a" meant word-order or bit-order and then forgot I'd not answered the question before then assuming it was bit-order, when it isn't, and then proceeding to not find the reordering I expected. So, yes, I was still too tired.
Another ah-ha, also found out why we're not agreeing on the immediate mode command buffer too. The length of $ffff is special not just in perpetuity, it also seems to be like an XINIT in that the command it's attached to takes immediate effect.
This may affect all modes! I haven't tested.
EDIT: Tony, presumably this one will be the root of any lingering questions you've got with your test code as well.
@evanh said:
Another ah-ha, also found out why we're not agreeing on the immediate mode command buffer too. The length of $ffff is special not just in perpetuity, it also seems to be like an XINIT in that the command it's attached to takes immediate effect.
This may affect all modes! I haven't tested.
From my testing of perpetual modes, XINIT takes effect immediately and XCONT takes effect after next NCO rollover.
Well, without any control on the data sequence other than the waitx's, it's going to be overlapping in weird ways. First thing I'd do is replace all the $FFFF's with something sensible.
Here's the existing documentation regarding the "a" mode bit:
Modes which shift data use bits bottom-first, by default. Some of these modes have the %a bit in D[16] to reorder the data sequence within the individual bytes to top-first when %a = 1.
Here's a suggested addition to flesh it out with an example sequence:
Comments
Evanh, the 'a' bit is working fine. I have problem with $FFFF (that is supposed to run perpetually).
@cgracey , Please can you check if the streamer documentation is correct/accurate/complete? Could it be improved to include a step by step guide for idiots like me?
I am testing with the following code, and the streamer stops after the initial command.
CON _clkfreq = 4_000_000 DOWNLOAD_BAUD = 115_200 rx_pin = 63 tx_pin = 62 baud = 115_200 OUTPIN = 36 OBJ ser: "spin/SmartSerial" PUB main() | md, i ser.start(rx_pin, tx_pin, 0, baud) md := %0100_0000_1<<23 + OUTPIN<<17 + $FFFF 'streamer mode: imm 32x1, 32 bits, run perpetually ser.printf("md: %x The streamer is supposed to run perpetually\n", md) org setxfrq ##3216 'streamer freq: 3 Hz drvl #OUTPIN 'pin = output, low xinit md, ##%1010_1010_1010_1010_1010_1010_1010_1010 ' It starts sending '0', ... and send '1' last end waitms(9000) ser.printf("But it is not runnning perpetually!\n", md) ' md := %0100_0000_1<<23 + OUTPIN<<17 + 1<<16 + $FFFF 'streamer mode: imm 32x1, 32 bits, set bit 'a' (bit-16) to reverse MSB, run perpetually ser.printf("md: %x The streamer is supposed to run perpetually in reverse order\n", md) org setxfrq ##3216 'streamer freq: 3 Hz drvl #OUTPIN 'pin = output, low xinit md, ##%1010_1010_1010_1010_1010_1010_1010_1010 ' It should start sending '1', ... and send '0' last end repeat org nop end
How do you know it has stopped. Could it be that it has run out of data and is just sending 0's? Does it stop after 32 bits?
Mike
It's very easy to know if it has stopped or not. The frequency is set to 3 Hz, so I am staring my eyes to an LED on pin 36
If you have the opportunity to run the example code you can see how the first xinit sends the bits from right to left, and stops on a 'HIGH' (rightmost '1' bit near ##%1010 .....). So the led keeps turned ON, only during the 9 seconds delay I have hardcoded
before it starts the second XINIT. (waitms(9000))
The second XINIT has the 'a' bit set (bit 16) and then it starts sending a one (HIGH) reading the bits in the same order as an english reader will read the code (##%1010_ ... and _1010 last). So in the last bit will turn the led OFF.
I don't need to feed more data as the whole purpose of $FFFF in D(15:0) bits is to just to run perpetually. Or did I misread the docs?
If you don't keep feeding the streamer with data in immediate mode the last value will be output perpetually (after the previous ones).
So confusing. We are talking about the streamer. (what is that? something that sends a stream of bits??).
My mother tongue is not English, but I would have not chosen 'Run perpetually' and just I would said instead that "It will latch the pin(s) to the last value(s) sent."
That said, now please test the following code and tell me what you see.
CON _clkfreq = 4_000_000 DOWNLOAD_BAUD = 115_200 OUTPIN = 36 PUB main() | md, i md := %0100_0000_1<<23 + OUTPIN<<17 + %1<<16 + $FFFF 'streamer mode: imm 32x1, 32 bits, a-bit set, run perpetually org setxfrq ##3216 'streamer freq: 3 Hz drvl #OUTPIN 'pin = output, low xinit md, ##%1010_1010_1010_1010_1010_1010_1010_1011 ' It starts sending '1010', ... and send '1011' last ... and 'Run perpetually' end repeat org nop end
In your examples the streamer will output the last bit perpetually after the earlier 31 bits. It is running perpetually but you give it only enough data for 32 bits. To repeat the 32-bit pattern perpetually you can do one of two things:
1. Give the streamer an immediate data long before the end of every 32-bit time period, e.g. using XCONT.
2. Use RDFAST -> Pins/DACs mode. Write 16 identical longs to hub RAM, say to address ptra, then do RDFAST #1,ptra before XINIT to output the block of 16 longs / 64 bytes / 512 bits perpetually. However you will not be able to use the FIFO for anything else while the streamer is running a RDFAST mode.
perpetually = continuously = repeats without limit
Have you run the code?
Please, can you test it? You can try it without a-bit set, and with a-bit set (as above code).
md := %0100_0000_1<<23 + OUTPIN<<17 + %1<<16 + $FFFF md := %0100_0000_1<<23 + OUTPIN<<17 + $FFFF
What do you see?
Complete test code :
CON _clkfreq = 4_000_000 DOWNLOAD_BAUD = 115_200 OUTPIN = 36 PUB main() | md, i ' SEND stream without a-bit SET and run perpetually (until the 9 second wait) md := %0100_0000_1<<23 + OUTPIN<<17 + $FFFF 'streamer mode: imm 32x1, 32 bits, run perpetually org setxfrq ##3216 'streamer freq: 3 Hz drvl #OUTPIN 'pin = output, low xinit md, ##%1010_1010_1010_1010_1010_1010_1010_1011 ' It starts sending '1101', ... and send '0101' last ... and 'Run perpetually' end waitms(9000) ' SEND stream now with the a-bit SET and run perpetually (or not?) md := %0100_0000_1<<23 + OUTPIN<<17 + %1<<16 + $FFFF 'streamer mode: imm 32x1, 32 bits, a-bit set, run perpetually org setxfrq ##3216 'streamer freq: 3 Hz drvl #OUTPIN 'pin = output, low xinit md, ##%1010_1010_1010_1010_1010_1010_1010_1011 ' It starts sending '1010', ... and send '1011' last ... and 'Run perpetually'? end repeat org nop end
I changed OUTPIN from 36 to 56 for Eval board and changed bit frequency from 6 Hz to 2 Hz with setxfrq ##1074 which makes it much easier to count the LED flashes. I also increased the wait to 18000 milliseconds.
In "perpetual immediate mode" there is no very little XCONT buffering and a new immediate value takes effect immediately after first NCO rollover probably. Therefore a wait longer than 32 bits is necessary to see all the flashes due to the first XINIT and I have edited my previous post because point 1. was wrong.
I use imm->LUT in my video driver (nostalgic, usable beta, and displaylisted, in constuction - displaylist works and it is fun
to have text line upside down , zoomed, or interleaved by blank or color lines)
While doing this I learned, that If the streamer don't get its data on time, it outputs the last bit. In HDMI mode it means instant picture loss.
You have to feed it continuously either as I did, by a timed loop, or via interrupts.
It is important that the streamer gets its LUT data when it needs it, and not when xcont is executed, so you may execute xcont, and after this update the LUT with new values while the previous xcont is still working, I thought it reads LUT at the time it is executed and I didn't understand why my colors are shifted.
Better not use the same LUT entries for every xcont if you want to change their value in the real time,.or miracles happen (colors not at the places where they are supposed to be). I use 2 LUT banks separated by 32 longs (the least possible amount) and update them while they are not used for displaying pixels..
Yes, the timing is deceptive. Both in the streamer command buffer delaying the start of a particular command until the prior one is completed, and also in the pacing of the active command.
The current discussion is mainly about "perpetual immediate mode" which has little or no command buffering.
Try this prog which flashes an LED. 4th stream is repeated after 1st, 2nd & 3rd.
Without a-bit: 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 With a-bit: 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24
I am re-reading the docs again "Modes which shift data use bits bottom-first, by default. Some of these modes have the %a bit in D[16] to reorder the data sequence within the individual bytes to top-first when %a = 1."
Several things doesn't make any sense (what was the purpose? I have no idea):
It's not the always the last bit that is repeated, but whatever the last datum is, which could be 1, 2, 4, 8, 16, or 32 bits.
The %a reorders data within each byte. It doesn't reorder the bytes. It's just for sub-byte data. For nibbles, it swaps the nibbles. For two-bit data, it reorders them from top to bottom of the byte. For one-bit data, it reverses all the bits.
deleted
My attempt to get immediate streamer mode to do that didn't have any affect. The bit order didn't change at all. I tried as 32 x 1-bit, and as 16 x 2-bit.
Of note is these "immediate" modes aren't "byte" based. Is that a factor?
deleted
deleted
The command buffer is always there. But obviously, when those commands run out then any fresh command will be actioned much quicker. Presumably on the next NCO trigger for XCONT.
Evan, setting %a does work in immediate mode, try my stream1.spin2 program.
I haven't yet. As a quick read, I'm guessing the very first $FFFF length is holding the first command in action indefinitely. All the others never run.
Evan, you'll need to edit at least two posts once you have tried the prog.
Lol, I'll leave the posts there. Amusingly, I've got the "a" bit working now in my old program. Dunno what I'd done wrong last time. Maybe was too tired and not remembering the polarity correctly.
EDIT: Ah-ha! Got it! I'd got side tracked on trying to identify whether "a" meant word-order or bit-order and then forgot I'd not answered the question before then assuming it was bit-order, when it isn't, and then proceeding to not find the reordering I expected. So, yes, I was still too tired.
Another ah-ha, also found out why we're not agreeing on the immediate mode command buffer too. The length of $ffff is special not just in perpetuity, it also seems to be like an XINIT in that the command it's attached to takes immediate effect.
This may affect all modes! I haven't tested.
EDIT: Tony, presumably this one will be the root of any lingering questions you've got with your test code as well.
From my testing of perpetual modes, XINIT takes effect immediately and XCONT takes effect after next NCO rollover.
Well, without any control on the data sequence other than the waitx's, it's going to be overlapping in weird ways. First thing I'd do is replace all the $FFFF's with something sensible.
XCONT, and XZERO, is supposed to take effect at the end of the sequence count of prior command.
EDIT: Oh, of course, having said it out loud ... It isn't the newly issued $ffff that induces the immediate effect, it's the prior $ffff.
EDIT2: It is even documented in the hardware doc, albeit a little buried:
Here's the existing documentation regarding the "a" mode bit:
Here's a suggested addition to flesh it out with an example sequence:
eg: Shifting out %1000_1100_1110_1111_0111_0011_0001_0000 in 4-bit elements: Step | D3 D2 D1 D0 ( "a" mode bit set, big-endian ) -------+----------------- ( Streamer mode: %0110 dddd eppp p101 ) 1 | 1 0 0 0 2 | 1 1 0 0 3 | 1 1 1 0 4 | 1 1 1 1 5 | 0 1 1 1 6 | 0 0 1 1 7 | 0 0 0 1 8 | 0 0 0 0 Step | D3 D2 D1 D0 ( "a" mode bit clear, little-endian ) -------+----------------- ( Streamer mode: %0110 dddd eppp p100 ) 1 | 0 0 0 0 2 | 0 0 0 1 3 | 0 0 1 1 4 | 0 1 1 1 5 | 1 1 1 1 6 | 1 1 1 0 7 | 1 1 0 0 8 | 1 0 0 0
Lol, the colour coding in the code box is weird. Almost random seemingly.