HyperPixel 4 - Touch screen dimensions are swapped

Hi @AndyCap, thanks for fixing the portrait touchscreen issue - just what I needed!

How do I go about installing your fix please? I see from the GitHub page (https://github.com/AndrewCapon/HyperPixel4TouchScreen/tree/master/driver) that I need to install hyperpixel4-goodix-dkms_1.0_all.deb, but where do I find this?

That is a good question, Pimoroni have packaged this up so I am not sure.

Iā€™m sure @gadgetoid will post today about where it is.

The deb file is available here: https://github.com/pimoroni/HyperPixel4TouchScreen/releases

You will still need to:

sudo apt install raspberrypi-kernel-headers dkms

Thanks @gadgetoid and @AndyCap, it works a treat in portrait mode now!

1 Like

Actually, just realised that when in portrait mode (screen mode 2), the left/right orientation is opposite to what it should be. Up/down works ok (this is all I tested beforeā€¦).

I use these settings:

	dtoverlay=hyperpixel4:rotate_2
	framebuffer_width=480
	framebuffer_height=800
	display_rotate=2

Thanks.

Not sure how pimoroni have this setup but the way I did it was to use the dts settings as detailed here: https://github.com/AndrewCapon/HyperPixel4TouchScreen/tree/master/driver

So touchscreen-inverted-y would be set which doesnā€™t make much sense for your problem as you are having problems with the other axis.

@gadgetoid will be along with better infoā€¦

Thanks Andy, double checked the dts settings against yours and all looks the same. I would be interested to know if you experience the same issue in portrait mode (display mode 2 with USB ports at the bottom) please?

Further testing reveals the following issues:

Portrait, USB ports on top
X axis ok, but Y is inverted

dtoverlay=hyperpixel4:rotate_0
framebuffer_width=480
framebuffer_height=800
display_rotate=0

Landscape, USB ports on left
X and Y on the wrong axis - down = left and right = up

dtoverlay=hyperpixel4:rotate_1
framebuffer_width=800
framebuffer_height=480
display_rotate=1

Portrait, USB ports underneath
Y axis ok, X axis inverted

dtoverlay=hyperpixel4:rotate_2
framebuffer_width=480
framebuffer_height=800
display_rotate=2

Landscape, USB ports on right
X and Y on the wrong axis

dtoverlay=hyperpixel4:rotate_3
framebuffer_width=800
framebuffer_height=480
display_rotate=3

Just to confirm steps, this is a fresh install of 2018-06-27-raspbian-stretch.img, with the following commands to set up Hyperpixel:

sudo apt update
sudo apt upgrade
git clone https://github.com/pimoroni/hyperpixel4
cd hyperpixel4
sudo ./install.sh
cd src
make
sudo cp hyperpixel4.dtbo /boot/overlays/
wget https://github.com/pimoroni/HyperPixel4TouchScreen/releases/download/v1.0/hyperpixel4-goodix-dkms_1.0_all.deb
sudo apt install raspberrypi-kernel-headers dkms
sudo dpkg -i hyperpixel4-goodix-dkms_1.0_all.deb
sudo nano /boot/config.txt

I tried going back to the original settings:

Landscape, USB ports on left
X and Y on the wrong axis - this time down = right and right = down

dtoverlay=hyperpixel4:rotate
framebuffer_width=800
framebuffer_height=480
display_rotate=1

Landscape, USB ports on right
X and Y on the wrong axis

dtoverlay=hyperpixel4
framebuffer_width=800
framebuffer_height=480
display_rotate=3

So in conclusion, installing hyperpixel4-goodix-dkms_1.0_all.deb doesnā€™t appear to work in any orientation. I will flash a new Stretch image and await further instructions from @gadgetoid.

Everything works fine here but I didnā€™t use the deb file, I built the .ko file and tested all the config/dts settings to get the right settings which I put in the readme.md file.

Iā€™m not really sure what pimoroni have done since then, sorry.

P.S. With my original solution you need to build and copy the DTS file, for portrait mode with ports at bottom I have:

/dts-v1/;
/plugin/;
/ {
    compatible = "brcm,bcm2708";
    fragment@0 {
        target = <0xdeadbeef>;
        __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <0x1>;
        };
    };
    fragment@1 {
        target = <0xdeadbeef>;
        __overlay__ {
            dpi18_pins {
//              brcm,pins = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9    0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13       0x14 0x15>;
                brcm,pins = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9    0xc 0xd 0xe 0xf 0x10 0x11     0x14 0x15 0x16 0x17 0x18 0x19>;
                brcm,function = <0x6>;
                brcm,pull = <0x0>;
                phandle = <0x1>;
            };
        };
    };
    fragment@2 {
        target-path = "/";
        __overlay__ {
            i2c_gpio: i2c@0 {
                compatible = "i2c-gpio";
                gpios = <&gpio 10 0 /* sda */
                     &gpio 11 0 /* scl */
                    >;
                i2c-gpio,delay-us = <2>;        /* ~100 kHz */
                #address-cells = <1>;
                #size-cells = <0>;
            };
        };
    };
    fragment@3 {
        target = <&i2c_gpio>;
        __overlay__ {
            /* needed to avoid dtc warning */
            #address-cells = <1>;
            #size-cells = <0>;
            ft6236: ft6236@5d {
                compatible = "goodix,gt911";
                reg = <0x5d>;
                interrupt-parent = <&gpio>;
                interrupts = <27 2>;
                touchscreen-inverted-y;
                touchscreen-size-x = <480>;
                touchscreen-size-y = <800>;
	    };
        };
    };
    fragment@4 {
        target-path = "/";
        __overlay__ {
            rpi_backlight: rpi_backlight {
                compatible = "gpio-backlight";
                gpios = <&gpio 19 0>;
                default-on;
            };
        };
    };
    __symbols__ {
        dpi18_pins = "/fragment@1/__overlay__/dpi18_pins";
    };
    __local_fixups__ {
        fragment@0 {
            __overlay__ {
                pinctrl-0 = <0x0>;
            };
        };
    };
    __fixups__ {
        leds = "/fragment@0:target:0";
        gpio = "/fragment@1:target:0";
    };
    __overrides__ {
        rotate = <0>,"-5";
    };
};

From the src folder to build and copy:

make
sudo cp hyperpixel4.dtbo /boot/overlays/
sync

Then reboot and see if that helps?

my boot.config:

dtoverlay=hyperpixel4:rotate
framebuffer_width=480
framebuffer_height=800
display_rotate=2

Superb! Thank you very much Andy, I can confirm touchscreen now works with both axis in that portrait mode. :)

Iā€™ve not had chance to test other orientations as got to dash, but this is all I need for now so thanks!

This is bizarre- I tested all of the orientations before making the PR and packing it up. I was quite proud of my little match-the-touch-orientation-to-the-screen setup. Dā€™oh. Now Iā€™m confused. Iā€™ll have to add this to my TODO list for when I have some time to spare.

just got the Hyperpixel touch 4. but no luck with the touch to work correctly on RPi Jersy. I have done rebuild on dts file based on https://github.com/pimoroni/hyperpixel4. but no luck.
can anyone suggest the correct step to make it work?

just got one of this great displays for a mini dashboard project.
but i ran into the same problemā€¦ followed all steps, but have screwed up touch screen at all in portrait mode.
this is the reason i bought itā€¦ for a portrait mode touch dashboard.
this would not work until pimoroni or @gadgetoid give some more help here.
please help otherwise i would send it back, cause it does not work properly.

1 Like

Hi Guys.

Maybe it is a problem with the deb file.

It definitely works if you build the driver yourself: https://github.com/AndrewCapon/HyperPixel4TouchScreen/tree/master/driver

If you can tell me exactly what bit isnā€™t working, display or touchscreen maybe I can help.

Andy

I also tried your driver @AndyCap along with your documentation over on github.

i have my screen in portrait with ports down.

problem is that x and y seems to be inverted or swappedā€¦ (or both?)
and because of that the courser would never react where you touch.

any help or a specific .dtbo or .dts file with instruction for /boot/config.txt would be helpfull.

here are my files:

hyperpixel4.dts

/dts-v1/;
/plugin/;
/ {
    compatible = "brcm,bcm2708";
    fragment@0 {
        target = <0xdeadbeef>;
        __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <0x1>;
        };
    };
    fragment@1 {
        target = <0xdeadbeef>;
        __overlay__ {
            dpi18_pins {
//              brcm,pins = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9    0xa 0xb 0xc 0xd 0xe 0xf 0x1$
                brcm,pins = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9    0xc 0xd 0xe 0xf 0x10 0x11  $
                brcm,function = <0x6>;
                brcm,pull = <0x0>;
                phandle = <0x1>;
            };
        };
    };
    fragment@2 {
        target-path = "/";
        __overlay__ {
            i2c_gpio: i2c@0 {
                compatible = "i2c-gpio";
                gpios = <&gpio 10 0 /* sda */
                     &gpio 11 0 /* scl */
                    >;
                i2c-gpio,delay-us = <4>;        /* ~100 kHz */
                #address-cells = <1>;
                #size-cells = <0>;
            };
        };
    };
    fragment@3 {
        target = <&i2c_gpio>;
        __overlay__ {
            /* needed to avoid dtc warning */
            #address-cells = <1>;
            #size-cells = <0>;
            ft6236: ft6236@5d {
                compatible = "goodix,gt911";
                reg = <0x5d>;
                interrupt-parent = <&gpio>;
                interrupts = <27 2>;
                touchscreen-hyperpixel4;
                touchscreen-size-x = <800>;
                touchscreen-size-y = <480>;
            };
        };
    };
    fragment@4 {
        target-path = "/";
        __overlay__ {
            rpi_backlight: rpi_backlight {
                compatible = "gpio-backlight";
                gpios = <&gpio 19 0>;
                default-on;
            };
        };
    };
    /* display_lcd_rotate=2 */
    /* Portrait, USB ports on bottom */
    fragment@5 {
        target = <&ft6236>;
        __dormant__ {
            touchscreen-inverted-y;
            touchscreen-size-x = <480>;
            touchscreen-size-y = <800>;
        };
    };
    /* display_lcd_rotate=0 */
    /* Portrait, USB ports on top */
    fragment@6 {
        target = <&ft6236>;
        __dormant__ {
            touchscreen-inverted-x;
            touchscreen-size-x = <480>;
            touchscreen-size-y = <800>;
        };
    };
    /* display_lcd_rotate=3 */
    /* Landscape, USB ports on right */
    fragment@7 {
        target = <&ft6236>;
        __overlay__ {
            touchscreen-swapped-x-y;
            touchscreen-inverted-x;
            touchscreen-inverted-y;
        };
    };
    /* display_lcd_rotate=1 */
    /* Landscape, USB ports on left */
    fragment@8 {
        target = <&ft6236>;
        __dormant__ {
            touchscreen-swapped-x-y;
        };
    };
    __symbols__ {
        dpi18_pins = "/fragment@1/__overlay__/dpi18_pins";
    };
    __local_fixups__ {
        fragment@0 {
            __overlay__ {
                pinctrl-0 = <0x0>;
            };
        };
    };
    __fixups__ {
        leds = "/fragment@0:target:0";
        gpio = "/fragment@1:target:0";
    };
    __overrides__ {
        rotate = <0>,"-5-7-8+6";
        rotate_0 = <0>,"-5-7-8+6";
        rotate_1 = <0>,"-5-6-7+8";
        rotate_2 = <0>,"-6-7-8+5";
        rotate_3 = <0>,"-5-6-8+7";
    };
};

and my /boot/config.txt

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details
# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=683
#framebuffer_height=384

# uncomment if hdmi display is not detected and composite is being output
#hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
#dtparam=i2s=on
dtparam=spi=on

# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi

# Additional overlays and parameters are documented /boot/overlays/README
# Enable audio (loads snd_bcm2835)
dtparam=audio=on

# hyperpixel4
overscan_left=0
overscan_right=0
overscan_top=0
overscan_bottom=0
enable_dpi_lcd=1
display_default_lcd=1
dpi_group=2
dpi_mode=87
dpi_output_format=0x7f216
hdmi_timings=480 0 10 16 59 800 0 15 113 15 0 0 0 60 0 32000000 6

dtoverlay=hyperpixel4:rotate_2
framebuffer_width=480
framebuffer_height=800
display_rotate=2
display_lcd_rotate=2

any help would be awesome.

kind regards from berlin

I will fire my one up later today and get back to you about how to set it upā€¦

For anything directly accessing the touch screen, I rescaled the axes eg:

                if event.code == ABS_MT_POSITION_X:
                    value = int((event.value/480.0)*800)
                    self._current_touch.x = value
            
                if event.code == ABS_MT_POSITION_Y:
                    value = int((event.value/800.0)*480)
                    self._current_touch.y = value

From https://github.com/pimoroni/python-multitouch/blob/2b8678773224d49e94c1da174aa269fd3b433564/library/hp4ts.py#L203-L209

This is, effectively, what X does internally although Iā€™ve no idea how it manages to accomplish this seemlessly- in fact X glossing over these swapped dimensions is what led me to approve the Goodix touch IC in the first place, which is frustrating since we wanted sane upstream drivers andā€¦ got this :(

If I recall correctly, the alternate driver fixes this, but Iā€™ve been busy with a million-and-one other projects so Iā€™ve not had the opportunity to look into it again. There seem to be a number of reports of various issues with HP4 and achieving various rotation settings, though, so itā€™s something Iā€™ll look into.

@locutus2007

Ok, for mine with portrait and ports at bottom:

/boot/config.txt

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment this if your display has a black border of unused pixels visible
# and your display can output without overscan
#disable_overscan=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
hdmi_group=2
hdmi_mode=9

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Uncomment this to enable the lirc-rpi module
#dtoverlay=lirc-rpi

# Additional overlays and parameters are documented /boot/overlays/README

# Enable audio (loads snd_bcm2835)
dtparam=audio=on
dtoverlay=hyperpixel4:rotate
overscan_left=0
overscan_right=0
overscan_top=0
overscan_bottom=0
enable_dpi_lcd=1
display_default_lcd=1
dpi_group=2
dpi_mode=87
dpi_output_format=0x7f216
hdmi_timings=480 0 10 16 59 800 0 15 113 15 0 0 0 60 0 32000000 6
framebuffer_width=480
framebuffer_height=800
display_rotate=2

gpu_mem=128

hyperpixel4.dts

/dts-v1/;
/plugin/;
/ {
    compatible = "brcm,bcm2708";
    fragment@0 {
        target = <0xdeadbeef>;
        __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <0x1>;
        };
    };
    fragment@1 {
        target = <0xdeadbeef>;
        __overlay__ {
            dpi18_pins {
//              brcm,pins = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9    0xa 0xb 0xc 0xd 0xe 0xf 0x10 0x11 0x12 0x13       0x14 0x15>;
                brcm,pins = <0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9    0xc 0xd 0xe 0xf 0x10 0x11     0x14 0x15 0x16 0x17 0x18 0x19>;
                brcm,function = <0x6>;
                brcm,pull = <0x0>;
                phandle = <0x1>;
            };
        };
    };
    fragment@2 {
        target-path = "/";
        __overlay__ {
            i2c_gpio: i2c@0 {
                compatible = "i2c-gpio";
                gpios = <&gpio 10 0 /* sda */
                     &gpio 11 0 /* scl */
                    >;
                i2c-gpio,delay-us = <2>;        /* ~100 kHz */
                #address-cells = <1>;
                #size-cells = <0>;
            };
        };
    };
    fragment@3 {
        target = <&i2c_gpio>;
        __overlay__ {
            /* needed to avoid dtc warning */
            #address-cells = <1>;
            #size-cells = <0>;
            ft6236: ft6236@5d {
                compatible = "goodix,gt911";
                reg = <0x5d>;
                interrupt-parent = <&gpio>;
                interrupts = <27 2>;
                touchscreen-inverted-y;
                touchscreen-size-x = <4800>;
                touchscreen-size-y = <8000>;
                touchscreen-refresh-rate = <0>;
	    };
        };
    };
    fragment@4 {
        target-path = "/";
        __overlay__ {
            rpi_backlight: rpi_backlight {
                compatible = "gpio-backlight";
                gpios = <&gpio 19 0>;
                default-on;
            };
        };
    };
    __symbols__ {
        dpi18_pins = "/fragment@1/__overlay__/dpi18_pins";
    };
    __local_fixups__ {
        fragment@0 {
            __overlay__ {
                pinctrl-0 = <0x0>;
            };
        };
    };
    __fixups__ {
        leds = "/fragment@0:target:0";
        gpio = "/fragment@1:target:0";
    };
    __overrides__ {
        rotate = <0>,"-5";
    };
};

I have increased resolution for the touchscreen set here (4800x8000) you probably want to maybe set this to (480, 800) instead.

Cheers

Andy