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 = 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
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 = 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.
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.
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.
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.
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.
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).
What do you see?
Complete test code :
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.
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:
Lol, the colour coding in the code box is weird. Almost random seemingly.