ESC
其他 9 分钟阅读

Show HN: Hacking a $20 4G wireless hotspot into a texting device

Show HN: Hacking a $20 4G wireless hotspot into a texting device

来源:Hacker News

One thing became clear to me quite fast - I was going to have to add a custom PCB. I wasn’t exactly sure what the MF800 had on-board, and I never did end up opening the shield can - but I am fairly certain there is no 5V booster on-board.

Because of the physical sizes, which we will go over further in the post, the USB connector will end up chopped off - so we need a way to handle that too.

The final PCB ended up handling the USB host mode power, USB host/device mode switching, display power and display signal level conversion.

I ordered the PCB along with assembly. And because 2 sided assembly is expensive, I made a few compromises to fit all the components on one side. The non-component side is used for the solder points for the PCB-to-PCB connections.

All files can be found on GitHub, but in short the PCB consists of:

The MF800 is quite a bit bigger than other opensticks, partly because of the battery it has to include, partly because of it’s slop nature.

So to fit inside a Clicks case, we either orient it verticaly and and up with a humongous abomination, or we trim the pcb to fit horizontally.

Notice that my right cut (on the bottom picture) cuts off the battery connection line, so this will have to be patched up later.

Cutting the PCB went unexpectedly well. The device booted up immediately and everything seemed to work. Turns out there really were no crucial lines going through those areas of the PCB.

Only things I didn’t test were the USB connection and the 4G modem. The modem I was 99% sure wouldn’t be an issue as there is no reason to route anything for it under those areas - but regarding the USB I was worried that I hadn’t maybe nicked the via.

I decided to reuse the pads from the old display. I don’t really know why anymore - possibly because my initial ideas was to use a rigid flex PCB and solder it similar to how the original display was. (which I decided against immediately upon seeing the prices)

Looking at all this now, it seems very dumb. I should have used the labeled pads next to the unpopulated micro SD connector. Note that never did check if these were shared with the SIM card though.

Since I could boot the device and I had the original android device trees, I extracted which pins were used for the display SPI. I then tested those with gpioset to make sure that I was indeed correct. Same goes for the power supplies (although I tested those by disabling them in the device tree and rebooting) and grounds.

The first thing I wired and checked were the power supplies followed by the USB. This is because I could test this as an isolated unit. I was also more skeptical about this because it involved a bit of circuitry on my part as well as that iffy via.

Of course, it didn’t work initially. After probing around the pads and seeing that all the voltages were OK I noticed in my laptop’s dmesg that it TRIED to enumerate - meaning something was going on.

I also noticed that it says “high-speed”. This caught me a bit off guard. I didn’t expect it to use “high-speed” USB. My first thought was that the wires were too long. But before shortening them, I tried a quick fix - twisting them more tightly - and it worked 😲!

Immediately following this success, I tried to get the other direction working. This took some time. Turns out, not all aliexpress adapters correctly wire the CC lines. The keyboard did work immediately, though - only issue is I was afraid to test with it first in case something was wired incorrectly.

Before wiring the SPI lines to the display, I wanted to check if I had correctly reconfigured my device tree. I knew the pads were correct from the earlier testing, but there is quite a lot which can go wrong here.

spi@78b9000 { compatible = "qcom,spi-qup-v2.2.1"; reg = <0x78b9000 0x500>; interrupts = <0x00 0x63 0x04>; clocks = <0x13 0x41 0x13 0x36>; clock-names = "core", "iface"; dmas = <0x6d 0x0c 0x6d 0x0d>; dma-names = "tx", "rx"; pinctrl-names = "default", "sleep"; pinctrl-0 = <0x84>; pinctrl-1 = <0x85>; #address-cells = <0x01>; #size-cells = <0x00>; status = "okay"; spidev@0 { //compatible = "linux,spidev"; compatible = "rohm,dh2228fv"; reg = <0>; spi-max-frequency = <16000000>; spi-cs-high; }; }; For example, qualcomm drivers are sketchy and the commented out compatible won’t actually export the spidev, so we scam it with this the dh2228fv compatibility.

Using the spi-pipe utility running in a loop, I was able to measure voltage change on the MOSI and CLK lines - which was enough for me to conclude that something was happening. I would, of course, prefer to do this with a scope or a logic analyzer - but I didn’t have any of those at hand.

Encouraged by the major success of power supplies and USB, I carelessly connected the display into the PCB (while the device was on 🤦).

Immediately something happened to the display and I was sure I broke it. Fortunately nothing came of this and the display was fine. (This actually happens every time I turn on the device. I don’t yet know if I should be concerned 😬.)

Once I reassured myself that nothing bad had happened, and that nothing was smoking or overheating - I proceeded with trying to get the display to work.

After an hour of slopping through this with AI python code I was absolutely nowhere. There were multiple possible points of failure. Level converter, bad routing, contacts, etc…

Turns out, as is quite common (IDK why), the qualcomm driver doesn’t handle the CS well (or correctly - or maybe it does but for other use cases). In any case, I tried again the same test script, but this time toggling the CS pin manually (via libgpiod) - and it actually worked.

I was immediately dissapointed with the everything. From the “electrical” wire I used to connect the power supplies to the sketchy tiny magnet wire I used for the signals all the way to the twisted ground I wrapped around MOSI and CLK (which seemed to do nothing) - so I decided to rewire everything once more.

This time i used magnet wire for both signals and power, but this one was quite a bit thicker and also kept position once bent. I didn’t rewire the USB data lines though, as the pads on the main board look very iffy.

All the previous tests were done with just dumb python scripts, but the real way forward is with a kernel driver. There are quite a few drivers available, but the one I picked is ardangelo’s sharp-drm-driver. My reasons for wanting a DRM driver are as follows:

This worked almost immediately. I did have to playing around with CS and it’s active high default.

For probably the first time in my life I didn’t have any issues compiling the kernel module and running it. The mystery kernel I was running was a 6.12.1-msm8916 one with modules enabled. It had a .config file present which I took.

Next I downloaded the mainline linux 6.12.1 kernel and hoped that there weren’t any (or significant) changes. This ended up being enough, and after a few small patches to the driver the thing just worked.

Below is what the device tree ended up looking like. Notice that the CS logic being handled by the display driver.

`spi@78b9000 { compatible = “qcom,spi-qup-v2.2.1”; reg = <0x78b9000 0x500>; interrupts = <0x00 0x63 0x04>; clocks = <0x13 0x41 0x13 0x36>; clock-names = “core”, “iface”; dmas = <0x6d 0x0c 0x6d 0x0d>; dma-names = “tx”, “rx”; pinctrl-names = “default”, “sleep”; pinctrl-0 = <0x84>; pinctrl-1 = <0x85>; #address-cells = <0x01>; #size-cells = <0x00>; status = “okay”;

sharp_drm@0 { compatible = “sharp-drm”; reg = <0>; spi-max-frequency = <4000000>; cs-gpios = <0x49 18 1>; }; };`

Standard linux console login prompt showed up

Standard linux console login prompt showed up

Issue now is that the driver just rounds pixel color under some value to black, above that to white (or inverted, depends on parameters). For text (or if you do the visuals yourself in your app) this works great - but for a general purpose solution where you want to play videos or show images - this looks like ass. The fix for this is to add dithering to the driver.

I added a custom sys value which allows the user to enable dithering, as well as to pick which algorithm they want:

All the initial functionality was left intact.

You can find more information about this, or the DRM driver patches on the project’s GitHub repo.

With everything on my table and working, mainly meaning the dimensions are set and can be measured, I jumped into modeling the near-final case which I can hopefully put into the keyboard case without worrying about breaking anything.

This was kinda sketchy since apple doesn’t give dimensions of how far the USB-C connector is inside the iPhone - but I got around this by measuring apple standard USB-C cables (which fit snug up to the device) and interpolating from there.

This print still wasn’t particullarly useful but served it’s purpose to confirm that the USB connector dimensions (among others) were measured correctly.

Also, 2 sidewalls didn’t print correctly and while modelling (this was before I receive’d one visible in the pictures) I didn’t have a display (except the one bonded to the devkit PCB) to model off of, so the cover is lacking.

This is what ended up being the final enclosure. Mostly everything fit correctly. I first whipped up a quick test held together by kapton tape.

This was the point at which, becuase of some ongoing life stuff, I temporarily lost access to a big chunk of my tools (mainly the 3D printer but also other stuff).

My hand being forced, I decided to hot glue the case together instead of printing a final final one which clips together.

I also forgot about the power button, which despite being on the PCB and working - didn’t get a case cutout and a plunger. This was solved with a small hole and a pin. Very ugly but it works.

Now the big boy moment - cutting down the keyboard case with no tools. It went about as well as you can expect. Though I made sure to cut less than needed so that I can sand it down and make it look pretty once I get my gear back.

It realistically doesn’t look that bad, but the edges could use some cleaning. The case hot glue protrusion is a bigger issue.

With the magic of top-down photos I have hidden most of this from you.

I forgot to take photos while assembling this. It’s exactly the same as before plus a 4G flex PCB antenna which I soldered to the PCB and glued below the display on the top half of the enclosure. There is now also a mini SIM in it’s slot.

The android device trees I copied from the device come predefined with the battery and charger configurations. These are also more advanced than the ones offered by the mainline linux i’m running.