Saturday, April 13, 2019

DIY laptop: LCD

To pick up on the DIY laptop project post from a year ago. Since then, I gradually developed an aversion to the idea of buying a p5x. Besides, it would be fun to build a piece of hardware for a change from software. My standard was still 15" Thinkpad T61/T500. Coffee Lake and 300-series chipsets having come out, I searched for Thin Mini-ITX motherboards with a 300-series chipset and an embedded DisplayPort output. There aren't many, and there are no consumer-oriented ones so far, but some AsRock and MiTAC industrial motherboards fit the bill. I bought a MiTAC PH12FEI through their German distributor, an unterminated ACES 88441-040 cable from Quadrangle, and the standard Thin Mini-ITX cooler, HTS1155LP, to use until I get around to making a thinner one (HTS1155LP is 26mm thick and the keyboard would have to go on top of it, making the body too thick for my taste). I decided on reusing stock parts as much as possible, so I bought a dead T500 (minus LCD screen) for $20. It would also provide the keyboard and trackpad connectors, which aren't otherwise readily available.

As it happens, A1398's Retina LCD is a centimeter too big to fit into T500's LCD housing. I briefly considered a completely custom lid, which would also save about 5mm in height, but hinges and hinge mounting would be a problem. Also that LCD model is now quite old. On the other hand, A1707 is narrower and there were indications that its LCD would possibly fit. Therefore, I obtained a cracked but functional A1707 LCD, p/n LSN154YL03, from a repair shop for $15, and it fits perfectly - there is not even 0.5mm of space anywhere. The crucial question for the whole project was whether I could get it to work with the motherboard. Panelook shows that this LCD, like the older one, has a 40-pin eDP interface. Mike of Mike's Mods had already shown that the older LCD does not need any special initialization, and I could reasonably expect that this would be the case with the newer one.

This was absolutely no fun to solder.

I could figure out most of the pinout from labeled test points on the controller board and from the pattern of ground lines. I was saved the trouble of figuring out which pair of differential wires was AUX, and the polarity, because schematics are now easily found on the global garbage dump internet. The LCD connector is, however, different from the older model, probably due to space restrictions in the smaller and thinner A1707. It is quite distinctive, and a search by pin pitch and count quickly turned up the part - it is I-PEX NOVASTACK 35-HDP 42p+4p, p/n 20698-042E-01, or an equivalent. It goes without saying that this part is not carried by the usual distributors. I resorted to scavenging them from replacement LCD "cables" (actually a small flexible PCB with two of these I-PEX plugs on opposite sides) sold on eBay. I figured that at the minimum I had to connect power, HPD, AUX and EDP_PWR_EN lines to get the LCD up and running. The controller apparently needs +5V and +3.3V, but I could take both from the motherboard's LCD power voltage jumper. As for EDP_PWR_EN, I connected it to one of the CABLE_ID pins of the motherboard's eDP connector which always has +3.3V on it.

First I carefully removed one of the plugs with a hot plate and tried soldering wires directly to the plug's pins, but the plugs' plastic is very weak mechanically and instantly melts if accidentally touched by the soldering iron. I had better luck with soldering wires to the flexible PCB with the remaining plug. I had to use superglue to hold down the three AUX wires after they were soldered, because (another lesson learned) a careless swipe can easily tear off a contact pad off the flexible PCB. It took a few hours, but the connector worked and Windows detected the LCD as 2880x1800, device name APPA031, meaning I can proceed with the project. The next big hurdle is the heatsink mod.

Saturday, December 9, 2017

DIY laptop

Some time ago, laptops have displaced desktops as primary machines for many, perhaps most, users who don't go in for high-end gaming, and I am no exception. Now my trusty Thinkpad T500 has been getting a bit long in the tooth, and recent models coming on the market have been less than inspiring — I had hopes for Thinkpad Retro, but it turned out to be just a very expensive T470 with a better keyboard — so I was toying with the idea of a DIY laptop. This post is a dump of my research (such as there was) and considerations pertaining thereto.

My list of requirements for a DIY laptop is

  1. good 15" display
  2. good keyboard
  3. powerful: good upgradeable CPU, lots of memory
  4. be presentable and approach laptop-class size and thickness

1. For the first point, there is nothing better than the LP154WT1-S* or LSN154YL0* "retina" LCDs that are installed in MacBook Pro 15.4" A1398 models. Like my T500, these are 16:10, a rarity in an age when every other maker has given up and is putting 16:9 (or even wider) movie panels into their laptops. I (and a lot of other people) need the laptop for work, not for goddamn movies! Anyway. These panels have a standard 30-pin eDP interface, but use a rare connector part need a custom board for the lighting controller/power supply. Fortunately for the DIY laptop project, a couple of hardware geeks have figured it out and shared schematics, part numbers and so on. Replacement panels can be bought on panelook and eBay; a bare panel costs $160-$180 and would need diffusers and backlight LEDs, while a complete display assembly is now north of $300 and isn't usable as such anyway due to branding. However, diffusers and backlights from MBPs with totaled LCDs aren't difficult to find. MBP's complete display assembly is 7mm thick in the thickest place — the bulge with the logo — so 5mm is probably a reasonable target thickness for a DIY display assembly.

2. Replacement classic 7-row Thinkpad keyboards with trackpoint are excellent quality, cheap and easily obtainable, and being so popular other hardware geeks have figured out how to connect them to computers. The trackpoint has a PS/2 interface, but the keyboard itself needs a microcontroller with firmware to read the key matrix and generate appropriate messages. This calls for a custom board, but any DIY laptop would need one, so it's not a big deal. The biggest problem with the keyboard is that it has to be screwed to the case, and the geometry can get tricky. More on this later.

3. This basically means socketed server-grade CPUs and slotted memory, and rules out soldered Atom CPUs, Celerons etc. Discrete graphics cards are probably out of the question, but modern integrated graphics should be good enough if you aren't editing video or playing high-end games.

Cool, but not really what I'd like to pack around.

4. The requirement of laptop-class thickness (say less than 40mm) drastically limits one's choices. A motherboard with DIMM memory is already a hair above that limit by itself; add 5-6mm for the display, 5-6mm for the keyboard and a couple millimeters for the case, and you're looking at something over two inches thick. Barring completely impractical options, this means Thin Mini-ITX motherboards with SoDIMM memory. The motherboard with all components (including memory) is constrained by standard to be at most 20mm thick, and a few millimeters must be allowed for bottom side stand-offs. Unfortunately, the Thin Mini-ITX standard seems to be dead in the water. There are few products on the market that support eDP and Skylake/Kaby Lake (Socket 1151) CPUs simultaneously, and nothing at all for AMD; about the only consumer-grade choice is Asus Q170T and its variants (the V2 upgrade, which is apparently not yet sold anywhere, has a bonus "disable ME" jumper — good to have even though firmware geeks have learned how to turn it off on the firmware level like the big boys in the spy agencies do). For cooling a CPU with interesting (read: more than 15W) TDPs, passive heat sinks are out. Given the stringent height limit, the most reasonable solution I have discovered is Intel HTS1155LP, targeted at half-unit rack servers. Its thickest part — its off-board heatsink, connected to the CPU plate with three heat pipes — measures 26mm. If this turns out to be too thick, heatsinks can be modded with some care.

The basic elements of the design are thus: 16:10 15" display, Q170T motherboard with Socket 1151 (up to i7-8xxx), up to 32GB DDR4-2133 SoDIMM DRAM and a M.2 NVMe SSD, HTS1155LP heat sink, one or two custom boards for display connectors, keyboard controller, battery controller/regulator and incidentals. The tricky part is to find a suitable geometry of all the key components. After some consideration and scribbling some layouts, I have settled on one where the motherboard's I/O shield faces backwards, and the heat sink sits under the left palm rest. (Other options either sacrifice 6-7mm of thickness as the keyboard goes on top of the heat sink, or sacrifice 20% of the heat sink, which I'm not willing to do.) A millimeter of cork or similar thermal insulation on top and bottom of the heat sink should suffice to keep surfaces at reasonable temperatures as long as the fan is working. The hot-air outlet is on the left side. Since the design uses the Thinkpad keyboard, it might as well use the Thinkpad palm rest (with its PS/2 trackpad), the top bezel, and the matching display bezel from a dead "donor" laptop. The keyboard is located mostly above the motherboard, where it can be supported by HTS1155LP's motherboard mount via some struts. Other keyboard mounting holes can be arranged to fall outside motherboard footprint. The bottom of the body (as well as the top of the display assembly) can be cut out of 1mm sheet aluminium, folded, welded together and spray-painted with plasti-dip or similar finish at an auto body repair shop. Body thickness is then 30-31mm — 1mm/case/+1mm/insulation/+26mm/heat sink/+1mm/insulation/+1-2mm/palm rest/. With a 5-6mm display assembly, this is, of course, nowhere as thin as today's ultrabook butter-knives, but neither is it monstrous; T-series Thinkpads measure around 34mm depending on model. As for peripherials, one can add them to taste — front ports, SD and smart card readers, NFC, wi-fi, broadband modem, etc. For the battery, laptop batteries are based on standard 11865 3.7V 3400mAh Li-ion elements anyway, so one can add as many as fits one's desired weight. Six will give 75Wh for 300 grams.

Wednesday, April 25, 2012

How to present to an executive

Good article by Gray Knowlton, hope it will come in useful some day.

Tuesday, April 24, 2012

Three excellent articles about the state of IT

Frighteningly Ambitious Startup Ideas (Paul Graham)

The Jig Is Up: Time to Get Past Facebook and Invent a New Future (The Atlantic)

This Tech Bubble Is Different (Bloomberg Business Week)

Choice quote: "The best minds of my generation are thinking about how to make people click ads," [Hammerbacher] says. "That sucks."

Friday, January 20, 2012

Russian programmers

Russian programmers got a nice plug over at Marginal Revolution in the comment section:
My experience with Russians are that they are the best hackers. They trust themselves, they are self-contained and they work with meager resources and really sweat the details. I’ve worked with a few and I would love for all of my code to be eyeballed by a Russian programmer who’d make it work in less memory. I like the fatalism built into Russian engineering, makes stuff robust.
Being one, I heartily concur. Thanks!

Sunday, July 3, 2011

LINQ Expressions and Reflection.Emit: an uncomfortable union

The other day I needed a component for a project of mine, which would rewrite methods into state machines like the CTP C# compiler does for async methods. The rewriter would accept a callback to identify the sites where a continuation must be created, and another one to emit glue code for the site using two primitives: SAVE_STATE() which returns the continuation delegate and RESTORE_STATE() which returns the value passed to the continuation. This approach permits the users of the rewriter to avoid the overhead of saving and restoring state when the continuation turns out to be unnecessary (in async terms, when the awaited thing is already complete). The new CTP compiler implements this optimization. My component would eventually have to work with IL methods either via Reflection.Emit or Cecil, but I thought it would be interesting to make it work with LINQ Expressions first. Besides, the DLR has a similar rewriter for yield which I could scavenge for useful hints. The DLR rewriter uses a nested lambda to create the 'environment', shifting the work to the LINQ Expression compiler (EC). Probably because of permission issues, EC does not create new closure classes and instead uses a thinly veiled object[] to store closure locals. I did not want this, I wanted to generate a proper closure class. After all, EC can compile a lambda expression into a MethodBuilder!

Although I more-or-less made it work, I must report that LINQ Expressions don't work all that well with Reflection.Emit:

  1. A LambdaExpression cannot have parameters of unbaked type. EC appears to have no problems with this, but Expression.CreateLambda uses generic lambda factories and an unbaked type cannot serve as a type argument. One must have the lambda accept a suitable base class or object.

  2. It is impossible to generate a call to any method which has not been 'baked' because LINQ Expression constructors insist on validating a method's parameters and call MethodBase.GetParameters(). This extends to object construction as Expression.New validates constructor parameters. These two problems are very obnoxious and make any serious use of LINQ Expressions with Reflection.Emit impossible.

    As a side note, I find it puzzling and inconvenient that MethodBuilder does not expose its parameter list.

  3. EC has no problems emitting constants referring to a TypeBuilder or a MethodBuilder, but one must tell Expression.Constant the correct types, viz. Type and MethodInfo. Otherwise EC happily emits casts to TypeBuilder which blow up at runtime. Just a minor gotcha, but still.

  4. There is no DelegateCreationExpression. This is strictly speaking not related to Reflection.Emit, but it is annoying to have to generate a call to CreateDelegate, complete with casts and stuff, instead of a ldftn-new combo.

  5. EC cannot compile lambda expressions into member methods even if the method signature is compatible. The target method has to be static, period.

This was a useful excercise and working directly with IL should not be much more complicated.