From fa4964bb3038877f748442d91919e59fa6f7932b Mon Sep 17 00:00:00 2001 From: Jon Langseth Date: Sun, 8 Jul 2012 20:19:21 +0200 Subject: [PATCH 1/1] Header-files and support-code allows for further expansion. I needed the set_speed tool first, so that's what goes in initial commit. --- build.sh | 11 +++ hm-trp.c | 196 +++++++++++++++++++++++++++++++++++++++++++++++++ hm-trp.h | 57 ++++++++++++++ read_hm-trp.c | 67 +++++++++++++++++ serial.c | 35 +++++++++ serial.h | 10 +++ set_speed.c | 85 +++++++++++++++++++++ swap.c_example | 19 +++++ 8 files changed, 480 insertions(+) create mode 100755 build.sh create mode 100644 hm-trp.c create mode 100644 hm-trp.h create mode 100644 read_hm-trp.c create mode 100644 serial.c create mode 100644 serial.h create mode 100644 set_speed.c create mode 100644 swap.c_example diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..21cc481 --- /dev/null +++ b/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Couldn't be bothered to make a proper make-file... + +for i in *.c +do + gcc -c $i +done + +gcc read_hm-trp.o hm-trp.o serial.o -o read_hm-trp +gcc set_speed.o hm-trp.o serial.o -o set_speed + diff --git a/hm-trp.c b/hm-trp.c new file mode 100644 index 0000000..4ca2cd3 --- /dev/null +++ b/hm-trp.c @@ -0,0 +1,196 @@ +#include "hm-trp.h" + +#include + +#ifndef CBUFFER_SIZE +#define CBUFFER_SIZE 32 +#endif + +const int count_devtype = 4; +const char* dev_name[4] = { + "HM-TRP-433", + "HM-TRP-470", + "HM-TRP-868", + "HM-TRP-915" +}; + +const uint32_t freq_min[4] = { + 414 * 1e6, + 450 * 1e6, + 849 * 1e6, + 895 * 1e6 +}; +const uint32_t freq_max[4] = { + 454 * 1e6, + 490 * 1e6, + 889 * 1e6, + 935 * 1e6 +}; +const uint32_t freq_default[4] = { + 434 * 1e6, + 470 * 1e6, + 869 * 1e6, + 915 * 1e6 +}; + +const int count_recv_bw = 12; +// Values selected somewhat randomly... +const int recv_bw[12] = { + 30, + 50, + 75, + 90, + 105, + 120, + 150, + 175, + 200, + 250, + 300, + 620 +}; + +const int count_freq_dev = 10; +// Values selected somewhat randomly... +const int freq_dev[10] = { // Values as kHz .. + 10, + 20, + 35, + 50, + 55, + 80, + 110, + 120, + 145, + 160 +}; + +const int count_powerlevel = 8; +const int powerlevel[8] = { 1, 2, 5, 8, 11, 14, 17, 20 }; + +const int count_rates = 9; +const int port_rate_value[9] = { + 1200, + 1800, + 2400, + 4800, + 9600, + 19200, + 38400, + 57600, + 115200 +}; + +const int port_rates[9] = { + B1200, + B1800, + B2400, + B4800, + B9600, + B19200, + B38400, + B57600, + B115200 +}; + +const char cmd_reset[3] = { 0xAA, 0xFA, 0xF0 }; +const char cmd_config[3] = { 0xAA, 0xFA, 0xE1 }; +const char cmd_frequency[3] = { 0xAA, 0xFA, 0xD2 }; +const char cmd_air_rate[3] = { 0xAA, 0xFA, 0xC3 }; +const char cmd_bw[3] = { 0xAA, 0xFA, 0xB4 }; +const char cmd_deviation[3] = { 0xAA, 0xFA, 0xA5 }; +const char cmd_power[3] = { 0xAA, 0xFA, 0x96 }; +const char cmd_uart_rate[3] = { 0xAA, 0xFA, 0x1E }; +const char cmd_RSSI[3] = { 0xAA, 0xFA, 0x87 }; +const char cmd_SNR[3] = { 0xAA, 0xFA, 0x78 }; + +int write_uint32_t ( int f, uint32_t v ) +{ + int i; + unsigned char buf[4]; + v = __bswap_32(v); + for ( i = 0; i < 4; i++ ) + buf[i] = (v>>(8*i) & 0xff ); + + return write( f, buf, 4 ); +} + +int write_uint16_t ( int f, uint16_t v ) +{ + int i; + unsigned char buf[2]; + v = __bswap_16(v); + for ( i = 0; i < 2; i++ ) + buf[i] = (v>>(8*i) & 0xff ); + + return write( f, buf, 2 ); +} + +int write_uint8_t ( int f, uint8_t v ) +{ + int i; + unsigned char buf[2]; + + //for ( i = 0; i < 2; i++ ) + // buf[i] = (v>>(8*i) & 0xff ); + + return write( f, &v, 1 ); +} + +int write_cmd ( int f, const char* buf ) +{ + return write( f, buf, 3 ); // Send the command to the device +} + +int read_config ( int fd, config_t * config ) +{ + + unsigned char buf[CBUFFER_SIZE]; + int res; + + res = write_cmd( fd, cmd_config ); // Send the command to the device + if ( res < 0 ) return(-1); // and die on failure.. + + int i = 0; + uint8_t* tmp_config = (uint8_t*)config; + do { + bzero(buf, CBUFFER_SIZE); + res = read( fd, buf, 1 ); + + if ( res ) + { + *tmp_config++ = (uint8_t)buf[0]; + // Make sure wo don't overflow the config struct. + if ( (void*)tmp_config > ((void*)config+sizeof(config_t)) ) return(-2); + } + + } while ( res > 0 ); + + if ( res < 0 ) + { + return -1; + } + + if ( config->freq ) + { + config->freq = __bswap_32( config->freq ); + config->air_rate = __bswap_32( config->air_rate ); + config->bw = __bswap_16( config->bw ); + config->uart_rate = __bswap_32( config->uart_rate ); + return 1; + } + + return 0; // No errors, but no valid config +} + +int read_ok ( int fd ) +{ + unsigned char ok[5]; + int i = 0; + unsigned char c; + bzero(ok, 5); + + while( (read( fd, &c, 1 ) > 0 ) && ( i < 4) ) ok[i++] = c; + if ( strcmp( ok, "OK\r\n" ) == 0 ) return 1; + return 0; +} diff --git a/hm-trp.h b/hm-trp.h new file mode 100644 index 0000000..68f106e --- /dev/null +++ b/hm-trp.h @@ -0,0 +1,57 @@ +#ifndef _HM_TRP_H +#define _HM_TRP_H + +#include /* String function definitions */ +#include /* uint*_t types */ +#include /* __bwap_{16,32} */ +#include "serial.h" + +typedef struct { + uint32_t freq; + uint32_t air_rate; + uint16_t bw; + uint8_t deviation; + uint8_t power; + uint32_t uart_rate; +} config_t; + +extern const int count_devtype; +extern const char* dev_name[4]; + +extern const uint32_t freq_min[4]; +extern const uint32_t freq_max[4]; +extern const uint32_t freq_default[4]; + +extern const int count_recv_bw; +extern const int recv_bw[12]; + +extern const int count_freq_dev; +extern const int freq_dev[10]; + +extern const int count_powerlevel; +extern const int powerlevel[8]; + +extern const int count_rates; +extern const int port_rate_value[9]; +extern const int port_rates[9]; + +extern const char cmd_reset[3]; +extern const char cmd_config[3]; +extern const char cmd_frequency[3]; +extern const char cmd_air_rate[3]; +extern const char cmd_bw[3]; +extern const char cmd_deviation[3]; +extern const char cmd_power[3]; +extern const char cmd_uart_rate[3]; +extern const char cmd_RSSI[3]; +extern const char cmd_SNR[3]; + +int write_uint32_t ( int f, uint32_t v ); +int write_uint16_t ( int f, uint16_t v ); +int write_uint8_t ( int f, uint8_t v ); +int write_cmd ( int f, const char* buf ); +int read_config ( int fd, config_t * config ); + +int read_ok( int fd ); + +#endif /* _HM_TRP_H */ diff --git a/read_hm-trp.c b/read_hm-trp.c new file mode 100644 index 0000000..71c5742 --- /dev/null +++ b/read_hm-trp.c @@ -0,0 +1,67 @@ +#include /* Error number definitions */ +#include /* String function definitions */ +#include /* Standard I/O */ +#include /* sleep */ +#include /* malloc, free */ + +#include "hm-trp.h" +#include "serial.h" + +#define CBUFFER_SIZE 32 + +int main ( int argc, char** argv ) +{ + int fd; + int res; + int r, c, f; + unsigned char buf[CBUFFER_SIZE]; + + config_t* config = malloc(sizeof(config_t)); + bzero(config, sizeof(config_t)); + + if ( ! argv[1] ) + { + printf("Serial port device required as argument, e.g. /dev/ttyUSB0\n"); + return 1; + } + + + printf("Looking for device on port %s\n", argv[1]); + + for ( r = 0; r <= count_rates; r++ ) + { + fd = open_port( argv[1], port_rates[r] ); + if ( fd < 0 ) + { + perror(argv[1]); + return(-1); + } + + if ( read_config( fd, config ) == 1 ) + { + printf("Found device at baud-rate %d, config:\n", port_rate_value[r] ); + printf("Freq %d \n", config->freq ); + printf("Air rate %d \n", config->air_rate ); + printf("Deviation %d \n", config->deviation ); + printf("TX Power %d \n", config->power ); + printf("BW %d \n", config->bw ); + printf("UART rate %d \n", config->uart_rate ); + + + for ( f = 0; f < count_devtype; f++ ) + { + if ( (config->freq >= freq_min[f]) && + (config->freq <= freq_max[f])) + { + printf("Device type is %s\n", dev_name[f]); + } + } + + return(0); + } + close(fd); + } + printf("Unable to find device on %s\n", argv[1]); + return(1); +} + diff --git a/serial.c b/serial.c new file mode 100644 index 0000000..7cb5ab0 --- /dev/null +++ b/serial.c @@ -0,0 +1,35 @@ +#include "serial.h" + +int open_port ( char* device, int rate ) +{ + int f; + struct termios tio; + + f = open ( device, O_RDWR | O_NOCTTY ); // Not using O_NDELAY, that caused ERR11: temp unavail. + if ( f < 0 ) + { + return(-1); + } + + tio.c_cflag = rate | CS8 | CLOCAL | CREAD; + + // 8 bits, local mode, read enabled + tio.c_cflag |= CS8 | CLOCAL | CREAD; + + // no flow-control, + tio.c_cflag &= ~CRTSCTS; + + // no parity + tio.c_iflag = IGNPAR; + + tio.c_oflag = 0; + tio.c_lflag = 0; // Non-canonical read, no other options. + tio.c_cc[VMIN] = 0; // Disable minimum characters for read + tio.c_cc[VTIME] = 5; // Wait for a max of 0.5 second + + tcsetattr(f,TCSANOW,&tio); // Apply this now. + + tcflush(f, TCIFLUSH); // the serial input buffer. + + return f; +} diff --git a/serial.h b/serial.h new file mode 100644 index 0000000..ed3db76 --- /dev/null +++ b/serial.h @@ -0,0 +1,10 @@ +#ifndef _SERIAL_H +#define _SERIAL_H + +#include /* Terminal I/O support */ +#include /* Error number definitions */ +#include /* File descriptor manipulation */ + +int open_port ( char* device, int rate ); + +#endif /* _SERIAL_H */ diff --git a/set_speed.c b/set_speed.c new file mode 100644 index 0000000..c29393c --- /dev/null +++ b/set_speed.c @@ -0,0 +1,85 @@ +#include /* Error number definitions */ +#include /* String function definitions */ +#include /* Standard I/O */ +#include /* sleep */ +#include /* malloc, free */ + +#include "hm-trp.h" +#include "serial.h" + +#define CBUFFER_SIZE 32 + +int main ( int argc, char** argv ) +{ + int fd; + int res; + int r, c, f; + long rate; + + unsigned char buf[CBUFFER_SIZE]; + + config_t* config = malloc(sizeof(config_t)); + bzero(config, sizeof(config_t)); + + if ( ! argv[1] ) + { + printf("Serial port device required as argument, e.g. /dev/ttyUSB0\n"); + return 1; + } + + if ( ! argv[2] ) + { + printf("Desired bit-rate required. Use RS232 rates only.\n"); + return 1; + } + + rate = atol( argv[2] ); + for ( r = 0; r <= count_rates; r++ ) + if ( port_rate_value[r] == rate ) { rate = r; break; } + + if ( r >= count_rates ) { printf("Invalid data rate requested\n"); return 1; } + + printf("Looking for device on port %s\n", argv[1]); + + for ( r = 0; r <= count_rates; r++ ) + { + fd = open_port( argv[1], port_rates[r] ); + if ( fd < 0 ) + { + perror(argv[1]); + return(-1); + } + + if ( read_config( fd, config ) == 1 ) + { + printf("Found device at baud-rate %d.\n", port_rate_value[r] ); + + if ( r == rate && ( config->air_rate == config->uart_rate ) ) + { + printf("Data rate is already set to %d\n", port_rate_value[r] ); + return 0; + } + + write_cmd( fd, cmd_air_rate ); + write_uint32_t( fd, port_rate_value[rate] ); + + if ( ! read_ok( fd ) ) + { + printf("Air rate NOT set\n"); + return 1; + } + + write_cmd( fd, cmd_uart_rate ); + write_uint32_t( fd, port_rate_value[rate] ); + + read_ok( fd ); // Clear buffer. + + printf("Device UART and air data rate set to %d\n", port_rate_value[rate] ); + return(0); + } + close(fd); + } + printf("Unable to find device on %s\n", argv[1]); + return(1); +} + diff --git a/swap.c_example b/swap.c_example new file mode 100644 index 0000000..401f53a --- /dev/null +++ b/swap.c_example @@ -0,0 +1,19 @@ +#include /* __bwap_{16,32} */ + +/* + Basically, does: +uint32_t swap_uint32 ( uint32_t num ) +{ + return ( (num>>24) & 0x000000ff) | // move byte 3 to byte 0 + ( (num<<8) & 0x00ff0000) | // move byte 1 to byte 2 + ( (num>>8) & 0x0000ff00) | // move byte 2 to byte 1 + ( (num<<24) & 0xff000000); // byte 0 to byte 3 +} + +uint16_t swap_uint16 ( uint16_t num ) +{ + // Move UP and mask | Move DOWN and mask + return( (num<<8) & 0xff00 ) | ( (num>>8) & 0x00ff ); +} +*/ + -- 2.39.2