Witam.
Posiadam taki oto wyświetlacz LCD OLED ze starego NASa NETGEAR ReadyNAS PRO. Raczej jest to jakiś customowy twór dedykowany do tego NASa niż jakiś z seryjnej produkcji. Z racji tego że NAS robi już za repo na kopie z Proxmoxa to chciałbym go w miarę możliwości wykorzystać. Na tem moment po włączeniu NASa zapala się napis Netgear i nic więcej. Przeglądnąłem log dmesg w poszukiwaniu jakiegoś nietypowego urządzenia czy portu LPT i niestety nic tam takiego nie wyczytałem. Po podłączeniu LCD w trakcie pracy w dmesg też nic nowego się nie pojawia. Nie jest to też nic na magistrali USB więc zapewne piny na płycie do których jest wpięty LCD to jakieś gpio. W oryginalnym sofcie znalazłem dwa pliki które wydają się być związane z obsługą wyświetlacza.
Pierwszy monitor_lcd
i drugi LCD.pl
Jest też plik binarny update_lcd_disk_status.
Niestety nie zlanazłem dedykowanego modułu odpowiedzialnego za obsługę gpio czy samego LCD. Nie widzę też nic takiego na liście w modules.buildin więc raczej nie uda mi się tego zaadaptować do kernela w Proxmox.
Ktoś ma pomysł jak to ugryźć?
Posiadam taki oto wyświetlacz LCD OLED ze starego NASa NETGEAR ReadyNAS PRO. Raczej jest to jakiś customowy twór dedykowany do tego NASa niż jakiś z seryjnej produkcji. Z racji tego że NAS robi już za repo na kopie z Proxmoxa to chciałbym go w miarę możliwości wykorzystać. Na tem moment po włączeniu NASa zapala się napis Netgear i nic więcej. Przeglądnąłem log dmesg w poszukiwaniu jakiegoś nietypowego urządzenia czy portu LPT i niestety nic tam takiego nie wyczytałem. Po podłączeniu LCD w trakcie pracy w dmesg też nic nowego się nie pojawia. Nie jest to też nic na magistrali USB więc zapewne piny na płycie do których jest wpięty LCD to jakieś gpio. W oryginalnym sofcie znalazłem dwa pliki które wydają się być związane z obsługą wyświetlacza.
Pierwszy monitor_lcd
#!/usr/bin/perl
$lcd="/dev/lcd";
$lcd_proc="/proc/sys/dev/lcd/cmd";
if ( -e $lcd_proc ) {
open FH, "+<", "$lcd" or die "cannot open $lcd\n";
select FH;
$| = 1;# set autoflush
} else {
exit;
}
$IOCTL_LCD_CMD =1;
$IOCTL_LCD_WRITE =2;
$IOCTL_LCD_READ =5;
$IOCTL_LCD_READ_ADDR =6;
$IOCTL_LCD_KEY_SCAN =9;
$IOCTL_LCD_WAIT_READY =14;
$IOCTL_LCD_RESET =15;
$IOCTL_LCD_BACKLIGHT =16;
$LCD_CLR =0x1;
$LCD_HOME =0x2;
$LCD_MODE =0x4;
$LCD_MOVE_L =0x10;
$LCD_MOVE_R =0x14;
$LCD_SCROLL_L =0x18;
$LCD_SCROLL_R =0x1c;
$LCD_SET_CGRAM =0x40;
$LCD_SET_DDRAM =0x80;
sub LCD_MOVE {
my $x=$_[0];
my $y=$_[1];
return 128+($y&1)*64+$x;
}
ioctl FH, $IOCTL_LCD_RESET, pack("L", 0);
sleepx("0.1");
# set display on/off
ioctl FH, $IOCTL_LCD_CMD, pack("L", 0xc); # no-cursor, no-blink
# set entry mode (no shift)
ioctl FH, $IOCTL_LCD_CMD, pack("L", $LCD_MODE|2);
# clear screen, and move to home posisition
ioctl FH, $IOCTL_LCD_CMD, pack("L", $LCD_CLR);
# need to wait after clear
ioctl FH, $IOCTL_LCD_WAIT_READY, 0;
#Display IP address
$ip=0;
ioctl FH, $IOCTL_LCD_CMD, pack("L", $LCD_HOME);
open IF, "/sbin/ifconfig |";
while (<IF>) {
chomp;
if (/ \s+ inet\saddr:(\S+) /x) {
if ($1) {
$ip = $1;
} else {
$ip = "Check Network...";
}
last;
}
}
close IF;
if ($ip == 0) {
$ip = "No Network link";
}
printf FH "%s" . " "x16, $ip;
#Display Hostname on second line
ioctl FH, $IOCTL_LCD_CMD, pack("L", LCD_MOVE(0,1));
open(HN, "/proc/sys/kernel/hostname");
chomp( $hostname = (<HN>)[0] );
close(HN);
printf FH "%s" . " "x16, $hostname;
#Wait for 150 sec to get updated enclosure.log
sleep 150;
#get failure info from enclosure.log
$enclosure_file = "/var/log/frontview/enclosure.log";
$fail_descr = " "x16;
$alert = 0;
open (IN, $enclosure_file) or die "Couldn't open $enclosure_file: $!";
while (<IN>) {
if(/=fail/) {
($tmp, $descr) = split /descr=/, $_;
$fail_descr .= $descr;
$fail_descr .= " ";
$fail_descr .= " "x8;
$alert = 1;
}
}
close ( IN );
$fail_descr .= " "x16;
if ($alert == 1) {
$i=0;
$LCDBL="/proc/sys/dev/lcd/backlight";
echo("1",">$LCDBL");
while (1) {
ioctl FH, $IOCTL_LCD_CMD, pack("L", LCD_MOVE(0,1));
printf FH substr($fail_descr, $i, 16);
$tick=0.5;
if ($i++==(length($fail_descr) -16)) {$i=0;}
sleepx("$tick");
}
} else {
echo("0",">$LCDBL");
}
close FH;
# Internal functions
sub sleepx {
my $dur = shift;
select(undef, undef, undef, $dur);
}
sub echo {
my $content = shift;
my $output = shift || ">/dev/null";
open(ECHO, "$output");
print ECHO "$content\n";
close(ECHO);
}i drugi LCD.pl
root@netgear:/tmp/test/frontview/lib# cat LCD.pl
#!/usr/bin/perl
#-------------------------------------------------------------------------
# Copyright 2007, NETGEAR
# All rights reserved.
#-------------------------------------------------------------------------
$LCD_PATH = "/sys/devices/system/rn_lcd/rn_lcd0";
$LCD_DELAY = "50";
sub lcd_is_supported
{
return( -d "$LCD_PATH" );
}
sub print_lcd_line
{
my $line = shift;
my $lcd_mesg = substr(shift,0,18);
if( ! $LCD_ON )
{
turnon_lcd();
}
msleep($LCD_DELAY);
open(LCD, ">$LCD_PATH/lcd_line$line") or return;
printf LCD ("%-18.18s\n", $lcd_mesg);
close LCD;
}
sub hotplug_lcd
{
my $mesg = shift;
my $mon_pid;
# Try to locate monitor_enclosure PID via .pid file
if( open(PID, "/var/run/monitor_enclosure.pid") )
{
$mon_pid = (<PID>)[0];
close PID;
}
print_lcd_line("2", $mesg);
kill(USR1, $mon_pid) if($mon_pid);
}
sub turnon_lcd
{
msleep($LCD_DELAY);
open(LCDCMD, ">$LCD_PATH/lcd_backlight") or return;
print LCDCMD "1\n";
close LCDCMD;
$LCD_ON = 1;
}
sub turnoff_lcd
{
return if( pgrep("LCD_ALWAYS_ON=1", "/etc/default/services") );
msleep($LCD_DELAY);
open(LCDCMD, ">$LCD_PATH/lcd_backlight") or return;
print LCDCMD "0\n";
close LCDCMD;
$LCD_ON = 0;
}
sub pgrep
{
my $string = shift;
my $infile = shift;
my $result;
open(INFILE, "$infile");
while( <INFILE> )
{
if( /$string/ )
{
chomp;
$result = $_;
last;
}
}
close(INFILE);
return $result;
}
sub msleep
{
select(undef, undef, undef, ((shift)/1000));
}
1;Jest też plik binarny update_lcd_disk_status.
Niestety nie zlanazłem dedykowanego modułu odpowiedzialnego za obsługę gpio czy samego LCD. Nie widzę też nic takiego na liście w modules.buildin więc raczej nie uda mi się tego zaadaptować do kernela w Proxmox.
Ktoś ma pomysł jak to ugryźć?