Sunday, April 17, 2016

Yamaha DGX-620 LCD Repair/Retrofit

UPDATE: Ulrich Borghoff did his repair slightly different and sent in photos. Thanks Ulrich!

Here's a Yamaha DGX-620 keyboard with a broken LCD. Judging from the fact that there are quite a few videos and tutorials on how to exchange a broken LCD with the proper spare part, I'd reckon these LCDs break quite easily and often.

 (Broken LCD)


(Original LCD module: The slightly kink in the flexfoil is enough to ruin the module, this slight damage is, unfortunately, not repairable.) 


I was a little surprised to get a quote of 130€ ($150) for the replacement (Yamaha Part # WG299100), and I was looking for a replacement that's cheaper. As this is a fill-in instrument, and long out of warranty, I wouldn't mind not getting the original part. Also I don't mind the tinkering.

Enter Pollin, a company selling electronic remnants, such as bags with 1kg of capacitors, sold as “perfect for tinkering”. By chance, they sell a “LCD-Modul NAN YA LTC79H202T50K, 240x320” (order #121307, €4/$5) which, on closer examination, is electrically 100% compatible to the Yamaha display. Only with a slightly different, smaller shape, and with a different pinout. Also, they sell the exact same flex-cable that Yamaha uses to connect the LCD to the CPU board: Flexprint-Kabel AXON FFC1.00A14/0200L5-5-10-10 (#562251) (€1).


(Pollin: Product Page)



(cheap replacement LCD)



Looking into the datasheet of the LCD provided by Pollin and the Yamaha DGX-620 service manual easily found online, it's clear that electrically the display is compatible.

(Yamaha)

(Pollin LCD Module)

FR (first row) is FLM (first line marker), LP (line pulse?) is CL1 (data latch), XCK (x? clock) is CL2 (shift clock). Everything else has identical designators. Sanding off the back of the replacement LCDs PCB a little to have good bonding to epoxy glue...

(replacement LCD, before gluing down flex cable)

(sanding off the back of the PCB and the white flex-cable, so that the epoxy sticks better, you can see the residue from a first attempt: The blue plastic on the flex cable didn't stick)

(jumper wires)

Ugly patching of wires from the 14-in cable to the pads on the LCD according to pinouts shown above. After soldering the wires (which is hard on the flexfoil, as the plastic melts and the copper traces of the flexfoil will move around, creating shorts) and emitting a few prayers to the deity of choice, a picture appears! :-)

(first signal on replacement LCD screen)

Then I added the display to the original plastic part from which I removed both the LCD logic and all the light spreading works. The complete LCD module almost fits in the cutout for the old glass, only a small plastic ridge had to be removed with a xacto-knive.  I had to add a small slot for the flexcable, to feed through and added a hole for the big blob of goo by which I glued down the cables so that they don't become loose.


(cutout for big lump of wires and goo)


The end result: A replaced LCD screen for €4. But I had to invest a few hours of work, which in this case I didn't mind.

(replaced screen on the Yamaha keyboard)



Update: As Ulrich pointed out, one can directly solder the cables for the LCD backlight to the cables going to the two-bin connector on the power supply on more recent models of the keyboard. Some onlder ones have high-voltage for an electroluminiscent foil, though, so beware.

Here are Ulrich's Photos:



Saturday, April 02, 2016

Superlux HMC660 Headset and PS 418-S Phantom Power Adapter

The HMC660 Headset made by Superlux is dirt-cheap, and not that bad, for the price. Certainly beats some other headphones sold for €39. But even though it has a XLR connector, it doesn't really work that well with phantom powered microphone inputs. That's because its Electret Capsule is directly connected to the XLR pins, which sometimes works, but generally doesn't.

From Chris’ Miscellanea

The microphone part is glued, but after heating it gently to about ~40..50 °C with a hair-dryer or a heating gun used for heat-shrink-tubing, it can just be pulled apart by hand.

From Chris’ Miscellanea

The proper way to adress the connection issue is to use a proper phantom-power adapter for electret microphones, luckily this taiwanese producer of cheap (and a little crappy) audio electronics also has something in store. The Superlux PS 418-S adapter!

Inside, this little marvel looks like this: Mostly through hole, one-sided PCB, waves-soldered.

From Chris’ Miscellanea

The schematics mostly adheres to the often copied "Schoeps" design, here's my attempt at the schematics.

From Chris’ Miscellanea

I think I got the type of Q1 wrong. It's probably wired as an emitter follower (the voltage gain of the drawn common emitter amp of 22x would be unreasonably high) with Q1 being a KSA1015 PNP Epitaxial Silicon Transistor. Q2 and Q3 are likely KTA1268
EPITAXIAL PLANAR PNP TRANSISTOR
.


The PCB is small enough to fit it inside one of the earcups of the HMC660. Just cut open the direct connection that go from the 6-conductor XLR & TRS cable (braided copper, yellow, green) to the 3 wires that make their way into the gooseneck (white, black, red).

From Chris’ Miscellanea

From Chris’ Miscellanea

Here's the PCB inside a piece of heat-shrink tubing, but in the end, I opted to just hot-glue the bare PCB into the cup. Also some foam (from inside the PS-418's small shipping box) was added to prevent the whole thing from rattling around.

From Chris’ Miscellanea


Here you go. 39€ + 19,90€ for a only halfway crappy headset ;-).

Wednesday, March 23, 2016

W&T 36201 Isolated USB to RS485 Interface: Fix "automatic" RS485 Transmit mode

Some time ago, I bought three used W&T 36201 isolated USB to RS485 interfaces. They have pretty good build quality and are intended to be mounted in control cabinets (on “DIN Rails”). You can see them in this photograph, it's the blue thing.

From Chris’ Miscellanea

And while I'm pretty impressed by their build quality, I found out that even for (normally pretty expensive) industrial kit, they get the control of RS485 transmission wrong.

RS485, in short, is a pair of cables named A and B which carry a differential signal. This means that the signal in one wire should always be the inverse of the signal in the other wire: If voltage on A increases, the voltage on B should decrease. The state of the bus is “1” when the voltage on B is higher than the voltage on A, and the state of the bus is “0” when the voltage on B is lower than the voltage on A. A RS485 bus, when idle, is kept at the level corresponding to a “1” bit by the termination voltage, which pull B to a higher voltage than A, keeping an impedance of 100 Ohms on the differential pair A and B.

When data is exchanged over the bus, the first thing being transmitted is the stop bit, at “0” level, then the first byte, ... until transmission is completed. Naively, one would think that a driver only has to supply the “0” level and let go of the wires, making the termination resistors pull them to “1” again.

Unfortunately, these resistors aren't typically able to do this fast enough, especially for higher baud rates, and active drive of the bus therefore must be maintained throughout the complete transmission.

Thus, we need some control signal that tells the driver IC when to turn on its output drivers, and there are several methods for this.

  1. some RS485 adapters cheat by only transmitting the “0” in full, and only output a very short “1” runt pulse to charge up the bus, leaving maintaining the idle voltage to the termination resistors,
  2. some RS485 adapters use a serial control line (RTS, DTR) as a control signal and
  3. many USB to RS485 adapters use a signal provided by the USB-UART for exactly this purpose.
2 has the downside that one typically has problems being fast enough in switching the control lines over USB, and 3 is obviously the preferred version.

Unfortunately the W&T 36201 interfaces only do 1 and 2, so I tried to modify them to provide for 3.

Here's a (very slow) 9600 baud transmission via the unmodified interface in "automatic" mode. The driver is only activated (blue) during 0-bits.

From Chris’ Miscellanea

The used USB to UART bridge fortunately has a TXEN pin (#16), which we jumper over to the line normally carrying the #DTR (inverted) signal that can be used to implement method (2). The chip is mounted on a separate small PCB which makes working on it pretty easy:

From Chris’ Miscellanea

From Chris’ Miscellanea

Unfortunately the polarity of TXEN is high-active, but as built the converter needs #DTR to go LOW to transmit. So we use a spare gate of the HC04 hex inverter conveniently located on the baseboard. One has to scratch open the very short trace between the pullup for the optocoupler and the via left to it.

From Chris’ Miscellanea

After this modification, set the device to computer-controlled transmit control (normally DTR, now TXEN). As can be seen on the scope, now the transmitter IC drives the bus for the whole duration of a character.

From Chris’ Miscellanea

Sunday, February 28, 2016

ASUS RT N12E Bootup

Debugging a problem with a ASUS RT-N12E 300Mbps Wireless N Router, I soldered a pin header to  J15 (next to the ethernet magnetics handling the yellow "LAN" ports).

Pinout is Vcc, GND, Tx, Rx. Vcc is the square pad, Rx and Tx as seen from the N12E soc. Port runs at 38400 bps.

Here's the bootup messages, just in case anyone is interested.

$ cu -l ttyUSB0 -s 38400
Connected.

========== SPI =============
SDRAM CLOCK:156MHZ
 ------------------------- Force into Single IO Mode ------------------------
|No chipID  Sft chipSize blkSize secSize pageSize sdCk opCk      chipName    |
| 0 c22016h  0h  400000h  10000h   1000h     100h   86   39      MX25L3205D/E|
 ----------------------------------------------------------------------------
Set 8196C PHY Patch OK

---RealTek(RTL8196C)at 2013.12.09-17:34+0800 version v1.1f [16bit](390MHz)

####return_addr: 0x05010000, root_bin_offset: 0x050dd012
Jump to image start=0x80500000...
decompressing kernel:
Uncompressing Linux... done, booting the kernel.
done decompressing kernel.
start address: 0x80003600
RTL8192C/RTL8188C driver version 1.6 (2011-07-18)



Probing RTL8186 10/100 NIC-kenel stack size order[2]...
chip name: 8196C, chip revid: 4
NOT YET
eth0 added. vid=9 Member port 0x10...
eth1 added. vid=8 Member port 0x1...
eth2 added. vid=9 Member port 0x2...
eth3 added. vid=9 Member port 0x4...
eth4 added. vid=9 Member port 0x8...
[peth0] added, mapping to [eth1]...
init started: BusyBox v1.13.4 (2014-09-18 18:08:32 CST)

##flash.c free apmib ##
Init Start...
wan_disconnect: option all

##system/sysconf.c free apmib ##

##flash.c free apmib ##
===== Set parameter for BSMI test=====
Init bridge interface...
wait for bridge initialization...
syslog will use 64KB for log(7 rotate, 1 original, 8KB for each)
route: SIOCDELRT: No such process
route: SIOCADDRT: Invalid argument
Init Start...
Init Wlan application...

##flash.c free apmib ##

##flash.c free apmib ##
update wps state to -1

WiFi Simple Config v2.9-wps2.0 (2014.09.18-10:09+0000).

Init Wlan application...

##flash.c free apmib ##

##flash.c free apmib ##
update wps state to -1

WiFi Simple Config v2.9-wps2.0 (2014.09.18-10:09+0000).

Register to wlan0
iwcontrol RegisterPID to (wlan0)
Register to wlan0

##system/sysconf.c free apmib ##
iwcontrol RegisterPID to (wlan0)
Init Firewall Rules....
firewall clean prerouting
firewall add iptables rule
No wan ip currently!
System TZ ENV = GMT-8

##system/sysconf.c free apmib ##
start infosvr
WLAN0_WLAN_DISABLED=0 ##flash.c free apmib ##
sh: ##flash.c: unknown operand
# Start httpd!
Start wanduck!

# <-- :-="" a="" b="" here="" rootshell="" s="">

MemTotal:          11144 kB
MemFree:            5164 kB
Buffers:             224 kB
Cached:             1128 kB
SwapCached:            0 kB
Active:             1672 kB
Inactive:            716 kB
Active(anon):       1036 kB
Inactive(anon):        0 kB
Active(file):        636 kB
Inactive(file):      716 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:          1044 kB
Mapped:              716 kB
Slab:               3064 kB
SReclaimable:        176 kB
SUnreclaim:         2888 kB
PageTables:          164 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:        5572 kB
Committed_AS:       2220 kB
VmallocTotal:    1048404 kB
VmallocUsed:         264 kB
VmallocChunk:    1048136 kB

# cat /proc/cpuinfo
system type : RTL8196C
processor : 0
cpu model : 52481
BogoMIPS : 389.12
tlb_entries : 32
mips16 implemented : yes

# busybox
BusyBox v1.13.4 (2014-09-18 18:08:32 CST) multi-call binary
Copyright (C) 1998-2008 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.

Usage: busybox [function] [arguments]...
   or: function [arguments]...

BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable.  Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as!

Currently defined functions:
arp, ash, bunzip2, bzcat, cat, cp, cut, date, echo, expr, false,
free, grep, gzip, halt, head, hostname, ifconfig, init, ip, kill,
killall, klogd, ln, ls, mkdir, mount, ping, poweroff, ps, reboot,
renice, rm, route, sh, sleep, sync, syslogd, tail, telnetd, top,
true, umount, vconfig, wc, zcip


Sunday, February 21, 2016

Linux/udev: Unbinding from one kernel driver, and rebinding to a different one. Automatically, using udev.

Quite a lot of USB devices claim to be a human interface device, the rationale being that you can access them on Windows without the need to supply your own "proper" driver.

Under Linux, one can easily unbind the usbhid driver from a particular usb device, but this gets tedious after a few dozen times. But there's a workaround using udev and a short script to rebind to a different kernel module.

First, create a udev rule, e.g. in /etc/udev/rules.d/99-rebind-driver.sh:


ACTION=="add", DRIVER=="usbhid", SUBSYSTEMS=="usb",
ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="00de",
RUN+="/usr/local/sbin/rebind_sysfs_driver.sh %p %k /bus/usb/drivers/mcp2210"



(all in one line)

Then use the following small script, stored as /usr/local/sbin/rebind_sysfs_driver.sh to do the actual work:


#!/bin/sh

if [ "$#" != 3 ] ; then
echo "Usage: $0 sysfs_path kernel_name new_driver_path" >&2
echo "" >&2
echo "To be used in udev rules:" >&2
echo "   RUN+=\"$0 %p %k /bus/usb/drivers/mcp2210\"" >&2
echo "which rebinds a particular device to a new driver." >&2
exit 1
fi

set -e
logger -t "$0" "Rebind device $1($2) to driver $3."

cd "/sys$1"
echo "$2" >driver/unbind
sleep 1
echo "$2" >"/sys$3/bind"



Sunday, November 29, 2015

Focusrite Scarlett 6i6 and Pulseaudio

Oh, pulseaudio, how do I love thee...

The Focusrite Scarlett 6i6 is a 2 Mic, 2 Line, 2 Digital input, 4 Line, 2 Digital output audio interface and is presented to the Linux machine as a 12 output, 6 input USB2.0 class compliant soundcard. Strange, but that's what it is. Now, pulseaudio, not very smart in the first place, gets confused and only ever wants to use this card as a "multichannel" output, with outputs 1/2 deprived of bass, and output 6 (typically mapped to the s/pdif output) being a subwoofer. Not useful when listening over headphones.

After looking through the non-existing pulseaudio-documentation regarding udev, and searching on the web, I've came up with a workaround. This is at least useful to use the card as a normal stereo output.

To get output on the 2nd headphone output, use alsamixer to map Master 2L and Master 2R source to PCM1 and PCM2. The same applies to the S/PDIF output (Master 3L/R).




Bug filed.

➜  ~  cat /usr/share/pulseaudio/alsa-mixer/profile-sets/focusrite-scarlett-6i6.conf 
; Based on native-instruments-traktor-audio10.conf

;
; Focusrite Scarlett 6i6 has 6 physical inputs/outputs
; Inputs
;  2x  Microphone/Line on front
;  2x  Line on back
;  2x  S/PDIF coaxial on back
; Outputs
;  2x  Headphone (Out1/2, Out 3/4) on front
;  2x  Line on back (Out 1..4)
;  2x  S/PDIF coaxial on back
;
; It's presented as a 6 input, 12 output interface to the PC, so
; we have to create some mappings. Actual routing is configurable
; in ALSA mixer. I prefer a 1:1 mapping to physical outputs.
;

[General]
auto-profiles = no

[Mapping analog-out]
description = Analog Outputs
device-strings = hw:%f
channel-map = left,right,aux0,aux1,aux2,aux3,aux4,aux5,aux6,aux7,aux8,aux9

[Mapping analog-in]
description = Analog Inputs
device-strings = hw:%f
channel-map = left,right,aux0,aux1,aux2,aux3
direction = input


[Profile output:analog-out+input:analog-in]
description = Analog Duplex
output-mappings = analog-out
input-mappings = analog-in
priority = 100
skip-probe = yes

➜  ~  cat /etc/udev/rules.d/99-pulseaudio-local.rules 

SUBSYSTEM!="sound", GOTO="pulseaudio_local_end"
ACTION!="change", GOTO="pulseaudio_local_end"
KERNEL!="card*", GOTO="pulseaudio_local_end"
SUBSYSTEMS=="usb", GOTO="pulseaudio_local_check_usb"

LABEL="pulseaudio_local_check_usb"

##
# The Focusrite Scarlett 6i6 only runs as 12 playback and 6 capture channels!
# (mappable using the internal mixer)
# Bus 002 Device 004: ID 1235:8012 Focusrite-Novation Scarlett 6i6
##
ATTRS{idVendor}=="1235", ATTRS{idProduct}=="8012", ENV{PULSE_PROFILE_SET}="focusrite-scarlett-6i6.conf"

LABEL="pulseaudio_local_end"

Monday, November 02, 2015

Behringer "X-Air" XR18 Teardown

Here's a teardown of a Behringer XR18 (sometimes spelled X18R) Compact Digital Mixer. There's a full album with all pictures I took.

To open the device, you have to remove the rubber bumpers on the sides (which can be replaced with rack-ears). Two of the tiny screws on each side don't have to be removed, this lets the bottom shell of the case keep more mechanical strength. Then two halves slide open, an L-shaped top-plus-front-side part, and the rest enclosing sides, bottom and back side.

From Behringer XR18 Teardown

In the inside, you can find the power supply, a digital board (+ analog outputs) and a stack of three boards mainly responsible for the analog mic/line inputs. The topmost board (which I didn't remove because it's attached to the case by all the XLR connectors) mainly has connectors and the headphone amp. The middle board carries circuitry for the actual mic preamp. The bottom board has a few opamps and the ADCs for the analog inputs.

From Behringer XR18 Teardown

Power Supply


Generally the manufacturing is pretty nice and everything looks produced to tight tolerances. I could see no gaps, nothing loose. The only downside I see is the powersupply and the mains connector: The supply gets very hot during normal operation (and no devices running on phantom power were connected during the few hours it was in operation before opening the case). The mains connector is isolated with an additional layer of sticky tape, and fastened with hot glue. This looks rather sloppy.

From Behringer XR18 Teardown

Interestingly Behringer (the Music Group) designed their own supply!

From Behringer XR18 Teardown

Digital/DSP (+analog output) PCB

People are generally annoyed by the lack of support for WPA/WPA2 with the builtin WiFi access point. It's essentially a Microchip MRF24WG0MB Module

From Behringer XR18 Teardown

The USB audio interface seems to be powered by a XMOS 16L7C10 1000 MIPS, 128 kB SRAM, 32-bit multicore microcontroller and its associated Microchip USB3340 Enhanced Single Supply Hi-Speed USB ULPI Transceiver.

From Behringer XR18 Teardown


The actual user-facing functionality obviously is orchestrated by a Freescale MCIMX253DJM4A i.MX25 400 MHz, single core, ARM 926EJ-S, the network is connected with a standard Microchip LAN8720A Small Footprint RMII 10/100 Ethernet Transceiver.

From Behringer XR18 Teardown

From Behringer XR18 Teardown

The eight XLR analog outputs are fed by a CS4385 Cirrus Logic octal 24 bit DAC, the CS4272 Cirrus Logic 24 bit stereo audio codec feeds the headphone output and digitizes the line input (ch 17/18). [it's the only ADC/DAC left after accounting for the 8 analog outputs and 16 analog inputs and corresponding octal converters].

From Behringer XR18 Teardown

Routing of signals probably is taken care of by the logic inside this Xilinx XC6SLX4 (Spartan 6) FPGA. It's the smallest of the Spartan 6 family -- and while it has 216 kBit of blockram and 8 "DSP Slices" which feature multipliers, adders and accumulators, I doubt that it does any computational work. Maybe it scales the output level or so, though...

From Behringer XR18 Teardown

There's a truckload of New Japan Radio Corporation NJM4580 Dual Opamps used inside the XR18, and
a bunch of them seem to take care of driving the differential XLR analog outputs.

From Behringer XR18 Teardown

Mic/Line ADC


The most interesting chip on the ADC board (bottom-most in the three-board stack) is the Cirrus Logic CS5368 octal 24bit ADC. There are two of them, for 16 inputs in total. There are also a bunch of NJM4580 (1+1/2 for each channel), likely for a final level adjust and to drive the differential inputs of the ADCs.

From Behringer XR18 Teardown

Mic Preamp


The board with the mic preamps is rather interesting. The layout seems to be a conventional frontend using discrete transistors as first stage amplification and a NJM4580 as a differential amplifier. There are two Coolaudio V411 analog switches per channel to adjust the gain, and quite a few shift registers to provide the control inputs to the analog switches.

From Behringer XR18 Teardown

From Behringer XR18 Teardown

From Behringer XR18 Teardown

From Behringer XR18 Teardown

Connector PCB

The connector PCB is very uninteresting. One very thoughtful detail, though, is that they drilled holes beneath the XLR/TRS combo jacks. If you ever had to desolder one of those because the TIP of a TRS connector broke off you appreciate this. I did not remove this board, because it's held in place by dozens of screws on the XLR jacks.

From Behringer XR18 Teardown

A OPAMP labeled JRC8074A seems to be the headphone amplifier.

From Behringer XR18 Teardown






Monday, August 17, 2015

Logarithmic Sine Sweep for Impulse Reponse Measurements (in Python/Numpy)

There's quite a lot of software available to do impulse response measurements, e.g. for doing measurements on loudspeakers or electronic audio equipment. Some also use it to sample the impulse responses of rooms and halls to get realistic reverb.

To learn about the technique (on which one can find quite a few publications using google) I'm going to implement the analyses in python/numpy.

The first building block is a small script to generate such a sweep and which I've published, as usual, on github: https://github.com/vogelchr/sweep_analysis

Below you can find a spectrogram made using the magnificent baudline.

From Chris’ Miscellanea

Saturday, August 08, 2015

Full Disk Encryption with Cyanogenmod CM12.1 on a Samsung Galaxy S4 Mini

Update August 9th: Just skip to the last line of this post where we realize that we could have spared us all of the hassles and resize2fs from within the running android system ☺.


If you try to enable full disk encryption on Cyanogenmod CM12.1 using the normal settings menu (Security -> Encrypt Phone) it doesn't work, the phone will just soft-reboot and nothing will have happened.

If you "logcat" the debugging log of your phone (using adb logcat) within the huge amount of data, some hint about what might have gone wrong can be found:

➜  ~  grep Cryptfs logcat_encryption.txt 
I/Cryptfs (  199): Check if PFE is activated on Boot
E/Cryptfs (  199): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
E/Cryptfs (  199): Error getting crypt footer and key
E/Cryptfs (  199): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
E/Cryptfs (  199): Orig filesystem overlaps crypto footer region.  Cannot encrypt in place.
E/Cryptfs (  199): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
E/Cryptfs (  199): Orig filesystem overlaps crypto footer region.  Cannot encrypt in place.

On android, the footer that tells the operating system that an partition is encrypted resides on the end of the filesystem and it needs a little space between the logical end of the filesystem in a partition, and the physical end of the partition to be squeezed in when converting a phone from unencrypted to encrypted.

http://forum.xda-developers.com/nexus-4/help/looking-encryption-footer-t2676700

Running the recovery system (boot while keeping Volume-Up and Home pressed), we can have a look at the partition sizes and filesystem details. We learn that on my S4 mini, the userdata partition (mmcblk0p24) has a size of 5685231 1k blocks, and the /data filesystem claims a size of 1421307 4k blocks.

$ adb shell
~ # cat /proc/partitions
major minor  #blocks  name
(...)
 179       24    5685231 mmcblk0p24
~ # tune2fs -l /dev/block/mmcblk0p24 
(...)
Block count:              1421307
(...)
Block size:               4096

As 5685231-1421307*4 = 3, that's only 3 meager 1k blocks at the end of the filesystem, whereas the encryption footer needs a space of at least 16k, the allmighty internet tells me. So, let's build a filesystem that leaves 128kByte of free space on the end as I don't know if Android 5 has enlarged the footer from what the websites I had found claims, or if there's some alignment requirement for it. So I'll be generous. (5685231-128)/4=1421275.75 so I'll create a ext4 filesystem occupying 1421275 4k blocks:

~ # mke2fs -b4096 -T ext4 /dev/block/platform/msm_sdcc.1/by-name/userdata 142127
(note: I made a mistake, ch0pped off the 5!)
mke2fs 1.41.14 (22-Dec-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
35600 inodes, 142127 blocks
7106 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=146800640
5 block groups
32768 blocks per group, 32768 fragments per group
7120 inodes per group
Superblock backups stored on blocks: 
32768, 98304

Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 33 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

Do I really have to mention at this point that this will erase all your files? Alternatively one could try "resizefs" to resize the filesystem, but that program isn't included in my recovery. Anyhow, it seems to be prudent to try encryption on an otherwise virgin install, as one risks data loss anyhow when performing the encryption process and there are reports of phones not booting up correctly after encyption had been enabled.

Then reboot the phone, do a half-hearted initial setup of the device, configure a simple PIN for testing, and encrypt your phone. (I also enabled debugging so that I can run logcat again to catch errors).

$ grep Cryptfs logcat_encryption_newfs.txt
(...)
I/Cryptfs (  196): Check if PFE is activated on Boot
E/Cryptfs (  196): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
E/Cryptfs (  196): Error getting crypt footer and key
E/Cryptfs (  196): not running with encryption, aborting
E/Cryptfs (  196): Bad magic for real block device /dev/block/platform/msm_sdcc.1/by-name/userdata
D/Cryptfs (  196): Just asked init to shut down class main
D/Cryptfs (  196): unmounting /mnt/shell/emulated succeeded
D/Cryptfs (  196): unmounting /data succeeded
I/Cryptfs (  196): keymaster version is 2
I/Cryptfs (  196): Using scrypt for cryptfs KDF
D/Cryptfs (  196): Just triggered post_fs_data
D/Cryptfs (  196): post_fs_data done
D/Cryptfs (  196): Just triggered restart_min_framework
I/Cryptfs (  196): Using scrypt for cryptfs KDF
I/Cryptfs (  196): Enabling support for allow_discards in dmcrypt.
I/Cryptfs (  196): load_crypto_mapping_table: target_type = crypt
I/Cryptfs (  196): load_crypto_mapping_table: real_blk_name = /dev/block/platform/msm_sdcc.1/by-name/userdata, extra_params = 1 allow_discards
I/Cryptfs (  196): Encrypting ext4 filesystem in place...
I/Cryptfs (  196): Encrypting group 0
I/Cryptfs (  196): Encrypting from sector 0
I/Cryptfs (  196): Encrypting group 1
I/Cryptfs (  196): Encrypted to sector 1356288
I/Cryptfs (  196): Encrypting from sector 16777216
I/Cryptfs (  196): Encrypted to sector 16867328
I/Cryptfs (  196): Encrypting from sector 16874496
I/Cryptfs (  196): Encrypted to sector 17014784

The phone will now reboot and ask for the PIN you entered. Unfortunately this takes *ages*! But if everything is fine, you can now setup your phone to your heart's content and set up a real password to have a securely encrypted phone. We'll have to see how stable this encrypted phone will be in daily use.

From Chris’ Miscellanea

Update: I made a mistake and chopped off the "5" at the end, so my filesystem only occupies 1/10 of the available space and has a completely unusable size of 500 MB :-(. So, to not have to start all over again, I'll try to resize the file system in place.

Login to your android device, and check the filesystem size. Indeed /data is completely ridiculous at 500MB.

➜  e2fs  adb shell
shell@serranoltexx:/ $ su
root@serranoltexx:/ # df
Filesystem               Size     Used     Free   Blksize
(...)
/data                  553.0M   490.2M    62.8M   4096

Check the sizes of the underlaying block device, and the dmcrypt mapper:

root@serranoltexx:/ # cat /proc/partitions
major minor  #blocks  name
(...)
 179       24    5685231 mmcblk0p24
(...)
 254        0    5685215 dm-0

Indeed, the crypted partition is exactly 16kB smaller (the crypt footer) than the raw block device. So we can hopefully let resize2fs autodiscover the target size. Unfortunately, we cannot access the block device hosting /data, and we can't umount /data because the android framework is still running. So we use the same method as the volume daemon to shutdown most of android. (your device will not no longer react to user input on the buttons or touch secreen):

root@serranoltexx:/ # setprop vold.decrypt trigger_shutdown_framework
root@serranoltexx:/ # umount /data
root@serranoltexx:/ # e2fsck -f /dev/block/dm-0       
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
(...)
(fix problems as they appear here)
root@serranoltexx:/ # resize2fs /dev/block/dm-0
resize2fs 1.42.9 (28-Dec-2013)
Resizing the filesystem on /dev/block/dm-0 to 1421303 (4k) blocks.
The filesystem on /dev/block/dm-0 is now 1421303 blocks long.

I rebooted the phone the hard way via sync; echo b >/proc/sysrq-trigger.

Now /data is at the expected size of 5.5 GB.

➜  ~  adb shell df
Filesystem               Size     Used     Free   Blksize
(...)
/data                    5.4G   734.3M     4.7G   4096

Of course, now that we have found out how to resize an ext4 filesystem in place from within android, we realize that we could have made it that way from the beginning 😉. Without data loss. Just run the last 4 commands but using the physical emmc device and append the right number of blocks we need to resize2fs while the device is still unencrypted...

e2fsck /dev/block/mmcblk0p24
resize2fs /dev/block/mmcblk0p24 14221303

That should do the trick. Reboot and run the normal encryption process.

Tuesday, July 07, 2015

Public Service Announcement: Putty

A recent upgrade of sshd apparently broke my saved putty connections, which have a deprecated key-exchange protocol on the top of the "Algorithm selection policy."

It manifests itself as a long pause, showing a black putty terminal window, followed by the message: PuTTY Fatal Error: Server unexpectedly closed network connection.


The putty event window will show it being stuck in the "Doing Diffie-Hellman group exchange" phase.

From Chris’ Miscellanea

If you run your sshd in debug mode, you'll see that sshd isn't happy with the selection of the key exchange protocol.

➜  ~  sudo /usr/sbin/sshd -p 2222 -d
debug1: sshd version OpenSSH_6.9, OpenSSL 1.0.2c 12 Jun 2015
(...)
debug1: kex: server->client aes256-ctr hmac-sha2-256 none [preauth]
debug1: expecting SSH2_MSG_KEX_DH_GEX_REQUEST [preauth]
Hm, kex protocol error: type 30 seq 1 [preauth]
Connection closed by 10.120.102.56 [preauth]
(...)

From Chris’ Miscellanea

It seems that OpenSSH recently had removed an ancient method of key exchange, as is to be read on this thread on the misc@OpenBSD mailing list.

If you open putty 's session configuration and move the "Diffie-Hellmann group exchange" right to the bottom of the "Algorithm selection policy" (Configuration / Connection / SSH / Kex), everything works again.

From Chris’ Miscellanea



Sunday, March 29, 2015

SDM220 Power Meter, MODBUS, Python, RS485

The Eastron SDM220 is a very inexpensive one-phase power/energy meter, which can be readout via RS485. I got myself one to play with, and there are a few observations I wanted to write down.

From Chris’ Miscellanea


From Chris’ Miscellanea


From Chris’ Miscellanea


It's actually a pretty nifty meter, measuring power and energy in both directions, voltage and line frequency. Furthermore it outputs power-factor (cosϕ) and reactive or apparent power (which is basically the same thing, just represented differently).

One thing that cost me some time to resolve, especially as I used a selfmade RS485 adapter in the first place about the correctnes of which I was unsure are: The RS485 terminals are wired incorrectly, B and A are swapped, this has been verified with an industrial/commercial interface. Connectors 7, 8 and 9 are GND, A and B. In that order. If the link is idle, B will be positive with respect to A.

There's an existing modbus library for Python (pymodbus) which works perfect, so far. The serial modbus link is instantiated like this (if the modbus runs with parity = None).

    cl = pymodbus.client.sync.ModbusSerialClient('rtu',
        port='/dev/ttyUSB1', baudrate=9600,
        parity='N',stopbits=2,
        timeout=0.125)

The values stored in the device are actually IEEE754 floating point values, which can be converted to python floats very conveniently, they are fetched as two consecutive 16bit register, concatenated to a 32bit field, and then reinterpreted as the 32bit float:

    resp = client.read_input_registers(basereg,2, unit=1)
    return struct.unpack('>f',struct.pack('>HH',*resp.registers))

The documentation for the SDM220 is actually quite comprehensive, but it took me quite a while until I really figured out what they meant... So here are the register numbers I sucessfully used to get date off the device:

        # Symbol    Reg#  Format
        ( 'V',      0x00, '%6.2f' ), # Voltage [V]
        ( 'Curr',   0x06, '%6.2f' ), # Current [A]
        ( 'P[act]', 0x0c, '%6.0f' ), # Active Power ("Wirkleistung") [W]
        ( 'P[app]', 0x12, '%6.0f' ), # Apparent Power ("Scheinl.") [W]
        ( 'P[rea]', 0x18, '%6.0f' ), # Reactive Power ("Blindl.") [W]
        ( 'PF',     0x1e, '%6.3f' ), # Power Factor   [1]
        ( 'Phi',    0x24, '%6.1f' ), # cos(Phi)?      [1]
        ( 'Freq',   0x46, '%6.2f' )  # Line Frequency [Hz]


Tuesday, December 02, 2014

esp8266 firmware upgrade, odd baudrate in bootloader?

So, I also got one of those ESP8266 wifi/serial modules, which are pretty neat. Unfortunately mine seemed to come with an ancient firmware on it, and pretty unconveniently those didn't want to be re-flashed with newer software.

From Chris’ Miscellanea

The bootloader seems to initialize the modules' serial port to the pretty insane value of 76923 bps, so that in "programming" mode, the stupid windows-utility (or, for that matter, any program expecting standard-baudrates) will fail to communicate with the module.

From Chris’ Miscellanea

If you have a suitable serial cable (a FTDIchip FT2232 is what I used), you can calculate "custom dividers" for most uncommon baudrates, and use those instead of 38,4kBps (the "magic" baudrate indicating that the custom one should be used).

Base-frequency for the ft2232 is 60 Mhz, so we'll use a custom divisor of 780 (60Mhz/76923).

$ setserial /dev/ttyUSB0 spd_cust divisor 780     
$ cu -l ttyUSB0 -s 38400
Connected.

 ets Jan  8 2013,rst cause:1, boot mode:(7,7)

waiting for host

 ets Jan  8 2013,rst cause:1, boot mode:(7,7)

waiting for host

 ets Jan  8 2013,rst cause:1, boot mode:(3,7)

load 0x40100000, len 24444, room 16 
tail 12
chksum 0xe0
ho 0 tail 12 room 4
load 0x3ffe8000, len 3168, room 12 
tail 4
chksum 0x93
load 0x3ffe8c60, len 4956, room 4 
tail 8
chksum 0xbd
csum 0xbd

Interestingly, that seems to be only the bootloader of the module, after this, the device switches to the more common 115200kbps and responds to AT-commands, given that GPIO15=GND, GPIO2=Vcc, GPIO0=Vcc and CH_PD=Vcc. (pullups to Vcc via ~5kΩ resistor)

So, to get the windows-only updater to run successfully, we...
  • connect GPIOs and CH_PD as listed above (AT-Mode)
  • power up module
  • module will start bootloader with 77kbps, then change into AT-command mode, at 115200 bps
  • connect GPIO0 to GND (firmware download mode)
  • pulse CH_PD to LOW to restart module
  • firmware will restart, but bootloader does NOT go back to 77kbps
  • run firmware-upgrade in windows

From Chris’ Miscellanea

Now I'm upgraded to version 170901 (whatever that means).

AT+GMR
00170901


Tuesday, August 26, 2014

Building pyqwt 5.2.0 by manually installing the pyqtconfig.py module.

For playing with GNU radio I had to install quite a lot of dependencies to get all the modules to build, unfortunately there's currently a build issue with PyQwt, which are the Python bindings for Qwt, the Qt Widgets for Technical Applications.

Installation of PyQwt-5.2.0 fails with an error message of...
Requires at least PyQt-4.2 and its development tools.
==> ERROR: A failure occurred in build().
    Aborting...
...and this is because of the configuration script of PyQwt that tries to import PyQT's pqtconfig.py, that no longer is installed by PyQt 4.11.1!

There are a few bugreports to be found on the web, e.g.

To fix this, get yourself the pyqt-x11 source, then run the configure script as appropriate for your particular Linux installation...
[optiplex …/chris/AUR/python2-pyqt4/src/Py2Qt-x11-gpl-4.11.1]
python2 configure.py -v /usr/share/sip --qsci-api -q /usr/bin/qmake-qt4 Determining the layout of your Qt installation...
This is the GPL version of PyQt 4.11.1 (licensed under the GNU General Public
License) for Python 2.7.8 on linux2.
Type '2' to view the GPL v2 license.
Type '3' to view the GPL v3 license.
Type 'yes' to accept the terms of the license.
Type 'no' to decline the terms of the license.
Do you accept the terms of the license? yes
Found the license file pyqt-gpl.sip.
Checking to see if the QtGui module should be built...
Checking to see if the QtHelp module should be built...
Checking to see if the QtMultimedia module should be built...
Checking to see if the QtNetwork module should be built...

(...)
Creating pyrcc4 Makefile...
Creating Qt Designer plugin Makefile...
Creating pyqtconfig.py...
At this point, the proper pyqtconfig.py script has been created, install to the python site-package directory.
[optiplex …/chris/AUR/python2-pyqt4/src/Py2Qt-x11-gpl-4.11.1]
$ sudo install -m644 pyqtconfig.py /usr/lib/python2.7/site-packages/PyQt4/pyqtconfig.py 
Now, the pyqwt bindings can be built, e.g. by using ArchLinux's makepkg utility, using the AUR package.
[optiplex /home/chris/AUR/pyqwt]
$ makepkg
==> Making package: pyqwt 5.2.0-10 (Tue Aug 26 21:37:07 CEST 2014)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
(...)
==> Starting build()...
patching file qt4lib/PyQt4/Qwt5/qplt.py
patching file configure/configure.py
patching file configure/configure.py
Command line options:
{'debug': False,
 'disable_numarray': False,
(...)
cp -f ../../qt4lib/PyQt4/uic/widget-plugins/qwt.py /home/chris/AUR/pyqwt/pkg/pyqwt/usr/lib/python2.7/site-packages/PyQt4/uic/widget-plugins/qwt.py
make[1]: Leaving directory '/home/chris/AUR/pyqwt/src/PyQwt-5.2.0/configure/qwt5qt4'
==> Tidying install...
  -> Purging unwanted files...
  -> Removing libtool files...
  -> Removing static library files...
  -> Compressing man and info pages...
  -> Stripping unneeded symbols from binaries and libraries...
==> Creating package "pyqwt"...
  -> Generating .PKGINFO file...
  -> Generating .MTREE file...
  -> Compressing package...
==> Leaving fakeroot environment.
==> Finished making: pyqwt 5.2.0-10 (Tue Aug 26 21:40:25 CEST 2014)