Ahanix D.Vine 5 IR/VFD module

This HTPC case comes with an IR/VFD module.

Ahanix D.Vine 5 Case

There used to be a driver for this device in drivers/staging/media/lirc/lirc_sasem.c, but that was removed in kernel v4.12. I’ve since found it on eBay, and here is the result of analysing it, and I’ve written a new driver.

Sasem Remote Controller

In the centre you can see the LCD, which is attached via a header. To the right you can see the IR receiver module. The LCD can be detached using the four screws. The LCD part is a NEC µPD16314 VFD (without a backlight). There is also a Cyruss CY7C63743 USB microcontroller. This drives the IR decoding and the LCD via its GPIO ports.

Main board with the CY7C63743 usb microcontroller

The NEC µPD16314 VFD is clearly visible on the back of the LCD

The NEC µPD16314 is a hd44780 compatible, which is ubiquitous and well documented. There is a driver for it in mainline, which can control it via gpio ports. So I tried to attach this LCD device to a Raspberry Pi via its gpio ports. This is easy to do with female-female jumper cables. After some measuring and experimenting, I got it to work.

Raspberry Pi with Sasem LCD module

The pinout of the LCD header is:

  1. Ground
  2. VCC - 5v not 3.3v
  3. Not Connected (the pin is removed)
  4. RS
  5. R/W (not needed, connect to ground)
  6. E
  7. Bit 0
  8. Bit 1
  9. Bit 2
  10. Bit 3
  11. Bit 4
  12. Bit 5
  13. Bit 6
  14. Bit 7

Now, after compiling a kernel for the raspberry pi with CONFIG_HD44780 enabled, and the following added to the device tree:

auxdisplay {
compatible = "hit,hd44780";

data-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>,
<&gpio 27 GPIO_ACTIVE_HIGH>,
<&gpio 22 GPIO_ACTIVE_HIGH>,
<&gpio 23 GPIO_ACTIVE_HIGH>,
<&gpio 24 GPIO_ACTIVE_HIGH>,
<&gpio 25 GPIO_ACTIVE_HIGH>,
enable-gpios = <&gpio 14 GPIO_ACTIVE_HIGH>;
rs-gpios = <&gpio 4 GPIO_ACTIVE_HIGH>;

display-height-chars = <2>;
display-width-chars = <16>;

So that worked! Using the CHARLCD driver, you can set a cursor position, cursor blinking, and reprogram character generator data. The original lirc_sasem driver could not do any of that!

Now that I know the pins of the LCD header, I can try to figure out what the Sasem Remote Controller sends it, and how that relates to usb packets we can send to it from the driver. The CY7C63743 is a OTP (One Time Program) device. It’s a device which makes it very easy to create keyboards, input devices, anything which is a low bandwidth usb device. Unfortunately I could find no way of dumping its program memory.

Saleae Logic 16 attached to Sasem Controler

So, instead I attached a Saleae Logic 16 logic analyser to the board to see what commands it sends. I quickly discovered that it’s actually using the 4-bit interface, even though all 8 bits are connected via the header. Also, when the device powers on, it sends a few write reg commands and “Welcome DIGN Home Theatre PC”. During this period it drops any commands it receives over usb. In order to decode the commands, I wrote a simple libsigrokdecode decoder called sasem.

Since the CY7C63743 has 16 gpio ports, I don’t know why 4-bit mode is used. 1 gpio port is need for IR receive, one for the power button, and presumably another for switching the motherboard on (in case power on was pressed on the remote). That still leaves 13 gpio ports, and the LCD needs just 10 (8 bits data, Enable and Register Select).

The LCD has two commands: write data and write register. If you want to reprogram the display characters, you first do write register to DDRAM (display data) to set the location, followed by the letters you want using write data. When you attempt this via usb, it sends an extra “Write register DDRAM” before each data byte, which increases every time (from 0x80 to 0x8f for the first line and then 0xc0 to 0xcf for the second line). This makes it impossible to write to character generator ram (for your own characters), since every write data it sends a superfluous set DDRAM write register. I have no idea why this was done!

In addition, if you want to write to a register, you write 0x07 followed by the register value to usb. This means it is impossible to write 0x07 to the display. However this is one of the custom characters, for which we can’t write the graphics ram anyway.

The other oddity is if you do a write register DDRAM (to the location), then that command is passed on the device. However, as soon as you write data to the device, it gets preceeded by an annoying extra “write reg DDRAM” with an different address! So, the usb microcontroller maintains its own display position address, which you can modify using 0x09 0xYX (Y=0x4 for top, 0x0 for bottom) and X can be 0x1 to 0x10 (not base 0).

As for the Infrared interface, using ir-ctl I tried sending every protocol, and it reports data for NEC, Sanyo and JVC protocols. For some reason the JVC and Sanyo protocols comes out as semi-garbage, so the new driver only supports NEC.

Armed with this knowledge, I’ve created a new driver drivers/media/rc/sasem_ir.c. The driver can do a lot more than the original driver (e.g. cursor, blink) but no character graphics. Alas.

The iMon SoundGraph has very similar hardware, and I’ll be looking at that soon. I only have one model, if anyone can help with getting access to some more, that would be great.