Hmm... I'm using UCN5821 driver chips from Allegro. They do indeed have a hardware latch (strobe) which latches the received serial data from the internal shift register to the outputs.
My write algorithm is (per row): 1> set_current_state(TASK_RUNNING) 2> If new data is ready in RAM, memcpy it to the real display buffer in RAM. 3> Serially shift out next row data in the background, but do not latch yet (background) 4> Blank the display - This is not actually working right now. I never see the blank line move. Hmm.... 5> Adjust the multiplexed row select pins to the next row (A2...A0) 6> Latch the data already in the serial buffers 7> Unblank the display 8> set_current_state(TASK_INTERRUPTIBLE) 9> usleep until time to update next row I wanted to spend a little time as possible with the LEDs off, which is why I'm shifting data while the LEDs are still showing the current row data. Using this technique, I've seen ghosting issues when a mcu is very fast as the drivers themselves need a little time to switch the state of their outputs, and also the high-side switching power transistors sometimes need some time to fully turn off. I don't think that's what I'm seeing here though. The display artifacts that I see look like stuttering on the display when the processor gets busy. I suspect that this is due to inconsistent usleep times (Linux isn't an RTOS) but I'm still trying to catch it with my logic analyzer. My basic question is this: Does the Linux kernel "usually" do this kind of bit-banged driver for other things (I2C, video, framebuffers, audio, etc.) or does it "usually" pass these tasks off to hardware peripherals? The question behind the question is: Am I doing this the "usual" way or am I trying something very specialized. My goal is to look into the framebuffer devices and see if I can learn anything there, but kernel programming is very new to me. Thanks for your feedback! --David On Mon, Mar 21, 2016 at 9:40 AM, Harvey White <[email protected]> wrote: > On Mon, 21 Mar 2016 01:20:34 -0500, you wrote: > > I've often seen artifacts in LED displays where the write to the > display process (which should be amazingly short for each digit) is > interrupted. You might be seeing some differences in digit brightness > as well. > > Once you have the pattern in Ram, ready to be written, you would > ideally update right at the beginning of each scan for each digit. You > want to make sure that the pattern is not updated during the active > strobe to display process as well. (I'm assuming that there's a > hardware latch in there that you write, and you're not depending on > the output pins to be constant, that strobe to activate the display is > also a latch). This approach would minimize the critical time where > the display data cannot be interfered with. This would ideally be in > the microsecond range (i.e. turn off previous strobe, load next data, > turn on this strobe). That part of the code cannot be interrupted and > should ideally protected by turning interrupts off during those few > instructions. > > So the first question to ask is "what's going on with the strobes and > data?" > > Harvey > > > > >Ok, I posted the full source code here: > >https://github.com/davidgood1/ledmsgchar > > > >I'm not sure that userspace has much to do with what I'm seeing right now. > >I'm using a kthread that runs until a flag is set indicating that there is > >a new buffer of data ready from user space and my task (update_row) copies > >the buffer, so no one should be waiting on slow user space operations, but > >maybe there's something I don't see. > > > >I didn't know if I was getting interrupted in the memcpy call in > >update_row, so I am going to try to copy the buffer by rows one call at a > >time rather than copy the whole buffer at once. > > > >Also, I notice that I see visual artifacts whenever anything else is going > >on, such as ssh, typing on the terminal, etc. The CPU usage is ~3% using > >the timing in the file right now. BTW, the update_row task regulates its > >timing by calling usleep_range() which is supposed to be backed by high > >resolution timers. I am using the same number on the upper and lower > >bounds to try and force stricter timing and because when I did +/- 10% you > >could definitely see more visual artifacts. > > > >Also, you will notice that the strobe pin is toggled high and then > >immediately low, which I've measured to be about 2us. So, that seems to > be > >the best the gpio interface can do. > > > >Thanks! > > > >--David > > > >On Sun, Mar 20, 2016 at 11:03 PM, William Hermans <[email protected]> > wrote: > > > >> OK so yes, seeing your code would help us understand what you're > >> bottleneck but I've a pretty good idea why you're LCD matrix refresh is > so > >> slow. It has to do with userspace communicating with kernel space, and > >> you're either invoking some system API calls ( which are notoriously > slow > >> ), or you're copying data from userspace to kernel space, which again is > >> slow. > >> > >> The reason I said to show us some code above however is that I think it > >> *should* be possible to use /dev/mem/ + mmap() to access whatever you're > >> controlling. Using mmap() in this manner gives you no userspace to > kernel > >> overheard . . . but again I need to see some relevant code to give you a > >> better idea how that might work. > >> > >> On Sun, Mar 20, 2016 at 8:58 PM, William Hermans <[email protected]> > >> wrote: > >> > >>> Show us some code. > >>> > >>> On Sun, Mar 20, 2016 at 6:28 PM, David Good <[email protected]> > >>> wrote: > >>> > >>>> Hi All, > >>>> > >>>> I've been experimenting with embedded linux and matrixed LED displays. > >>>> I started on a Raspberry pi user space program, but could see visual > >>>> artifacts on the display due to inconsistent timing of my sleep > command. > >>>> So, I figured that moving the basic row scanning into the kernel > would help > >>>> out. After failing to get the right kernel headers for the pi, I > switched > >>>> to a BeagleBone White. I've now got a working character device LKM > which > >>>> takes new images by writing ASCII formatted hex strings to the device > in > >>>> /dev. The performance is pretty good, but not great. I still see > visible > >>>> artifacts, but am playing with things. > >>>> > >>>> My basic question is this: I know that Linux is not a RTOS, so timing > >>>> will never be guaranteed, yet linux does a lot of things very quickly > >>>> (video, audio, i2c, etc). My driver is bit-banging a spi like stream > over > >>>> 8 rows at a rate of ~3ms per row (333Hz row scanning or ~41Hz per > complete > >>>> frame) and is really struggling. How does linux usually get large > smooth > >>>> video at over 60FPS while doing other things??? Is it simply taking > >>>> advantage of special hardware resources? > >>>> > >>>> The obvious solution for this display is to use a little 8051 or M0 > >>>> microcontroller (or PRU!) and let the Bone feed it over uart or > something, > >>>> but I really thought I could do better with the LKM. > >>>> > >>>> Am I just doing something totally wrong? Any other ideas? > >>>> > >>>> Thanks! > >>>> > >>>> --David > >>>> > >>>> -- > >>>> For more options, visit http://beagleboard.org/discuss > >>>> --- > >>>> You received this message because you are subscribed to the Google > >>>> Groups "BeagleBoard" group. > >>>> To unsubscribe from this group and stop receiving emails from it, send > >>>> an email to [email protected]. > >>>> For more options, visit https://groups.google.com/d/optout. > >>>> > >>> > >>> > >> -- > >> For more options, visit http://beagleboard.org/discuss > >> --- > >> You received this message because you are subscribed to the Google > Groups > >> "BeagleBoard" group. > >> To unsubscribe from this group and stop receiving emails from it, send > an > >> email to [email protected]. > >> For more options, visit https://groups.google.com/d/optout. > >> > > -- > For more options, visit http://beagleboard.org/discuss > --- > You received this message because you are subscribed to the Google Groups > "BeagleBoard" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- For more options, visit http://beagleboard.org/discuss --- You received this message because you are subscribed to the Google Groups "BeagleBoard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
