August 21, 2018

T102HAAS.303 Considered Harmful For Linux

T102HAAS.303 Breaks Suspend


After upgrading my Asus Transformer Mini's BIOS to T102HAAS.303 suspend was completely broken. Closing the "lid" would cause some kind of suspend that cannot be disabled in software and from which Linux 4.15.0 cannot successfully resume from (actually it does resume but the display will stay blank).

This behaviour cannot be disabled in software by editing logind.conf or acpi-support or any of the solutions found on the web about disabling lid action. Messing about with acpi_osi didn't help either.

Downgrading from T102HAAS.303


If you are reading this after upgrading to T102HAAS.303 you probably want to downgrade. Unfortunately the firmware that ships with the computers, version 202, cannot be found on the Asus website. You can however find the 300 firmware if you click on "View all downloads" under the BIOS section. Download this file and put it on a FAT32 formatted USB drive then:

  1. Reboot, hold then ESC to enter Setup
  2. Find the Easy Update entry and press ENTER, starting the easy update program
  3. Navigate to your USB drive, it will be FS0 or FS1
  4. Locate the T102HAAS.303 file and press ENTER
  5. When the dialogue complains that the build date is too old type the word risky on the keyboard
  6. Select Yes on the dialogue that appears after
  7. Wait for the computer to reboot

The key to this process is the word risky which is an undocumented feature that by-passes the build date check, allowing you to downgrade. You just type this in when the error dialogue appears, there will be no text box or anything.

Re-enabling Hibernation


Downgrading will re-enable Secure Boot, which disables hibernation on Linux. Just disable it and hibernation will work again.

August 06, 2018

Ubuntu 18.04 on Asus Transformer Mini (T102H)

Installation


Create a USB drive with a single FAT32 partition then extract the installation ISO into it using 7z:

7z x /path/to/ISO -o/path/to/usb

Note that there is no space between -o and the following path.

Plug in the USB drive then turn on the T102H while pressing the ESC key. This will allow you to enter the settings menu and allow you to boot from USB. Select installation and follow the instructions until asked to reboot.

Xorg Setup


An immediate problem is that the display is portrait by default. Additionally the modesetting driver is used which has worse performance than the intel driver. Fix both of these issue by placing the following file in /usr/share/X11/xorg.conf.d/99-transformer.conf:

Section "Device"
 Identifier "i915"
 Driver "intel"
 Option "TearFree" "true"
 Option "DRI" "2"
 Option "Backlight" "intel_backlight"
EndSection

Section "Screen"
 Identifier "Screen0"
 Monitor "BuiltInLCD"
EndSection

Section "Monitor"
 Identifier "BuiltInLCD"
 Option "Rotate" "right"
EndSection

Section "InputClass"
 Identifier "BuiltInTouchscreen"
 MatchProduct "ELAN22A6:00 04F3:22A6"
 Option "TransformationMatrix" "0 1 0 -1 0 1 0 0 1"
EndSection

This sets the display driver to intel, rotates the monitor, and also transforms touchscreen inputs to match the landscape orientation.

i915

To further improve performance place the following into /etc/modprobe.d/i915.conf
options i915 enable_fbc=1 enable_guc=3 enable_psr=1 disable_power_well=0 semaphores=1

Backlight


Out of the box backlight doesn't work because of a module loading order issue [96571]. The easiest fix, found in the bug report thread, is to use dracut to remove the i915 module from initramfs so it loads after the PWM modules.

sudo apt install dracut
sudo dracut -f --omit-drivers="i915"
sudo update-grub

This issue may be fixed in a later release as the issue has been reported to Ubuntu.

After rebooting /sys/class/backlight/intel_backlight/ should exist, indicating that backlight control is available.

Keyboard Backlight Control


Unfortunately while we can now control the backlight using programs like xbacklight, the screen brightness keys (fn+F5 and fn+F6) don't work. We can get around this by binding control-F5 and control-F6 to trigger xbacklight -dec 20 and xbacklight -inc 20 respectively to decrement/increment screen brightness by 20% per keyboard press.

Airplane Mode


Similar to the backlight control buttons the airplane mode button also doesn't work. The following script uses rfkill to toggle bluetooth and wifi on/off, effectively implementing airplane mode in software. I haven't found a way to disable bluetooth and wifi in hardware.

#!/bin/bash

BLUETOOTH_OFF_BY_DEFAULT=1

n_devices="$(rfkill -n | wc -l)"
n_blocked="$(rfkill -n | grep -w blocked | wc -l)"

echo "$n_devices devices, $n_blocked blocked"

if [ "$n_blocked" == "$n_devices" ]; then
  rfkill unblock bluetooth wlan

  if [ "$BLUETOOTH_OFF_BY_DEFAULT" == "1" ]; then
    rfkill block bluetooth
  fi
else
  rfkill block bluetooth wlan
fi

Power Saving


It is a good idea to install tlp to improve the running time

TODOs:

  • Script and keybindings to rotate the screen and touchscreen
  • Pressure level with the pen

April 28, 2016

IPython Notebook on GPS Timing and CDMA


In [1]:
%matplotlib inline

import matplotlib
import numpy as np
import matplotlib.pyplot as plt


GPS Timing

Carrier-phase detection is suppose to yield better timing information than tracking the pseudorandom code stream. The reason for this is supposedly that the higher frequency carrier allows for more accurate measurements of the mismatch between the generated pseduorandom code stream and the broadcasted one. This increase in accuracy comes from sharper peaks in the autocorrelation function.
Lets try this out:

In [2]:
def corr(npoints, repeat):
    A = np.random.randint(0, 2, npoints)
    A = np.repeat(A, repeat)

    xcor = np.correlate(A, A, mode='same')
    plt.figure()
    N = len(A)
    offvec = np.arange(0, N)-N/2
    print offvec.size, xcor.size
    plt.plot(offvec, xcor, 'x-')


    

# generate 5 points each repeating 20 times, a slow signal    
corr(5,20)

# a much faster signal
corr(100,1)




100 100
100 100










It is clear that if you were trying to figure out the sample delay, you are much better off with the faster signal because the it is very obvious when you have the timing right. With the slower signal, you can be a little wrong and still get within a few pc of the correct correlation value.

Code Division Multiplexing

Try out CDM for myself. It is important that -1,1 is used instead of 0,1 because multiplying by 0 is always 0.

In [3]:
def gen_code(N):
    """
    Generatea a random array containing -1 and 1 of size N
    """
    out = np.random.randint(0, 2, N)
    out *= 2
    out -= 1
    return out
    
def code_modulate(signal, stretch=5, carrier=None):
    signal = np.repeat(signal, stretch)
    if carrier is None:
        carrier = gen_code(len(signal))
    
    return np.multiply(signal, carrier), carrier

sig_1 = gen_code(100)
sig_2 = gen_code(100)

out_1, c_1 = code_modulate(sig_1)

# generate an orthogonal array by flipping every other element
c_2 = np.array(c_1)
c_2[::2] = -1*c_1[::2]
out_2, _ = code_modulate(sig_2, carrier=c_2)

out_comb = out_1 + out_2

def plot_sig(s, title=''):
    plt.figure()
    plt.stem(s)
    plt.ylim([min(s)-0.5, max(s)+0.5])
    plt.title(title)
    
plot_sig(sig_1, 'sig_1')
plot_sig(sig_2, 'sig_2')
plot_sig(out_comb, 'combined output')

















In [6]:
def code_demodulate(signal, carrier, stretch=5):
    y = np.multiply(signal, carrier)
    ysubs = np.split(y, len(y)/5)
    ysubs = map(sum, ysubs)
    ysubs = map(lambda x:max(-1, x), ysubs)
    ysubs = map(lambda x:min(1, x), ysubs)    
    return ysubs

x = code_demodulate(out_comb, c_1)
plot_sig(x, 'sig_1 recovered')
plot_sig(sig_1, 'sig_1 expected')

x = code_demodulate(out_comb, c_2)
plot_sig(x, 'sig_2 recovered')
plot_sig(sig_2, 'sig_2 expected')





















Perfect.

In [ ]: