Drive LVDS with ARM9?

This is for a device that’s designed to be used under direct sunlight. We’ve tried a lot of displays. Nothing came close to the Pixel Qi in our tests. There’s almost no color under direct sunlight, but excellent monochrome contrast.

And we compared a lot of transflective displays. I’m not sure what Pixel Qi does differently, but the only thing that had higher contrast was eink. And the refresh rate on eink is too low for us.

Pixel Qi is our first choice, too. Unfortunately, making it work with NETMF will probably tack on a few months to our time-to-market, so i’ll have have to look at something else.

So I visited a non-Pixel Qi display vendor which uses a 1400-nit backlight to provide sunlight readability. I came on a very bright day.

If the Pixel Qi get an A for sunlight readability, I would give the powerful backlight approach a B-. It was a passable effort, but not particularly impressive. And because the LCD screen material didn’t have very high transmissivity, at just the right angle, all you would see in the sun reflected right back at you. At most other angles, provided the image you were displaying was pure black and white, it was OK. For full-color images, contrast would wash out significantly and the images were a bit difficult to see.

The other thing I wasn’t too enthused about was the requirement for some sort of cooling solution for the high-power backlight.

In summary, I really really would like a Pixel Qi. On GHI’s end, how difficult is it to increase the frame buffer so that screens larger than 800x600 can be supported?

(Dunno if this makes a difference or not, but my target platform for this project will probably be the G400.)

EDIT: According to the G400’s Atmel SAM9X35 datasheet, the processor only supports a maximum of 800x600, so it looks like higher resolutions are not possible anytime soon.

To anyone who might also be looking for a sunlight-readable LCD, I recommend a TrioLCD module, which I’ve recently finished testing: http://www.alpincorp.com/Transflective_LCD.html

It’s a transflective display that, unlike the Pixel Qi, maintains full color even in really bright direct sunlight. Pixel Qi still wins purely on contrast, since its readability approaches E-Ink levels by turning monochrome in sunlight, but the TrioLCD is a very close second, and it stays in color! I also like how the modules can be ordered with a variety of interfaces – RGB, VGA, and/or LVDS.

The company has a variety of demo units that they ship out regularly to anyone who wants to evaluate them.

1 Like

Nice one. I was on the lookout for a decent display as my remote systems are out in fields and not easy to read during the day.

I’ve been working on other projects, but now I’m back on the task of adding LVDS support to Cerb and Hydra.

I know I could easily do this by adding an addition component, but I want to see if I can drive the display directly from the microprocessor.

Of course, to even have a prayer I know I have to go Native. I’m not comfortable in Native Land, but I’m hacking my way through it.

If this is even remotely possible I’ll need to be able to toggle seven pins (3 +/- I/O pins and 1 Clock) at 20Mhz.

To my surprise, I can’t even toggle 1 pin at over 35Mhz. I’m using C++ code like this in my firmware…

GPIO_TypeDef* port1 = Port(pin1 >> 4); // pointer to the actual port registers
UINT16 bit1 = 1 << (pin1 & 0x0F);

while (true)
{
port1->BSRRL = bit1; // set bit
port1->BSRRH = bit1; // reset bit
}

Why can’t I go over 35Mhz?

Why are you surprised? You want to toggle a pin at 35mhz! No micro is setup to do this and this is wrong anyways. FPGA is what you need. Or the built in lcd controller.

I think you are looking at this from a wrong angle.

I plan on giving up if this isn’t possible. I’ve got a list of good suggestions for components to convert the Hydra’s ARM9 LCD feature to LVDS. And that’s probably what I’ll end up doing, but… I love knowing what the limits are.

I’m using BSRRL and BSRRH would ODR be any faster? What if I moved this from my firmware code to RLP?

Thanks for your time. I’m learning a lot on this site.

Hydra had LCD controller so why not use it?

People come up with the strangest project ideas on this forum.

You’re running a processor at 168 MHz, and since you said the best you can get is 35 MHz, it sounds like your GPIO code is getting compiled to about 5 instructions per write. That makes sense, given you’re writing stuff really high-level, using C with structs and stuff.

Check your decompiled assembly version to see what “port1->BSRRL” actually gets compiled to. You’re making rookie mistakes – like wondering if you’d see any performance difference by running your code in RLP versus as an interop, and you’re doing stuff like


UINT16 bit1 = 1 << (pin1 & 0x0F);

instead of


 #define BIT1 0x00000002

If you want to do what you want, you’ll have to program things either in assembly, or as direct memory writes in C, i.e.,


*(0x338F01FA) = 0x00000002;
*(0x338F01FA) = 0x00000000;

(the register I made up is fictitious, but you get the idea)

Or turn your compiler’s optimizations on and pray that it figures it out for you. Honestly, I’d just implement it as an assembly routine – it’s really easy to do in-line assembly, and ARM assembly is really easy to write.

The bigger mistake you’re making is that you don’t seem to realize that while it’s true you could sit in an assembly routine and drive these pins directly at 20 MHz, you’d have to hard-code the exact GPIO writes, and the processor would be incapable of doing anything else.

You do realize this is why companies go to the trouble of integrating an LCD controller on-die, right? Parallel LCD controllers at that (which are much easier to implement!)

I believe that TI makes a parallel-to-LVDS driver that’s fairly inexpensive. Just solder that to a board and be done with it already!

1 Like

I was told to try this approach first. I strongly prefer using the internal microcontroller features. In my mind that’s the whole point of using an ARM chip. I’m sure I’ll end up using something to convert the LCD output on the Hydra’s ARM7 to LVDS. Maybe my boss is doing this to force me into learning some assembly?

My thinking was this, when RLP executes all interrupts, etc. are suspended and my code has exclusive access to the microprocessor. Is this not true?

Ultimately I was hoping someone would post an example of how to toggle pins using RLP (ideally using assembly code). Jay almost did that. I’ll lookup the registers myself and post an example when I have the code working.

If I can prove I can’t read 3 bits of memory and toggle 7 GPIOs at 20Mhz on the STM32F4 I think my boss will back off and let me use the ARM7. That seems confusing. One of my GPIOs is supposed to be the clock, the other 6 are differential so I only need to read 3 bits of data per clock.

Anyone who wants to help me is welcome to do so. At some point somebody else is going to be happy there’s an example of toggling STM32F4 GPIO’s using assembly. …In another thread we’ve spoke about giving Arduino peeps a library that accommodates their BitBanging speed requirements. This seems like this would do that.

Please note that you CAN NOT bit bang LVDS. It is not about the data content but about the way the data is sent. Low Voltage Differential Signalling is not, in my mind, something you bit bang.

LVDS for a display is worse still. The LVDS is generally running at 1Ghz as it is 4 data pairs transferring 200Mb data per second plus all the syncs.

LVDS is such a pain that even the pcb must be designed as an RF board and track lengths must be matched to within a few mm, between the two tracks of a pair as well as between the pairs

Have you looked at an LVDS cable? I wanted to solder a new connector on one side. Big mistake. Each “wire” in the cable is a very thin coaxial cable with a shield on the outside and a core on the inside.

My impression is that differential signaling simply means the difference in voltage between two pins indicates the state rather than the voltage of one specific pin.

My LVDS clock runs at 22-60Mhz. During a single cycle I’d need to read 21 bits and toggle 22 pins. I don’t think the 168Mhz chip can do this. I wish I had some faster options. …Why hasn’t someone ported the Raspberry Pi already?

But even if this isn’t possible, I want to learn how to toggle GPIOs from assembly (if there’s a real useful performance advantage).

Like so many suggested, I think I’ll end up using the LCD feature on the ARM7 with some other component that converts the single to LVDS. That seems like the right way to do this.

22 pins are NOT LVDS. It is parallel RGB. If you are using parallel LVDS and only have 22 pins then you only have around 8 bit color. If you have a full color display running in parallel LVDS then you will need 22 pairs, ie 44 pins.

LVDS serialises those 22 bits onto 8 wires, 4 pairs, sending 3 bits at a time, at 7 times the original clock rate, ie 420MHz.

See FPD-Link, which is the LVDS used for Flat Panel Displays

The ARM does not have LVDS either. Only Parallel RGB.

If you want LVDS then you will have to feed the Parallel RGB into a serialiser chip to convert it into LVDS.

I have looked into LVDS before. Did a PCB design but dropped it due to the RF design/impedance matching requirements.

The Raspberry Pi certainly can’t do this – it tops out at about 20 MHz for GPIO writes, if I remember correctly.

There should be no difference in assembly or register writes in C. There are other ways of making your code faster other than #defining the bits as I suggested. Try prepending your bit variable with the “const” keyword – the compiler should turn your 1 << bitShift into a literal value.

I’ve never taken a compilers class, but I know that GCC and MDK can both be caressed into compiling C code into different instructions. Assembly lets you get things done without messing with C keywords and different expression forms, but honestly, I’d recommend learning that C stuff; it will make your code more portable and allow you to gain better insight into what’s actually happening when you compile your code.

Every programmer should know what things like “inline” “const” and “static” are, and when to use them.