Skip to content

Instantly share code, notes, and snippets.

@errzey
Last active February 2, 2022 10:22
Show Gist options
  • Save errzey/57f5943fca14263e80bb50d92117ec0d to your computer and use it in GitHub Desktop.
Save errzey/57f5943fca14263e80bb50d92117ec0d to your computer and use it in GitHub Desktop.
trx-1 / trx-2 api in one header
/*
Output is something like:
ellzey@bluedream ~/Code/libtrx/src ./example
line1:
line2: ALM EBRCS
line3: TGRP psDr
line4: A2D
line5: ALCO Northwest S
line6: RadioID: 2DF98B
Homework: Print out the correct string2flags for status and led
flags. I.e., RSSI = (response.icons1 & TRX_ICON1_FLAG_RSSI)
*/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include "libtrx.h"
int
main(int argc, char ** argv)
{
int rc;
struct libusb_device_handle * devh;
struct trx_status_command status_cmd = { 0 };
struct trx_status_response status_resp = { 0 };
struct trx_led_command led_cmd = { 0 };
struct trx_led_response led_resp = { 0 };
libusb_init(NULL);
libusb_set_debug(NULL, 3);
devh = libusb_open_device_with_vid_pid(NULL, TRX_VENDOR_ID, TRX_PRODUCT_ID);
libusb_claim_interface(devh, 1);
libusb_clear_halt(devh, TRX_I);
libusb_clear_halt(devh, TRX_O);
trx_transfer_clear(devh);
trx_command_finalize(&status_cmd, trx_code_status);
trx_command_finalize(&led_cmd, trx_code_lcd);
while (1)
{
trx_write_blocking(devh, &status_cmd, sizeof(struct trx_status_command));
trx_read_blocking(devh, &status_resp, sizeof(struct trx_status_response));
trx_write_blocking(devh, &led_cmd, sizeof(struct trx_led_command));
trx_read_blocking(devh, &led_resp, sizeof(struct trx_led_response));
printf("line1: %.*s\n", 16, led_resp.line1);
printf("line2: %.*s\n", 16, led_resp.line2);
printf("line3: %.*s\n", 16, led_resp.line3);
printf("line4: %.*s\n", 16, led_resp.line4);
printf("line5: %.*s\n", 16, led_resp.line5);
printf("line6: %.*s\n", 16, led_resp.line6);
usleep(900000);
}
return 0;
}
#include <libusb-1.0/libusb.h>
#ifndef __LIBTRX_H__
#define __LIBTRX_H__
#ifdef __cplusplus
extern "C" {
#endif
enum trx_code {
trx_code_status = 'A',
trx_code_lcd = 'L',
trx_code_sendkey = 'K'
};
typedef uint8_t trx_keycode;
#define trx_keycode_skip 1
#define trx_keycode_right 2
#define trx_keycode_wx 3
#define trx_keycode_pri 5
#define trx_keycode_up 8
#define trx_keycode_sel 9
#define trx_keycode_down 10
#define trx_keycode_fn 12
#define trx_keycode_att 15
#define trx_keycode_left 16
#define trx_keycode_menu 17
#define trx_keycode_dot 19
#define trx_keycode_2 22
#define trx_keycode_4 23
#define trx_keycode_6 24
#define trx_keycode_8 25
#define trx_keycode_0 26
#define trx_keycode_1 29
#define trx_keycode_3 30
#define trx_keycode_5 31
#define trx_keycode_7 32
#define trx_keycode_9 33
#define trx_keycode_knob_cw 40
#define trx_keycode_knob_ccw 41
#define trx_keycode_knob_push 43
#define trx_keycode_power 44
struct trx_sendkey_command {
uint8_t STX_;
uint8_t CODE_;
trx_keycode key;
uint8_t ETX_;
uint8_t SUM_;
} __attribute__ ((packed));
struct trx_sendkey_response {
};
struct trx_status_command {
uint8_t STX_;
uint8_t CODE_;
uint8_t ETX_;
uint8_t SUM_;
} __attribute__ ((packed));
struct trx_status_response {
uint8_t STX_;
uint8_t CODE_;
uint8_t mode;
uint8_t sq;
uint16_t batt;
uint16_t rssi;
uint16_t zm;
uint8_t ledR;
uint8_t ledG;
uint8_t ledB;
uint32_t freq;
uint8_t rxmode;
uint8_t ETX_;
uint8_t SUM_;
} __attribute__ ((packed));
struct trx_led_command {
uint8_t STX_;
uint8_t CODE_;
uint8_t ETX_;
uint8_t SUM_;
} __attribute__ ((packed));
struct trx_led_response {
uint8_t STX_;
uint8_t CODE_;
uint8_t line1[16];
uint8_t line2[16];
uint8_t line3[16];
uint8_t line4[16];
uint8_t line5[16];
uint8_t line6[16];
#define TRX_ICON1_FLAG_RSSI 0x07
#define TRX_ICON1_FLAG_SICON (1 << 3)
#define TRX_ICON1_FLAG_BATON (1 << 4)
#define TRX_ICON1_FLAG_BATBL (1 << 5)
#define TRX_ICON1_FLAG_EXTPW (1 << 4)
uint8_t icons1;
#define TRX_ICON2_FLAG_FUNC (1 << 1)
#define TRX_ICON2_FLAG_G (1 << 2)
#define TRX_ICON2_FLAG_A (1 << 3)
#define TRX_ICON2_FLAG_T (1 << 4)
#define TRX_ICON2_FLAG_UNUSED1 (1 << 5)
#define TRX_ICON2_FLAG_UNUSED2 (1 << 6)
#define TRX_ICON2_FLAG_PLAY (1 << 7)
#define TRX_ICON2_FLAG_PAUSE (1 << 8)
uint8_t icons2;
#define TRX_ICON3_FLAG_SIGTYPE 0x07
#define TRX_ICON3_FLAG_IF (1 << 3)
#define TRX_ICON3_FLAG_TRUNK2 (1 << 4)
#define TRX_ICON3_FLAG_PRI (1 << 5)
#define TRX_ICON3_FLAG_TRUNKS (1 << 6)
#define TRX_ICON3_FLAG_UNUSED (1 << 7)
uint8_t icons3;
/*uint8_t sigtype; */
uint8_t ETX_;
uint8_t SUM_;
} __attribute__ ((packed));
#define TRX_VENDOR_ID 0x2a59
#define TRX_PRODUCT_ID 0x0011
#define TRX_I (0x83 | LIBUSB_ENDPOINT_IN)
#define TRX_O (0x03 | LIBUSB_ENDPOINT_OUT)
#define trx_calculate_sum(BUF_, LEN_) \
({ uint8_t sum = 0; \
int i; \
\
for (i = 0; i <= LEN_; i++) \
{ \
sum = sum + (uint8_t)BUF_[i]; \
} \
sum &= 0xFF; sum; })
static inline uint8_t
trx_makesum(unsigned char * buf, size_t len)
{
return trx_calculate_sum(buf, len);
}
#define trx_command_finalize(TRXMSG, TRXCODE) do { \
(TRXMSG)->STX_ = 0x02; \
(TRXMSG)->ETX_ = 0x03; \
(TRXMSG)->CODE_ = TRXCODE; \
\
(TRXMSG)->SUM_ = trx_makesum((unsigned char *)TRXMSG + 1, \
&(TRXMSG)->ETX_ - &(TRXMSG)->STX_); \
} while (0)
#define trx_transfer_blocking(TRXHDL_, TRXDAT_, TRXLEN_, TRXADDR_) ({ \
int res; \
int real_len; \
size_t nbytes; \
\
nbytes = 0; \
res = 0; \
\
do { \
res = \
libusb_bulk_transfer(TRXHDL_, TRXADDR_, \
TRXDAT_ + nbytes, \
TRXLEN_ - nbytes, &real_len, 300); \
\
if (res < 0) \
{ \
break; \
} \
\
nbytes += real_len; \
} while (nbytes < TRXLEN_); \
res; \
} \
)
#define trx_transfer_clear(TRXHDL_) do { \
unsigned char buf[512]; \
int real_len; \
while (libusb_bulk_transfer(TRXHDL_, TRX_I, buf, sizeof(buf), &real_len, \
3000) > 0) \
{ \
; \
} \
} while (0)
#define trx_read_blocking(H, D, L) \
trx_transfer_blocking( \
H, \
(unsigned char *)D, \
L, \
TRX_I)
#define trx_write_blocking(H, D, L) \
trx_transfer_blocking( \
H, \
(unsigned char *)D, \
L, \
TRX_O)
#ifdef __cplusplus
}
#endif
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment