Reverse-Engineering a chinese LED screen control.. thing. | INTERESTING! - Page 1
Forum section: electronics / projects

author: chinglish
author_rank: Contributor
timestamp: March 06, 2014, 09:11:53 pm
content: Dear Constumer,You may warned by this thread potentially strengthen your thinking ability.I love chinglish!The screen control system to be 'tamed' is manufactured by a company called 'Linsn'. 'Linsn' produces the de facto standard hardware for chinese big-a*s LED screens (really big ones). I dug up some information about the system for you guys, so that you know what we're dealing with:'The eighth generation [of the Linsn control system] is developed based on the seventh. Compared with the seventh, the eighth has all the functions of the seventh.'So, yes... Essentially, it's all the same. Just different! 'Linsn -- think different, do the same'. Or whatever their slogan is.As much as I love their ability to present new products, I desperatly need to find a solution to the following problem. Linsn kind of developed some software to control their LED system. It's Linsn, it's Windows, it's great! No. So I thought... Maybe I could reverse engineer the serial protocol to control our screens with my own software (or anything that won't crash every 2 hours giving you lots of '?' with a frustrating 'OK' button).HOWEVER, I never reverse engineered such a piece of kit, and I probably will never do it again. Anyway... I managed to capture some serial data to lear how the software controls the brightness. To get a better picture of how such a system works, take a look at this information I kindly provide for your enlightenment (or kindly skip this section if you're only interested in the serial data stuff... NERD!):FUNFACT: What you are looking at is - you guessed right - a PCI card. Thing is... it's not PCI. It only draws power from the slot, you have to wire it up using loop cables!Oh, and yes, you can power it with a 4-pin molex, which actually came in very handy by the time I discovered that the PC i bought for our next project had it's PCI port covered by the graphics card. Well done, chinese friends! The actual reason behind this weirdness is that Linsn sells a 'sending box' that contains exactly this card screwed into a metal box for customers that want to use a laptop, or no PC at all. Compared to the PCI card, the box has all the features of the PCI card. Only costs a lot more.Anyway, this so called 'sending card' works as follows.... Get a device that provides DVI/HDMI digital video output (preferrably mirrored output) and hook it up to the board using a DVI connector on the Linsn side of things (dvi - hdmi - it's the same, just different). The card then grabs a piece of the input in the size of your LED screen like this:Most big-ass screens have a very limited resolution, so most of the time it's a tiny window of like 240x180 up to 800x600. Fortunately (or maybe unfortunately) you can/have to specify the position of this windows using the Linsn software, ugh, and you can't resize/stretch/skew or something. The card then converts the DVI signal into some kind of unknown chinese noodle bit stream format and sends it through 1 or 2 of the 2 RJ45 connectors to your actual screen(s). You can send 2 different screen areas over those 2 connectors, or combine them for a higher resolution, but only configure the screens over the one labled 'D'. The other one is labled 'U', which most probably stands for 'useless'.The screen itself typically consists of several elements (thats what we call them in germany, might be bad english), which are daisy-chained by standard cat5 network cables, each one containing a so called 'receiving card'. They grab a 'chunk' of the signal ('their' chunk of the screen area'), passively pass the full video signal to their own output and slap on a 'stamp', saying... 'FIRST!!!', kind of like in other forums. The second one then recognizes it and says 'SECOND!!!', and so on. So they actually 'know' what position in the singal line they're in, but only in a 1-dimensional sense. That's why you need the 'D' connector -- It is able to program the receiving cards with stuff like 'If you are first, display 64x64 px at 1x1, if you are second, show the chunk at 1x65', and so on.The good thing is, once the data is pushed into the non-volatile memory (you have to 'save' manually after 'sending' the config data), you won't need the Linsn software again... Well, most the time. Because if you want to install those screens fixed on.. say a building, you want to control the brightness, contrast, etc.. to avoid astronomical eletrical bills. To give you a better idea of the costs: 1 'element' of a 1x1m P16 screen (16 mm pixel pitch) draws up to 1kw full white. That doesn't sound like much, but a rather small screen of 4x3 meters consists of 12 of those, and running for 16 hours a day, this adds up to typically 4kWh a month, which will cost you about EUR 1.000 (in germany). There are sensors available, but I really don't like those. They tend to over-dim or over-brighten the screen. So... I need to control the brightness with some custom software (or maybe even hardware) that runs on linux (or android, whatever). The 'sending card' connects to a PC via the USB connector, which is actually just a SL CP2102 UART-Bridge.Besides the bad software, the Linsnhardwareproved to be pretty realiable and easy to repair. The solder jobs are decent (for a chinese product), they use generic chips you can get everywhere for cheap, and best of all... The nice Mrs. Sarah that kindly provides phone support to all international customers.To my surprise, Mrs. Sarah is actually a guy that doen't speak english. The first time I called her I was so confused, I accidently ordered some fried noodles to go.Alright, now that I wasted several hours of my valuable time, let's start with the 'fun' stuff!Code:START 60%W d8 58 80 ff 00 55 aa 55 aa 55 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 faR c5R c3W d8 58 80 ff 00 1e 00 22 00 02 00 00 00 00 00 00 00 99 99 99 ff 00 00 00 00 0bd8 58 80 ff 00 1f 00 22 10 05 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59d8 58 80 ff 00 18 00 22 20 00 00 00W d8 58 80 ff 00 1e 00 22 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bfd8 58 80 ff 00 1f 00 22 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0d8 58 80 ff 00 18 00 22 a0 00 00 00R c5R c3R c5R c3 c5R c3 c5R c3 c5R c3R c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3W d8 58 80 ff 00 56 aa 55 aa 00 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 a6R c5R c3W d8 58 80 ff 00 57 aa 55 aa 55 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 fcR c5R c3W d8 58 80 ff 00 18 00 22 00 02 00 00 00 00 00 00 00 99 99 99 ff 00 00 00 00 05d8 58 80 ff 00 19 00 22 10 05 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 53d8 58 80 ff 00 1a 00 22 20 00 00 00W d8 58 80 ff 00 18 00 22 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b9d8 58 80 ff 00 19 00 22 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cad8 58 80 ff 00 1a 00 22 a0 00 00 00R c5R c3 c5R c3 c5R c3 c5R c3 c5R c3R c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3 c5R c3R c5R c3 c5R c3W d8 58 80 ff 00 50 aa 55 aa 00 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 a0R c5R c3W d8 58 80 ff 00 1a 00 22 00 02 00 00 00 00 00 00 00 99 99 99 ff 00 00 00 00 07d8 58 80 ff 00 1b 00 22 10 05 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55d8 58 80 ff 00 1c 00 22 20 00 00 00W d8 58 80 ff 00 1a 00 22 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 bbd8 58 80 ff 00 1b 00 22 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ccd8 58 80 ff 00 1c 00 22 a0 00 00 00R c5R c3R c5R c3 c5R c3 c5R c3 c5R c3R c5R c3 c5R c3 c5R c3 c5R c3R c5R c3 c5R c3 c5R c3 c5R c3R c5R c3 c5R c3 c5R c3W d8 58 80 ff 00 52 aa 55 aa 00 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 a2R c5R c3STOPWhat you can see up there is the communication that takes place after setting the brightness to 60%. 'W' means that the software 'writes' to the card, 'R' that it receives/reads stuff. Every 'W' or 'R' indicates a new package. Appearently, the 'sending card' and PC don't do fancy hand-shaking stuff for this, you can just open the software, go to the brightness slider, plug it in, no comm taking place, and this pops up after setting it.Let's go into some detail. As soon as you click and release the slider, the card always first sends data in the following flavour:d858 80 ff 0055aa 55 aa55d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8faNow I don't know for sure - as I have zero exp with this stuff - but this it what I came up with as a newbie:Green bytes: Those are some sort of instruction to write to a certain type of memory (there are several: DDRs, NVRAMs, EPROMs), and these exact ones are always sent when adjusting brightness, in every package.Orange byte: Seems to indicate wether it wants to actually write data to this location or skip it.Blue byte: Probably checksum/parity stuff.Red bytes: Seems to be the location in the memory the instuction points to. Every time you adjust the brightness, no matter what percentage, it points to 6 different locations. I first thought... Well, this must be some simple shift register, converting the serial data into parallel output for the control circuit. BUT - maybe I just lack the needed experience - I don't really understand how this system works. There seems to be a pattern that doesn't make sense to me:There are 8 different 'locations'. Every time you start the program, it always points to 57 first. Now the orange bytes tell me if the program will write more data at this point. It always writes to the first location. The card then replies with c5, then c3. After that, the actual data that contains the brightness level is sent (more on that later).Take a look at the example above again. The orange bytes say '55', indicating that more data specific to this instruction will follow. If the orange bytes are set to '00', it skips to the next instruction after the generic reply from the sending card.Code:W d8 58 80 ff 00 56 aa 55 aa 00 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 a6R c5R c3W d8 58 80 ff 00 57 aa 55 aa 55 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 fcR c5R c3W d8 58 80 ff 00 18 00 22 00 02 00 00 00 00 00 00 00 99 99 99 ff 00 00 00 00 05d8 58 80 ff 00 19 00 22 10 05 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 53d8 58 80 ff 00 1a 00 22 20 00 00 00W d8 58 80 ff 00 18 00 22 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b9d8 58 80 ff 00 19 00 22 90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 cad8 58 80 ff 00 1a 00 22 a0 00 00 00In the first package sent, the orange bytes are 00, so the card replies as usual, program skips, then the next instruction in the same flavour follows. Only this time, the red bytes are increased by 1, and the orange is set to '55', and after the reply, data containing brightness follows.Change brightness for the first time:Red 57 + Orange 55 -> data followsRed 50 + Orange 00 -> skipRed 51 + Orange 55 -> data followsRed 52 + Orange 00 -> skipRed 53 + Orange 55 -> data followsRed 54 + Orange 00 -> skipStop. Then if I change it again (or re-set to the same values once more):Red 55 + Orange 55 -> data followsRed 56 + Orange 00 -> skipRed 57 + Orange 55 -> data followsRed 50 + Orange 00 -> skipRed 51 + Orange 55 -> data followsRed 52 + Orange 00 -> skipIt cycles thru the total of 8 'locations', over and over again, and almost always only writes to the odd ones. In rare cases, it seems to mess up and start with even bytes, and only writes to those. I suspect that it may write to 1 location per LED color, and 1 extra per extra screen. So... Red, green, blue, 1 screen -> 3 of 6 writes. Red, green, blue, 2 screens (remember the 2 connectors) -> 6 of 6 writes, BUT i can't confirm this.As I said, this doesn't make sense at all to me, because why whould it write the SAME value is just wrote seconds ago to a different location? Are these even locations? Why am I doing this stuff?!?!!!!At this point, you probably know if you even want to continue reading this sort of crap.There are more patterns and things I recognized.... But I'm really tired right know, and need a break. I will add more information as soon as I'm replenished with chineses crap energy. If you are interested in more of this stuff, or already know what I'm dealing with, need more information/logs, etc. -- Feel free to reply!Also, if you got (kind of off-topic) questions regarding those big-ass screens or Linsn, or if you're just lonely... whatever... Please don't hesitate to ask/reply here too!Cheers.

author: SeanB
author_rank: Super Contributor
timestamp: March 06, 2014, 09:49:56 pm
content: I have seen the OS of some of these units, and one I saw was running Win98, just from the mouse cursor and the portion of the error box it was half displaying. Funny how most of these get bad blocks with time, you get either one colour missing or stuck on always. At night they can be incredibly bright, especially with flashing graphics.

author: chinglish
author_rank: Contributor
timestamp: March 06, 2014, 10:38:02 pm
content: Well, most of the screens you see, I estimate around 80%, got configured once, then... nothing. You'd be surprised by how many companies buy screens and don't even know how to config them properly. There aren't many people around (at least here in Germany) that know this kind of tech, and the rest doesn't want to know it.Try for yourself -- You can download the Linsn software for free. It's a horrible mess, counter-intuitive and unstable. If you press the wrong button at the wrong time you may have to desolder all the EPROMS on the receiver cards or the screen is just dead. I guess most of them are also scared to damage the hardware, which actually happens quite fast. One customer chose the wrong timing, so his LEDs all died within a matter of days because of too much heat/current. The screen wasn't designed for such high active cycle rates, and the software doesn't know the screen-hardware it's talking to. Well, it was a rather small screen, around 15 m², purchased it used.. Still, about Euro 20.000 just gone. Try to find someone who will solder 200.000 thru-hole LEDs onto your segments. Most of them are covered in silicone too... We ended up desoldering all the chips to use them as spare ones.The bad blocks you discribe are actually quite common and not the software's fault. 90% of the time it's due to moisture, simply drying the segments with a hair dryer fixes it. I cover them with lacquer to prevent this. Works pretty good. The actual LED segments aren't manufactured by Linsn, they do just the control stuff afaik. What also happens a lot is costumers not caring for those block faults, so the pins corrode and eventually just vanish into rusty dust. You can solder new memory chips onto there in a matter of minutes, so it's not really a problem. In most chinese screens, the segments contain several of those memory chips. Because the data is just shifted from left to right thru them at a rather low rate, they need to store the pixeldata locally.I really wonder why so many people use Windows for critical commercial applications. It's not like you have to output your video from a Windows pc. I never do that. Most of the time, I set up a single linux PC with a windows virtual machine. Linux for the video output runs bare metal, and the hypervisor hosts a headless windows os for the config stuff (we use Windows Embedded, which gives you all the good windows thing without most of the bad stuff. you can even use it as a full desktop without problems). One good thing about the Linsn software is that it's networking capabilities. I connect the Windows guest to our Server with vpn, then manage the screens remotely via webcam.

author: dannyf
author_rank: Super Contributor
timestamp: March 07, 2014, 12:57:45 am
content: QuoteFor the same reason that so many people buy Ford or Chevy, or for the same reason that you fly commercial: you wish you could fly on a Golfstream, but you don't, for a variety of reasons.The fact that you cannot figure out why others do what they do is no indication of others' irrationality, but only your lack of imagination.

author: SL4P
author_rank: Super Contributor
timestamp: March 07, 2014, 01:07:08 am
content: My first question would be tounderstand the in-panel decoding and displaytopology.This may help understand how the data packets are organised and their contents.I've built test controllers for some differing Chinese displays (eliminating the provided units for diagnostics purposes) - to specifically test for addressing, bad/sticky LEDs, comms and other issues.Is each LED pixel or cluster driven by a local micro?Is the brightness set for the whole panel, by sub panel, or on a pixel-by-pixel basis by the 'local' controller?Once you have the display panels figured out - it's often productive to build a simple controller for the above reasons - and to understand 99% of the design intentions... which arenotalways the best way of doing things (;-).

author: Psi
author_rank: Super Contributor
timestamp: March 07, 2014, 01:10:55 am
content: When reverse engineering something like this don't try and understand every single byte in the protocol. Just try things and make your software reproduce the communications you see in the official software.As you implement more and more of this the understanding of the protocol will come naturally.e.g. If you can't work out why a particular byte is 0x4F don't worry, send 0x4F when the unit expects it and move on to the serial data which contains more interesting stuff.At least, i find this a better approach than trying to figure out the exact protocol from the start.

author: nuhamind2
author_rank: Regular Contributor
timestamp: March 07, 2014, 01:51:52 am
content: Quote from: SL4P on March 07, 2014, 01:07:08 amCheck out adafruit for the led display this controller control (uh). It is basically ton of shift register. The control signal is latch, output enable and clock the data is R1,G1,B1 and R2,G2,B2. They both provide data for upper half and bottom half of display.

author: chinglish
author_rank: Contributor
timestamp: March 07, 2014, 03:30:00 am
content: QuoteWell, I thought about it a bit more, and I realized that I actually don't wonder why they do. However, I can't quite figure out what you were trying to say. My imagination works fine, it's just that I don't like to rely on assumptions, rather than asking a question.Regarding irrationality... I hope you don't consider using consumer-targeted desktop OS for such applications rational. Even Microsoft won't recommend this. Maybe... :pQuoteCouldn't agree more, but it's quite complicated to test this 'live' with an actual screen attached. Will have to wait till I got one @home. The other thing is... I don't really like this kind of approach. Yes, it works, and may be faster, but to me, it's the 'figuring out' what brings most of the fun, the moment where you realize that you understand everything, rather then hard-coding some bitstreams into an application. I will probably end up doing it, however, my goal is to completely eliminate the need for any Linsn software, and that requires a LOT more knowledge, because those other instruction seem to be completely different. My first, smaller goal is to understand the basic things. Where these values are stored, and how.QuoteThis basically. Although it depends on the type of screen what the receiver does with the 2 seperate RGB data signals. Sometimes they divide the whole screen, sometimes the segments are divided... Never know whats comming next.The configuration of the screen is quite complex. Altho I do understand most of it, I often spend days on figuring out how this certain type of segment is adressed. Try to find a manual for these things....It's getting a bit late here (4:20 AM), will provide you with some more info regarding the Linsn universe tomorrow.Thanks so far!

author: nuhamind2
author_rank: Regular Contributor
timestamp: March 07, 2014, 04:16:26 am
content: Quote from: chinglish on March 07, 2014, 03:30:00 amI don't have the display myself, but adafruit tutorial show it clearly how it's work. They even make tutorial how to drive these display by arduino and fpga. The smallest module is 16x32 or 32x32. On the 16x32 you drive 8x32 upper half with rgb1 and the 8x32 bottom half with rgb2.On 32x32 rgb1 drive 16x32 upper half and rgb2 drive 16x32 bottom half. Oh and I forgot on thing, there is more control signal a,b,c for 16x32 and a,b,c,d for 32x32. These signal is for multiplexing which line you're powering. For 16x32 you only need 3 select signalsince you select 1 line over 8 (1/8 duty cycle) and for 32x32 you need 4 select signal (1 from 16).The chip count and the led count is matching. A single module has 12 16-bit shift register (constant current output) that's mean 6 shift register for each half . 6 shift register equal to 96 output equal to number of led in a row which is 32 pixel times 3 (R,G,B)A bigger screen is basically those small module tail chained.

author: Psi
author_rank: Super Contributor
timestamp: March 07, 2014, 04:58:00 am
content: Quote from: chinglish on March 07, 2014, 03:30:00 amTrue, if you only have limited access to the screen then you're really forced to do it the slow way.I would assemble a long test plan of things you want to try sending the display (to confirm your assumptions or prove them wrong).You want to be able to rock up to the display and quickly fire many commands at it while recording the communication and noting down exactly what the display does.Then you can analyse the data you collected later and start to understand the protocol during the times when you don't have display access.At first this will just create more questions.So write more tests to run next time you have access and repeat.Try to fork the tests a bit to maximize your results, like, "if test Y does what i expect then try test A and B but if test Y fails try test C and D"Eventually you will have so much data you can confirm/reject assumptions by looking at your previous communication logs without needing physical access .

author: Artlav
author_rank: Frequent Contributor
timestamp: March 07, 2014, 08:18:59 am
content: Quote from: chinglish on March 06, 2014, 09:11:53 pmGermany, right?Do you have legal restrictions on where you put such screens over there?There are a few places in Moscow where you drive along an avenue at night, curve out of a turn, and get a face full of building-sized LED screen with blinking advertisements.I was kind of wondering if such triumphs of commerce over safety are common in other parts of the world.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: March 07, 2014, 10:56:59 am
content: chinglish, why don't just try their source code?http://www.linsn.com/LED/LedSetSp.exe

author: poorchava
author_rank: Super Contributor
timestamp: March 07, 2014, 11:57:15 am
content: Dunno how about Germany but in Poland we have a huge problem with this. Those screens are typically mounted at big crossings / communication hubs. Theoretically there is a ragulation, that it is forbidden to place near public roads any devices that emit of reflect light in a manner that can blind or distract drivers. The problem is that there is no hard limit (eg. that much lux, that much lumen blablabla) and there is no penalty specified for this.Most of the owners of such billboards set them to 100% all the time, because their boss or client cannot ask "why they are not using all the attention attraction possible" (that's an actual quote...). There have been few cases, when people from nearby apartament blocks dealt with the billboard. In some cases by repeatedly calling police on the owner, in some cases they sued the owner, but in most cases there were more direct countermeasures (bricks, stones, spraypaint, paintball guns, boltcutters at the power cable etc).

author: amyk
author_rank: Super Contributor
timestamp: March 07, 2014, 12:14:20 pm
content: Now I have a much better understanding of how this could happen:

author: dannyf
author_rank: Super Contributor
timestamp: March 07, 2014, 01:35:26 pm
content: QuoteWhy not?QuoteWho cares about what Microsoft recommends or not.Microsoft didn't recommend you to reverse engineer the board; you did it anyway;Microsoft didn't recommend you to go to sleep last night; you did it anyway;Microsoft didn't recommend you to date that girl; you did it anyway;Microsoft didn't recommend you to drink that 6-pack; you did it anyway;....If you have to live your life by what Microsoft (or any other company/entity) recommends, it is a life not worth living. You are a human, not a computer. So live by what you think is right, not what Microsoft thinks is right.

author: TerraHertz
author_rank: Super Contributor
timestamp: March 08, 2014, 10:28:16 am
content: Minor point, but sequences like "55 aa 55 aa 55" are usually present as 'magic numbers' where the programmer though something like "I know, lets have some bytes here to check the comms link is working and there are no stuck bits or stuff."Because those are alternating bit patterns: 55= 01010101, aa=10101010.

author: made2hack
author_rank: Frequent Contributor
timestamp: March 08, 2014, 01:01:11 pm
content: What's a Constumer?Is that a Consumer-Customer?Some kind of new economic model hybrid???The Chinese are way ahead of the rest on this one O0

author: chinglish
author_rank: Contributor
timestamp: March 09, 2014, 12:06:59 am
content: QuoteNone so far, because...QuoteWe got lots of restrictions. Some years ago, you couldn't even show animations, or pictures with a lot of green or red content for example, because of - quote - "possible confusion with traffic lights"... I'm no expert on traffic safety, but that seemed a bit silly and over the top. They eventually came to that conclusion too it seems, as the restrictions get less and less, but still, it's a lot of trouble even getting a building permission for smaller ones. However, I think that's a good thing, and if you install such screens, you should apply some common sense yourself to not cause any issues. There's enough money out there to make without pushing the law to it's limits. But that's just my POV.QuoteI don't exactly consider some buggy binaries 'source code'. I might end up disassembling some libraries, but this is far too complex for my untrained mind to understand, I presume.You are welcome to try if you know that kinda stuff.QuotePlease stop wasting my time by trolling this thread. Thank you.QuoteI see, but would there be any reason to use such a 'magic' sequence to actually control stuff (see my first post) too? And if you are right... To what conclusions might this lead? E.g., I assume using such safety measures would only be reasonable if the code is somehow processed further by something that has control over way more stuff than just simple settings.Let me ask some more noob questions....Is there any pattern you recognize that might be typical for a certain type hardware? Or the other way around? For example... "Such code can only be processed by XXXX", or " a YYYY is not capable of that kind of stuff", and so on.What I do know is, that the brightness settings get saved locally somewhere on the sending card, and that they're first written to some volatile memory. If I power down the card without pressing 'save', the previously stored values are displayed upon opening the software, and they do get stored without a screen attached. Looking at the hardware and fpga datasheet, the Spartan seems to be running in Master SPI Mode (seehttp://www.xilinx.com/support/documentation/user_guides/ug332.pdfpage 101...), because of the DDR chips and spi flash underneath. This would also allow for storing user data in the spi flash thing, which seems to be the only non-volatile memory onboard.QuoteThere are some other interesting things in the Spartan datasheet, likeQuoteorQuoteThey talk about MicroBlaze, PicoBlaze, etc... which are Microprocessors 'coded' into the fpga.I think it might lead better understanding of the data if anyone could confirm some of these assumptions. The Spartan and everything related to is very well documented.I'll keep you updated. Will be doing some more practical tests tomorrow, as suggested.CheersEDIT: Btw, this is not just about reversing the board, it's also about learning stuff. This is my style of doing things... I rather spend 10x the hours to understand what I'm dealing with, because it WILL come in handy. Always does.

author: dannyf
author_rank: Super Contributor
timestamp: March 09, 2014, 01:19:13 am
content: QuoteI suppose that's recommended by Microsoft?

author: dannyf
author_rank: Super Contributor
timestamp: March 09, 2014, 01:21:05 am
content: QuoteIt can be and is often used for baud rate detection.However, it could also be the result of wrong baud rates. Renesas has a paper on that.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: March 09, 2014, 06:45:54 pm
content: Your dumps doesn't match the things I see in LedCtrl.dll: the fill byte should be CA, not D8. Are you tapping TxD/RxD lines directly? Use 115200 8-N-2 (2 stop bits !) params in this case. Or just use some sw-side COM/USB monitor.Reading Spartan docs is a waste of time: this protocol doesn't originate from Xilinx, it just runs on this chip, but is coded by Linsn.

author: chinglish
author_rank: Contributor
timestamp: March 09, 2014, 07:44:08 pm
content: Quote from: dannyf on March 09, 2014, 01:21:05 amI appreciate your constructive feedback.I tried to send some commands using different baud rates, but 115200 was the only one that got me some response. The software I used to cap the data also detected that rate. See below.QuoteI captured the data using some sw called 'Serial Port Monitor'. As the board is missing some components near the RS232 port (there are 2 versions, we use the USB one), I figured it might be safer to monitor the communication this way. Have to check on the stop bits though. I assumed the software was able to detect the correct settings. Is that not the case?What LED software did you download? There are different models of the sending card, each uses a different version number. The correct one for this type would be LedStudio9.60D. There is also a simplified version called LedSet, which seems to work. The library you mentioned presumably belongs to V10, which is incompatible.I uploaded the working one to my dropbox:https://www.dropbox.com/s/0k2jzdldri4x41s/LedSoft8.zipQuoteI see. I assumed it may be possible that Linsn didn't actually code that stuff, leaving the (generic) serial communication/data storage stuff to some pre-built soft-micro (see my previous post), and just reading the values from the mem using their own code. Dunno if that's even possible, as I never used FPGAs in my (rather simple) projects, but such an approach would fit their general attitude...EDIT: I just read a paper about decompiling xilinx bit files, but it seems it's only been done in therory... Anyone know anything about this?

author: abyrvalg
author_rank: Frequent Contributor
timestamp: March 09, 2014, 08:10:27 pm
content: I've tried a dll from this packagehttp://www.linsn.com/LED/LedSetSp.exefirst. Your software is different - it uses D8 fill bytes, so your dumps gets sense now.Which LedSet are you talking about? I would like to check that one too: your sw has all comms linked into LedStudio.exe, which isn't so handy. Perhaps LedSet will have a separate dll for that.

author: chinglish
author_rank: Contributor
timestamp: March 09, 2014, 08:33:34 pm
content: Unbelievable! Looking into that LedSet folder, which I never did before (because I never really used this software outside this 'reversal').... There actually IS source code... What the hell?! I feel pretty dumb right now, I thougt you were (jokingly) referring to the binaries as source code... LOLHowever, the version you were looking into is still different from mine, use this one:LedSet10.zipI skipped thru the files, and didn't find information regarding the serial data, but it really looks promising and might even be sufficient to implement this into a custom, more stable application with only core features!Thanks so far, really appreciate your effords.Oh, and here is a more complete serial data dump:https://www.dropbox.com/s/61l7wgoqp7ivt2l/60percent100percent.htmlWhat I did there is setting the brightness to 60% 3 times, then 100% 3 times in a row. Looking at the time stamps you can distinguish these events, as I waited for like 3-5 seconds till the next click.I'll try to contact Linsn tomorrow... Maybe they just send me the source for the precompiled bit.

author: chinglish
author_rank: Contributor
timestamp: March 09, 2014, 08:58:13 pm
content: I updated the dropbox link, packed the wrong version (the one you were using). Sorry!

author: abyrvalg
author_rank: Frequent Contributor
timestamp: March 09, 2014, 10:03:56 pm
content: There is no protocol itself in the sources, they just use LedCtrl.dll which contains functions like SetBrightness.Since I did some disasm already, I'll post the results:Serial link parameters: 115200, 8 bits, NONE parity, 2 stop bitsframe type 50 (single frame at the start) format:W d8 58 80 - constff 00 - cmd_h cmd_l55 - frame_type=50 | (++seq & 7)aa 55 aa - const55 - paramd8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 d8 - fillfa - checksum = byte sum buf[3:]R c5 c3 - this means "OK"frame type 18 (frame that repeats 16 times with different data) has the same header (but with frame_type=18) and checksum, but I didn't studied the body part (between type | seq and checksum) yet.

author: chinglish
author_rank: Contributor
timestamp: March 09, 2014, 11:53:34 pm
content: QuoteLooking at the dll and code, it seems EVERYTHING is in there... 5mb? It's really annyoing if you lack the needed asm skills, confuses the sht out of me.The source is just a cosmetic thing to.. I don't know, maybe slap your company name on it. THANKS LINSN.Your data looks good though!d8 58 80 ff 00 18 00 22 00 02 00 00 00 00 00 00 0099 99 99 ff00 00 00 00 05That's a brightness data containing package. The purple bytes seem to contain the actual brightness data, see the new dump. The 55 or 00 - 'param' - seems to indicate wether a second screen is attached. What I'm most interested in is how the brightness input dec 0-100 gets translated into that sequence... Will look into it too.d8 58 80 ff 00 18 00 22 00 02 00 00 00 00 00 00 00 99 99 99 ff 00 00 00 00 05...d8 58 80 ff 00 1a 00 22 00 02 00 00 00 00 00 00 00 99 99 99 ff 00 00 00 00 07...d8 58 80 ff 00 1c 00 22 00 02 00 00 00 00 00 00 00 99 99 99 ff 00 00 00 00 09That would be 60%.d8 58 80 ff 00 1e 00 22 00 02 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 3d...d8 58 80 ff 00 18 00 22 00 02 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 37...d8 58 80 ff 00 1a 00 22 00 02 00 00 00 00 00 00 00 ff ff ff ff 00 00 00 00 39That's 100%.ff ff ff ff -> 10099 99 99 ff -> 60Looking at the software it's clear that the brightness value must get written 3 times, because you can also set RBG separatly to change the color temperature.Also, the frame type bytes of the initial packet correspond to the bytes of the packet that contains the actual brightness data.Type 51 -> Type 1a53 -> 1c55 -> 1e57 -> 18Looking at the dump it's clear that every time such a packet gets sent, the type is incresed by 1 until it hits 57, then repeats, corresponding to your disasm. It's also evident that the type doesn't follow some specific pattern related to the brightness values. It doesn't really matter what type the packet contains, as long as it's in the 8 bit range from 50h-57h and increased by 1 after the first brightness value has been transmitted/was adressed. After It's been transmitted, you can start from anywhere in that range without issues.Going to bed now, will update as soon as I figured out some more things regarding 2nd screen and seperate values for the 3 colors.CHeers

author: abyrvalg
author_rank: Frequent Contributor
timestamp: March 10, 2014, 08:28:15 am
content: The type field is combined with packet sequence: lower 3 bits are sequence, rest is type. There are two types used in your dump: single packets with type 50 (type gets ORed with seq, so you see values like 55 there) and 16x batches of type 18 packets (where the brightness value is). The sequence var is common for all packet types and gets incremented on every send, but since it is masked to 3 bits it rolls over to 0 after reaching 7: 0, 1, 2,...7, 0, 1...

author: abyrvalg
author_rank: Frequent Contributor
timestamp: March 10, 2014, 11:16:49 am
content: Frame type 18 (write regirsters):d8 58 80 - constff 00 - cmd (I think cmd is wrong name, it's something like board address I guess)18 - type 18 | (seq & 7)00 22 00 - regs start address02 00 00 00 00 00 00 00 99 99 99 ff 00 00 00 00 - regs data05 - checksum (sum of bytes 3-last)set brightness:SendFrame50(0xFF00, 0x55) //start write regsfor(i=0; i<0x100; i+=0x10) //write regdata to addr 0x002200 in 0x10 chunks{SendFrame18(0xFF00, 0x002200+i, regdata+i, 0x10)}SendFrame50(0xFF00, 0x00) //end write regsregdata[8,9,A] bytes are 3 separate brightness values (R,G,B channels?). The calculation is simple: 0xFF * 60 / 100 = 0x99 (0xFF * 60%).Looks like many other params (contrast etc) are just different locations within regdata.

author: chinglish
author_rank: Contributor
timestamp: March 11, 2014, 09:26:07 am
content: Awesome!Funny though, I actually discovered the code myself during analysis of my disassembly, yet i failed to verify this is the correct sequence for actually setting the brightness. I used hex-rays to generate pseudo-code of instructions related to LNS_SetBright and renamed the vars quite confusingly in a hurry, I guess that was quite a fail. On the other hand, my results are pretty much pleasing considering I know close to nothing about assembler. Just kind of figured it out myself in the process.QuoteSo I guess the data regarding image adjustment is all written to a pretty restricted area in memory? This might be interesting to set up several parameters at once using a single frame (or frame sequence like the dumped ones), instead of sending hugh amounts of frames.QuoteWhat do you think is the purpose of the seq var?I'm a bit afraid to test this out on a live card, as I only got one here right now and I need it for live testing of new screen parts that are going to be isntalled within the next 3-10 weeks. I really don't want to write possibly messed up data to locations i shouldn't. You never know how those things react, I whitnessed a lot of strange problems using them in the past few years.However, as stated before, these frames seem to only write to volatile memory. I will upload a new dump containing the frames to actually write this to flash. I hope these instructions are less complex, maybe something in the style of 'alright, now write this to flash', instead of a completely different instruction containing the actual data..BTW: What software do you use for disassembly?cheersEDIT: I just noticed.... 99 99 99, 3 values... so it actually writes essentially the same data to the same location 3 times in a row?

author: bookaboo
author_rank: Frequent Contributor
timestamp: March 11, 2014, 10:07:52 am
content: Interesting about the code.What applications do you have in mind once you can control the modules?I find the way the screen acts as a 2nd monitor to be great for most applications. Although LED Studio is a rubbish you can just write a small prog in VB to do what you need as its wysisyg.The only downside is that you need to have a PC running all the time, which is cumbersome if you just want to repeat a cycle of text/images, would it be possible to make a psuedo-interface card that stores a cycle of graphics and just spits it at the screen in a loop?

author: chinglish
author_rank: Contributor
timestamp: March 11, 2014, 10:57:43 am
content: QuoteWell, I would't go so far, there are more simple solutions that work nearly out-of-the-box.For example: Write some small program to control the values you need to set while the screen is running and grab a small pc-like device that runs linux, like the raspberry-pi (which has hdmi/dvi out). You could program the control software to periodically read the config data from a plain text file and run another (already existing) software to display pictures in a specific folder. A simple ftp-server could be installed to update the config file and pictures remotely. As the Pi got an ethernet connection, you just need to plug it into some existend network, set up dhcp, and you're good to go.Total cost: 25$Another approach I had in mind would be to build a hardware-controller using something generic like an arduino. It's cheap and quick to program/build, with all those shields available. That way you could update your code to control different types of screens with minimum software overhead, yet you'd have all the advantages of a hardware solution. But that would be something i'd only consider for say public viewing style applications, or other live screnarios where remote management is unnessesary or impractical.The whole point of this reverse engineering is to eliminate the need for windows, which would reduce costs significantly, and also increase reliability (which are the top concerns in commercial applications).QuoteI don't plan on doing so currently. My job is to keep these things running, and this will make it a lot easier. That's all I wanted.Also, as I wouldn't be able to accomplish this alone, it would be quite unfair to let some of you guy do a major part fo the work, then just sell it for my own profit. However, I can assure the effort one puts in here won't go unnoticed if money will be made from this.

author: bookaboo
author_rank: Frequent Contributor
timestamp: March 11, 2014, 11:14:24 am
content: Would be glad to help out in any way I can. I have a test rig with a Linsn LX801 and some P16 RGB modules that were used to make a very customised set up but are now awaiting a suitable project.I will have to dig the parts out and see what version the send card is (and if the cards are still working). I will report back.

author: chinglish
author_rank: Contributor
timestamp: March 11, 2014, 11:37:29 am
content: Quote from: bookaboo on March 11, 2014, 11:14:24 amGood to hear. Please keep in mind that different generations of the sending card need different software, so we gotta make sure those match.Cheers

author: bookaboo
author_rank: Frequent Contributor
timestamp: March 11, 2014, 11:58:06 am
content: Sending cards have come down in price a lot, if it makes things easier you could just chose one version and change the send card each time.

author: chinglish
author_rank: Contributor
timestamp: March 11, 2014, 12:55:46 pm
content: Indeed. For you to test this stuff out though you need a matching one (and I currently only got the one you can see in the first post at my disposal).

author: abyrvalg
author_rank: Frequent Contributor
timestamp: March 12, 2014, 10:44:10 pm
content: chinglish, can you post what exactly do you see in hex-rays there?

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: March 12, 2014, 10:58:36 pm
content: Quote from: bookaboo on March 11, 2014, 10:07:52 amThere are versions of this range that will play video from SD cards in standalone mode.

author: Myles
author_rank: Newbie
timestamp: March 13, 2014, 03:14:18 pm
content: Hello from Myles in AustraliaI am very impressed with this post and the forum, I have been looking for information on the Linsn cards with very little luck. Can I please have help with some beginner questions.1. What is the protocol between the "sending" and "receiving" cards? RS232, RS485 or some crazy Chinese invention2. Could someone please give me the pin-out of the RJ45 socket on the sending card3. Is there a way the create a wireless link between the sending and receiving cards ( I want real time synchronous control without the cat5 cable)Thank you so much for any help you can giveMyles

author: bookaboo
author_rank: Frequent Contributor
timestamp: March 13, 2014, 03:41:12 pm
content: Quote from: Myles on March 13, 2014, 03:14:18 pm1) OP has figured it to be some crazy Chinese invention2) Pass3) This is possible, I've been quoted for such a system and I'm just waiting on the technical info.Quote from: mikeselectricstuff on March 12, 2014, 10:58:36 pmIs that a Linsn product? Something like that would be most useful for a probable upcoming project I'm doing.

author: Myles
author_rank: Newbie
timestamp: March 13, 2014, 04:02:41 pm
content: Hi From Myles againCould you give me some details of the wireless option you have been quoted, what sort of price are you looking at?Thank you

author: chinglish
author_rank: Contributor
timestamp: March 13, 2014, 09:26:46 pm
content: Quote from: Myles on March 13, 2014, 03:14:18 pm1. Not a widely used protocol outside such products, if at all, probably Linsn only. Don't know for sure. The connection to the screen is made via cat5.2. I'm afraid not. I didn't spend too much time on going into such detail regarding parts of the system I'm currently not very interested in. I will take a look at the card. In the meantime, go look at adafruit, appearantly theres lots of information on the Linsn.3.http://www.szlamp.net/LED-controller-and-software-F_i6.htmlNever seen it, never used it. Probably crap and not what youre looking for. Might be interesting though.The only (easy and already available) wireless solutions i could think of would be connecting a DVI over ethernet style device to the sending card, then hook it up to a wireless AP (never tried this, but there sure will be limitations regarding range and reliability), or just connecting a (mini-) computer to the card, that streams the video wirelessly. I personally hate WiFi in such applications, because it's limited in transmit power (legal reasons), thus range, and pretty much unreliable, because those freq are used everywhere by tons of people. Even in microwave ovens. Consumer-style hardware is just not the way-to-go if you ask me.Why exactly do you need a wireless connection?QuoteCan't remember tbh. Have to disassemble the thing again to look it up. Pretty busy right now, so might take a day or two. What exactly do you need to know? Want screenshots? Code?QuoteDo you have any interesting info on the hardware of the Linsn system? Feel free to speculate, guess, whatever. Could be useful to me!Thanks guys, will be back.

author: chinglish
author_rank: Contributor
timestamp: March 13, 2014, 10:30:35 pm
content: Quote from: abyrvalg on March 12, 2014, 10:44:10 pmCode:int __usercall sub_10090E40<eax>(signed int a1<eax>, signed int a2<ecx>){if ( a1 >= 0 ){if ( a1 > 100 )a1 = 100;}else{a1 = 0;}if ( a2 < 0 || a2 >= (signed int)wParam )sub_100FF1DD();*(_DWORD *)(*(_DWORD *)(dword_10367F04 + 4 * a2) + 8) = a1;return sub_100CCF00(a2, 0);}Code:char __userpurge sub_100CCF00<al>(int a1<esi>, __int64 a2){int v2; // edi@3int v3; // eax@3signed int v4; // eax@4int v5; // ecx@4signed int v6; // eax@7int v7; // ecx@7bool v8; // cl@11int v9; // eax@14int v10; // edx@15int v11; // ecx@18int v12; // eax@20char v13; // bl@22char v15; // [sp+2Dh] [bp-1Bh]@3char v16; // [sp+2Eh] [bp-1Ah]@3char v17; // [sp+2Fh] [bp-19h]@3int v18; // [sp+34h] [bp-14h]@3int v19; // [sp+38h] [bp-10h]@3__int16 v20; // [sp+3Ch] [bp-Ch]@3__int16 v21; // [sp+40h] [bp-8h]@3__int16 v22; // [sp+44h] [bp-4h]@3if ( (signed int)a2 < 0 || (signed int)a2 >= *(_DWORD *)(a1 + 16648) )sub_100FF1DD();v2 = *(_DWORD *)(*(_DWORD *)(a1 + 16644) + 4 * a2);v3 = *(_DWORD *)(a1 + 16424);v18 = *(_DWORD *)(v3 + 13457) & 1;v19 = (*(_DWORD *)(v3 + 13457) >> 1) & 1;v20 = *(_WORD *)(v3 + 13461);v21 = *(_WORD *)(v3 + 13463);v15 = *(_BYTE *)(v3 + 13465);v16 = *(_BYTE *)(v3 + 13466);v17 = *(_BYTE *)(v3 + 13467);v22 = *(_WORD *)(v3 + 13473);if ( *(_DWORD *)(v2 + 40) ){v4 = 0;v5 = v2 + 56;do{*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 14993) = *(_WORD *)(v5 - 2);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 15505) = *(_WORD *)v5;*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 16017) = *(_WORD *)(v5 + 2);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 12945) = *(_WORD *)(v5 + 4);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 14995) = *(_WORD *)(v5 + 6);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 15507) = *(_WORD *)(v5 + 8);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 16019) = *(_WORD *)(v5 + 10);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 12947) = *(_WORD *)(v5 + 12);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 14997) = *(_WORD *)(v5 + 14);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 15509) = *(_WORD *)(v5 + 16);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 16021) = *(_WORD *)(v5 + 18);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 12949) = *(_WORD *)(v5 + 20);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 14999) = *(_WORD *)(v5 + 22);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 15511) = *(_WORD *)(v5 + 24);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 16023) = *(_WORD *)(v5 + 26);*(_WORD *)(v4 + *(_DWORD *)(a1 + 16424) + 12951) = *(_WORD *)(v5 + 28);v4 += 8;v5 += 32;}while ( v4 < 512 );}else{sub_10091370(*(_DWORD *)(v2 + 44),*(_DWORD *)(a1 + 16424) + 12945,(double)(*(_DWORD *)(v2 + 24) * *(_DWORD *)(v2 + 2116) / 100));v6 = 0;v7 = v2 + 56;do{*(_WORD *)(v7 - 2) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 14993);*(_WORD *)v7 = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 15505);*(_WORD *)(v7 + 2) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 16017);*(_WORD *)(v7 + 4) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 12945);*(_WORD *)(v7 + 6) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 14995);*(_WORD *)(v7 + 8) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 15507);*(_WORD *)(v7 + 10) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 16019);*(_WORD *)(v7 + 12) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 12947);*(_WORD *)(v7 + 14) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 14997);*(_WORD *)(v7 + 16) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 15509);*(_WORD *)(v7 + 18) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 16021);*(_WORD *)(v7 + 20) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 12949);*(_WORD *)(v7 + 22) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 14999);*(_WORD *)(v7 + 24) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 15511);*(_WORD *)(v7 + 26) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 16023);*(_WORD *)(v7 + 28) = *(_WORD *)(*(_DWORD *)(a1 + 16424) + v6 + 12951);v6 += 8;v7 += 32;}while ( v6 < 512 );}v8 = *(_DWORD *)(v2 + 2420) && *(_DWORD *)(v2 + 2156) == 3;*(_DWORD *)(*(_DWORD *)(a1 + 16424) + 13457) ^= (v8 ^ (unsigned __int8)*(_DWORD *)(*(_DWORD *)(a1 + 16424) + 13457)) & 1;*(_DWORD *)(*(_DWORD *)(a1 + 16424) + 13457) ^= (*(_DWORD *)(*(_DWORD *)(a1 + 16424) + 13457) ^ 2* *(_DWORD *)(v2 + 32)) & 2;*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13461) = *(_WORD *)(v2 + 2160);*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13463) = *(_WORD *)(v2 + 2164);*(_BYTE *)(*(_DWORD *)(a1 + 16424) + 13465) = ((signed int)((unsigned __int64)(448600744275i64* *(_DWORD *)(v2 + 8)* *(_DWORD *)(v2 + 12)) >> 32) >> 12)+ ((unsigned int)((unsigned __int64)(448600744275i64* *(_DWORD *)(v2 + 8)* *(_DWORD *)(v2 + 12)) >> 32) >> 31);*(_BYTE *)(*(_DWORD *)(a1 + 16424) + 13466) = ((signed int)((unsigned __int64)(448600744275i64* *(_DWORD *)(v2 + 8)* *(_DWORD *)(v2 + 16)) >> 32) >> 12)+ ((unsigned int)((unsigned __int64)(448600744275i64* *(_DWORD *)(v2 + 8)* *(_DWORD *)(v2 + 16)) >> 32) >> 31);*(_BYTE *)(*(_DWORD *)(a1 + 16424) + 13467) = ((signed int)((unsigned __int64)(448600744275i64* *(_DWORD *)(v2 + 8)* *(_DWORD *)(v2 + 20)) >> 32) >> 12)+ ((unsigned int)((unsigned __int64)(448600744275i64* *(_DWORD *)(v2 + 8)* *(_DWORD *)(v2 + 20)) >> 32) >> 31);*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13473) = *(_WORD *)(v2 + 52);if ( *(_DWORD *)(v2 + 36) && (v9 = *(_DWORD *)(v2 + 2168), v9 > 0) && (v10 = *(_DWORD *)(v2 + 2180), v10 > 0) ){if ( *(_DWORD *)(v2 + 2176) < v9 )*(_DWORD *)(v2 + 2176) = v9;v11 = *(_DWORD *)(v2 + 2172);if ( v10 < v11 )*(_DWORD *)(v2 + 2180) = v11;*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13469) = (v9 << 16) / *(_DWORD *)(v2 + 2176);v12 = (*(_DWORD *)(v2 + 2172) << 16) / *(_DWORD *)(v2 + 2180);}else{*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13469) = 0;LOWORD(v12) = 0;}*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13471) = v12;v13 = sub_100998A0(a2, HIDWORD(a2));*(_DWORD *)(*(_DWORD *)(a1 + 16424) + 13457) ^= ((unsigned __int8)v18 ^ (unsigned __int8)*(_DWORD *)(*(_DWORD *)(a1 + 16424) + 13457)) & 1;*(_DWORD *)(*(_DWORD *)(a1 + 16424) + 13457) ^= (*(_DWORD *)(*(_DWORD *)(a1 + 16424) + 13457) ^ 2 * v19) & 2;*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13461) = v20;*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13463) = v21;*(_BYTE *)(*(_DWORD *)(a1 + 16424) + 13465) = v15;*(_BYTE *)(*(_DWORD *)(a1 + 16424) + 13466) = v16;*(_BYTE *)(*(_DWORD *)(a1 + 16424) + 13467) = v17;*(_WORD *)(*(_DWORD *)(a1 + 16424) + 13473) = v22;sub_10091600();return v13;}I think this is a part of the code. As I didn't rename vars and.. well, didn't do anything at all this time, I'm not 100% sure. Please report back. As said before, am pretty busy atm, so I can't really put much time into this until saturday. Also, check PM.

author: bookaboo
author_rank: Frequent Contributor
timestamp: March 14, 2014, 09:38:02 am
content: Quote from: Myles on March 13, 2014, 04:02:41 pmThese are the two wireless controllers I've been recommended:http://www.ledsign.cc/productK20.htmlhttp://www.ledsign.cc/productA31.htmlI haven't had a chance to look at the spec in detail (travelling at the moment), also I have not used this company before so can't vouch for anything.

author: chinglish
author_rank: Contributor
timestamp: March 14, 2014, 06:07:49 pm
content: QuoteSounds like you can only upload stuff to the attached sd card. Live video over GPRS? Yea..Don't see any reason to use this if you already have a sending card. The Pi supports SIM, ethernet, USB and HDMI for a little over 25 bucks and you can run a linux distribution of you choice on it. I think I wouldn't even use it if I didn't have the sending card. It's most probably cheaper and supports higher resolutions for big screens, maybe even live video stream (never tested it).

author: asasensio
author_rank: Newbie
timestamp: March 22, 2014, 09:55:43 pm
content: Hi there,I work probably in the biggest LED screen suppliers company in Spain. I've been working for at least 6 years with LED screens and I normally use LINSN controllers.That's a great idea, I'm looking for this project for long time ago. I'm wondering to use a PI for every LED screen controlled with a external server. I talk often with LINSN company developers, there's some people that knows english, unfortunately they are not able to help new external developers or hackers (entrerprise policy). For this project i recomend you to use LedSetp10 (you can download it from linsn website). This application is for change brightness, contrast, send CON and RCG file.There's some mistakes in your post:LINSN always is based on the last generation but every new one has new features.Both outputs U and D works perfectly.If I could help in some case let me know it. I'm very interested in work together.

author: David_AVD
author_rank: Super Contributor
timestamp: May 19, 2014, 11:34:18 am
content: I have a sign panel at the moment that has a small controller card and 20 8x16 single colour modules.The LED modules seem like they could be fitted with R, G & B LEDs but they only have the red (or green) fitted on the modules I have.A preliminary look at the 16 pin data connectors shows that there are 5 signal lines (2 pins each), 4 grounds and 2 other pins that don't seem to be used.I haven't setup a capture on the signal lines yet, but could it be clock, load (select) and 3 data lines (one for each colour) ?The modules are similar to these, but have no chips visible and separate screw posts for the +5 and 0V connections.

author: amyk
author_rank: Super Contributor
timestamp: May 19, 2014, 11:38:55 am
content: You may want to watch this:

author: David_AVD
author_rank: Super Contributor
timestamp: May 19, 2014, 11:55:26 am
content: I watched that video the other week, but thought these may be a simpler version as I didn't think the modules I have support intensity control.Sounds like I need to capture some data and go from there.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 19, 2014, 05:00:02 pm
content: Quote from: David_AVD on May 19, 2014, 11:34:18 amI have a panel similar to this with white LEDs.I've only given it a brief look, but I think it is structured like this :The row multiplex is 4:1, so 2 row select lines. For 8x16 it's electrically 4x32Columns are driven by 74HC595's with no current-limiting resistors (!)There is no global enable, so can't easily do greyscales, but if you hooked into the HC138 row decoder's enable pin you cpuld probably do it - not quite as fast as a true column select but should be adequate.The signal lines are2 row selectData, Clock and Latch to the HC595'sI just realised it is possible that the Latch line also drives the 595 OE lines, in which case it could do greyscale unmodified - don't recall if I checked this when I was looking at it.

author: David_AVD
author_rank: Super Contributor
timestamp: May 19, 2014, 08:44:43 pm
content: Thanks for that Mike. I'll take a closer look at the driver board and what chips it uses.The LED modules I have have all of the electronics hidden (potted), except for 2 electrolytic caps so no chance of probing or examining any chips on them.I'll take a photo today when I get into work.

author: David_AVD
author_rank: Super Contributor
timestamp: May 19, 2014, 10:33:43 pm
content: The controller board has a micro (8051 ?), RS485 transceiver and a couple of HC245 buffers.Here's some pictures of the controller board and LED module:

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 19, 2014, 10:57:00 pm
content: Quote from: David_AVD on May 19, 2014, 10:33:43 pmFor non-greyscale control, bandwidth requirement is fairly minimal, so easy to drive from any micro.I think I noted the pinouts of the one I have - will take a look tomorrow.

author: David_AVD
author_rank: Super Contributor
timestamp: May 20, 2014, 02:01:30 am
content: I removed the silicone fill from part of one of the dead LED modules and it uses MBI5023 chips. (looking for English data sheet now)There are 2 unpopulated chip positions for every populated one, so I guess they just fit whatever chips and LEDs are required for the colour type.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 20, 2014, 08:51:34 am
content: Quote from: David_AVD on May 20, 2014, 02:01:30 amGoogle finds a chinese datasheet with enough info to ID it as a standard 16-channel constant-current driverhttp://www.lantec.cn/Private/Files/MBI5023%20Preliminary%20Datasheet%20V1.00-SC.pdfLooks very similar to MBI5024 :http://www.autcomp.com.br/fichas/macroblock/drivers/dcdc/MBI5024%20Datasheet%20VA%2002-EN%20.pdf

author: David_AVD
author_rank: Super Contributor
timestamp: May 20, 2014, 09:06:45 am
content: Thanks for the links. I think I already have the first one.I've mapped out most of the 16 pin connector now so should be able to create a test jig for them when I get a chance.I actually have a new product application for modules like these so driving them with my own hardware is the ultimate goal.

author: poorchava
author_rank: Super Contributor
timestamp: May 20, 2014, 09:15:16 am
content: Those drivers are made by Macroblock. Strange that there is no info on their website. They are Taiwanese company, but they know what they're doing. They have a distributor in EU:www.maritex.com.pl(https://www.maritex.com.pl/en/shop/products/33061/?cid=33061&views=&form%5B378%5D%5B%5D=3103)

author: amyk
author_rank: Super Contributor
timestamp: May 20, 2014, 10:59:19 am
content: The info is there on their site, it's just in Chinese.http://www.mblock.com.cn/products.php?KindID=4&ID=72

author: CaCtus491
author_rank: Newbie
timestamp: February 26, 2015, 01:36:59 am
content: I'm currently looking at a new project that would require a library that allows control of the Linsn cards from Linux. This thread is an excellent starting pointIs anyone still interested in working on such a library? I'm particularly interested in controlling brightness and dead pixel detection.As a longer term project, a Linux framebuffer driver would be interesting that talks via Ethernet directly to the receiving card - we can do away with the sending card entirely!http://www.linsnled.com/images/solutions/linsn-led-gigabit-network-card.png

author: firehopper
author_rank: Frequent Contributor
timestamp: February 26, 2015, 09:24:05 am
content: I have one of those adafruit type displays 32x32 xrgb. I'm currently driving it using a teensy 3.1 and smart matrix shield. they dont have any pwm to controll brightness.. thats handled by writing the display repeatedly.look at the smart matrix/fastled lib's to see how they do it.

author: CaCtus491
author_rank: Newbie
timestamp: March 05, 2015, 05:04:08 am
content: Thanks for the reply.In this case we're specifically working with Linsn 'sending' and 'receiving' cards. As described earlier in this thread, the USB port on the sending card is just a serial over USB interface. It is this protocol I'm interested in learning about and creating a library for to adjust brightness amongst other things.

author: azaghi
author_rank: Newbie
timestamp: March 04, 2016, 03:13:46 pm
content: I known it is an old post but i think my infos can be of interestI have a similar goal. I want to do basic commands and monitor from remote LINSN ledwall.I have found a different command sniffing serial in order to READ/WRITE the LINSN "register" and inquiring a chinese exporter:Register read and write mode of the specified register read and write, need to be a new version of sending card program (D5 or above) or ninth generation send cards to support this mode. Read and write using the same command.The command consists of 8 bytes, as follows:nbyte Value1 0xD82 0xD83 0x704 0x985 0-127 register where perform read or write6 bitmask field 1 - write that bit or 0 doesn't write that bit (0xFF write all, 0x00 only read)7 value to write8 accumulation (sum of bytes 5+6+7 casted in a byte)it returns with 4 bytes of data, the following composition:0xC5, bytes 2 and 3 is the same as the original value of the register, 0xC3With this command i can set some register like brightness of whole screenregister 98 brightness 0-255or reading register 112-115 i can get the status of the receiving card (the first one or what i put in register 39)but that reading status i can't get a sense... this is what i got as docuemntation from LINSN:Register112 - 115: to form a 32-bit registerBit0 -11: receiving card temperatureBit12: receiving card smokeBit13: receiving card smokeBit14 -23: receiving card humidityThe bit24 -31: receiving card operating voltagebut i get something like45 85 69 36 (hex value from register 112 to 115 in order). These values are in my office so internal enviroment and i can get values that seem good....If someone can solve this puzzle i will be very happy.Bye,Andrea

author: EdwinB
author_rank: Newbie
timestamp: November 04, 2016, 07:53:55 am
content: Quote from: amyk on March 07, 2014, 12:14:20 pmHow can i fix this problem, i have it also with 2 different screens.Kindly regardsEdwinB

author: tantrwm
author_rank: Newbie
timestamp: December 06, 2016, 10:26:16 pm
content: Hi GuysBrilliant, brilliant and very informative thread.It has inspired me to get back into this field (I have been out of it for since 1996!)I have recently bought a pile of second hand 64 x64 panelshttp://www.lighthouseaudiovisual.co.uk/eurolite-pixel-wall-panel-led-pixel-mesh-64x64-video-panel-50696-p.asp?gclid=Cj0KEQiA4JnCBRDQ5be3nKCPhpwBEiQAjwN1bmNvdxV85PFBVugZi3TdbNJxJzkLS6t_UceTfc4-500aAkgB8P8HAQalong with a Linsn SB-8 sender and numerous receiver (linsn).The problem i am having is that the SB8 has an RJ11 telephone style socket on the back instead of a USB port. The enclosure is labelled with USB but it is not there. On opening the enclosure the Rj11 socket seems to be factory installed and not a retrospective fit.I have trawlled the Linsn site and cannot find mention of this implementation.The system came with a rj11 to rs232 cable. Alas i have no computers with RS232 inputs. I purchased a USB to 232 adaptor but this does not seem to function or recognise the SB-8 when connected.Any help would be appreciated.Andrew

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: December 06, 2016, 10:43:15 pm
content: Is there any reason to think the Lighthouse units have any similarity to or compatibility with the Chinese units?The pics in the link look like the tiles have a completely different architecture

author: CaptainMurdoch
author_rank: Newbie
timestamp: February 17, 2017, 09:46:04 pm
content: Did anyone ever make any progress in deciphering the protocol or packets used between LED Studio and the receiver boards when not using a sender card? I work on an Open Source program called the Falcon Player (aka FPP) available viahttp://FalconChristmas.comFPP can currently be used to drive the LED panels directly from a Pi or BBB using a couple different Open Source libraries, but I would like to add support for driving Linsn receiver boards directly over Gig-E as well. I already have code to drive ColorLight receiver boards directly over Gig-E, but they use a different protocol.I'm not currently interested in configuring a sender card, I would like to bypass the sender and send packets directly to the low-cost receiver boards.I have been able to look at the packet capture posted earlier in this thread as well as some others I have performed and I made a simple script to take the data and put it into a raw data file which can be viewed using ImageMagick or any other program that can display raw RGB data. The image is discernable, but not exact. The Linsn protocol is not as simple as the ColorLight protocol which uses one packet per row of display. The Linsn protocol appears to pack the data together to have a more efficient packet-per-frame count, but it also appears to be padded or encoded in some way because the data in the file does not match the colors on the actual computer screen or LED panel.I have written some test code and am able to make the LED panels blink by sending packets from Linux to my RV908T, but the panels don't display any correct data because I am not formatting the RGB data correctly in the packets.Has anyone else made any more progress on this, or is currently working on or interested in driving the Linsn receiver cards directly?

author: james_s
author_rank: Super Contributor
timestamp: February 18, 2017, 08:20:09 am
content: This thread reminds me a year or two ago I drove down the freeway and a huge LED video screen in front of a casino was displaying the Win9x desktop with an error that the program had stopped responding.Those screens are obnoxious though. I wouldn't mind them except they're SO bright at night that it's blinding. They really ought to have a light sensor with a night mode and maximum allowed brightness if they're along a road.

author: rankink
author_rank: Newbie
timestamp: June 26, 2017, 04:19:41 am
content: Does anyone have any active questions regarding LINSN sign architecture at this point? I just saw this and have spent a bit of time focusing on these cards.

author: zamboni
author_rank: Newbie
timestamp: June 27, 2017, 09:46:47 pm
content: Quote from: rankink on June 26, 2017, 04:19:41 amhi, yes I am just starting to looking at the LINSN products such as RV908 receiving cards and very interested to find out the communication protocol and whether it is possible to control these using custom hardware (RPi/BBB/FPGA/etc)?

author: fpgaarcade
author_rank: Contributor
timestamp: July 09, 2018, 09:58:43 am
content: I've got a bunch of p3 64x64 modules with an RV908 rx card. I've also got the video processor, sender and contacts with the factory (kinda).My aim is to drive the RV908 direct from an FPGA.Has anybody made any progress figuring out the protocol, or is it time to get the logic analyzer out?/Mike

author: tyalie
author_rank: Newbie
timestamp: December 17, 2024, 12:48:51 pm
content: Hi,I started RE'ing the protocol for the funsies so that I could write a linux driver for it and I think I've gotten quite far.I've so far only looked at the protocol they speak over Ethernet, but the way they configure the system mirrors the way they do it over serial. So the information I gathered can easily be applied for serial too I believe.You can find the documentation as a PDF here (if you have improvements either wording or content, please write me an issue)https://github.com/tyalie/LinsnLED-eth-protocol-docs/releases/tag/nightlyAnd the Linux driver (currently very rough) here:https://github.com/Mimoja/LinsnLedSenderThis is a user space linux driver, that is a GStreamer backend. So using gstreamer you can route basically anything that has a video out into it.