Chip, I think it's only the byte order that's the wrong way around, as I've done a 2bpp driver that I needed to change the order of the 2bits in each byte, keep it little endian in longs it just makes more sense.
Chip, I think it's only the byte order that's the wrong way around, as I've done a 2bpp driver that I needed to change the order of the 2bits in each byte, keep it little endian in longs it just makes more sense.
Hope this helps.
You mean the byte order is okay, but the bitfield order is the issue?
The SSD1921 offers both byte and word swap options...
This, together with nibble and bit order options that we have now would let you do anything you want (say you wanted to mirror image the display, for instance):
The SSD1921 also has a "floating window" option which is an inset image that can be at a different bit per pixel. I think that can be done here with streamer too...
I just saw that Photoshop can save as 16-bpp BMP after all. Guess I remembered wrong...
There are several types of 16-bpp actually, but one is 565.
Here's a bird photo scaled to 640x350 (which happens to be a standard VGA mode).
This will be fun to try. See if my monitor will accept that resolution. Also, see how 16bpp at 640x350 compares in real life to 852x480 at 8bpp.
After adding those bitfield swappers, I realized there were a few things that were bugging me about the transfer unit:
1) You couldn't synchronously change the frequency at the start of a command (this got really out-of-whack with command buffering).
2) You couldn't constrain DDS activity to part of the LUT and have fine offsets.
So, to solve the frequency issue, I made it so you can do SETQ+XINIT/XZERO/XCONT to buffer Q along with the command's D and S value. When the command is started, the frequency is updated right on the appropriate clock edge, for totally predictable operation. You can still use SETXFRQ to change the frequency, on the fly.
For constraining DDS to certain parts of the LUT, I started using the S/# of XINIT/XZERO/XCONT (in DDS mode) to set up the size of the area, its location, and its initial offset, as it wraps within the confines of the area. This lets you set up playable lookup tables of 512/256/128/64/32/16/8/4 samples at any offset of the same granularity. Combing the SETQ+ frequency updating makes for a really flexible and accurate waveform generator.
I'm compiling new FPGA images now, and I hope to get these out and have the documentation updated this evening.
This mode (640x350x16bpp) looks pretty good on my monitor, although there are ~1/2" black bands on top and bottom of picture:
I'm thinking that 640x350x1bpp will fit in DE0...
That really looks nice!
I changed the field loop to make 525 total lines, which that 640x480 mode expects, and it made the image perfectly proportional. I'm glad you are testing out all these modes!
'
'
' Field loop
'
field mov x,#85 'top blanks
call #blank
mov x,#350 'set visible lines
line call #hsync 'do horizontal sync
xcont m_rf,#0 'visible line
djnz x,#line 'another line?
mov x,#88 'bottom blanks
call #blank
notb outa+vsync>>5,#vsync 'sync on
mov x,#2 'sync blanks
call #blank
notb outa+vsync>>5,#vsync 'sync off
jmp #field 'loop
Yes, several waveforms inside the LUT is very useful.
Chip, if you anyway make new files:
I think there is still a problem with the REP instruction and a big repeat count. It seems to be a PNUT problem. If I do this:
rep @.end,##24576
...
.end
the loop is not executed correct, but if I do it like that:
Yes, several waveforms inside the LUT is very useful.
Chip, if you anyway make new files:
I think there is still a problem with the REP instruction and a big repeat count. It seems to be a PNUT problem. If I do this:
rep @.end,##24576
...
.end
the loop is not executed correct, but if I do it like that:
augs #24576
rep @.end,#24576 & 511
...
.end
it works well.
Andy
Yes, someone pointed that out. Thanks for bringing that up again. I will fix that in the next release tonight. It's a PNut issue, of course.
Chip, your change to 640x350 adds black bars to the sides of the image, so the proportions do look better. Monitor now thinks it has 640x480 instead of the 720x400 it had before...
Maybe I'll see if I can get it to fill the screen back in this 720x400 mode...
No, it's not required. But without it you can't do video. The add-on board mainly adds four R-2R DACs.
There is a FPGA image for the DE0-Nano without the Add-on board. Then you only need a PropPlug.
I just completed the CORDIC documentation in the Google Doc at the top of this thread.
I'm kind of surprised at how little text is actually required to explain some things that are so complex. That sounds kind of delusional, I know. Maybe I didn't do it right.
Chip,
I have just been reading the documents and the Cordic section.
You explained, when multiple cordic operations are underway, if the cog misses reading a result in time, GETQX/GETQY could cause a cog lockup.
This might be a potential solution to prevent this situation...
When a GETQX or GETQY instruction is executed, a 6 bit counter is reset. If the instruction pauses waiting for a result, on each clock the counter is incremented. When the 6bit counter overflows (a count of 64 being less logic than 36) the GETQX/GETQY instruction terminates with a (say $0 or $FFFFFFFF ???) result. Alternately even an interrupt could occur (such as the debug interrupt - used as an "error" interrupt).
Chip,
I have just been reading the documents and the Cordic section.
You explained, when multiple cordic operations are underway, if the cog misses reading a result in time, GETQX/GETQY could cause a cog lockup.
This might be a potential solution to prevent this situation...
When a GETQX or GETQY instruction is executed, a 6 bit counter is reset. If the instruction pauses waiting for a result, on each clock the counter is incremented. When the 6bit counter overflows (a count of 64 being less logic than 36) the GETQX/GETQY instruction terminates with a (say $0 or $FFFFFFFF ???) result. Alternately even an interrupt could occur (such as the debug interrupt - used as an "error" interrupt).
You explained, when multiple cordic operations are underway, if the cog misses reading a result in time, GETQX/GETQY could cause a cog lockup.
I thought the cog-lockup-solid issues had been sorted ? - but it seems not ?
It would be great to avoid this, as it is a nasty failure mode, that may have a low 'hit rate', if close to the threshold.
I went ahead and checked 2bpp mode and the optional bit order options and they work just fine. I got a nice 4 color lookup and I got the correct characters in 1bpp mode.
That one looks good.
I also gave the dynamic frequency change a try, and had a good result.
line call #hsync 'do horizontal sync
mov whichbuff, x 'prepare to determine line buffer for scanline
and whichbuff, #1 wz 'is odd?
if_z rdfast #0,linerame 'No! Use even buffer
if_nz rdfast #0,lineramo 'Yep. Use odd buffer
SETQ ##round(f_fat)
xcont m_rf,#1 'visible line rflong 1 bit per pixel, reverse order
mov numchar, #32 'Get the character pixels for the next scanline written
call #dochars
cmp subchar, #%111 wz 'last line of current line of characters? don't roll back PTRB
if_nz sub ptrb, #32 'gotta do all the scanlines, before advancing screen pointer
add activescan, #1 'scanline done, indicate current scanline
djnz x,#line 'all done? No, loop to line.
See the SETQ, just prior to XCONT? Works a treat, and I've got fat pixels in the display without having to adjust all the other timing. We needed this one. Thanks Chip. I've got another one in the HSYNC routine that puts the timing back to the standard for the rest of the frame.
This can give us windows of different color depths and or pixel sizes on the same screen.
With this, it's pretty easy to go and lift sync and other pixel sequences from P1. That's on my list next, now that my DE2 is running again.
line call #hsync 'do horizontal sync
mov whichbuff, x 'prepare to determine line buffer for scanline
and whichbuff, #1 wz 'is odd?
if_z rdfast #0,linerame 'No! Use even buffer
if_nz rdfast #0,lineramo 'Yep. Use odd buffer
SETQ ##round(f_fat)
xcont m_rf,#1 'visible line rflong 1 bit per pixel, reverse order
SETQ ##round(f_xfr)
xcont m_rfa, #1
mov numchar, #32 'Get the character pixels for the next scanline written
call #dochars
cmp subchar, #%111 wz 'last line of current line of characters? don't roll back PTRB
if_nz sub ptrb, #32 'gotta do all the scanlines, before advancing screen pointer
add activescan, #1 'scanline done, indicate current scanline
djnz x,#line 'all done? No, loop to line.
Just tried mode change mid line. I seem to have lost a little time in the scanline, but it worked otherwise. I'm sure that is due to the rounding going on in the constants. First 16 chars are 4x8, 2 bits per pixel, last 16 chars are 8x8, 1 bit per pixel. So far so good on the new streamer features at low pixel rates and color depths.
Lots of rainbow shimmer on this one. For TV, we are going to need to specify time with a bit more precision, or avoid stuff like this. I've attached it, just as a test of the streamer feature additions.
Comments
Hope this helps.
You mean the byte order is okay, but the bitfield order is the issue?
The SSD1921 offers both byte and word swap options...
This, together with nibble and bit order options that we have now would let you do anything you want (say you wanted to mirror image the display, for instance):
The SSD1921 also has a "floating window" option which is an inset image that can be at a different bit per pixel. I think that can be done here with streamer too...
There are several types of 16-bpp actually, but one is 565.
Here's a bird photo scaled to 640x350 (which happens to be a standard VGA mode).
This will be fun to try. See if my monitor will accept that resolution. Also, see how 16bpp at 640x350 compares in real life to 852x480 at 8bpp.
Here's the 16-bpp BMP file:
I'm thinking that 640x350x1bpp will fit in DE0...
1) You couldn't synchronously change the frequency at the start of a command (this got really out-of-whack with command buffering).
2) You couldn't constrain DDS activity to part of the LUT and have fine offsets.
So, to solve the frequency issue, I made it so you can do SETQ+XINIT/XZERO/XCONT to buffer Q along with the command's D and S value. When the command is started, the frequency is updated right on the appropriate clock edge, for totally predictable operation. You can still use SETXFRQ to change the frequency, on the fly.
For constraining DDS to certain parts of the LUT, I started using the S/# of XINIT/XZERO/XCONT (in DDS mode) to set up the size of the area, its location, and its initial offset, as it wraps within the confines of the area. This lets you set up playable lookup tables of 512/256/128/64/32/16/8/4 samples at any offset of the same granularity. Combing the SETQ+ frequency updating makes for a really flexible and accurate waveform generator.
I'm compiling new FPGA images now, and I hope to get these out and have the documentation updated this evening.
2bpp check later tonite.
That really looks nice!
I changed the field loop to make 525 total lines, which that 640x480 mode expects, and it made the image perfectly proportional. I'm glad you are testing out all these modes!
Chip, if you anyway make new files:
I think there is still a problem with the REP instruction and a big repeat count. It seems to be a PNUT problem. If I do this: the loop is not executed correct, but if I do it like that: it works well.
Andy
Yes, someone pointed that out. Thanks for bringing that up again. I will fix that in the next release tonight. It's a PNut issue, of course.
here's the link to the REP issue
http://forums.parallax.com/discussion/162743/pnut-bug-with-rep-and-augs
In the next 30 minutes, I'll have the Google Doc file updated with all the changes.
Maybe I'll see if I can get it to fill the screen back in this 720x400 mode...
Thanks,
dgately
There is a FPGA image for the DE0-Nano without the Add-on board. Then you only need a PropPlug.
Andy
Just configure it with the DE0_Nano_Prop2_v6.jic file from the .zip at the top of this thread.
I'm kind of surprised at how little text is actually required to explain some things that are so complex. That sounds kind of delusional, I know. Maybe I didn't do it right.
I got something out of your documentation, so you must have done some good explaining!
If you ever get into audio synthesis, you're going to LOVE rotation, vectoring, logarithm, and exponent functions.
I have just been reading the documents and the Cordic section.
You explained, when multiple cordic operations are underway, if the cog misses reading a result in time, GETQX/GETQY could cause a cog lockup.
This might be a potential solution to prevent this situation...
When a GETQX or GETQY instruction is executed, a 6 bit counter is reset. If the instruction pauses waiting for a result, on each clock the counter is incremented. When the 6bit counter overflows (a count of 64 being less logic than 36) the GETQX/GETQY instruction terminates with a (say $0 or $FFFFFFFF ???) result. Alternately even an interrupt could occur (such as the debug interrupt - used as an "error" interrupt).
Good idea - a timeout and an event!
It would be great to avoid this, as it is a nasty failure mode, that may have a low 'hit rate', if close to the threshold.
I ended up preferring an extra internal flag. Amongst other features, it returns immediately upon a no-result condition. See - http://forums.parallax.com/discussion/comment/1352089/#Comment_1352089
That one looks good.
I also gave the dynamic frequency change a try, and had a good result.
See the SETQ, just prior to XCONT? Works a treat, and I've got fat pixels in the display without having to adjust all the other timing. We needed this one. Thanks Chip. I've got another one in the HSYNC routine that puts the timing back to the standard for the rest of the frame.
This can give us windows of different color depths and or pixel sizes on the same screen.
With this, it's pretty easy to go and lift sync and other pixel sequences from P1. That's on my list next, now that my DE2 is running again.
Guys, don't let the DE2 get cold. It gets cranky.
Just tried mode change mid line. I seem to have lost a little time in the scanline, but it worked otherwise. I'm sure that is due to the rounding going on in the constants. First 16 chars are 4x8, 2 bits per pixel, last 16 chars are 8x8, 1 bit per pixel. So far so good on the new streamer features at low pixel rates and color depths.
Lots of rainbow shimmer on this one. For TV, we are going to need to specify time with a bit more precision, or avoid stuff like this. I've attached it, just as a test of the streamer feature additions.