Hello,

I succeed to recover a disable command (I followed tips from the Stefan's post). A simple user space configuration utility is in the attachment. Compile it then run the following before a setup of an interface

./hsr 98

What'll be available : scan shows channels 1 and 11; clients on channels 1 and 11 can connect and transmit data; n mode works.

I think that they tune an external receiver via some sort of SPI bus (GPIO pins are 5,6,7,8). Write procedure is quite simple, but I can't still get how enable works (for sure it sends a disable); it is quite possible that we need to read from a device before sending a command.


Kirill.

P.S. Sorry for duplicate from the different address.
/*
Copyright (c) 2015, Kirill Berezin
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.

*/

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

// High Selectitity Receiver?? Huh ...

// device seems to be a SPI bus
typedef struct {
  int csn;     // Chip Select, active low 
  int clk;    // clock
  int dout;   // data out
  int din;    // data in
} hsr_dev_t;

void del_dev(hsr_dev_t* dev) {
  if ( NULL != dev) {
    if ( -1 != dev->csn) {
      close(dev->csn);
    }
    if ( -1 != dev->clk) {
      close(dev->clk);
    }
    if ( -1 != dev->dout) {
      close(dev->dout);
    }
    if ( -1 != dev->din) {
      close(dev->din);
    }
    dev->csn = -1;
    dev->clk = -1;
    dev->dout = -1;
    dev->din = -1;
  }
}

int create_pin(int edesc, int num, char* dir) {
  char cline[1024];
  int ret, ret1, err;
  int pin_flags;

  sprintf(cline, "%d", num);
  write(edesc, cline, strlen(cline));

  sprintf(cline, "/sys/class/gpio/gpio%d/direction", num);
  ret = open(cline, O_WRONLY);
  if ( -1 == ret) {
    printf("Can't create pin #%d : %s\n", num, strerror(errno));
    return -1;
  }

  ret1 =  write(ret, dir, strlen(dir));
  err = errno;
  close(ret);

  if ( -1 == ret1) {
    printf("Can't configure pin #%d : %s\n", num, strerror(err));
    return -1;
  }

  pin_flags = !strcmp(dir, "out") ? O_WRONLY : O_RDONLY;
  sprintf(cline, "/sys/class/gpio/gpio%d/value", num);

  if ( -1 == (ret = open(cline, pin_flags))) {
    return -1;
  }
    
  return ret;
} 

int create_dev(hsr_dev_t*dev) {
  int ret = 0;
  int gpio_export;

  gpio_export = open("/sys/class/gpio/export", O_WRONLY);
  if ( -1 == gpio_export) {
    printf("Can't open export : %s \n", strerror(errno));
    return -1;
  }

  if ( -1 == (ret = create_pin(gpio_export, 8, "out"))) {
    goto over;
  }
  dev->csn = ret;

  if ( -1 == (ret = create_pin(gpio_export, 6, "out"))) {
    goto over;
  }
  dev->clk = ret;

  if ( -1 == (ret = create_pin(gpio_export, 7, "out"))) {
    goto over;
  }
  dev->dout = ret;

  if ( -1 == (ret = create_pin(gpio_export, 5, "in"))) {
    goto over;
  }
  dev->din = ret;


over:
  close(gpio_export);

  return ret;
}

int dev_write_value(int desc, uint8_t val) {
  char buf[5];
  sprintf(buf, "%d", val%10); 
  return write(desc, buf, 1);
}

int dev_read_value(int desc) {
  char buf[32];
  long rval;

  if ( -1 == read(desc, buf, 32)) {
    printf("can't read a value: %s \n", strerror(errno));
    return 1;
  }

  rval = strtol(buf, NULL, 10);

  return (rval >= 1) || (rval < 0) ? 1 : 0;
}

void hsr_init(hsr_dev_t* dev) {
    dev_write_value(dev->dout, 0);
    dev_write_value(dev->clk, 0);
    dev_write_value(dev->csn, 1);
}

uint32_t hsr_write_byte(hsr_dev_t *dev, int delay, uint32_t value){
  int i;
  usleep(delay);
  uint32_t rval = 0;

  dev_write_value(dev->csn, 0);
  usleep(100);

  for( i = 0; i < 8; ++i) {
    rval = rval << 1;

    // pattern is left to right, that is 7-th bit runs first
    dev_write_value(dev->dout, (value >> (7 - i)) & 0x1);
    usleep(100);
    
    dev_write_value(dev->clk, 1);
    usleep(100);

    rval |= dev_read_value(dev->din);

    dev_write_value(dev->clk, 0);
    usleep(100);
  }

  dev_write_value(dev->csn, 1);
  usleep(100);

  printf("write byte %d return value is %x \n", value, rval);
  
  return rval & 0xff;
}

// known good commands: disable 98

int main(int argc, char** argv) {
  hsr_dev_t dev = {-1, -1, -1, -1};
  int command;
  if ( argc < 2) {
    printf("%s: command \n", argv[0]);
    printf(" Known good commands: \n");
    printf("  98 -- disable hsr, this enables all channels. \n");
    printf("\n\n  Run this commands before create an interface or change a channel.\n");
    return 1;
  }
  command = strtol(argv[1], NULL, 10);

  printf("command %d %x \n", command, command);

  if ( -1 != create_dev(&dev)) {
    int i;

    // do an initialization
    

    // do an initialization
    hsr_write_byte(&dev, 75, 0);  
    hsr_write_byte(&dev, 75, 0);
    // an original code uses up to 0x1fff attempts  
    for ( i = 0; i < 42; ++i) {
      if ( !hsr_write_byte(&dev, 75, 0)) {
        break;
      }
    }
    // write a real data
    hsr_write_byte(&dev, 75, command);
   
    hsr_write_byte(&dev, 75, 0);  

    usleep(20000);
  }
  del_dev(&dev);

  return 0;
}
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to