Fantastic! Just pre-ordered one smile

162

(6 replies, posted in Nintendo Handhelds)

Gamer_freak8520 wrote:

There are 3 rows of dead pixels on my screen and they will not go away when i reheat the ribbon cable. I think it is something to do with the ribbon cable connecting the 2 boards together as i had to fix that cable as it was broke when i bought it.


The subject says columns, you say rows. What is it you can not fix - rows or columns? Columns are fixed by heating ribbon cable below the LCD. I'm not sure rows can be fixed that way since the vertical ribbon cable responsible for horizontal pixels is tricky to get to and a big risk to burn the thing.

The image on the screen is built pixel by pixel by the LCD. So if the problem was connection between the pcb boards you'd likely to see some random dots or nothing at all.

uXe wrote:

...if you try this code, it should toggle the LED with every clock - ie. the LED should be illuminated on every second clock

And how do you tell how many times the LED blinked? A 10 000 000 FPS per second time lapse video? smile

I though about deploying a logic analyzer. What they do (if understand it correctly) is record a sample to the memory (e.g. flash) and then you read it to PC. A good thing would be to know how to build one and use for real time data processing.

Another option is FPGA. The way it works allows really fast signal processing. In fact in can be clocked by the gameboy and still be able to send data to PC. This is what a guy named Snesy did. I tried to contact him through several sources, but without any luck.

Next - Nitro's suggestion to use uC as clock master. I don't understand how (in case of Teensy at least) it solves the issue of only 24 clocks available to do something with the data? 24 is an optimistic estimate.

Finally - DSP. I think logic analyzers are built upon these. However I've no idea where even start with that.

Any other options?

Before diving into the next idea it would be great to figure which of them will (given enough effort) guarantee success. Not some ugly hacked code that will fail 50% of time, but neat and reliable solution. We know it was done on FPGA.

Pros: it will solve this problem, it should suffice to have even more outputs (VGA and composite) and it can be even used as an adapter to plug a controller - so the whole "desktopification" module can be done with one (probably quite big though) board. Since it can have multiple clock domains, and programmed to do virtually everything (no teleportation though).

Cons: Prototyping boards from Atmega (as an example) cost around $80, not only they are programmed in very strange way I can't find any good comprehensive introduction in programming FPGA.

I need to reflect on this... and wank...

Glitch Militia wrote:

Just a quick question; If you succeed, will you share it?


Of course, that's the whole point smile

uXe wrote:

I still think it is worth trying friendofmegaman's code without the Serial.write slowing down the interrupt to see what difference it makes, as I wrote earlier:

http://chipmusic.org/forums/post/206984/#p206984

Also, using low-level AVR port manipulation commands (PORT, PIN, DDR) isn't necessarily going to speed things up on a Teensy 3.x (ARM) because they just end up going through another level of AVR to ARM emulation:

http://github.com/PaulStoffregen/cores/ … mulation.h

http://forum.pjrc.com/threads/17532

You need to actually use ARM low level commands! Grab the MK20DX256 manual here:

http://www.pjrc.com/teensy/datasheets.html

and check out Chapter 11 - Port control and interrupts (PORT) and Chapter 49 - General-Purpose Input/Output (GPIO)


Thanks for sharing. It's definitely an interesting reading, but still 24 clocks guys, don't be overoptimistic big_smile

Jazzmarazz wrote:

I would say that it is enough, but we are missing something obvious. What if, 96MHz is in fact 'too' fast. Could you possibly be reading data that has yet to be populated on D0 and D1? There is always a propagation delay, but it still doesn't account for mostly 4's...My excuse is that Im tired. Don't blame me for my ramblings. tongue

Nope, that's not possible. You see the data signals come when one clock pulse is still high. Which means if we're reading data on CLOCK's falling edge (an this is exactly what we're doing) the bits are already there.  Clock and data signals are kind of overlapping if you plot them. Thus it's guaranteed that data is read.

24 cycles in not much really. For example a 1 line of C code can compile to 10 commands and each command may be several bytes long.

I checked with Craig from Flashing LEDs and he confirmed this theory and suggested to use external SPI chips. I need to dig in this direction. But so far to do this really neatly probably an FPGA is needed. I love the idea of FPGA but the opportunity of learning absolutely counter intuitive Verilog or VHDL hurts me before I even started.

Jazzmarazz wrote:

1am...time for the demoralized to go to bed....
Maybe someone can shed light on this in that meantime since you shared all of your various bits of code. The Teensy code is so "dumb" (having only a few dozen lines) it can't possibly be wrong!

good luck

It's still 10:30 on the west coast smile

I actually tend to think that this idea was doomed from the very beginning. Let's theorize a bit. In order to read the data correctly we need to wait for each clock signal to come and then process it. Clock comes 4M times per second. Teensy over-clocked frequency is 96MHz. 96M/4M = 24.  At the very best we have only 24 cycles to handle our clock data. Is it enough with all other things intact (other interrupts etc)? I'd say no it is not.

So my final report for you (because after that I'm entering demoralized state again):

I wanted to determine how many clocks I can detect at very best.

I set up two interrupts VSYNC and HSYNC.

When VSYNC comes I just write frame delimiter to serial.
When HSYNC comes I run a 160 step loop (that's it, no checks, no conditions just a loop) and send data to PC.

And I get no more than 15 clocks between VSYNC signals. So unless I find better explanation I consider Teensy (for whatever reason) simply not to be able to handle the data. Because I've no idea how can I optimize that.

Jazzmarazz wrote:

There is nothing inside of loop. I don't think...your code does anything at all right now. :S

The 4's could be some high-impedance / capacitance on the serial wire or some nonsense like that. Then again, I could be well off-base.


Loop is empty because the workflow is based on interrupt handlers. And they work fine otherwise I wouldn't get any data. In fact I tried to put some constant value there and I can see it appear in my hex dump. So this is not the problem. The code works just fine. And it seems that the only explanation of missing clocks is one I mentioned in the previous post.

Conjecture:

I'm missing bits because the CLOCK handler for the previous interrupt hasn't finished executing.

I can only detect 70 clocks between two HSYNCs...

The sketch:

#include <avr/io.h>
#include <avr/interrupt.h>

const int pVsync = 2;
const int pClock = 3;
const int pData0 = 4;
const int pData1 = 5;
const int pHsync = 6;


volatile unsigned char pixels_in_line = 0;

void setup(){
  Serial.begin(1);
  
  pinMode(pClock, INPUT);
  pinMode(pHsync, INPUT);
  pinMode(pVsync, INPUT);
  pinMode(pData0, INPUT);
  pinMode(pData1, INPUT);

  
  attachInterrupt(pClock, readClock, FALLING);
  attachInterrupt(pHsync, readHsync, RISING);  
}

void loop() {}

void readHsync(){
   Serial.write(pixels_in_line);
   pixels_in_line = 0;
}


void readClock(){
  pixels_in_line++;
}

The hex dump I receive on PC side:

000009a0  45 45 41 44 44 44 44 44  44 44 43 44 44 44 44 44  |EEADDDDDDDCDDDDD|
000009b0  44 44 44 44 44 44 44 44  44 44 44 44 44 41 44 44  |DDDDDDDDDDDDDADD|
000009c0  42 41 44 44 44 44 41 44  44 44 44 44 44 44 43 44  |BADDDDADDDDDDDCD|
000009d0  44 44 44 45 45 45 46 46  46 45 46 44 44 45 45 44  |DDDEEEFFFEFDDEED|
000009e0  44 45 44 44 44 44 44 44  44 44 44 41 44 44 44 44  |DEDDDDDDDDDADDDD|
000009f0  44 44 44 44 40 44 44 44  44 44 44 44 43 44 44 44  |DDDD@DDDDDDDCDDD|
00000a00  42 42 44 44 44 43 44 44  44 44 44 44 44 44 44 44  |BBDDDCDDDDDDDDDD|
00000a10  44 44 44 44 44 44 44 44  44 43 44 44 44 44 44 44  |DDDDDDDDDCDDDDDD|
00000a20  44 44 40 46 46 46 46 46  46 46 46 41 45 45 45 45  |DD@FFFFFFFFAEEEE|
00000a30  45 45 45 43 44 44 44 44  44 44 44 44 44 44 44 44  |EEECDDDDDDDDDDDD|

Please tell me there's an error in my code that gives me this discouraging results sad

Can anybody explain me the following:

So I set up interrupts for CLOCK, HSYNC and VSYNC.

Inside the interrupt handlers I simply send data to PC.

Serial.write(pixel) for CLCOK,
Serial.write(0xE0) for HSYNC and
Serial.write(0xF0) for VSYNC

On the PC I count how many there are pixels per line and lines per frame.

There are 15 (in average) pixels per line
And 144 lines per frame.

Why is that?

Is it because I'm loosing bytes in the serial communication? But shouldn't all the data be buffered and the delivery guaranteed?

If that's the case, then even with the sketch so short it could be a T-shirt print we're missing 90% of pixels (15 our of 160). Which means that something is very wrong here.

Oh, I can actually check that by setting a counter inside the uC and receive only byte count.... be back in 10 mins...

uXe wrote:
friendofmegaman wrote:

Guys, have you actually benchmarked USB serial in Teensy? I'm a bit worried because of this page http://www.pjrc.com/teensy/usb_serial.html. It doesn't show very high speed which means we might need to keep our data as small as possible.

Even the very worst case benchmark on that page of 639 kbytes/sec (654336 bytes) using your current frame size of 5760 bytes would still mean 113.6 frames per second, so what's the problem?

There's no problem smile Just checking and pointing out that we need to pack our data and can't afford 144x160 byte array.
Also it's not 5760 bytes anymore. We need error-free frame delimiter so it's gonna be 7680, i.e. 85 fps. I'll share the code later, need to check it first.

Jazzmarazz wrote:

I was thinking that your baud was a little crazy. Care to reduce it to something more common?
No, I have not benchmarked a teensy.

4000000 is fairly common. But according to rvan you can use 1 and will go on maximum speed.

Jazzmarazz wrote:
rvan wrote:

I just tested this on the Teensy, and this seems to not be the case.  This is possibly different from Arduinos.  Explicitly declaring pins makes for more readable code, too.

Well, what the hell? That is very good to know, but very disappointing at the same time...

rvan wrote:

I had a think about this, and I think the only foolproof way is to store only three pixels per byte and use the remaining two bits to store new line and/or new frame markers.  Another option would be to simply count pixels (assuming we always begin sending at the start of a frame) and hope we don't drop any bytes, but that is not as robust.

I like that, 3 pixels per byte and a 2-bit marker. Serial is sure fast enough to handle that.

Guys, have you actually benchmarked USB serial in Teensy? I'm a bit worried because of this page http://www.pjrc.com/teensy/usb_serial.html. It doesn't show very high speed which means we might need to keep our data as small as possible.