logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak wykorzystać wyświetlacz LCD OLED z NASa NETGEAR ReadyNAS PRO?

sebastianrolek 31 Gru 2024 11:51 150 0
REKLAMA
  • #1 21370412
    sebastianrolek
    Poziom 4  
    Posty: 6
    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
    #!/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źć?

    Ekran LCD z napisem ReadyNAS na urządzeniu NETGEAR ReadyNAS PRO. Wyświetlacz LCD OLED z napisem QC OK i oznaczeniem FLB-LCDCTRL V1.0. Płytka drukowana z wyświetlaczem LCD NETGEAR i mikrokontrolerem Microchip.
  • REKLAMA
REKLAMA