v1.0.0
* Initial release for SX1302 CoreCell Reference Design.
This commit is contained in:
parent
c7a5171a47
commit
4c61c5d48e
79 changed files with 30157 additions and 0 deletions
126
libloragw/Makefile
Normal file
126
libloragw/Makefile
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
### get external defined data
|
||||
|
||||
LIBLORAGW_VERSION := `cat ../VERSION`
|
||||
include library.cfg
|
||||
include ../target.cfg
|
||||
|
||||
### constant symbols
|
||||
|
||||
ARCH ?=
|
||||
CROSS_COMPILE ?=
|
||||
CC := $(CROSS_COMPILE)gcc
|
||||
AR := $(CROSS_COMPILE)ar
|
||||
|
||||
CFLAGS := -O2 -Wall -Wextra -std=c99 -Iinc -I. -I../libtools/inc
|
||||
|
||||
OBJDIR = obj
|
||||
INCLUDES = $(wildcard inc/*.h) $(wildcard ../libtools/inc/*.h)
|
||||
|
||||
### linking options
|
||||
|
||||
LIBS := -lloragw -ltinymt32 -lrt -lm
|
||||
|
||||
### general build targets
|
||||
|
||||
all: libloragw.a test_loragw_spi test_loragw_i2c test_loragw_reg test_loragw_hal_tx test_loragw_hal_rx test_loragw_cal test_loragw_capture_ram test_loragw_spi_sx1250 test_loragw_counter test_loragw_gps
|
||||
|
||||
clean:
|
||||
rm -f libloragw.a
|
||||
rm -f test_loragw_*
|
||||
rm -f $(OBJDIR)/*.o
|
||||
rm -f inc/config.h
|
||||
|
||||
install:
|
||||
ifneq ($(strip $(TARGET_IP)),)
|
||||
ifneq ($(strip $(TARGET_DIR)),)
|
||||
ifneq ($(strip $(TARGET_USR)),)
|
||||
@echo "---- Copying libloragw files to $(TARGET_IP):$(TARGET_DIR)"
|
||||
@ssh $(TARGET_USR)@$(TARGET_IP) "mkdir -p $(TARGET_DIR)"
|
||||
@scp test_loragw_* $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR)
|
||||
@scp ../tools/reset_lgw.sh $(TARGET_USR)@$(TARGET_IP):$(TARGET_DIR)
|
||||
else
|
||||
@echo "ERROR: TARGET_USR is not configured in target.cfg"
|
||||
endif
|
||||
else
|
||||
@echo "ERROR: TARGET_DIR is not configured in target.cfg"
|
||||
endif
|
||||
else
|
||||
@echo "ERROR: TARGET_IP is not configured in target.cfg"
|
||||
endif
|
||||
|
||||
### transpose library.cfg into a C header file : config.h
|
||||
|
||||
inc/config.h: ../VERSION library.cfg
|
||||
@echo "*** Checking libloragw library configuration ***"
|
||||
@rm -f $@
|
||||
#File initialization
|
||||
@echo "#ifndef _LORAGW_CONFIGURATION_H" >> $@
|
||||
@echo "#define _LORAGW_CONFIGURATION_H" >> $@
|
||||
# Release version
|
||||
@echo "Release version : $(LIBLORAGW_VERSION)"
|
||||
@echo " #define LIBLORAGW_VERSION "\"$(LIBLORAGW_VERSION)\""" >> $@
|
||||
# Debug options
|
||||
@echo " #define DEBUG_AUX $(DEBUG_AUX)" >> $@
|
||||
@echo " #define DEBUG_SPI $(DEBUG_SPI)" >> $@
|
||||
@echo " #define DEBUG_I2C $(DEBUG_SPI)" >> $@
|
||||
@echo " #define DEBUG_REG $(DEBUG_REG)" >> $@
|
||||
@echo " #define DEBUG_HAL $(DEBUG_HAL)" >> $@
|
||||
@echo " #define DEBUG_GPS $(DEBUG_GPS)" >> $@
|
||||
@echo " #define DEBUG_GPIO $(DEBUG_GPIO)" >> $@
|
||||
@echo " #define DEBUG_LBT $(DEBUG_LBT)" >> $@
|
||||
@echo " #define DEBUG_RAD $(DEBUG_RAD)" >> $@
|
||||
@echo " #define DEBUG_CAL $(DEBUG_CAL)" >> $@
|
||||
@echo " #define DEBUG_SX1302 $(DEBUG_SX1302)" >> $@
|
||||
# Configuration options
|
||||
@echo " #define BYPASS_FW_INIT $(BYPASS_FW_INIT)" >> $@
|
||||
@echo " #define FPGA_BOARD_16_CH $(FPGA_BOARD_16_CH)" >> $@
|
||||
# end of file
|
||||
@echo "#endif" >> $@
|
||||
@echo "*** Configuration seems ok ***"
|
||||
|
||||
### library module target
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir -p $(OBJDIR)
|
||||
|
||||
$(OBJDIR)/%.o: src/%.c $(INCLUDES) inc/config.h | $(OBJDIR)
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
### static library
|
||||
|
||||
libloragw.a: $(OBJDIR)/loragw_spi.o $(OBJDIR)/loragw_i2c.o $(OBJDIR)/loragw_aux.o $(OBJDIR)/loragw_reg.o $(OBJDIR)/loragw_sx1250.o $(OBJDIR)/loragw_sx125x.o $(OBJDIR)/loragw_sx1302.o $(OBJDIR)/loragw_cal.o $(OBJDIR)/loragw_debug.o $(OBJDIR)/loragw_hal.o $(OBJDIR)/loragw_stts751.o $(OBJDIR)/loragw_gps.o $(OBJDIR)/loragw_sx1302_timestamp.o $(OBJDIR)/loragw_sx1302_rx.o
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
### test programs
|
||||
|
||||
test_loragw_spi: tst/test_loragw_spi.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_i2c: tst/test_loragw_i2c.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_reg: tst/test_loragw_reg.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_hal_tx: tst/test_loragw_hal_tx.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_hal_rx: tst/test_loragw_hal_rx.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_capture_ram: tst/test_loragw_capture_ram.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_cal: tst/test_loragw_cal.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_spi_sx1250: tst/test_loragw_spi_sx1250.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_counter: tst/test_loragw_counter.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
test_loragw_gps: tst/test_loragw_gps.c libloragw.a
|
||||
$(CC) $(CFLAGS) -L. -L../libtools $< -o $@ $(LIBS)
|
||||
|
||||
### EOF
|
||||
84
libloragw/inc/loragw_agc_params.h
Normal file
84
libloragw/inc/loragw_agc_params.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
SX1302 AGC parameters definition.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_AGC_PARAMS_H
|
||||
#define _LORAGW_AGC_PARAMS_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE TYPES -------------------------------------------------------- */
|
||||
|
||||
struct agc_gain_params_s {
|
||||
uint8_t ana_min;
|
||||
uint8_t ana_max;
|
||||
uint8_t ana_thresh_l;
|
||||
uint8_t ana_thresh_h;
|
||||
uint8_t dec_attn_min;
|
||||
uint8_t dec_attn_max;
|
||||
uint8_t dec_thresh_l;
|
||||
uint8_t dec_thresh_h1;
|
||||
uint8_t dec_thresh_h2;
|
||||
uint8_t chan_attn_min;
|
||||
uint8_t chan_attn_max;
|
||||
uint8_t chan_thresh_l;
|
||||
uint8_t chan_thresh_h;
|
||||
uint8_t deviceSel; /* sx1250 only */
|
||||
uint8_t hpMax; /* sx1250 only */
|
||||
uint8_t paDutyCycle; /* sx1250 only */
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
const struct agc_gain_params_s agc_params_sx1250 = {
|
||||
.ana_min = 1,
|
||||
.ana_max = 13,
|
||||
.ana_thresh_l = 3,
|
||||
.ana_thresh_h = 12,
|
||||
.dec_attn_min = 4,
|
||||
.dec_attn_max = 15,
|
||||
.dec_thresh_l = 40,
|
||||
.dec_thresh_h1 = 80,
|
||||
.dec_thresh_h2 = 90,
|
||||
.chan_attn_min = 4,
|
||||
.chan_attn_max = 14,
|
||||
.chan_thresh_l = 52,
|
||||
.chan_thresh_h = 132,
|
||||
.deviceSel = 0,
|
||||
.hpMax = 7,
|
||||
.paDutyCycle = 4
|
||||
};
|
||||
|
||||
const struct agc_gain_params_s agc_params_sx125x = {
|
||||
.ana_min = 0,
|
||||
.ana_max = 9,
|
||||
.ana_thresh_l = 16,
|
||||
.ana_thresh_h = 35,
|
||||
.dec_attn_min = 7,
|
||||
.dec_attn_max = 11,
|
||||
.dec_thresh_l = 45,
|
||||
.dec_thresh_h1 = 100,
|
||||
.dec_thresh_h2 = 115,
|
||||
.chan_attn_min = 4,
|
||||
.chan_attn_max = 14,
|
||||
.chan_thresh_l = 52,
|
||||
.chan_thresh_h = 132,
|
||||
.deviceSel = 0,
|
||||
.hpMax = 0,
|
||||
.paDutyCycle = 0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
47
libloragw/inc/loragw_aux.h
Normal file
47
libloragw/inc/loragw_aux.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
LoRa concentrator HAL common auxiliary functions
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_AUX_H
|
||||
#define _LORAGW_AUX_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
@brief Get a particular bit value from a byte
|
||||
@param b [in] Any byte from which we want a bit value
|
||||
@param p [in] Position of the bit in the byte [0..7]
|
||||
@param n [in] Number of bits we want to get
|
||||
@return The value corresponding the requested bits
|
||||
*/
|
||||
#define TAKE_N_BITS_FROM(b, p, n) (((b) >> (p)) & ((1 << (n)) - 1))
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
/**
|
||||
@brief Wait for a certain time (millisecond accuracy)
|
||||
@param t number of milliseconds to wait.
|
||||
*/
|
||||
void wait_ms(unsigned long t);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
59
libloragw/inc/loragw_cal.h
Normal file
59
libloragw/inc/loragw_cal.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
LoRa concentrator radio calibration functions
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_CAL_H
|
||||
#define _LORAGW_CAL_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types*/
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC TYPES --------------------------------------------------------- */
|
||||
|
||||
struct lgw_sx125x_cal_rx_result_s {
|
||||
int8_t amp;
|
||||
int8_t phi;
|
||||
uint16_t rej;
|
||||
uint16_t rej_init;
|
||||
uint16_t snr;
|
||||
};
|
||||
|
||||
struct lgw_sx125x_cal_tx_result_s {
|
||||
uint8_t dac_gain;
|
||||
uint8_t mix_gain;
|
||||
int8_t offset_i;
|
||||
int8_t offset_q;
|
||||
uint16_t rej;
|
||||
uint16_t sig;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
int sx1302_cal_start(uint8_t version, struct lgw_conf_rxrf_s * rf_chain_cfg, struct lgw_tx_gain_lut_s * txgain_lut);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
74
libloragw/inc/loragw_debug.h
Normal file
74
libloragw/inc/loragw_debug.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
LoRa concentrator HAL debug functions
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_DBG_H
|
||||
#define _LORAGW_DBG_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
/**
|
||||
@brief
|
||||
@param
|
||||
*/
|
||||
void dbg_log_buffer_to_file(FILE * file, uint8_t * buffer, uint16_t size);
|
||||
|
||||
/**
|
||||
@brief
|
||||
@param
|
||||
*/
|
||||
void dbg_log_payload_diff_to_file(FILE * file, uint8_t * buffer1, uint8_t * buffer2, uint16_t size);
|
||||
|
||||
/**
|
||||
@brief
|
||||
@param
|
||||
*/
|
||||
void dbg_init_random(void);
|
||||
|
||||
/**
|
||||
@brief
|
||||
@param
|
||||
*/
|
||||
void dbg_generate_random_payload(uint32_t pkt_cnt, uint8_t * buffer_expected, uint8_t size);
|
||||
|
||||
/**
|
||||
@brief
|
||||
@param
|
||||
*/
|
||||
int dbg_check_payload(struct lgw_conf_debug_s * context, FILE * file, uint8_t * payload_received, uint8_t size, uint8_t ref_payload_idx, uint8_t sf);
|
||||
|
||||
/**
|
||||
@brief
|
||||
@param
|
||||
*/
|
||||
void dbg_init_gpio(void);
|
||||
|
||||
/**
|
||||
@brief
|
||||
@param
|
||||
*/
|
||||
void dbg_toggle_gpio(void);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
234
libloragw/inc/loragw_gps.h
Normal file
234
libloragw/inc/loragw_gps.h
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Library of functions to manage a GNSS module (typically GPS) for accurate
|
||||
timestamping of packets and synchronisation of gateways.
|
||||
A limited set of module brands/models are supported.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_GPS_H
|
||||
#define _LORAGW_GPS_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <time.h> /* time library */
|
||||
#include <termios.h> /* speed_t */
|
||||
#include <unistd.h> /* ssize_t */
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC TYPES --------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
@struct coord_s
|
||||
@brief Time solution required for timestamp to absolute time conversion
|
||||
*/
|
||||
struct tref {
|
||||
time_t systime; /*!> system time when solution was calculated */
|
||||
uint32_t count_us; /*!> reference concentrator internal timestamp */
|
||||
struct timespec utc; /*!> reference UTC time (from GPS/NMEA) */
|
||||
struct timespec gps; /*!> reference GPS time (since 01.Jan.1980) */
|
||||
double xtal_err; /*!> raw clock error (eg. <1 'slow' XTAL) */
|
||||
};
|
||||
|
||||
/**
|
||||
@struct coord_s
|
||||
@brief Geodesic coordinates
|
||||
*/
|
||||
struct coord_s {
|
||||
double lat; /*!> latitude [-90,90] (North +, South -) */
|
||||
double lon; /*!> longitude [-180,180] (East +, West -)*/
|
||||
short alt; /*!> altitude in meters (WGS 84 geoid ref.) */
|
||||
};
|
||||
|
||||
/**
|
||||
@enum gps_msg
|
||||
@brief Type of GPS (and other GNSS) sentences
|
||||
*/
|
||||
enum gps_msg {
|
||||
UNKNOWN, /*!> neutral value */
|
||||
IGNORED, /*!> frame was not parsed by the system */
|
||||
INVALID, /*!> system try to parse frame but failed */
|
||||
INCOMPLETE, /*!> frame parsed was missing bytes */
|
||||
/* NMEA messages of interest */
|
||||
NMEA_RMC, /*!> Recommended Minimum data (time + date) */
|
||||
NMEA_GGA, /*!> Global positioning system fix data (pos + alt) */
|
||||
NMEA_GNS, /*!> GNSS fix data (pos + alt, sat number) */
|
||||
NMEA_ZDA, /*!> Time and Date */
|
||||
/* NMEA message useful for time reference quality assessment */
|
||||
NMEA_GBS, /*!> GNSS Satellite Fault Detection */
|
||||
NMEA_GST, /*!> GNSS Pseudo Range Error Statistics */
|
||||
NMEA_GSA, /*!> GNSS DOP and Active Satellites (sat number) */
|
||||
NMEA_GSV, /*!> GNSS Satellites in View (sat SNR) */
|
||||
/* Misc. NMEA messages */
|
||||
NMEA_GLL, /*!> Latitude and longitude, with time fix and status */
|
||||
NMEA_TXT, /*!> Text Transmission */
|
||||
NMEA_VTG, /*!> Course over ground and Ground speed */
|
||||
/* uBlox proprietary NMEA messages of interest */
|
||||
UBX_NAV_TIMEGPS, /*!> GPS Time Solution */
|
||||
UBX_NAV_TIMEUTC /*!> UTC Time Solution */
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
#define LGW_GPS_SUCCESS 0
|
||||
#define LGW_GPS_ERROR -1
|
||||
|
||||
#define LGW_GPS_MIN_MSG_SIZE (8)
|
||||
#define LGW_GPS_UBX_SYNC_CHAR (0xB5)
|
||||
#define LGW_GPS_NMEA_SYNC_CHAR (0x24)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
/**
|
||||
@brief Configure a GPS module
|
||||
|
||||
@param tty_path path to the TTY connected to the GPS
|
||||
@param gps_familly parameter (eg. ubx6 for uBlox gen.6)
|
||||
@param target_brate target baudrate for communication (0 keeps default target baudrate)
|
||||
@param fd_ptr pointer to a variable to receive file descriptor on GPS tty
|
||||
@return success if the function was able to connect and configure a GPS module
|
||||
*/
|
||||
int lgw_gps_enable(char* tty_path, char* gps_familly, speed_t target_brate, int* fd_ptr);
|
||||
|
||||
/**
|
||||
@brief Restore GPS serial configuration and close serial device
|
||||
|
||||
@param fd file descriptor on GPS tty
|
||||
@return success if the function was able to complete
|
||||
*/
|
||||
int lgw_gps_disable(int fd);
|
||||
|
||||
/**
|
||||
@brief Parse messages coming from the GPS system (or other GNSS)
|
||||
|
||||
@param serial_buff pointer to the string to be parsed
|
||||
@param buff_size maximum string lengths for NMEA parsing (incl. null char)
|
||||
@return type of frame parsed
|
||||
|
||||
The RAW NMEA sentences are parsed to a global set of variables shared with the
|
||||
lgw_gps_get function.
|
||||
If the lgw_parse_nmea and lgw_gps_get are used in different threads, a mutex
|
||||
lock must be acquired before calling either function.
|
||||
*/
|
||||
enum gps_msg lgw_parse_nmea(const char* serial_buff, int buff_size);
|
||||
|
||||
/**
|
||||
@brief Parse Ublox proprietary messages coming from the GPS system
|
||||
|
||||
@param serial_buff pointer to the string to be parsed
|
||||
@param buff_size maximum string lengths for UBX parsing (incl. null char)
|
||||
@param msg_size number of bytes parsed as UBX message if found
|
||||
@return type of frame parsed
|
||||
|
||||
The RAW UBX sentences are parsed to a global set of variables shared with the
|
||||
lgw_gps_get function.
|
||||
If the lgw_parse_ubx and lgw_gps_get are used in different threads, a mutex
|
||||
lock must be acquired before calling either function.
|
||||
*/
|
||||
enum gps_msg lgw_parse_ubx(const char* serial_buff, size_t buff_size, size_t *msg_size);
|
||||
|
||||
/**
|
||||
@brief Get the GPS solution (space & time) for the concentrator
|
||||
|
||||
@param utc pointer to store UTC time, with ns precision (NULL to ignore)
|
||||
@param gps_time pointer to store GPS time, with ns precision (NULL to ignore)
|
||||
@param loc pointer to store coordinates (NULL to ignore)
|
||||
@param err pointer to store coordinates standard deviation (NULL to ignore)
|
||||
@return success if the chosen elements could be returned
|
||||
|
||||
This function read the global variables generated by the NMEA/UBX parsing
|
||||
functions lgw_parse_nmea/lgw_parse_ubx. It returns time and location data in a
|
||||
format that is exploitable by other functions in that library sub-module.
|
||||
If the lgw_parse_nmea/lgw_parse_ubx and lgw_gps_get are used in different
|
||||
threads, a mutex lock must be acquired before calling either function.
|
||||
*/
|
||||
int lgw_gps_get(struct timespec *utc, struct timespec *gps_time, struct coord_s *loc, struct coord_s *err);
|
||||
|
||||
/**
|
||||
@brief Get time and position information from the serial GPS last message received
|
||||
@param utc UTC time, with ns precision (leap seconds are ignored)
|
||||
@param gps_time timestamp of last time pulse from the GPS module converted to the UNIX epoch
|
||||
(leap seconds are ignored)
|
||||
@param loc location information
|
||||
@param err location error estimate if supported
|
||||
@return success if timestamp was read and time reference could be refreshed
|
||||
|
||||
Set systime to 0 in ref to trigger initial synchronization.
|
||||
*/
|
||||
int lgw_gps_sync(struct tref *ref, uint32_t count_us, struct timespec utc, struct timespec gps_time);
|
||||
|
||||
/**
|
||||
@brief Convert concentrator timestamp counter value to UTC time
|
||||
|
||||
@param ref time reference structure required for time conversion
|
||||
@param count_us internal timestamp counter of the LoRa concentrator
|
||||
@param utc pointer to store UTC time, with ns precision (leap seconds ignored)
|
||||
@return success if the function was able to convert timestamp to UTC
|
||||
|
||||
This function is typically used when a packet is received to transform the
|
||||
internal counter-based timestamp in an absolute timestamp with an accuracy in
|
||||
the order of a couple microseconds (ns resolution).
|
||||
*/
|
||||
int lgw_cnt2utc(struct tref ref, uint32_t count_us, struct timespec* utc);
|
||||
|
||||
/**
|
||||
@brief Convert UTC time to concentrator timestamp counter value
|
||||
|
||||
@param ref time reference structure required for time conversion
|
||||
@param utc UTC time, with ns precision (leap seconds are ignored)
|
||||
@param count_us pointer to store internal timestamp counter of LoRa concentrator
|
||||
@return success if the function was able to convert UTC to timestamp
|
||||
|
||||
This function is typically used when a packet must be sent at an accurate time
|
||||
(eg. to send a piggy-back response after receiving a packet from a node) to
|
||||
transform an absolute UTC time into a matching internal concentrator timestamp.
|
||||
*/
|
||||
int lgw_utc2cnt(struct tref ref,struct timespec utc, uint32_t* count_us);
|
||||
|
||||
/**
|
||||
@brief Convert concentrator timestamp counter value to GPS time
|
||||
|
||||
@param ref time reference structure required for time conversion
|
||||
@param count_us internal timestamp counter of the LoRa concentrator
|
||||
@param gps_time pointer to store GPS time, with ns precision (leap seconds ignored)
|
||||
@return success if the function was able to convert timestamp to GPS time
|
||||
|
||||
This function is typically used when a packet is received to transform the
|
||||
internal counter-based timestamp in an absolute timestamp with an accuracy in
|
||||
the order of a millisecond.
|
||||
*/
|
||||
int lgw_cnt2gps(struct tref ref, uint32_t count_us, struct timespec* gps_time);
|
||||
|
||||
/**
|
||||
@brief Convert GPS time to concentrator timestamp counter value
|
||||
|
||||
@param ref time reference structure required for time conversion
|
||||
@param gps_time GPS time, with ns precision (leap seconds are ignored)
|
||||
@param count_us pointer to store internal timestamp counter of LoRa concentrator
|
||||
@return success if the function was able to convert GPS time to timestamp
|
||||
|
||||
This function is typically used when a packet must be sent at an accurate time
|
||||
(eg. to send a piggy-back response after receiving a packet from a node) to
|
||||
transform an absolute GPS time into a matching internal concentrator timestamp.
|
||||
*/
|
||||
int lgw_gps2cnt(struct tref ref, struct timespec gps_time, uint32_t* count_us);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
463
libloragw/inc/loragw_hal.h
Normal file
463
libloragw/inc/loragw_hal.h
Normal file
|
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
LoRa concentrator Hardware Abstraction Layer
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_HAL_H
|
||||
#define _LORAGW_HAL_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdbool.h> /* bool type */
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
#define IS_LORA_BW(bw) ((bw == BW_125KHZ) || (bw == BW_250KHZ) || (bw == BW_500KHZ))
|
||||
#define IS_LORA_DR(dr) ((dr == DR_LORA_SF5) || (dr == DR_LORA_SF6) || (dr == DR_LORA_SF7) || (dr == DR_LORA_SF8) || (dr == DR_LORA_SF9) || (dr == DR_LORA_SF10) || (dr == DR_LORA_SF11) || (dr == DR_LORA_SF12))
|
||||
#define IS_LORA_CR(cr) ((cr == CR_LORA_4_5) || (cr == CR_LORA_4_6) || (cr == CR_LORA_4_7) || (cr == CR_LORA_4_8))
|
||||
|
||||
#define IS_FSK_BW(bw) ((bw >= 1) && (bw <= 7))
|
||||
#define IS_FSK_DR(dr) ((dr >= DR_FSK_MIN) && (dr <= DR_FSK_MAX))
|
||||
|
||||
#define IS_TX_MODE(mode) ((mode == IMMEDIATE) || (mode == TIMESTAMPED) || (mode == ON_GPS))
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
/* return status code */
|
||||
#define LGW_HAL_SUCCESS 0
|
||||
#define LGW_HAL_ERROR -1
|
||||
#define LGW_LBT_ISSUE 1
|
||||
|
||||
/* radio-specific parameters */
|
||||
#define LGW_XTAL_FREQU 32000000 /* frequency of the RF reference oscillator */
|
||||
#define LGW_RF_CHAIN_NB 2 /* number of RF chains */
|
||||
#define LGW_RF_RX_BANDWIDTH {1000000, 1000000} /* bandwidth of the radios */
|
||||
|
||||
/* concentrator chipset-specific parameters */
|
||||
/* to use array parameters, declare a local const and use 'if_chain' as index */
|
||||
#define LGW_IF_CHAIN_NB 10 /* number of IF+modem RX chains */
|
||||
#define LGW_REF_BW 125000 /* typical bandwidth of data channel */
|
||||
#define LGW_MULTI_NB 8 /* number of LoRa 'multi SF' chains */
|
||||
|
||||
/* values available for the 'modulation' parameters */
|
||||
/* NOTE: arbitrary values */
|
||||
#define MOD_UNDEFINED 0
|
||||
#define MOD_CW 0x08
|
||||
#define MOD_LORA 0x10
|
||||
#define MOD_FSK 0x20
|
||||
|
||||
/* values available for the 'bandwidth' parameters (LoRa & FSK) */
|
||||
/* NOTE: directly encode FSK RX bandwidth, do not change */
|
||||
#define BW_UNDEFINED 0
|
||||
#define BW_500KHZ 0x06
|
||||
#define BW_250KHZ 0x05
|
||||
#define BW_125KHZ 0x04
|
||||
|
||||
/* values available for the 'datarate' parameters */
|
||||
/* NOTE: LoRa values used directly to code SF bitmask in 'multi' modem, do not change */
|
||||
#define DR_UNDEFINED 0
|
||||
#define DR_LORA_SF5 5
|
||||
#define DR_LORA_SF6 6
|
||||
#define DR_LORA_SF7 7
|
||||
#define DR_LORA_SF8 8
|
||||
#define DR_LORA_SF9 9
|
||||
#define DR_LORA_SF10 10
|
||||
#define DR_LORA_SF11 11
|
||||
#define DR_LORA_SF12 12
|
||||
/* NOTE: for FSK directly use baudrate between 500 bauds and 250 kbauds */
|
||||
#define DR_FSK_MIN 500
|
||||
#define DR_FSK_MAX 250000
|
||||
|
||||
/* values available for the 'coderate' parameters (LoRa only) */
|
||||
/* NOTE: arbitrary values */
|
||||
#define CR_UNDEFINED 0
|
||||
#define CR_LORA_4_5 0x01
|
||||
#define CR_LORA_4_6 0x02
|
||||
#define CR_LORA_4_7 0x03
|
||||
#define CR_LORA_4_8 0x04
|
||||
|
||||
/* values available for the 'status' parameter */
|
||||
/* NOTE: values according to hardware specification */
|
||||
#define STAT_UNDEFINED 0x00
|
||||
#define STAT_NO_CRC 0x01
|
||||
#define STAT_CRC_BAD 0x11
|
||||
#define STAT_CRC_OK 0x10
|
||||
|
||||
/* values available for the 'tx_mode' parameter */
|
||||
#define IMMEDIATE 0
|
||||
#define TIMESTAMPED 1
|
||||
#define ON_GPS 2
|
||||
|
||||
/* values available for 'select' in the status function */
|
||||
#define TX_STATUS 1
|
||||
#define RX_STATUS 2
|
||||
|
||||
/* status code for TX_STATUS */
|
||||
/* NOTE: arbitrary values */
|
||||
#define TX_STATUS_UNKNOWN 0
|
||||
#define TX_OFF 1 /* TX modem disabled, it will ignore commands */
|
||||
#define TX_FREE 2 /* TX modem is free, ready to receive a command */
|
||||
#define TX_SCHEDULED 3 /* TX modem is loaded, ready to send the packet after an event and/or delay */
|
||||
#define TX_EMITTING 4 /* TX modem is emitting */
|
||||
|
||||
/* status code for RX_STATUS */
|
||||
/* NOTE: arbitrary values */
|
||||
#define RX_STATUS_UNKNOWN 0
|
||||
#define RX_OFF 1 /* RX modem is disabled, it will ignore commands */
|
||||
#define RX_ON 2 /* RX modem is receiving */
|
||||
#define RX_SUSPENDED 3 /* RX is suspended while a TX is ongoing */
|
||||
|
||||
/* Maximum size of Tx gain LUT */
|
||||
#define TX_GAIN_LUT_SIZE_MAX 16
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC TYPES --------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
@enum lgw_radio_type_t
|
||||
@brief Radio types that can be found on the LoRa Gateway
|
||||
*/
|
||||
typedef enum {
|
||||
LGW_RADIO_TYPE_NONE,
|
||||
LGW_RADIO_TYPE_SX1255,
|
||||
LGW_RADIO_TYPE_SX1257,
|
||||
LGW_RADIO_TYPE_SX1272,
|
||||
LGW_RADIO_TYPE_SX1276,
|
||||
LGW_RADIO_TYPE_SX1250
|
||||
} lgw_radio_type_t;
|
||||
|
||||
/**
|
||||
@struct lgw_conf_board_s
|
||||
@brief Configuration structure for board specificities
|
||||
*/
|
||||
struct lgw_conf_board_s {
|
||||
bool lorawan_public; /*!> Enable ONLY for *public* networks using the LoRa MAC protocol */
|
||||
uint8_t clksrc; /*!> Index of RF chain which provides clock to concentrator */
|
||||
bool full_duplex; /*!> Indicates if the gateway operates in full duplex mode or not */
|
||||
char spidev_path[64];/*!> Path to access the SPI device to connect to the SX1302 */
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_rssi_tcomp_s
|
||||
@brief Structure containing all coefficients necessary to compute the offset to be applied on RSSI for current temperature
|
||||
*/
|
||||
struct lgw_rssi_tcomp_s {
|
||||
float coeff_a;
|
||||
float coeff_b;
|
||||
float coeff_c;
|
||||
float coeff_d;
|
||||
float coeff_e;
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_conf_rxrf_s
|
||||
@brief Configuration structure for a RF chain
|
||||
*/
|
||||
struct lgw_conf_rxrf_s {
|
||||
bool enable; /*!> enable or disable that RF chain */
|
||||
uint32_t freq_hz; /*!> center frequency of the radio in Hz */
|
||||
float rssi_offset; /*!> Board-specific RSSI correction factor */
|
||||
struct lgw_rssi_tcomp_s rssi_tcomp; /*!> Board-specific RSSI temperature compensation coefficients */
|
||||
lgw_radio_type_t type; /*!> Radio type for that RF chain (SX1255, SX1257....) */
|
||||
bool tx_enable; /*!> enable or disable TX on that RF chain */
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_conf_rxif_s
|
||||
@brief Configuration structure for an IF chain
|
||||
*/
|
||||
struct lgw_conf_rxif_s {
|
||||
bool enable; /*!> enable or disable that IF chain */
|
||||
uint8_t rf_chain; /*!> to which RF chain is that IF chain associated */
|
||||
int32_t freq_hz; /*!> center frequ of the IF chain, relative to RF chain frequency */
|
||||
uint8_t bandwidth; /*!> RX bandwidth, 0 for default */
|
||||
uint32_t datarate; /*!> RX datarate, 0 for default */
|
||||
uint8_t sync_word_size; /*!> size of FSK sync word (number of bytes, 0 for default) */
|
||||
uint64_t sync_word; /*!> FSK sync word (ALIGN RIGHT, eg. 0xC194C1) */
|
||||
bool implicit_hdr; /*!> LoRa Service implicit header */
|
||||
uint8_t implicit_payload_length; /*!> LoRa Service implicit header payload length (number of bytes, 0 for default) */
|
||||
bool implicit_crc_en; /*!> LoRa Service implicit header CRC enable */
|
||||
uint8_t implicit_coderate; /*!> LoRa Service implicit header coding rate */
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_pkt_rx_s
|
||||
@brief Structure containing the metadata of a packet that was received and a pointer to the payload
|
||||
*/
|
||||
struct lgw_pkt_rx_s {
|
||||
uint32_t freq_hz; /*!> central frequency of the IF chain */
|
||||
int32_t freq_offset;
|
||||
uint8_t if_chain; /*!> by which IF chain was packet received */
|
||||
uint8_t status; /*!> status of the received packet */
|
||||
uint32_t count_us; /*!> internal concentrator counter for timestamping, 1 microsecond resolution */
|
||||
uint8_t rf_chain; /*!> through which RF chain the packet was received */
|
||||
uint8_t modem_id;
|
||||
uint8_t modulation; /*!> modulation used by the packet */
|
||||
uint8_t bandwidth; /*!> modulation bandwidth (LoRa only) */
|
||||
uint32_t datarate; /*!> RX datarate of the packet (SF for LoRa) */
|
||||
uint8_t coderate; /*!> error-correcting code of the packet (LoRa only) */
|
||||
float rssic; /*!> average RSSI of the channel in dB */
|
||||
float rssis; /*!> average RSSI of the signal in dB */
|
||||
float snr; /*!> average packet SNR, in dB (LoRa only) */
|
||||
float snr_min; /*!> minimum packet SNR, in dB (LoRa only) */
|
||||
float snr_max; /*!> maximum packet SNR, in dB (LoRa only) */
|
||||
uint16_t crc; /*!> CRC that was received in the payload */
|
||||
uint16_t size; /*!> payload size in bytes */
|
||||
uint8_t payload[256]; /*!> buffer containing the payload */
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_pkt_tx_s
|
||||
@brief Structure containing the configuration of a packet to send and a pointer to the payload
|
||||
*/
|
||||
struct lgw_pkt_tx_s {
|
||||
uint32_t freq_hz; /*!> center frequency of TX */
|
||||
uint8_t tx_mode; /*!> select on what event/time the TX is triggered */
|
||||
uint32_t count_us; /*!> timestamp or delay in microseconds for TX trigger */
|
||||
uint8_t rf_chain; /*!> through which RF chain will the packet be sent */
|
||||
int8_t rf_power; /*!> TX power, in dBm */
|
||||
uint8_t modulation; /*!> modulation to use for the packet */
|
||||
int8_t freq_offset; /*!> frequency offset from Radio Tx frequency (CW mode) */
|
||||
uint8_t bandwidth; /*!> modulation bandwidth (LoRa only) */
|
||||
uint32_t datarate; /*!> TX datarate (baudrate for FSK, SF for LoRa) */
|
||||
uint8_t coderate; /*!> error-correcting code of the packet (LoRa only) */
|
||||
bool invert_pol; /*!> invert signal polarity, for orthogonal downlinks (LoRa only) */
|
||||
uint8_t f_dev; /*!> frequency deviation, in kHz (FSK only) */
|
||||
uint16_t preamble; /*!> set the preamble length, 0 for default */
|
||||
bool no_crc; /*!> if true, do not send a CRC in the packet */
|
||||
bool no_header; /*!> if true, enable implicit header mode (LoRa), fixed length (FSK) */
|
||||
uint16_t size; /*!> payload size in bytes */
|
||||
uint8_t payload[256]; /*!> buffer containing the payload */
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_tx_gain_s
|
||||
@brief Structure containing all gains of Tx chain
|
||||
*/
|
||||
struct lgw_tx_gain_s {
|
||||
int8_t rf_power; /*!> measured TX power at the board connector, in dBm */
|
||||
uint8_t dig_gain; /*!> (sx125x) 2 bits: control of the digital gain of SX1302 */
|
||||
uint8_t pa_gain; /*!> (sx125x) 2 bits: control of the external PA (SX1302 I/O)
|
||||
(sx1250) 1 bits: enable/disable the external PA (SX1302 I/O) */
|
||||
uint8_t dac_gain; /*!> (sx125x) 2 bits: control of the radio DAC */
|
||||
uint8_t mix_gain; /*!> (sx125x) 4 bits: control of the radio mixer */
|
||||
int8_t offset_i; /*!> (sx125x) calibrated I offset */
|
||||
int8_t offset_q; /*!> (sx125x) calibrated Q offset */
|
||||
uint8_t pwr_idx; /*!> (sx1250) 6 bits: control the radio power index to be used for configuration */
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_tx_gain_lut_s
|
||||
@brief Structure defining the Tx gain LUT
|
||||
*/
|
||||
struct lgw_tx_gain_lut_s {
|
||||
struct lgw_tx_gain_s lut[TX_GAIN_LUT_SIZE_MAX]; /*!> Array of Tx gain struct */
|
||||
uint8_t size; /*!> Number of LUT indexes */
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_conf_debug_s
|
||||
@brief Configuration structure for debug
|
||||
*/
|
||||
struct conf_ref_payload_s {
|
||||
uint32_t id;
|
||||
uint8_t payload[255];
|
||||
uint32_t prev_cnt;
|
||||
};
|
||||
struct lgw_conf_debug_s {
|
||||
uint8_t nb_ref_payload;
|
||||
struct conf_ref_payload_s ref_payload[16];
|
||||
char log_file_name[128];
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_conf_debug_s
|
||||
@brief Configuration structure for debug
|
||||
*/
|
||||
struct lgw_conf_timestamp_s {
|
||||
bool enable_precision_ts;
|
||||
uint8_t max_ts_metrics;
|
||||
uint8_t nb_symbols;
|
||||
};
|
||||
|
||||
/**
|
||||
@struct lgw_context_s
|
||||
@brief Configuration context shared across modules
|
||||
*/
|
||||
typedef struct lgw_context_s {
|
||||
/* Global context */
|
||||
bool is_started;
|
||||
struct lgw_conf_board_s board_cfg;
|
||||
/* RX context */
|
||||
struct lgw_conf_rxrf_s rf_chain_cfg[LGW_RF_CHAIN_NB];
|
||||
struct lgw_conf_rxif_s if_chain_cfg[LGW_IF_CHAIN_NB];
|
||||
struct lgw_conf_rxif_s lora_service_cfg; /* LoRa service channel config parameters */
|
||||
struct lgw_conf_rxif_s fsk_cfg; /* FSK channel config parameters */
|
||||
/* TX context */
|
||||
struct lgw_tx_gain_lut_s tx_gain_lut[LGW_RF_CHAIN_NB];
|
||||
/* Misc */
|
||||
struct lgw_conf_timestamp_s timestamp_cfg;
|
||||
/* Debug */
|
||||
struct lgw_conf_debug_s debug_cfg;
|
||||
} lgw_context_t;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
/**
|
||||
@brief Configure the gateway board
|
||||
@param conf structure containing the configuration parameters
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_board_setconf(struct lgw_conf_board_s * conf);
|
||||
|
||||
/**
|
||||
@brief Configure an RF chain (must configure before start)
|
||||
@param rf_chain number of the RF chain to configure [0, LGW_RF_CHAIN_NB - 1]
|
||||
@param conf structure containing the configuration parameters
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_rxrf_setconf(uint8_t rf_chain, struct lgw_conf_rxrf_s * conf);
|
||||
|
||||
/**
|
||||
@brief Configure an IF chain + modem (must configure before start)
|
||||
@param if_chain number of the IF chain + modem to configure [0, LGW_IF_CHAIN_NB - 1]
|
||||
@param conf structure containing the configuration parameters
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_rxif_setconf(uint8_t if_chain, struct lgw_conf_rxif_s * conf);
|
||||
|
||||
/**
|
||||
@brief Configure the Tx gain LUT
|
||||
@param pointer to structure defining the LUT
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_txgain_setconf(uint8_t rf_chain, struct lgw_tx_gain_lut_s * conf);
|
||||
|
||||
/**
|
||||
@brief Configure the precision timestamp
|
||||
@param pointer to structure defining the config to be applied
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_timestamp_setconf(struct lgw_conf_timestamp_s * conf);
|
||||
|
||||
/**
|
||||
@brief Configure the debug context
|
||||
@param pointer to structure defining the config to be applied
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_debug_setconf(struct lgw_conf_debug_s * conf);
|
||||
|
||||
/**
|
||||
@brief Connect to the LoRa concentrator, reset it and configure it according to previously set parameters
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_start(void);
|
||||
|
||||
/**
|
||||
@brief Stop the LoRa concentrator and disconnect it
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_stop(void);
|
||||
|
||||
/**
|
||||
@brief A non-blocking function that will fetch up to 'max_pkt' packets from the LoRa concentrator FIFO and data buffer
|
||||
@param max_pkt maximum number of packet that must be retrieved (equal to the size of the array of struct)
|
||||
@param pkt_data pointer to an array of struct that will receive the packet metadata and payload pointers
|
||||
@return LGW_HAL_ERROR id the operation failed, else the number of packets retrieved
|
||||
*/
|
||||
int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s * pkt_data);
|
||||
|
||||
/**
|
||||
@brief Schedule a packet to be send immediately or after a delay depending on tx_mode
|
||||
@param pkt_data structure containing the data and metadata for the packet to send
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
|
||||
/!\ When sending a packet, there is a delay (approx 1.5ms) for the analog
|
||||
circuitry to start and be stable. This delay is adjusted by the HAL depending
|
||||
on the board version (lgw_i_tx_start_delay_us).
|
||||
|
||||
In 'timestamp' mode, this is transparent: the modem is started
|
||||
lgw_i_tx_start_delay_us microseconds before the user-set timestamp value is
|
||||
reached, the preamble of the packet start right when the internal timestamp
|
||||
counter reach target value.
|
||||
|
||||
In 'immediate' mode, the packet is emitted as soon as possible: transferring the
|
||||
packet (and its parameters) from the host to the concentrator takes some time,
|
||||
then there is the lgw_i_tx_start_delay_us, then the packet is emitted.
|
||||
|
||||
In 'triggered' mode (aka PPS/GPS mode), the packet, typically a beacon, is
|
||||
emitted lgw_i_tx_start_delay_us microsenconds after a rising edge of the
|
||||
trigger signal. Because there is no way to anticipate the triggering event and
|
||||
start the analog circuitry beforehand, that delay must be taken into account in
|
||||
the protocol.
|
||||
*/
|
||||
int lgw_send(struct lgw_pkt_tx_s * pkt_data);
|
||||
|
||||
/**
|
||||
@brief Give the the status of different part of the LoRa concentrator
|
||||
@param select is used to select what status we want to know
|
||||
@param code is used to return the status code
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_status(uint8_t rf_chain, uint8_t select, uint8_t * code);
|
||||
|
||||
/**
|
||||
@brief Abort a currently scheduled or ongoing TX
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_abort_tx(uint8_t rf_chain);
|
||||
|
||||
/**
|
||||
@brief Return value of internal counter when latest event (eg GPS pulse) was captured
|
||||
@param trig_cnt_us pointer to receive timestamp value
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_get_trigcnt(uint32_t * trig_cnt_us);
|
||||
|
||||
/**
|
||||
@brief Return instateneous value of internal counter
|
||||
@param inst_cnt_us pointer to receive timestamp value
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_get_instcnt(uint32_t * inst_cnt_us);
|
||||
|
||||
/**
|
||||
@brief Return the LoRa concentrator EUI
|
||||
@param eui pointer to receive eui
|
||||
@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else
|
||||
*/
|
||||
int lgw_get_eui(uint64_t * eui);
|
||||
|
||||
/**
|
||||
@brief Allow user to check the version/options of the library once compiled
|
||||
@return pointer on a human-readable null terminated string
|
||||
*/
|
||||
const char* lgw_version_info(void);
|
||||
|
||||
/**
|
||||
@brief Return time on air of given packet, in milliseconds
|
||||
@param packet is a pointer to the packet structure
|
||||
@return the packet time on air in milliseconds
|
||||
*/
|
||||
uint32_t lgw_time_on_air(struct lgw_pkt_tx_s * packet);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
75
libloragw/inc/loragw_i2c.h
Normal file
75
libloragw/inc/loragw_i2c.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Host specific functions to address the LoRa concentrator I2C peripherals.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_I2C_H
|
||||
#define _LORAGW_I2C_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types*/
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
#define LGW_I2C_SUCCESS 0
|
||||
#define LGW_I2C_ERROR -1
|
||||
|
||||
#define I2C_DEVICE "/dev/i2c-1"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
/**
|
||||
@brief Open I2C port
|
||||
@param path Path to the I2C device driver (absolute or relative)
|
||||
@param device_addr Address of the device
|
||||
@param i2c_fd Pointer to receive I2C port file descriptor index
|
||||
@return 0 if I2C port was open successfully, -1 else
|
||||
*/
|
||||
int i2c_linuxdev_open(const char *path, uint8_t device_addr, int *i2c_fd);
|
||||
|
||||
/**
|
||||
@brief Close I2C port
|
||||
@param i2c_fd I2C port file descriptor index
|
||||
@return 0 if I2C port was closed successfully, -1 else
|
||||
*/
|
||||
int i2c_linuxdev_close(int i2c_fd);
|
||||
|
||||
/**
|
||||
@brief Read data from an I2C port
|
||||
@param i2c_fd I2C port file descriptor index
|
||||
@param device_addr I2C device address
|
||||
@param reg_addr Address of the register to be read
|
||||
@param data Pointer to a buffer to store read data
|
||||
@return 0 if I2C data read is successful, -1 else
|
||||
*/
|
||||
int i2c_linuxdev_read(int i2c_fd, uint8_t device_addr, uint8_t reg_addr, uint8_t *data);
|
||||
|
||||
/**
|
||||
@brief Write data to an I2C port
|
||||
@param i2c_fd I2C port file descriptor index
|
||||
@param device_addr I2C device address
|
||||
@param reg_addr Address of the register to write to
|
||||
@param data byte to write in the register
|
||||
@return 0 if I2C data write is successful, -1 else
|
||||
*/
|
||||
int i2c_linuxdev_write(int i2c_fd, uint8_t device_addr, uint8_t reg_addr, uint8_t data);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
1493
libloragw/inc/loragw_reg.h
Normal file
1493
libloragw/inc/loragw_reg.h
Normal file
File diff suppressed because it is too large
Load diff
102
libloragw/inc/loragw_spi.h
Normal file
102
libloragw/inc/loragw_spi.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Host specific functions to address the LoRa concentrator registers through
|
||||
a SPI interface.
|
||||
Single-byte read/write and burst read/write.
|
||||
Could be used with multiple SPI ports in parallel (explicit file descriptor)
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_SPI_H
|
||||
#define _LORAGW_SPI_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types*/
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
#define LGW_SPI_SUCCESS 0
|
||||
#define LGW_SPI_ERROR -1
|
||||
#define LGW_BURST_CHUNK 1024
|
||||
|
||||
#define SPI_SPEED 2000000
|
||||
|
||||
#define LGW_SPI_MUX_TARGET_SX1302 0x00
|
||||
#define LGW_SPI_MUX_TARGET_RADIOA 0x01
|
||||
#define LGW_SPI_MUX_TARGET_RADIOB 0x02
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
/**
|
||||
@brief LoRa concentrator SPI setup (configure I/O and peripherals)
|
||||
@param spidev_path path to the SPI device to be used to connect to the SX1302
|
||||
@param spi_target_ptr pointer on a generic pointer to SPI target (implementation dependant)
|
||||
@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
|
||||
*/
|
||||
|
||||
int lgw_spi_open(const char * spidev_path, void **spi_target_ptr);
|
||||
|
||||
/**
|
||||
@brief LoRa concentrator SPI close
|
||||
@param spi_target generic pointer to SPI target (implementation dependant)
|
||||
@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
|
||||
*/
|
||||
|
||||
int lgw_spi_close(void *spi_target);
|
||||
|
||||
/**
|
||||
@brief LoRa concentrator SPI single-byte write
|
||||
@param spi_target generic pointer to SPI target (implementation dependant)
|
||||
@param address 7-bit register address
|
||||
@param data data byte to write
|
||||
@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
|
||||
*/
|
||||
int lgw_spi_w(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t data);
|
||||
|
||||
/**
|
||||
@brief LoRa concentrator SPI single-byte read
|
||||
@param spi_target generic pointer to SPI target (implementation dependant)
|
||||
@param address 7-bit register address
|
||||
@param data data byte to write
|
||||
@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
|
||||
*/
|
||||
int lgw_spi_r(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t *data);
|
||||
|
||||
/**
|
||||
@brief LoRa concentrator SPI burst (multiple-byte) write
|
||||
@param spi_target generic pointer to SPI target (implementation dependant)
|
||||
@param address 7-bit register address
|
||||
@param data pointer to byte array that will be sent to the LoRa concentrator
|
||||
@param size size of the transfer, in byte(s)
|
||||
@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
|
||||
*/
|
||||
int lgw_spi_wb(void *spi_target, uint8_t spi_mux_target, uint16_t address, const uint8_t *data, uint16_t size);
|
||||
|
||||
/**
|
||||
@brief LoRa concentrator SPI burst (multiple-byte) read
|
||||
@param spi_target generic pointer to SPI target (implementation dependant)
|
||||
@param address 7-bit register address
|
||||
@param data pointer to byte array that will be written from the LoRa concentrator
|
||||
@param size size of the transfer, in byte(s)
|
||||
@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR)
|
||||
*/
|
||||
int lgw_spi_rb(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t *data, uint16_t size);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
57
libloragw/inc/loragw_stts751.h
Normal file
57
libloragw/inc/loragw_stts751.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Basic driver for ST ts751 temperature sensor
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_STTS751_H
|
||||
#define _LORAGW_STTS751_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdbool.h> /* bool type */
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- INTERNAL SHARED TYPES ------------------------------------------------ */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- INTERNAL SHARED FUNCTIONS -------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
#define I2C_PORT_TEMP_SENSOR 0x39
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS ----------------------------------------------------- */
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int lgw_stts751_configure(void);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int lgw_stts751_get_temperature(float * temperature);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
101
libloragw/inc/loragw_sx1250.h
Normal file
101
libloragw/inc/loragw_sx1250.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Functions used to handle LoRa concentrator SX1250 radios.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_SX1250_H
|
||||
#define _LORAGW_SX1250_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types*/
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
#define SX1250_FREQ_TO_REG(f) (uint32_t)((uint64_t)f * (1 << 25) / 32000000U)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC TYPES --------------------------------------------------------- */
|
||||
|
||||
typedef enum {
|
||||
CALIBRATE_IMAGE = 0x98,
|
||||
CLR_IRQ_STATUS = 0x02,
|
||||
STOP_TIMER_ON_PREAMBLE = 0x9F,
|
||||
SET_RFSWITCHMODE = 0x9D,
|
||||
GET_IRQ_STATUS = 0x12,
|
||||
GET_RX_BUFFER_STATUS = 0x13,
|
||||
GET_PACKET_STATUS = 0x14,
|
||||
READ_BUFFER = 0x1E,
|
||||
READ_REGISTER = 0x1D,
|
||||
SET_DIO_IRQ_PARAMS = 0x08,
|
||||
SET_MODULATION_PARAMS = 0x8B,
|
||||
SET_PA_CONFIG = 0x95,
|
||||
SET_PACKET_PARAMS = 0x8C,
|
||||
SET_PACKET_TYPE = 0x8A,
|
||||
SET_RF_FREQUENCY = 0x86,
|
||||
SET_BUFFER_BASE_ADDRESS = 0x8F,
|
||||
SET_SLEEP = 0x84,
|
||||
SET_STANDBY = 0x80,
|
||||
SET_RX = 0x82,
|
||||
SET_TX = 0x83,
|
||||
SET_TX_PARAMS = 0x8E,
|
||||
WRITE_BUFFER = 0x0E,
|
||||
WRITE_REGISTER = 0x0D,
|
||||
SET_TXCONTINUOUSWAVE = 0xD1,
|
||||
SET_TXCONTINUOUSPREAMBLE= 0xD2,
|
||||
GET_STATUS = 0xC0,
|
||||
SET_REGULATORMODE = 0x96,
|
||||
SET_FS = 0xC1,
|
||||
GET_DEVICE_ERRORS = 0x17
|
||||
} sx1250_op_code_t;
|
||||
|
||||
typedef enum {
|
||||
STDBY_RC = 0x00,
|
||||
STDBY_XOSC = 0x01
|
||||
} sx1250_standby_modes_t;
|
||||
|
||||
typedef enum {
|
||||
PACKET_TYPE_GFSK = 0x00,
|
||||
PACKET_TYPE_LORA = 0x01
|
||||
} sx1250_packet_type_t;
|
||||
|
||||
typedef enum {
|
||||
SET_RAMP_10U = 0x00,
|
||||
SET_RAMP_20U = 0x01,
|
||||
SET_RAMP_40U = 0x02,
|
||||
SET_RAMP_80U = 0x03,
|
||||
SET_RAMP_200U = 0x04,
|
||||
SET_RAMP_800U = 0x05,
|
||||
SET_RAMP_1700U = 0x06,
|
||||
SET_RAMP_3400U = 0x07
|
||||
} sx1250_ramp_time_t;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
int sx1250_write_command(uint8_t rf_chain, sx1250_op_code_t op_code, uint8_t *data, uint16_t size);
|
||||
int sx1250_read_command(uint8_t rf_chain, sx1250_op_code_t op_code, uint8_t *data, uint16_t size);
|
||||
|
||||
int sx1250_calibrate(uint8_t rf_chain, uint32_t freq_hz);
|
||||
int sx1250_setup(uint8_t rf_chain, uint32_t freq_hz);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
148
libloragw/inc/loragw_sx125x.h
Normal file
148
libloragw/inc/loragw_sx125x.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Functions used to handle LoRa concentrator SX1255/SX1257 radios.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
#ifndef _LORAGW_SX125X_H
|
||||
#define _LORAGW_SX125X_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdbool.h> /* bool type */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- INTERNAL SHARED TYPES ------------------------------------------------ */
|
||||
|
||||
struct radio_reg_s
|
||||
{
|
||||
uint8_t addr; /* base address of the register */
|
||||
uint8_t offs; /* position of the register LSB (between 0 to 7) */
|
||||
uint8_t leng; /* number of bits in the register */
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
#define SX1257_FREQ_TO_REG(f) (uint32_t)((uint64_t)f * (1 << 19) / 32000000U)
|
||||
#define SX1255_FREQ_TO_REG(f) (uint32_t)((uint64_t)f * (1 << 20) / 32000000U)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
#define LGW_REG_SUCCESS 0
|
||||
#define LGW_REG_ERROR -1
|
||||
|
||||
#define SX125x_32MHz_FRAC 15625 /* irreductible fraction for PLL register caculation */
|
||||
|
||||
#define SX125x_TX_DAC_CLK_SEL 0 /* 0:int, 1:ext */
|
||||
#define SX125x_TX_DAC_GAIN 2 /* 3:0, 2:-3, 1:-6, 0:-9 dBFS (default 2) */
|
||||
#define SX125x_TX_MIX_GAIN 14 /* -38 + 2*TxMixGain dB (default 14) */
|
||||
#define SX125x_TX_PLL_BW 1 /* 0:75, 1:150, 2:225, 3:300 kHz (default 3) */
|
||||
#define SX125x_TX_ANA_BW 0 /* 17.5 / 2*(41-TxAnaBw) MHz (default 0) */
|
||||
#define SX125x_TX_DAC_BW 5 /* 24 + 8*TxDacBw Nb FIR taps (default 2) */
|
||||
#define SX125x_RX_LNA_GAIN 1 /* 1 to 6, 1 highest gain */
|
||||
#define SX125x_RX_BB_GAIN 15 /* 0 to 15 , 15 highest gain */
|
||||
#define SX125x_LNA_ZIN 0 /* 0:50, 1:200 Ohms (default 1) */
|
||||
#define SX125x_RX_ADC_BW 7 /* 0 to 7, 2:100<BW<200, 5:200<BW<400,7:400<BW kHz SSB (default 7) */
|
||||
#define SX125x_RX_ADC_TRIM 6 /* 0 to 7, 6 for 32MHz ref, 5 for 36MHz ref */
|
||||
#define SX125x_RX_BB_BW 0 /* 0:750, 1:500, 2:375; 3:250 kHz SSB (default 1, max 3) */
|
||||
#define SX125x_RX_PLL_BW 0 /* 0:75, 1:150, 2:225, 3:300 kHz (default 3, max 3) */
|
||||
#define SX125x_ADC_TEMP 0 /* ADC temperature measurement mode (default 0) */
|
||||
#define SX125x_XOSC_GM_STARTUP 13 /* (default 13) */
|
||||
#define SX125x_XOSC_DISABLE 2 /* Disable of Xtal Oscillator blocks bit0:regulator, bit1:core(gm), bit2:amplifier */
|
||||
|
||||
typedef enum {
|
||||
SX125x_REG_MODE = 0,
|
||||
SX125x_REG_MODE__PA_DRIVER_EN = 1,
|
||||
SX125x_REG_MODE__TX_EN = 2,
|
||||
SX125x_REG_MODE__RX_EN = 3,
|
||||
SX125x_REG_MODE__STANDBY_EN = 4,
|
||||
SX125x_REG_FRF_RX_MSB = 5,
|
||||
SX125x_REG_FRF_RX_MID = 6,
|
||||
SX125x_REG_FRF_RX_LSB = 7,
|
||||
SX125x_REG_FRF_TX_MSB = 8,
|
||||
SX125x_REG_FRF_TX_MID = 9,
|
||||
SX125x_REG_FRF_TX_LSB = 10,
|
||||
SX125x_REG_VERSION = 11,
|
||||
SX125x_REG_TX_GAIN = 12,
|
||||
SX125x_REG_TX_GAIN__DAC_GAIN = 13,
|
||||
SX125x_REG_TX_GAIN__MIX_GAIN = 14,
|
||||
SX125x_REG_TX_BW = 15,
|
||||
SX125x_REG_TX_BW__PLL_BW = 16,
|
||||
SX125x_REG_TX_BW__ANA_BW = 17,
|
||||
SX125x_REG_TX_DAC_BW = 18,
|
||||
SX125x_REG_RX_ANA_GAIN = 19,
|
||||
SX125x_REG_RX_ANA_GAIN__LNA_GAIN = 20,
|
||||
SX125x_REG_RX_ANA_GAIN__BB_GAIN = 21,
|
||||
SX125x_REG_RX_ANA_GAIN__LNA_ZIN = 22,
|
||||
SX125x_REG_RX_BW = 23,
|
||||
SX125x_REG_RX_BW__ADC_BW = 24,
|
||||
SX125x_REG_RX_BW__ADC_TRIM = 25,
|
||||
SX125x_REG_RX_BW__BB_BW = 26,
|
||||
SX125x_REG_RX_PLL_BW = 27,
|
||||
SX125x_REG_RX_PLL_BW__PLL_BW = 28,
|
||||
SX125x_REG_RX_PLL_BW__ADC_TEMP_EN = 29,
|
||||
SX125x_REG_DIO_MAPPING = 30,
|
||||
SX125x_REG_DIO_MAPPING__DIO_0_MAPPING = 31,
|
||||
SX125x_REG_DIO_MAPPING__DIO_1_MAPPING = 32,
|
||||
SX125x_REG_DIO_MAPPING__DIO_2_MAPPING = 33,
|
||||
SX125x_REG_DIO_MAPPING__DIO_3_MAPPING = 34,
|
||||
SX125x_REG_CLK_SELECT = 35,
|
||||
SX125x_REG_CLK_SELECT__DIG_LOOPBACK_EN = 36,
|
||||
SX125x_REG_CLK_SELECT__RF_LOOPBACK_EN = 37,
|
||||
SX125x_REG_CLK_SELECT__CLK_OUT = 38,
|
||||
SX125x_REG_CLK_SELECT__DAC_CLK_SELECT = 39,
|
||||
SX125x_REG_MODE_STATUS = 40,
|
||||
SX125x_REG_MODE_STATUS__LOW_BAT_EN = 41,
|
||||
SX125x_REG_MODE_STATUS__RX_PLL_LOCKED = 42,
|
||||
SX125x_REG_MODE_STATUS__TX_PLL_LOCKED = 43,
|
||||
SX125x_REG_LOW_BAT_THRESH = 44,
|
||||
SX125x_REG_SX1257_XOSC_TEST = 45,
|
||||
SX125x_REG_SX1257_XOSC_TEST__DISABLE = 46,
|
||||
SX125x_REG_SX1257_XOSC_TEST__GM_STARTUP = 47,
|
||||
SX125x_REG_SX1255_XOSC_TEST = 48,
|
||||
SX125x_REG_SX1255_XOSC_TEST__DISABLE = 49,
|
||||
SX125x_REG_SX1255_XOSC_TEST__GM_STARTUP = 50
|
||||
}
|
||||
radio_reg_t;
|
||||
|
||||
#define RADIO_TOTALREGS 51
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
/*
|
||||
|
||||
SX1257 frequency setting :
|
||||
F_register(24bit) = F_rf (Hz) / F_step(Hz)
|
||||
= F_rf (Hz) * 2^19 / F_xtal(Hz)
|
||||
= F_rf (Hz) * 2^19 / 32e6
|
||||
= F_rf (Hz) * 256/15625
|
||||
|
||||
SX1255 frequency setting :
|
||||
F_register(24bit) = F_rf (Hz) / F_step(Hz)
|
||||
= F_rf (Hz) * 2^20 / F_xtal(Hz)
|
||||
= F_rf (Hz) * 2^20 / 32e6
|
||||
= F_rf (Hz) * 512/15625
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
int sx125x_setup(uint8_t rf_chain, uint8_t rf_clkout, bool rf_enable, uint8_t rf_radio_type, uint32_t freq_hz);
|
||||
|
||||
int lgw_sx125x_reg_w(radio_reg_t idx, uint8_t data, uint8_t rf_chain);
|
||||
int lgw_sx125x_reg_r(radio_reg_t idx, uint8_t *data, uint8_t rf_chain);
|
||||
|
||||
#endif
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
437
libloragw/inc/loragw_sx1302.h
Normal file
437
libloragw/inc/loragw_sx1302.h
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
SX1302 Hardware Abstraction Layer entry functions.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
#ifndef _LORAGW_SX1302_H
|
||||
#define _LORAGW_SX1302_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types*/
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
/* Default values */
|
||||
#define SX1302_AGC_RADIO_GAIN_AUTO 0xFF
|
||||
#define TX_START_DELAY_DEFAULT 1500 /* Calibrated value for 500KHz BW */
|
||||
|
||||
/* type of if_chain + modem */
|
||||
#define IF_UNDEFINED 0
|
||||
#define IF_LORA_STD 0x10 /* if + standard single-SF LoRa modem */
|
||||
#define IF_LORA_MULTI 0x11 /* if + LoRa receiver with multi-SF capability */
|
||||
#define IF_FSK_STD 0x20 /* if + standard FSK modem */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
#define REG_SELECT(rf_chain, a, b) ((rf_chain == 0) ? a : b)
|
||||
|
||||
#define SET_PPM_ON(bw,dr) (((bw == BW_125KHZ) && ((dr == DR_LORA_SF11) || (dr == DR_LORA_SF12))) || ((bw == BW_250KHZ) && (dr == DR_LORA_SF12)))
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC TYPES --------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
@struct sx1302_if_cfg_t
|
||||
@brief TODO
|
||||
*/
|
||||
typedef struct {
|
||||
bool if_enable;
|
||||
bool if_rf_chain; /* for each IF, 0 -> radio A, 1 -> radio B */
|
||||
int32_t if_freq; /* relative to radio frequency, +/- in Hz */
|
||||
} sx1302_if_cfg_t;
|
||||
|
||||
/**
|
||||
@struct sx1302_lora_service_cfg_t
|
||||
@brief TODO
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t lora_rx_bw; /* bandwidth setting for LoRa standalone modem */
|
||||
uint8_t lora_rx_sf; /* spreading factor setting for LoRa standalone modem */
|
||||
bool lora_rx_implicit_hdr; /* implicit header setting for LoRa standalone modem */
|
||||
uint8_t lora_rx_implicit_length; /* implicit header payload length setting for LoRa standalone modem */
|
||||
bool lora_rx_implicit_crc_en; /* implicit header payload crc enable setting for LoRa standalone modem */
|
||||
uint8_t lora_rx_implicit_coderate; /* implicit header payload coderate setting for LoRa standalone modem */
|
||||
} sx1302_lora_service_cfg_t;
|
||||
|
||||
/**
|
||||
@struct sx1302_fsk_cfg_t
|
||||
@brief TODO
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t fsk_rx_bw; /* bandwidth setting of FSK modem */
|
||||
uint32_t fsk_rx_dr; /* FSK modem datarate in bauds */
|
||||
uint8_t fsk_sync_word_size; /* default number of bytes for FSK sync word */
|
||||
uint64_t fsk_sync_word; /* default FSK sync word (ALIGNED RIGHT, MSbit first) */
|
||||
} sx1302_fsk_cfg_t;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
void sx1302_init(struct lgw_conf_timestamp_s *conf);
|
||||
|
||||
/**
|
||||
@brief Get the SX1302 unique identifier
|
||||
@param eui pointerto the memory holding the concentrator EUI
|
||||
@return LGW_REG_SUCCESS if no error, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_get_eui(uint64_t * eui);
|
||||
|
||||
/**
|
||||
@brief Check AGC & ARB MCUs parity error, and update timestamp counter wraping status
|
||||
@brief This function needs to be called regularly (every few seconds) by the upper layer
|
||||
@param N/A
|
||||
@return LGW_REG_SUCCESS if no error, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_update(void);
|
||||
|
||||
/**
|
||||
@brief Select the clock source radio
|
||||
@param rf_chain The RF chain index from which to get the clock source
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_radio_clock_select(uint8_t rf_chain);
|
||||
|
||||
/**
|
||||
@brief Apply the radio reset sequence to the required RF chain index
|
||||
@param rf_chain The RF chain index of the radio to be reset
|
||||
@param type The type of radio to be reset
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_radio_reset(uint8_t rf_chain, lgw_radio_type_t type);
|
||||
|
||||
/**
|
||||
@brief Configure the radio type for the given RF chain
|
||||
@param rf_chain The RF chain index to be configured
|
||||
@param type The type of radio to be set for the given RF chain
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_radio_set_mode(uint8_t rf_chain, lgw_radio_type_t type);
|
||||
|
||||
/**
|
||||
@brief Give/Release control over the radios to/from the Host
|
||||
@param host_ctrl Set to true to give control to the host, false otherwise
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_radio_host_ctrl(bool host_ctrl);
|
||||
|
||||
/**
|
||||
@brief Perform the radio calibration sequence and fill the TX gain LUT with calibration offsets
|
||||
@param context_rf_chain The RF chains array from which to get RF chains current configuration
|
||||
@param clksrc The RF chain index which provides the clock source
|
||||
@param txgain_lut A pointer to the TX gain LUT to be filled
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_radio_calibrate(struct lgw_conf_rxrf_s * context_rf_chain, uint8_t clksrc, struct lgw_tx_gain_lut_s * txgain_lut);
|
||||
|
||||
/**
|
||||
@brief Configure the PA and LNA LUTs
|
||||
@param N/A
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_pa_lna_lut_configure(void);
|
||||
|
||||
/**
|
||||
@brief Configure the Radio Front-End stage of the SX1302
|
||||
@param N/A
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_radio_fe_configure(void);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
uint8_t sx1302_get_ifmod_config(uint8_t if_chain);
|
||||
|
||||
/**
|
||||
@brief Configure the channelizer stage of the SX1302
|
||||
@param if_cfg A pointer to the channels configuration
|
||||
@param fix_gain Set to true to force the channelizer to a fixed gain, false to let the AGC controlling it
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_channelizer_configure(struct lgw_conf_rxif_s * if_cfg, bool fix_gain);
|
||||
|
||||
/**
|
||||
@brief Configure the correlator stage of the SX1302 LoRa multi-SF modems
|
||||
@param N/A
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_lora_correlator_configure(void);
|
||||
|
||||
/**
|
||||
@brief Configure the correlator stage of the SX1302 LoRa single-SF modem
|
||||
@param cfg A pointer to the channel configuration
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_lora_service_correlator_configure(struct lgw_conf_rxif_s * cfg);
|
||||
|
||||
/**
|
||||
@brief Configure the syncword to be used by LoRa modems (public:0x34, private:0x12)
|
||||
@param public Set to true to use the "public" syncword, false to use the private one
|
||||
@param lora_service_sf The spreading factor configured for the single-SF LoRa modem
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_lora_syncword(bool public, uint8_t lora_service_sf);
|
||||
|
||||
/**
|
||||
@brief Configure the LoRa multi-SF modems
|
||||
@param radio_freq_hz The center frequency of the RF chain (0 or 1)
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_lora_modem_configure(uint32_t radio_freq_hz);
|
||||
|
||||
/**
|
||||
@brief Configure the LoRa single-SF modem
|
||||
@param cfg A pointer to the channel configuration
|
||||
@param radio_freq_hz The center frequency of the RF chain (0 or 1)
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_lora_service_modem_configure(struct lgw_conf_rxif_s * cfg, uint32_t radio_freq_hz);
|
||||
|
||||
/**
|
||||
@brief Configure the FSK modem
|
||||
@param cfg A pointer to the channel configuration
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_fsk_configure(struct lgw_conf_rxif_s * cfg);
|
||||
|
||||
/**
|
||||
@brief Enable the modems
|
||||
@param N/A
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_modem_enable(void);
|
||||
|
||||
/**
|
||||
@brief Enable/Disable the GPS to allow PPS trigger and counter sampling
|
||||
@param enbale Set to true to enable, false otherwise
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_gps_enable(bool enable);
|
||||
|
||||
/**
|
||||
@brief Get the current SX1302 internal counter value
|
||||
@param pps True for getting the counter value at last PPS
|
||||
@return the counter value in mciroseconds (32-bits)
|
||||
*/
|
||||
uint32_t sx1302_timestamp_counter(bool pps);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_agc_load_firmware(const uint8_t *firmware);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_agc_status(uint8_t* status);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_agc_wait_status(uint8_t status);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_agc_mailbox_read(uint8_t mailbox, uint8_t* value);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_agc_mailbox_write(uint8_t mailbox, uint8_t value);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_agc_start(uint8_t version, lgw_radio_type_t radio_type, uint8_t ana_gain, uint8_t dec_gain, uint8_t fdd_mode);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_arb_load_firmware(const uint8_t *firmware);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_arb_status(uint8_t* status);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_arb_wait_status(uint8_t status);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_arb_debug_read(uint8_t reg_id, uint8_t* value);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_arb_debug_write(uint8_t reg_id, uint8_t value);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_arb_start(uint8_t version);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
uint8_t sx1302_arb_get_debug_stats_detect(uint8_t channel);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
uint8_t sx1302_arb_get_debug_stats_alloc(uint8_t channel);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
void sx1302_arb_print_debug_stats(void);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
uint16_t sx1302_lora_payload_crc(const uint8_t * data, uint8_t size);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
uint16_t sx1302_rx_buffer_read_ptr_addr(void);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
uint16_t sx1302_rx_buffer_write_ptr_addr(void);
|
||||
|
||||
/**
|
||||
@brief Check if any data to be fetched from the SX1302 RX buffer and fetch it if any.
|
||||
@param nb_bytes A pointer to allocated memory to hold the number of bytes fetched
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_fetch(uint16_t * nb_bytes);
|
||||
|
||||
/**
|
||||
@brief Parse and return the next packet available in the fetched RX buffer.
|
||||
@param context Gateway configuration context
|
||||
@param p The structure to get the packet parsed
|
||||
@return LGW_REG_SUCCESS if a packet could be parsed, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_parse(lgw_context_t * context, struct lgw_pkt_rx_s * p);
|
||||
|
||||
/**
|
||||
@brief Configure the delay to be applied by the SX1302 for TX to start
|
||||
@param rf_chain The RF chain index to be configured
|
||||
@param radio_type The type of radio for this RF chain
|
||||
@param modulation The modulation used for the TX
|
||||
@param bandwidth The bandwidth used for the TX
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_tx_set_start_delay(uint8_t rf_chain, lgw_radio_type_t radio_type, uint8_t modulation, uint8_t bandwidth);
|
||||
|
||||
/**
|
||||
@brief Compute the offset to be applied on RSSI for temperature compensation
|
||||
@param context a pointer to the memory that holds the current temp comp context
|
||||
@param temperature the temperature for which to compute the offset to be applied
|
||||
@return the offset to be applied to RSSI
|
||||
*/
|
||||
float sx1302_rssi_get_temperature_offset(struct lgw_rssi_tcomp_s * context, float temperature);
|
||||
|
||||
/**
|
||||
@brief Get current TX status of the SX1302
|
||||
@param rf_chain the TX chain we want to get the status from
|
||||
@return current status
|
||||
*/
|
||||
uint8_t sx1302_tx_status(uint8_t rf_chain);
|
||||
|
||||
/**
|
||||
@brief Get current RX status of the SX1302
|
||||
@param rf_chain the RX chain we want to get the status from
|
||||
@return current status
|
||||
@note NOT IMPLEMENTED
|
||||
*/
|
||||
uint8_t sx1302_rx_status(uint8_t rf_chain);
|
||||
|
||||
/**
|
||||
@brief Abort current transmit
|
||||
@param rf_chain the TX chain on which we want to abort transmit
|
||||
@return LGW_REG_SUCCESS if success, LGW_REG_ERROR otherwise
|
||||
*/
|
||||
int sx1302_tx_abort(uint8_t rf_chain);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_tx_configure(lgw_radio_type_t radio_type);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int sx1302_send(lgw_radio_type_t radio_type, struct lgw_tx_gain_lut_s * tx_lut, bool lwan_public, struct lgw_conf_rxif_s * context_fsk, struct lgw_pkt_tx_s * pkt_data);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
134
libloragw/inc/loragw_sx1302_rx.h
Normal file
134
libloragw/inc/loragw_sx1302_rx.h
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
SX1302 RX buffer Hardware Abstraction Layer
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_SX1302_RX_H
|
||||
#define _LORAGW_SX1302_RX_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types*/
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC TYPES --------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
@struct rx_packet_s
|
||||
@brief packet structure as contained in the sx1302 RX packet engine
|
||||
*/
|
||||
typedef struct rx_packet_s {
|
||||
uint8_t rxbytenb_modem;
|
||||
uint8_t rx_channel_in;
|
||||
bool crc_en;
|
||||
uint8_t coding_rate; /* LoRa only */
|
||||
uint8_t rx_rate_sf; /* LoRa only */
|
||||
uint8_t modem_id;
|
||||
int32_t frequency_offset_error; /* LoRa only */
|
||||
uint8_t payload[255];
|
||||
bool payload_crc_error;
|
||||
bool sync_error; /* LoRa only */
|
||||
bool header_error; /* LoRa only */
|
||||
bool timing_set; /* LoRa only */
|
||||
int8_t snr_average; /* LoRa only */
|
||||
uint8_t rssi_chan_avg;
|
||||
uint8_t rssi_signal_avg; /* LoRa only */
|
||||
uint8_t rssi_chan_max_neg_delta;
|
||||
uint8_t rssi_chan_max_pos_delta;
|
||||
uint8_t rssi_sig_max_neg_delta; /* LoRa only */
|
||||
uint8_t rssi_sig_max_pos_delta; /* LoRa only */
|
||||
uint32_t timestamp_cnt;
|
||||
uint16_t rx_crc16_value; /* LoRa only */
|
||||
uint8_t num_ts_metrics_stored; /* LoRa only */
|
||||
uint8_t timestamp_avg[255]; /* LoRa only */
|
||||
uint8_t timestamp_stddev[255]; /* LoRa only */
|
||||
uint8_t packet_checksum;
|
||||
} rx_packet_t;
|
||||
|
||||
/**
|
||||
@struct rx_buffer_s
|
||||
@brief buffer to hold the data fetched from the sx1302 RX buffer
|
||||
*/
|
||||
typedef struct rx_buffer_s {
|
||||
uint8_t buffer[4096]; /*!> byte array to hald the data fetched from the RX buffer */
|
||||
uint16_t buffer_size; /*!> The number of bytes currently stored in the buffer */
|
||||
int buffer_index; /*!> Current parsing index in the buffer */
|
||||
} rx_buffer_t;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int rx_buffer_new(rx_buffer_t * self);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int rx_buffer_del(rx_buffer_t * self);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int rx_buffer_fetch(rx_buffer_t * self);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int rx_buffer_pop(rx_buffer_t * self, rx_packet_t * pkt);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEBUG FUNCTIONS PROTOTYPES ------------------------------------------- */
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
uint16_t rx_buffer_read_ptr_addr(void);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
uint16_t rx_buffer_write_ptr_addr(void);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
void rx_buffer_dump(FILE * file, uint16_t start_addr, uint16_t end_addr);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
117
libloragw/inc/loragw_sx1302_timestamp.h
Normal file
117
libloragw/inc/loragw_sx1302_timestamp.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
SX1302 timestamp counter Hardware Abstraction Layer
|
||||
Handles the conversion of a 32-bits 32MHz counter into a 32-bits 1 MHz counter.
|
||||
This modules MUST be called regularly by the application to maintain counter
|
||||
wrapping handling for conversion in 1MHz counter.
|
||||
Provides function to compute the correction to be applied to the received
|
||||
timestamp for demodulation processing time.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _LORAGW_SX1302_TIMESTAMP_H
|
||||
#define _LORAGW_SX1302_TIMESTAMP_H
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types*/
|
||||
#include <stdbool.h> /* boolean type */
|
||||
|
||||
|
||||
#include "config.h" /* library configuration options (dynamically generated) */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC CONSTANTS ----------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC MACROS -------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC TYPES --------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
@struct timestamp_counter_s
|
||||
@brief context to maintain the internal counters (inst and pps trig) wrapping
|
||||
*/
|
||||
typedef struct timestamp_counter_s {
|
||||
uint32_t counter_us_raw_27bits_inst_prev;
|
||||
uint32_t counter_us_raw_27bits_pps_prev;
|
||||
uint8_t counter_us_raw_27bits_inst_wrap;
|
||||
uint8_t counter_us_raw_27bits_pps_wrap;
|
||||
} timestamp_counter_t;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS ----------------------------------------------------- */
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
void timestamp_counter_new(timestamp_counter_t * self);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
void timestamp_counter_delete(timestamp_counter_t * self);
|
||||
|
||||
/**
|
||||
@brief Update the counter wrapping status based on given current counter
|
||||
@param self Pointer to the counter handler
|
||||
@param pps Set to true to update the PPS trig counter status
|
||||
@param cnt Current value of the counter to be used for the update
|
||||
@return N/A
|
||||
*/
|
||||
void timestamp_counter_update(timestamp_counter_t * self, bool pps, uint32_t cnt);
|
||||
|
||||
/**
|
||||
@brief Convert the 27-bits counter given by the SX1302 to a 32-bits counter which wraps on a uint32_t.
|
||||
@param self Pointer to the counter handler
|
||||
@param pps Set to true to expand the counter based on the PPS trig wrapping status
|
||||
@param cnt_us The 27-bits counter to be expanded
|
||||
@return the 32-bits counter
|
||||
*/
|
||||
uint32_t timestamp_counter_expand(timestamp_counter_t * self, bool pps, uint32_t cnt_us);
|
||||
|
||||
/**
|
||||
@brief Reads the SX1302 internal counter register, and return the 32-bits 1 MHz counter
|
||||
@param self Pointer to the counter handler
|
||||
@param pps Set to true to expand the counter based on the PPS trig wrapping status
|
||||
@return the current 32-bits counter
|
||||
*/
|
||||
uint32_t timestamp_counter_get(timestamp_counter_t * self, bool pps);
|
||||
|
||||
/**
|
||||
@brief Get the timestamp correction to applied to the packet timestamp
|
||||
@param ifmod modem type
|
||||
@param bandwidth modulation bandwidth
|
||||
@param datarate modulation datarate
|
||||
@param coderate modulation coding rate
|
||||
@param crc_en indicates if CRC is enabled or disabled
|
||||
@param payload_length payload length
|
||||
@return The correction to be applied to the packet timestamp, in microseconds
|
||||
*/
|
||||
uint32_t timestamp_counter_correction(int ifmod, uint8_t bandwidth, uint8_t datarate, uint8_t coderate, uint32_t crc_en, uint16_t payload_length);
|
||||
|
||||
/**
|
||||
@brief TODO
|
||||
@param TODO
|
||||
@return TODO
|
||||
*/
|
||||
int timestamp_counter_mode(bool enable_precision_ts, uint8_t max_ts_metrics, uint8_t nb_symbols);
|
||||
|
||||
#endif
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
19
libloragw/library.cfg
Normal file
19
libloragw/library.cfg
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# That file will be included in the Makefile files that have hardware dependencies
|
||||
|
||||
### Debug options ###
|
||||
# Set the DEBUG_* to 1 to activate debug mode in individual modules.
|
||||
# Warning: that makes the module *very verbose*, do not use for production
|
||||
|
||||
DEBUG_AUX= 0
|
||||
DEBUG_SPI= 0
|
||||
DEBUG_REG= 0
|
||||
DEBUG_HAL= 0
|
||||
DEBUG_LBT= 0
|
||||
DEBUG_GPS= 0
|
||||
DEBUG_RAD= 0
|
||||
DEBUG_CAL= 0
|
||||
DEBUG_SX1302= 0
|
||||
|
||||
### Configuration options ###
|
||||
BYPASS_FW_INIT = 0
|
||||
FPGA_BOARD_16_CH = 1
|
||||
393
libloragw/readme.md
Normal file
393
libloragw/readme.md
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
LoRa concentrator HAL user manual
|
||||
=================================
|
||||
|
||||
## 1. Introduction
|
||||
|
||||
The LoRa concentrator Hardware Abstraction Layer is a C library that allow you
|
||||
to use a Semtech concentrator chip through a reduced number of high level C
|
||||
functions to configure the hardware, send and receive packets.
|
||||
|
||||
The Semtech LoRa concentrator is a digital multi-channel multi-standard packet
|
||||
radio used to send and receive packets wirelessly using LoRa or FSK modulations.
|
||||
|
||||
## 2. Components of the library
|
||||
|
||||
The library is composed of the following modules:
|
||||
|
||||
* loragw_hal
|
||||
* loragw_reg
|
||||
* loragw_spi
|
||||
* loragw_i2c
|
||||
* loragw_aux
|
||||
* loragw_gps
|
||||
* loragw_sx125x
|
||||
* loragw_sx1250
|
||||
* loragw_sx1302
|
||||
* loragw_sx1302_rx
|
||||
* loragw_sx1302_timestamp
|
||||
* loragw_stts751
|
||||
|
||||
The library also contains basic test programs to demonstrate code use and check
|
||||
functionality.
|
||||
|
||||
### 2.1. loragw_hal
|
||||
|
||||
This is the main module and contains the high level functions to configure and
|
||||
use the LoRa concentrator:
|
||||
|
||||
* lgw_board_setconf, to set the configuration of the concentrator
|
||||
* lgw_rxrf_setconf, to set the configuration of the radio channels
|
||||
* lgw_rxif_setconf, to set the configuration of the IF+modem channels
|
||||
* lgw_txgain_setconf, to set the configuration of the concentrator gain table
|
||||
* lgw_start, to apply the set configuration to the hardware and start it
|
||||
* lgw_stop, to stop the hardware
|
||||
* lgw_receive, to fetch packets if any was received
|
||||
* lgw_send, to send a single packet (non-blocking, see warning in usage section)
|
||||
* lgw_status, to check when a packet has effectively been sent
|
||||
|
||||
For an standard application, include only this module.
|
||||
The use of this module is detailed on the usage section.
|
||||
|
||||
/!\ When sending a packet, there is a delay (approx 1.5ms) for the analog
|
||||
circuitry to start and be stable. This delay is adjusted by the HAL depending
|
||||
on the board version (lgw_i_tx_start_delay_us).
|
||||
|
||||
In 'timestamp' mode, this is transparent: the modem is started
|
||||
lgw_i_tx_start_delay_us microseconds before the user-set timestamp value is
|
||||
reached, the preamble of the packet start right when the internal timestamp
|
||||
counter reach target value.
|
||||
|
||||
In 'immediate' mode, the packet is emitted as soon as possible: transferring the
|
||||
packet (and its parameters) from the host to the concentrator takes some time,
|
||||
then there is the lgw_i_tx_start_delay_us, then the packet is emitted.
|
||||
|
||||
In 'triggered' mode (aka PPS/GPS mode), the packet, typically a beacon, is
|
||||
emitted lgw_i_tx_start_delay_us microsenconds after a rising edge of the
|
||||
trigger signal. Because there is no way to anticipate the triggering event and
|
||||
start the analog circuitry beforehand, that delay must be taken into account in
|
||||
the protocol.
|
||||
|
||||
### 2.2. loragw_reg
|
||||
|
||||
This module is used to access to the LoRa concentrator registers by name instead
|
||||
of by address:
|
||||
|
||||
* lgw_connect, to initialise and check the connection with the hardware
|
||||
* lgw_disconnect, to disconnect the hardware
|
||||
* lgw_reg_r, read a named register
|
||||
* lgw_reg_w, write a named register
|
||||
* lgw_reg_rb, read a name register in burst
|
||||
* lgw_reg_wb, write a named register in burst
|
||||
|
||||
This module handles read-only registers protection, multi-byte registers
|
||||
management, signed registers management, read-modify-write routines for
|
||||
sub-byte registers and read/write burst fragmentation to respect SPI maximum
|
||||
burst length constraints.
|
||||
|
||||
It make the code much easier to read and to debug.
|
||||
Moreover, if registers are relocated between different hardware revisions but
|
||||
keep the same function, the code written using register names can be reused "as
|
||||
is".
|
||||
|
||||
If you need access to all the registers, include this module in your
|
||||
application.
|
||||
|
||||
**/!\ Warning** please be sure to have a good understanding of the LoRa
|
||||
concentrator inner working before accessing the internal registers directly.
|
||||
|
||||
### 2.3. loragw_spi
|
||||
|
||||
This module contains the functions to access the LoRa concentrator register
|
||||
array through the SPI interface:
|
||||
|
||||
* lgw_spi_r to read one byte
|
||||
* lgw_spi_w to write one byte
|
||||
* lgw_spi_rb to read two bytes or more
|
||||
* lgw_spi_wb to write two bytes or more
|
||||
|
||||
Please *do not* include that module directly into your application.
|
||||
|
||||
**/!\ Warning** Accessing the LoRa concentrator register array without the
|
||||
checks and safety provided by the functions in loragw_reg is not recommended.
|
||||
|
||||
### 2.4. loragw_aux
|
||||
|
||||
This module contains a single host-dependant function wait_ms to pause for a
|
||||
defined amount of milliseconds.
|
||||
|
||||
The procedure to start and configure the LoRa concentrator hardware contained in
|
||||
the loragw_hal module requires to wait for several milliseconds at certain
|
||||
steps, typically to allow for supply voltages or clocks to stabilize after been
|
||||
switched on.
|
||||
|
||||
An accuracy of 1 ms or less is ideal.
|
||||
If your system does not allow that level of accuracy, make sure that the actual
|
||||
delay is *longer* that the time specified when the function is called (ie.
|
||||
wait_ms(X) **MUST NOT** before X milliseconds under any circumstance).
|
||||
|
||||
If the minimum delays are not guaranteed during the configuration and start
|
||||
procedure, the hardware might not work at nominal performance.
|
||||
Most likely, it will not work at all.
|
||||
|
||||
### 2.5. loragw_gps
|
||||
|
||||
This module contains functions to synchronize the concentrator internal
|
||||
counter with an absolute time reference, in our case a GPS satellite receiver.
|
||||
|
||||
The internal concentrator counter is used to timestamp incoming packets and to
|
||||
triggers outgoing packets with a microsecond accuracy.
|
||||
In some cases, it might be useful to be able to transform that internal
|
||||
timestamp (that is independent for each concentrator running in a typical
|
||||
networked system) into an absolute GPS time.
|
||||
|
||||
In a typical implementation a GPS specific thread will be called, doing the
|
||||
following things after opening the serial port:
|
||||
|
||||
* blocking reads on the serial port (using system read() function)
|
||||
* parse UBX messages (using lgw_parse_ubx) to get actual native GPS time
|
||||
* parse NMEA sentences (using lgw_parse_nmea) to get location and UTC time
|
||||
Note: the RMC sentence gives UTC time, not native GPS time.
|
||||
|
||||
And each time an NAV-TIMEGPS UBX message has been received:
|
||||
|
||||
* get the concentrator timestamp (using lgw_get_trigcnt, mutex needed to
|
||||
protect access to the concentrator)
|
||||
* get the GPS time contained in the UBX message (using lgw_gps_get)
|
||||
* call the lgw_gps_sync function (use mutex to protect the time reference that
|
||||
should be a global shared variable).
|
||||
|
||||
Then, in other threads, you can simply used that continuously adjusted time
|
||||
reference to convert internal timestamps to GPS time (using lgw_cnt2gps) or
|
||||
the other way around (using lgw_gps2cnt). Inernal concentrator timestamp can
|
||||
also be converted to/from UTC time using lgw_cnt2utc/lgw_utc2cnt functions.
|
||||
|
||||
### 2.6. loragw_sx125x
|
||||
|
||||
This module contains functions to handle the configuration of SX1255 and
|
||||
SX1257 radios.
|
||||
|
||||
### 2.7. loragw_sx1250
|
||||
|
||||
This module contains functions to handle the configuration of SX1250 radios.
|
||||
|
||||
### 2.8. loragw_sx1302
|
||||
|
||||
This module contains functions to abstract SX1302 concentrator capabilities.
|
||||
|
||||
### 2.9. loragw_sx1302_rx
|
||||
|
||||
This module is a sub-module of the loragw_sx1302 module focusing on abstracting
|
||||
the RX buffer of the SX1302.
|
||||
|
||||
### 2.10. loragw_sx1302_timestamp
|
||||
|
||||
This module is a sub-module of the loragw_sx1302 module focusing on abstracting
|
||||
the timestamp counter of the SX1302.
|
||||
It converts the 32-bits 32MHz internal counter of the SX1302 to a 32-bits 1MHz
|
||||
counter.
|
||||
This module needs to be called regularly by upper layers to maintain counter
|
||||
wrapping when converting from 32MHz to 1MHz.
|
||||
It also provides function to add correction to the timestamp counter to take
|
||||
into account the LoRa demodulation processing time.
|
||||
|
||||
### 2.11. loragw_stts751
|
||||
|
||||
This module contains a very basic driver for the STmicroelectronics ST751
|
||||
temeprature sensor which is on the CoreCell reference design.
|
||||
|
||||
### 2.12. loragw_i2c
|
||||
|
||||
This module provides basic function to communicate with I2C devices on the board.
|
||||
It is used in this project for accessing the temperature sensor.
|
||||
|
||||
## 3. Software build process
|
||||
|
||||
### 3.1. Details of the software
|
||||
|
||||
The library is written following ANSI C conventions but using C99 explicit
|
||||
length data type for all data exchanges with hardware and for parameters.
|
||||
|
||||
The loragw_aux module contains POSIX dependant functions for millisecond
|
||||
accuracy pause.
|
||||
For embedded platforms, the function could be rewritten using hardware timers.
|
||||
|
||||
### 3.2. Building options
|
||||
|
||||
All modules use a fprintf(stderr,...) function to display debug diagnostic
|
||||
messages if the DEBUG_xxx is set to 1 in library.cfg
|
||||
|
||||
### 3.3. Building procedures
|
||||
|
||||
For cross-compilation set the ARCH and CROSS_COMPILE variables in the Makefile,
|
||||
or in your shell environment, with the correct toolchain name and path.
|
||||
ex:
|
||||
export PATH=/home/foo/rpi-toolchain/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH
|
||||
export ARCH=arm
|
||||
export CROSS_COMPILE=arm-linux-gnueabihf-
|
||||
|
||||
The Makefile in the libloragw directory will parse the library.cfg file and
|
||||
generate a config.h C header file containing #define options.
|
||||
Those options enables and disables sections of code in the loragw_xxx.h files
|
||||
and the *.c source files.
|
||||
|
||||
The library.cfg is also used directly to select the proper set of dynamic
|
||||
libraries to be linked with.
|
||||
|
||||
### 3.4. Export
|
||||
|
||||
Once build, to use that library on another system, you need to export the
|
||||
following files :
|
||||
|
||||
* libloragw/library.cfg -> root configuration file
|
||||
* libloragw/libloragw.a -> static library, to be linked with a program
|
||||
* libloragw/readme.md -> required for license compliance
|
||||
* libloragw/inc/config.h -> C configuration flags, derived from library.cfg
|
||||
* libloragw/inc/loragw_*.h -> take only the ones you need (eg. _hal and _gps)
|
||||
|
||||
After statically linking the library to your application, only the license
|
||||
is required to be kept or copied inside your program documentation.
|
||||
|
||||
## 4. Hardware dependencies
|
||||
|
||||
### 4.1. Hardware revision
|
||||
|
||||
The loragw_reg and loragw_hal are written for a specific version on the Semtech
|
||||
hardware (IP and/or silicon revision).
|
||||
|
||||
This code has been written for:
|
||||
|
||||
* Semtech SX1302 chip
|
||||
* Semtech SX1250, SX1257 or SX1255 I/Q transceivers
|
||||
|
||||
The library will not work if there is a mismatch between the hardware version
|
||||
and the library version. You can use the test program test_loragw_reg to check
|
||||
if the hardware registers match their software declaration.
|
||||
|
||||
### 4.2. SPI communication
|
||||
|
||||
loragw_spi contains 4 SPI functions (read, write, burst read, burst write) that
|
||||
are platform-dependant.
|
||||
The functions must be rewritten depending on the SPI bridge you use:
|
||||
|
||||
* SPI master matched to the Linux SPI device driver (provided)
|
||||
* SPI over USB using FTDI components (not provided)
|
||||
* native SPI using a microcontroller peripheral (not provided)
|
||||
|
||||
You can use the test program test_loragw_spi to check with a logic analyser
|
||||
that the SPI communication is working
|
||||
|
||||
### 4.3. GPS receiver (or other GNSS system)
|
||||
|
||||
To use the GPS module of the library, the host must be connected to a GPS
|
||||
receiver via a serial link (or an equivalent receiver using a different
|
||||
satellite constellation).
|
||||
The serial link must appear as a "tty" device in the /dev/ directory, and the
|
||||
user launching the program must have the proper system rights to read and
|
||||
write on that device.
|
||||
Use `chmod a+rw` to allow all users to access that specific tty device, or use
|
||||
sudo to run all your programs (eg. `sudo ./test_loragw_gps`).
|
||||
|
||||
In the current revision, the library only reads data from the serial port,
|
||||
expecting to receive NMEA frames that are generally sent by GPS receivers as
|
||||
soon as they are powered up, and UBX messages which are proprietary to u-blox
|
||||
modules.
|
||||
|
||||
The GPS receiver **MUST** send UBX messages shortly after sending a PPS pulse
|
||||
on to allow internal concentrator timestamps to be converted to absolute GPS time.
|
||||
If the GPS receiver sends a GGA NMEA sentence, the gateway 3D position will
|
||||
also be available.
|
||||
|
||||
## 5. Usage
|
||||
|
||||
### 5.1. Setting the software environment
|
||||
|
||||
For a typical application you need to:
|
||||
|
||||
* include loragw_hal.h in your program source
|
||||
* link to the libloragw.a static library during compilation
|
||||
* link to the librt library due to loragw_aux dependencies (timing functions)
|
||||
|
||||
For an application that will also access the concentrator configuration
|
||||
registers directly (eg. for advanced configuration) you also need to:
|
||||
|
||||
* include loragw_reg.h in your program source
|
||||
|
||||
### 5.2. Using the software API
|
||||
|
||||
To use the HAL in your application, you must follow some basic rules:
|
||||
|
||||
* configure the radios path and IF+modem path before starting the radio
|
||||
* the configuration is only transferred to hardware when you call the *start*
|
||||
function
|
||||
* you cannot receive packets until one (or +) radio is enabled AND one (or +)
|
||||
IF+modem part is enabled AND the concentrator is started
|
||||
* you cannot send packets until one (or +) radio is enabled AND the concentrator
|
||||
is started
|
||||
* you must stop the concentrator before changing the configuration
|
||||
|
||||
A typical application flow for using the HAL is the following:
|
||||
|
||||
<configure the radios and IF+modems>
|
||||
<start the LoRa concentrator>
|
||||
loop {
|
||||
<fetch packets that were received by the concentrator>
|
||||
<process, store and/or forward received packets>
|
||||
<send packets through the concentrator>
|
||||
}
|
||||
<stop the concentrator>
|
||||
|
||||
**/!\ Warning** The lgw_send function is non-blocking and returns while the
|
||||
LoRa concentrator is still sending the packet, or even before the packet has
|
||||
started to be transmitted if the packet is triggered on a future event.
|
||||
While a packet is emitted, no packet can be received (limitation intrinsic to
|
||||
most radio frequency systems).
|
||||
|
||||
Your application *must* take into account the time it takes to send a packet or
|
||||
check the status (using lgw_status) before attempting to send another packet.
|
||||
|
||||
Trying to send a packet while the previous packet has not finished being send
|
||||
will result in the previous packet not being sent or being sent only partially
|
||||
(resulting in a CRC error in the receiver).
|
||||
|
||||
### 5.3. Debugging mode
|
||||
|
||||
To debug your application, it might help to compile the loragw_hal function
|
||||
with the debug messages activated (set DEBUG_HAL=1 in library.cfg).
|
||||
It then send a lot of details, including detailed error messages to *stderr*.
|
||||
|
||||
## 6. License
|
||||
|
||||
Copyright (c) 2019, SEMTECH S.A.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the Semtech corporation nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
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 SEMTECH S.A. 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.
|
||||
|
||||
*EOF*
|
||||
514
libloragw/src/agc_fw_sx1250.var
Normal file
514
libloragw/src/agc_fw_sx1250.var
Normal file
|
|
@ -0,0 +1,514 @@
|
|||
static uint8_t agc_firmware_sx1250[8192] = {
|
||||
0x8A, 0x51, 0xF0, 0x6F, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0x64, 0xC0, 0x80, 0x81, 0x84, 0x0A, 0x04, 0xC6, 0x03, 0x59, 0x00, 0xF4, 0x04, 0xC6,
|
||||
0x12, 0x28, 0xE5, 0x40, 0xCA, 0x00, 0x61, 0x08, 0xCB, 0x40, 0x62, 0x08, 0xCC, 0x00, 0x63, 0x48,
|
||||
0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40, 0x64, 0x08, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0x2F, 0x1D, 0xB0,
|
||||
0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0x8B, 0xB0, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81,
|
||||
0xCF, 0xC1, 0xD0, 0x01, 0xD1, 0x41, 0xDC, 0x40, 0x08, 0xF0, 0xDD, 0xC1, 0x6B, 0x67, 0x8A, 0x51,
|
||||
0x4D, 0x48, 0x83, 0x96, 0xBA, 0x40, 0x83, 0x52, 0x4C, 0x08, 0x83, 0x96, 0xB9, 0x40, 0x83, 0x52,
|
||||
0x4B, 0x48, 0x83, 0x96, 0xB8, 0x00, 0x83, 0x52, 0x4A, 0x08, 0x83, 0x96, 0xB7, 0x80, 0x1D, 0xB0,
|
||||
0x83, 0x52, 0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0x8B, 0xB0, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81,
|
||||
0xCE, 0x81, 0xCF, 0xC1, 0xD0, 0x01, 0xD1, 0x41, 0xDC, 0x40, 0x08, 0xF0, 0xDD, 0xC1, 0xDD, 0x0A,
|
||||
0x6B, 0x67, 0x4D, 0x48, 0x83, 0x96, 0xBE, 0x80, 0x83, 0x52, 0x4C, 0x08, 0x83, 0x96, 0xBD, 0x80,
|
||||
0x83, 0x52, 0x4B, 0x48, 0x83, 0x96, 0xBC, 0x40, 0x83, 0x52, 0x4A, 0x08, 0x83, 0x96, 0xBB, 0x80,
|
||||
0x08, 0x40, 0xE3, 0x40, 0xC1, 0x70, 0xCA, 0x00, 0x4A, 0x70, 0xDC, 0x40, 0x63, 0x48, 0xDD, 0x80,
|
||||
0x01, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x07, 0x70, 0xE2, 0x00, 0x3A, 0xB0, 0xE1, 0x00, 0xE1, 0xCB,
|
||||
0x77, 0x28, 0xE2, 0xCB, 0x77, 0x28, 0x00, 0x00, 0x0D, 0x70, 0x83, 0x52, 0x03, 0x53, 0xCA, 0x00,
|
||||
0x05, 0x30, 0xCB, 0x40, 0x84, 0x30, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xDC, 0x40, 0x63, 0x48,
|
||||
0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x0D, 0x70, 0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40,
|
||||
0x85, 0x70, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xDC, 0x40, 0x63, 0x48, 0xDD, 0x80, 0x04, 0xF0,
|
||||
0x32, 0xE7, 0x8A, 0x51, 0x0D, 0x70, 0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40, 0x82, 0x30, 0xCC, 0x00,
|
||||
0x4A, 0x70, 0xCD, 0x81, 0xDC, 0x40, 0x63, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51,
|
||||
0x0D, 0x70, 0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40, 0x80, 0xF0, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81,
|
||||
0xDC, 0x40, 0x63, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x0D, 0x70, 0xCA, 0x00,
|
||||
0x05, 0x30, 0xCB, 0x40, 0x83, 0x70, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xDC, 0x40, 0x63, 0x48,
|
||||
0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x63, 0x83, 0x03, 0x9D, 0xC9, 0xA8, 0x9C, 0x91,
|
||||
0xCA, 0xA8, 0x1C, 0x51, 0x05, 0x30, 0xE1, 0x00, 0xE1, 0xCB, 0xCC, 0xA8, 0x0D, 0x70, 0x83, 0x52,
|
||||
0x03, 0x53, 0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40, 0x87, 0xB0, 0xCC, 0x00, 0x0B, 0x70, 0xCD, 0x40,
|
||||
0x4A, 0x70, 0xDC, 0x40, 0x63, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x00, 0xB0,
|
||||
0xE3, 0x88, 0x03, 0x9D, 0xE8, 0xA8, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0xF3, 0x30, 0xEC, 0xE8,
|
||||
0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x3F, 0x30, 0xC9, 0x85, 0x49, 0x08, 0xDC, 0x40, 0x00, 0xB0,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x63, 0x98, 0xFB, 0x68, 0x00, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00,
|
||||
0xFE, 0xF9, 0x01, 0x38, 0x01, 0x29, 0x00, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0xEF, 0xF9,
|
||||
0x10, 0x38, 0xC9, 0x00, 0xDC, 0x40, 0x00, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x00, 0xB0, 0x2A, 0xE7,
|
||||
0x8A, 0x51, 0xC9, 0x00, 0xC9, 0x50, 0x49, 0x08, 0xDC, 0x40, 0x00, 0xB0, 0x22, 0xA7, 0x8A, 0x51,
|
||||
0x00, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0xC9, 0x92, 0x49, 0x08, 0xDC, 0x40, 0x00, 0xB0,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x86, 0x70, 0xCA, 0x00, 0xE3, 0x88, 0x03, 0x9D, 0x2E, 0xE9, 0x83, 0x96,
|
||||
0x3A, 0x48, 0x83, 0x52, 0xCB, 0x40, 0x83, 0x96, 0x39, 0x48, 0x83, 0x52, 0xCC, 0x00, 0x83, 0x96,
|
||||
0x38, 0x08, 0x83, 0x52, 0xCD, 0x40, 0x83, 0x96, 0x37, 0x88, 0x3C, 0xE9, 0x83, 0x96, 0x3E, 0x88,
|
||||
0x83, 0x52, 0xCB, 0x40, 0x83, 0x96, 0x3D, 0x88, 0x83, 0x52, 0xCC, 0x00, 0x83, 0x96, 0x3C, 0x48,
|
||||
0x83, 0x52, 0xCD, 0x40, 0x83, 0x96, 0x3B, 0x88, 0x83, 0x52, 0xCE, 0x40, 0x4A, 0x70, 0xDC, 0x40,
|
||||
0x63, 0x48, 0xDD, 0x80, 0x05, 0x30, 0x32, 0xE7, 0x8A, 0x51, 0x0D, 0x70, 0xCA, 0x00, 0x08, 0xF0,
|
||||
0xCB, 0x40, 0x8F, 0xF0, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81, 0xCF, 0xC1, 0xDC, 0x40,
|
||||
0x63, 0x48, 0xDD, 0x80, 0x06, 0x30, 0x32, 0xE7, 0x8A, 0x51, 0x82, 0x30, 0xCA, 0x00, 0xFF, 0xB0,
|
||||
0xCB, 0x40, 0xCC, 0x00, 0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40, 0x63, 0x48, 0xDD, 0x80, 0x04, 0xF0,
|
||||
0x32, 0xE7, 0x8A, 0x51, 0xC7, 0xF0, 0xE1, 0x00, 0x00, 0x00, 0xE1, 0xCB, 0x64, 0xA9, 0x68, 0xA9,
|
||||
0x00, 0x00, 0x08, 0x40, 0xEC, 0x40, 0xC1, 0x70, 0xCA, 0x00, 0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48,
|
||||
0xDD, 0x80, 0x01, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x9F, 0x30, 0xE1, 0x00, 0xE1, 0xCB, 0x76, 0x29,
|
||||
0x79, 0x29, 0x95, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xCA, 0x00, 0x42, 0xC8, 0xCB, 0x40, 0x41, 0xC8,
|
||||
0xCC, 0x00, 0x40, 0x88, 0xCD, 0x40, 0x4A, 0x70, 0xCE, 0x81, 0xCE, 0xCA, 0xDC, 0x40, 0x6C, 0x48,
|
||||
0xDD, 0x80, 0x05, 0x30, 0x32, 0xE7, 0x8A, 0x51, 0xEC, 0x88, 0x03, 0x9D, 0x91, 0xA9, 0x25, 0x70,
|
||||
0x92, 0xA9, 0x2A, 0x70, 0x2A, 0xE7, 0x8A, 0x51, 0xEB, 0x80, 0xEA, 0x40, 0x3F, 0x30, 0xEA, 0xC5,
|
||||
0x8E, 0xB0, 0xCA, 0x00, 0x6A, 0x48, 0xCB, 0x40, 0x02, 0xF0, 0xCC, 0x00, 0x4A, 0x70, 0xDC, 0x40,
|
||||
0x6C, 0x48, 0xDD, 0x80, 0x03, 0x30, 0x32, 0xE7, 0x8A, 0x51, 0x6B, 0x88, 0xE1, 0x00, 0x06, 0x30,
|
||||
0x03, 0xD0, 0xE1, 0x8C, 0xFF, 0x7E, 0x03, 0x9D, 0xA8, 0xA9, 0x61, 0x08, 0xEA, 0x40, 0x03, 0x30,
|
||||
0xEA, 0xC5, 0x00, 0xB0, 0xEC, 0x88, 0x03, 0x9D, 0xC1, 0xA9, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00,
|
||||
0x6A, 0x48, 0xE1, 0x00, 0x03, 0xD0, 0xE1, 0xCD, 0x03, 0xD0, 0xE1, 0xCD, 0x49, 0x08, 0xF3, 0xB9,
|
||||
0xCE, 0x29, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x6A, 0x48, 0xE1, 0x00, 0x06, 0x30, 0x03, 0xD0,
|
||||
0xE1, 0xCD, 0xFF, 0x7E, 0x03, 0x9D, 0xC7, 0x29, 0x49, 0x08, 0x3F, 0xB9, 0x61, 0x04, 0xC9, 0x00,
|
||||
0xDC, 0x40, 0x00, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0xEC, 0x88, 0x03, 0x9D, 0xE1, 0xE9, 0x27, 0xB0,
|
||||
0x2A, 0xE7, 0x8A, 0x51, 0xEA, 0x40, 0x28, 0x30, 0x2A, 0xE7, 0x8A, 0x51, 0xEB, 0x80, 0x29, 0x70,
|
||||
0xEA, 0x29, 0x2C, 0x70, 0x2A, 0xE7, 0x8A, 0x51, 0xEA, 0x40, 0x2D, 0xB0, 0x2A, 0xE7, 0x8A, 0x51,
|
||||
0xEB, 0x80, 0x2E, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xE3, 0x40, 0x86, 0x70, 0xCA, 0x00, 0x03, 0xD0,
|
||||
0x6A, 0x8C, 0xCB, 0x40, 0x6B, 0x88, 0xE1, 0x00, 0x03, 0xD0, 0xE1, 0x8C, 0x6A, 0x48, 0xE2, 0x00,
|
||||
0x06, 0x30, 0x03, 0xD0, 0xE2, 0xCD, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0xFA, 0x69, 0x62, 0x8D,
|
||||
0x61, 0x04, 0xCC, 0x00, 0x63, 0x48, 0xE1, 0x00, 0x03, 0xD0, 0xE1, 0x8C, 0x6B, 0x88, 0xE2, 0x00,
|
||||
0x06, 0x30, 0x03, 0xD0, 0xE2, 0xCD, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0x0A, 0x6A, 0x62, 0x8D,
|
||||
0x61, 0x04, 0xCD, 0x40, 0x63, 0x48, 0xE1, 0x00, 0x06, 0x30, 0x03, 0xD0, 0xE1, 0xCD, 0xFF, 0x7E,
|
||||
0x03, 0xD0, 0x03, 0x9D, 0x16, 0xAA, 0x61, 0x8D, 0xCE, 0x40, 0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48,
|
||||
0xDD, 0x80, 0x05, 0x30, 0x32, 0xE7, 0x8A, 0x51, 0xE6, 0x81, 0x02, 0xF0, 0x66, 0x42, 0x03, 0x18,
|
||||
0x45, 0xAA, 0xC7, 0xF0, 0xE1, 0x00, 0x00, 0x00, 0xE1, 0xCB, 0x2B, 0xEA, 0x2F, 0x2A, 0x00, 0x00,
|
||||
0x1D, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0xC8, 0x70, 0xCC, 0x00,
|
||||
0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x05, 0x30, 0x6B, 0x67,
|
||||
0x8A, 0x51, 0xCA, 0xDA, 0x45, 0xAA, 0xE6, 0xCA, 0x25, 0xAA, 0x4A, 0x08, 0x20, 0x79, 0x66, 0x44,
|
||||
0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x1D, 0xB0, 0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40,
|
||||
0xDD, 0x30, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80,
|
||||
0x05, 0x30, 0x6B, 0x67, 0x8A, 0x51, 0x4A, 0x08, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51,
|
||||
0x4A, 0x08, 0xE9, 0x40, 0x07, 0x70, 0xE9, 0xC5, 0x04, 0xF0, 0x69, 0x42, 0x03, 0x5C, 0x6A, 0xEA,
|
||||
0x04, 0xF0, 0xE9, 0x40, 0xEC, 0x88, 0x03, 0x9D, 0x74, 0xEA, 0x69, 0x48, 0xDC, 0x40, 0x1D, 0xB0,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x26, 0x70, 0x7B, 0x6A, 0x69, 0xCE, 0xF0, 0x39, 0xDC, 0x40, 0x1D, 0xB0,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x2B, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xEA, 0x40, 0xEA, 0x9F, 0x39, 0x2B,
|
||||
0x3D, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xEB, 0x80, 0x3E, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xEA, 0x40,
|
||||
0x06, 0x30, 0xDC, 0x40, 0x69, 0x48, 0xC6, 0x27, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60,
|
||||
0x8A, 0x51, 0xE8, 0x00, 0x06, 0x30, 0xDC, 0x40, 0x69, 0x48, 0xC6, 0x27, 0x02, 0xBE, 0x84, 0x80,
|
||||
0x8A, 0x95, 0x00, 0x60, 0x8A, 0x51, 0xE7, 0x80, 0x6B, 0x88, 0x68, 0x02, 0x03, 0x5C, 0xA8, 0xAA,
|
||||
0x6B, 0x88, 0x68, 0x46, 0x03, 0x9D, 0xCD, 0x2A, 0x6A, 0x48, 0x67, 0x82, 0x03, 0x18, 0xCD, 0x2A,
|
||||
0x01, 0xF0, 0x9E, 0x40, 0x1D, 0xB0, 0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0xC1, 0x70, 0xCC, 0x00,
|
||||
0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x05, 0x30, 0x6B, 0x67,
|
||||
0x8A, 0x51, 0x4A, 0x08, 0xEB, 0x80, 0x1F, 0x79, 0xE0, 0xB8, 0xEB, 0x80, 0x0D, 0x70, 0xCA, 0x00,
|
||||
0x08, 0xF0, 0xCB, 0x40, 0xC1, 0x70, 0xCC, 0x00, 0x6B, 0x88, 0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40,
|
||||
0x6C, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x06, 0x30, 0xDC, 0x40, 0x69, 0x48,
|
||||
0xC6, 0x27, 0x03, 0xFE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x51, 0xE8, 0x00, 0x06, 0x30,
|
||||
0xDC, 0x40, 0x69, 0x48, 0xC6, 0x27, 0x04, 0xBE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x51,
|
||||
0xE7, 0x80, 0x6B, 0x88, 0x68, 0x02, 0x03, 0x5C, 0xED, 0x6A, 0x6B, 0x88, 0x68, 0x46, 0x03, 0x9D,
|
||||
0xFF, 0x2B, 0x6A, 0x48, 0x67, 0x82, 0x03, 0x18, 0xFF, 0x2B, 0x06, 0x30, 0xDC, 0x40, 0x69, 0x48,
|
||||
0xC6, 0x27, 0x05, 0xFE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x51, 0xE8, 0x00, 0x06, 0x30,
|
||||
0xDC, 0x40, 0x69, 0x48, 0xC6, 0x27, 0x06, 0xFE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x51,
|
||||
0xE7, 0x80, 0x6B, 0x88, 0x68, 0x02, 0x03, 0x5C, 0x0D, 0xEB, 0x6B, 0x88, 0x68, 0x46, 0x03, 0x9D,
|
||||
0x23, 0xEB, 0x6A, 0x48, 0x67, 0x82, 0x03, 0x18, 0x23, 0xEB, 0x03, 0x30, 0x9E, 0x40, 0x1D, 0xB0,
|
||||
0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0xC2, 0x70, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81,
|
||||
0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x05, 0x30, 0x6B, 0x67, 0x8A, 0x51, 0x4A, 0x08, 0xEB, 0x80,
|
||||
0xE1, 0x39, 0x0E, 0xB8, 0xEF, 0xEB, 0x02, 0xF0, 0x9E, 0x40, 0x1D, 0xB0, 0xCA, 0x00, 0x08, 0xF0,
|
||||
0xCB, 0x40, 0xC2, 0x70, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81, 0xDC, 0x40, 0x6C, 0x48,
|
||||
0xDD, 0x80, 0x05, 0x30, 0x6B, 0x67, 0x8A, 0x51, 0x4A, 0x08, 0xEB, 0x80, 0xE1, 0x39, 0x06, 0x78,
|
||||
0xEF, 0xEB, 0x07, 0x70, 0xEA, 0xC5, 0x05, 0x30, 0x6A, 0x42, 0x03, 0x18, 0x49, 0xEB, 0x69, 0x48,
|
||||
0x3C, 0x7E, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x51, 0xE4, 0x00, 0x69, 0x48, 0x2D, 0x7E,
|
||||
0x64, 0xEB, 0x6A, 0x48, 0x05, 0xBA, 0x03, 0x9D, 0x57, 0x6B, 0x69, 0x48, 0x41, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x95, 0x00, 0x60, 0x8A, 0x51, 0xE4, 0x00, 0x69, 0x48, 0x32, 0x3E, 0x64, 0xEB, 0x06, 0x30,
|
||||
0x6A, 0x42, 0x03, 0x5C, 0x69, 0x2B, 0x69, 0x48, 0x46, 0x3E, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60,
|
||||
0x8A, 0x51, 0xE4, 0x00, 0x69, 0x48, 0x37, 0xBE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x51,
|
||||
0xE5, 0x40, 0x0D, 0x70, 0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0x89, 0x70, 0xCC, 0x00, 0x06, 0x30,
|
||||
0x6A, 0x42, 0x03, 0x5C, 0x75, 0x6B, 0x09, 0x30, 0x76, 0x6B, 0x0D, 0x70, 0xCD, 0x40, 0x4A, 0x70,
|
||||
0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x06, 0x30, 0x6A, 0x42,
|
||||
0x03, 0x5C, 0xA5, 0x2B, 0x1D, 0xB0, 0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0xC2, 0x70, 0xCC, 0x00,
|
||||
0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x05, 0x30, 0x6B, 0x67,
|
||||
0x8A, 0x51, 0x4A, 0x08, 0xEB, 0x80, 0x9F, 0xB9, 0x20, 0x38, 0xEB, 0x80, 0x0D, 0x70, 0xCA, 0x00,
|
||||
0x08, 0xF0, 0xCB, 0x40, 0xC2, 0x70, 0xCC, 0x00, 0x6B, 0x88, 0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40,
|
||||
0x6C, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x64, 0x08, 0x03, 0x59, 0xD4, 0x2B,
|
||||
0x1D, 0xB0, 0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0xC1, 0x70, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81,
|
||||
0xCE, 0x81, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x05, 0x30, 0x6B, 0x67, 0x8A, 0x51, 0x4A, 0x08,
|
||||
0xEB, 0x80, 0x64, 0x08, 0xE1, 0x00, 0x05, 0x30, 0x03, 0xD0, 0xE1, 0xCD, 0xFF, 0x7E, 0x03, 0x9D,
|
||||
0xBC, 0x6B, 0x6B, 0x88, 0x1F, 0x79, 0x61, 0x04, 0xEB, 0x80, 0x0D, 0x70, 0xCA, 0x00, 0x08, 0xF0,
|
||||
0xCB, 0x40, 0xC1, 0x70, 0xCC, 0x00, 0x6B, 0x88, 0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48,
|
||||
0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x65, 0x48, 0x03, 0x59, 0xFF, 0x2B, 0x1D, 0xB0,
|
||||
0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0xC2, 0x70, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xCE, 0x81,
|
||||
0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x05, 0x30, 0x6B, 0x67, 0x8A, 0x51, 0x4A, 0x08, 0xEB, 0x80,
|
||||
0x65, 0x48, 0xE1, 0x00, 0x03, 0xD0, 0xE1, 0xCD, 0x6B, 0x88, 0xE1, 0x39, 0x61, 0x04, 0xEB, 0x80,
|
||||
0x0D, 0x70, 0xCA, 0x00, 0x08, 0xF0, 0xCB, 0x40, 0xC2, 0x70, 0xCC, 0x00, 0x6B, 0x88, 0xCD, 0x40,
|
||||
0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x6C, 0xCB,
|
||||
0x07, 0xAC, 0x00, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x49, 0x52, 0x0C, 0x6C, 0x00, 0xB0,
|
||||
0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x49, 0x10, 0x49, 0x08, 0xDC, 0x40, 0x00, 0xB0, 0x22, 0xA7,
|
||||
0x8A, 0x51, 0x05, 0x30, 0xE1, 0x00, 0xE1, 0xCB, 0x13, 0xAC, 0x00, 0xB0, 0x2A, 0xE7, 0x8A, 0x51,
|
||||
0xC9, 0x00, 0xFD, 0xF9, 0x02, 0x38, 0xC9, 0x00, 0xDC, 0x40, 0x00, 0xB0, 0x22, 0xA7, 0x8A, 0x51,
|
||||
0x00, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0xDF, 0xF9, 0x20, 0x38, 0xC9, 0x00, 0x49, 0x08,
|
||||
0xDC, 0x40, 0x00, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x15, 0x70, 0xE2, 0x00, 0xC6, 0xB0, 0xE1, 0x00,
|
||||
0xE1, 0xCB, 0x30, 0x6C, 0xE2, 0xCB, 0x30, 0x6C, 0x00, 0x00, 0x0D, 0x70, 0x83, 0x52, 0x03, 0x53,
|
||||
0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40, 0x84, 0x30, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xDC, 0x40,
|
||||
0x6C, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x0D, 0x70, 0xCA, 0x00, 0x05, 0x30,
|
||||
0xCB, 0x40, 0x85, 0x70, 0xCC, 0x00, 0x4A, 0x70, 0xCD, 0x81, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80,
|
||||
0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x0D, 0x70, 0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40, 0x82, 0x30,
|
||||
0xCC, 0x00, 0x3F, 0x30, 0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x04, 0xF0,
|
||||
0x32, 0xE7, 0x8A, 0x51, 0x0D, 0x70, 0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40, 0x80, 0xF0, 0xCC, 0x00,
|
||||
0x3E, 0xF0, 0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7,
|
||||
0x8A, 0x51, 0x0D, 0x70, 0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40, 0x83, 0x70, 0xCC, 0x00, 0x3E, 0xF0,
|
||||
0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51,
|
||||
0x6C, 0x83, 0x03, 0x9D, 0x85, 0xAC, 0x9C, 0xD5, 0x86, 0xAC, 0x1C, 0x95, 0x05, 0x30, 0xE1, 0x00,
|
||||
0xE1, 0xCB, 0x88, 0x6C, 0x0D, 0x70, 0x83, 0x52, 0x03, 0x53, 0xCA, 0x00, 0x05, 0x30, 0xCB, 0x40,
|
||||
0x87, 0xB0, 0xCC, 0x00, 0x09, 0x30, 0xCD, 0x40, 0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48, 0xDD, 0x80,
|
||||
0x04, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0xD1, 0xB0, 0xCA, 0x00, 0x4A, 0x70, 0xDC, 0x40, 0x6C, 0x48,
|
||||
0xDD, 0x80, 0x01, 0xF0, 0x32, 0xE7, 0x8A, 0x51, 0x04, 0xF0, 0xE2, 0x00, 0x1C, 0x70, 0xE1, 0x00,
|
||||
0xE1, 0xCB, 0xA8, 0xAC, 0xE2, 0xCB, 0xA8, 0xAC, 0x00, 0x00, 0x08, 0x40, 0x55, 0xB0, 0x83, 0x52,
|
||||
0x9B, 0x40, 0xC8, 0x01, 0x02, 0xF0, 0x48, 0xC2, 0x03, 0x18, 0x72, 0x2D, 0x48, 0xC8, 0x01, 0xBE,
|
||||
0x9B, 0x40, 0x48, 0xC8, 0xB2, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0x48, 0xC8, 0xB2, 0x7E,
|
||||
0x84, 0x80, 0x80, 0x88, 0x03, 0x9D, 0xEA, 0x2C, 0x3C, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00,
|
||||
0x48, 0x18, 0xD6, 0x2C, 0x48, 0xC8, 0xB2, 0x7E, 0x84, 0x80, 0x49, 0x08, 0xDE, 0x80, 0x07, 0x70,
|
||||
0x03, 0xD0, 0xDE, 0x0C, 0xFF, 0x7E, 0x03, 0x9D, 0xD0, 0xAC, 0xE1, 0xEC, 0x48, 0xC8, 0xB2, 0x7E,
|
||||
0x84, 0x80, 0x49, 0x08, 0xDE, 0x80, 0x05, 0x30, 0x03, 0xD0, 0xDE, 0x0C, 0xFF, 0x7E, 0x03, 0x9D,
|
||||
0xDC, 0x2C, 0x5E, 0x88, 0x83, 0x93, 0x80, 0x40, 0x48, 0xC8, 0xB2, 0x7E, 0x84, 0x80, 0x01, 0xF0,
|
||||
0x80, 0xC5, 0xBE, 0x6C, 0x3E, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x49, 0x08, 0x03, 0x59,
|
||||
0x0A, 0xAD, 0x10, 0xF0, 0x49, 0x02, 0x03, 0x18, 0x0A, 0xAD, 0x48, 0xC8, 0xAE, 0xBE, 0x84, 0x80,
|
||||
0x49, 0x08, 0x83, 0x93, 0x80, 0x40, 0x48, 0xC8, 0xAE, 0xBE, 0x84, 0x80, 0x00, 0x48, 0xDC, 0x40,
|
||||
0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x48, 0xC8, 0xAC, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81,
|
||||
0x80, 0xCA, 0x29, 0xED, 0x49, 0x08, 0xFF, 0x3A, 0x03, 0x9D, 0x16, 0xED, 0x48, 0xC8, 0xAE, 0xBE,
|
||||
0x84, 0x80, 0x04, 0xF0, 0x83, 0x93, 0x80, 0x40, 0xFF, 0xB0, 0x20, 0x6D, 0x48, 0xC8, 0xAE, 0xBE,
|
||||
0x84, 0x80, 0x04, 0xF0, 0x83, 0x93, 0x80, 0x40, 0x48, 0xC8, 0xAE, 0xBE, 0x84, 0x80, 0x00, 0x48,
|
||||
0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x48, 0xC8, 0xAC, 0x7E, 0x84, 0x80, 0x83, 0x93,
|
||||
0x80, 0x81, 0x3F, 0x30, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x49, 0x08, 0x03, 0x59, 0x49, 0xED,
|
||||
0x0E, 0x70, 0x49, 0x02, 0x03, 0x18, 0x49, 0xED, 0x48, 0xC8, 0xA8, 0x3E, 0x84, 0x80, 0x49, 0x08,
|
||||
0x83, 0x93, 0x80, 0x40, 0x48, 0xC8, 0xA8, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xDC, 0x40, 0x1C, 0x70,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x48, 0xC8, 0x23, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0x80, 0xCA,
|
||||
0x68, 0xED, 0x49, 0x08, 0xFF, 0x3A, 0x03, 0x9D, 0x55, 0x2D, 0x48, 0xC8, 0xA8, 0x3E, 0x84, 0x80,
|
||||
0x0D, 0x70, 0x83, 0x93, 0x80, 0x40, 0xFF, 0xB0, 0x5F, 0xAD, 0x48, 0xC8, 0xA8, 0x3E, 0x84, 0x80,
|
||||
0x0D, 0x70, 0x83, 0x93, 0x80, 0x40, 0x48, 0xC8, 0xA8, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xDC, 0x40,
|
||||
0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x48, 0xC8, 0x23, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81,
|
||||
0x48, 0xC8, 0xB0, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xDC, 0x40, 0x1A, 0x70, 0x22, 0xA7, 0x8A, 0x51,
|
||||
0xC8, 0x4A, 0xB2, 0xEC, 0x03, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00,
|
||||
0x03, 0xBA, 0x03, 0x9D, 0x74, 0x2D, 0x3E, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xAA, 0x00, 0x3F, 0x30,
|
||||
0x2A, 0xE7, 0x8A, 0x51, 0xAC, 0x00, 0x2A, 0x02, 0x03, 0x5C, 0x9C, 0x2D, 0x0E, 0x70, 0x2A, 0x02,
|
||||
0x03, 0x18, 0x9C, 0x2D, 0x2C, 0x08, 0x03, 0x59, 0x9C, 0x2D, 0x2A, 0x08, 0xDC, 0x40, 0x1B, 0xB0,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x2C, 0x08, 0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x2A, 0x08,
|
||||
0xA9, 0x00, 0x2C, 0x08, 0xAB, 0x40, 0xAA, 0x2D, 0x0D, 0x70, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7,
|
||||
0x8A, 0x51, 0x1C, 0x70, 0xDC, 0x81, 0xDC, 0xCA, 0x22, 0xA7, 0x8A, 0x51, 0x0D, 0x70, 0xA9, 0x00,
|
||||
0xAB, 0x81, 0xAB, 0xCA, 0x04, 0xF0, 0x9B, 0x40, 0x3C, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00,
|
||||
0x04, 0x7A, 0x03, 0x9D, 0xAC, 0x2D, 0x3E, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xAE, 0x40, 0x3F, 0x30,
|
||||
0x2A, 0xE7, 0x8A, 0x51, 0xB0, 0xC0, 0x2E, 0x42, 0x03, 0x5C, 0xD0, 0xED, 0x02, 0xF0, 0x30, 0xC2,
|
||||
0x03, 0x5C, 0xD0, 0xED, 0x2E, 0x48, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x30, 0xC8,
|
||||
0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x2E, 0x48, 0xAD, 0x40, 0x30, 0xC8, 0xDD, 0xAD,
|
||||
0x0C, 0x30, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x03, 0x30, 0xDC, 0x40, 0x1C, 0x70,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x0C, 0x30, 0xAD, 0x40, 0x03, 0x30, 0xAF, 0x80, 0x05, 0x30, 0x9B, 0x40,
|
||||
0x3C, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x05, 0xBA, 0x03, 0x9D, 0xE0, 0xED, 0x3E, 0xF0,
|
||||
0x2A, 0xE7, 0x8A, 0x51, 0xB7, 0x80, 0x3F, 0x30, 0x2A, 0xE7, 0x8A, 0x51, 0xB9, 0x40, 0x37, 0x82,
|
||||
0x03, 0x5C, 0x07, 0xEE, 0x10, 0xF0, 0x37, 0x82, 0x03, 0x18, 0x07, 0xEE, 0x39, 0x48, 0x03, 0x59,
|
||||
0x07, 0xEE, 0x37, 0x88, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x39, 0x48, 0xDC, 0x40,
|
||||
0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x37, 0x88, 0xB6, 0x40, 0x39, 0x48, 0x14, 0xAE, 0x0F, 0xB0,
|
||||
0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x04, 0xF0, 0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7,
|
||||
0x8A, 0x51, 0x0F, 0xB0, 0xB6, 0x40, 0x04, 0xF0, 0xB8, 0x00, 0x06, 0x30, 0x9B, 0x40, 0x3C, 0xB0,
|
||||
0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x06, 0xBA, 0x03, 0x9D, 0x17, 0x2E, 0x3D, 0xF0, 0x2A, 0xE7,
|
||||
0x8A, 0x51, 0xBD, 0x80, 0x3E, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xBB, 0x80, 0x3F, 0x30, 0x2A, 0xE7,
|
||||
0x8A, 0x51, 0xBF, 0xC0, 0x3B, 0x88, 0x3D, 0x82, 0x03, 0x5C, 0x4A, 0xEE, 0x3F, 0xC8, 0x3B, 0x82,
|
||||
0x03, 0x5C, 0x4A, 0xEE, 0x3F, 0xC8, 0x03, 0x59, 0x4A, 0xEE, 0x3D, 0x88, 0xDC, 0x40, 0x1A, 0x70,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x3B, 0x88, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x3F, 0xC8,
|
||||
0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x3D, 0x88, 0xBC, 0x40, 0x3B, 0x88, 0xBA, 0x40,
|
||||
0x3F, 0xC8, 0x5E, 0x6E, 0x5A, 0xB0, 0xDC, 0x40, 0x1A, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x50, 0x30,
|
||||
0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x28, 0x30, 0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7,
|
||||
0x8A, 0x51, 0x5A, 0xB0, 0xBC, 0x40, 0x50, 0x30, 0xBA, 0x40, 0x28, 0x30, 0xBE, 0x80, 0x07, 0x70,
|
||||
0x9B, 0x40, 0x3C, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x07, 0xFA, 0x03, 0x9D, 0x61, 0xEE,
|
||||
0x3E, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xB1, 0x00, 0x3F, 0x30, 0x2A, 0xE7, 0x8A, 0x51, 0xB3, 0x40,
|
||||
0x31, 0x02, 0x03, 0x5C, 0x8A, 0xEE, 0x10, 0xF0, 0x31, 0x02, 0x03, 0x18, 0x8A, 0xEE, 0x33, 0x48,
|
||||
0x03, 0x59, 0x8A, 0xEE, 0x31, 0x08, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x33, 0x48,
|
||||
0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x31, 0x08, 0x83, 0x96, 0xB4, 0x00, 0x83, 0x52,
|
||||
0x33, 0x48, 0x99, 0x2E, 0x0E, 0x70, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x04, 0xF0,
|
||||
0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x0E, 0x70, 0x83, 0x96, 0xB4, 0x00, 0x04, 0xF0,
|
||||
0x83, 0x52, 0xB2, 0x00, 0x08, 0xF0, 0x9B, 0x40, 0x3C, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00,
|
||||
0x08, 0x7A, 0x03, 0x9D, 0x9C, 0x2E, 0x3E, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xB4, 0x00, 0x3F, 0x30,
|
||||
0x2A, 0xE7, 0x8A, 0x51, 0xB5, 0x40, 0x34, 0x08, 0x35, 0x42, 0x03, 0x18, 0xC4, 0xEE, 0x02, 0xF0,
|
||||
0x35, 0x42, 0x03, 0x5C, 0xC4, 0xEE, 0x34, 0x08, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51,
|
||||
0x35, 0x48, 0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x34, 0x08, 0x83, 0x96, 0xB5, 0x40,
|
||||
0x83, 0x52, 0x35, 0x48, 0x83, 0x96, 0xD2, 0x2E, 0x84, 0x30, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7,
|
||||
0x8A, 0x51, 0x34, 0x70, 0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x84, 0x30, 0x83, 0x96,
|
||||
0xB5, 0x40, 0x34, 0x70, 0xB6, 0x40, 0x09, 0x30, 0x83, 0x52, 0x9B, 0x40, 0x3C, 0xB0, 0x2A, 0xE7,
|
||||
0x8A, 0x51, 0xC9, 0x00, 0x09, 0xBA, 0x03, 0x9D, 0xD6, 0x6E, 0x3D, 0xF0, 0x2A, 0xE7, 0x8A, 0x51,
|
||||
0xC2, 0xC0, 0x3E, 0xF0, 0x2A, 0xE7, 0x8A, 0x51, 0xC1, 0xC0, 0x3F, 0x30, 0x2A, 0xE7, 0x8A, 0x51,
|
||||
0xC0, 0x80, 0x07, 0x70, 0x42, 0xC2, 0x03, 0x18, 0x05, 0xEF, 0x08, 0xF0, 0x41, 0xC2, 0x03, 0x18,
|
||||
0x05, 0xEF, 0x02, 0xF0, 0x40, 0x82, 0x03, 0x18, 0x05, 0xEF, 0x42, 0xC8, 0xDC, 0x40, 0x1A, 0x70,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x41, 0xC8, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x40, 0x88,
|
||||
0xDC, 0x40, 0x1C, 0x70, 0x22, 0xA7, 0x8A, 0x51, 0x18, 0xEF, 0x1A, 0x70, 0xDC, 0x81, 0xDC, 0xCA,
|
||||
0x22, 0xA7, 0x8A, 0x51, 0x02, 0xF0, 0xDC, 0x40, 0x1B, 0xB0, 0x22, 0xA7, 0x8A, 0x51, 0x1C, 0x70,
|
||||
0xDC, 0x81, 0x22, 0xA7, 0x8A, 0x51, 0x02, 0xF0, 0xC2, 0x01, 0xC2, 0x4A, 0xC1, 0xC0, 0xC0, 0xC1,
|
||||
0x0A, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0x2A, 0xE7, 0x8A, 0x51, 0xC9, 0x00, 0x0A, 0xBA, 0x03, 0x59,
|
||||
0x08, 0x40, 0x1A, 0x2F, 0xDD, 0x80, 0x5C, 0x48, 0x96, 0x00, 0x5D, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x08, 0x40, 0x83, 0x52, 0x03, 0x53, 0xDC, 0x40, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0x08, 0x40, 0xDF, 0xC0, 0x5D, 0xD8, 0x50, 0xEF, 0xE0, 0x01, 0x5F, 0xC8, 0x60, 0xC2,
|
||||
0x03, 0x18, 0x45, 0x2F, 0x60, 0xC8, 0x5C, 0xC7, 0xDE, 0x80, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48,
|
||||
0x99, 0x00, 0x18, 0x14, 0x18, 0xD0, 0xE0, 0x4A, 0x36, 0x6F, 0x18, 0x55, 0x18, 0x11, 0x83, 0x52,
|
||||
0x03, 0x53, 0x11, 0x5C, 0x08, 0x40, 0x05, 0x30, 0xDE, 0x80, 0xDE, 0x4B, 0x4D, 0x6F, 0x47, 0x6F,
|
||||
0xE0, 0x01, 0x5F, 0xC8, 0x60, 0xC2, 0x03, 0x18, 0x60, 0xEF, 0x60, 0xC8, 0x5C, 0xC7, 0xDE, 0x80,
|
||||
0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x9A, 0x00, 0x98, 0x95, 0x98, 0x51, 0xE0, 0x4A, 0x51, 0x2F,
|
||||
0x98, 0x96, 0x98, 0x52, 0x83, 0x52, 0x03, 0x53, 0x91, 0x9C, 0x08, 0x40, 0x05, 0x30, 0xDE, 0x80,
|
||||
0xDE, 0x4B, 0x68, 0x2F, 0x62, 0x2F, 0xDF, 0xC0, 0x5D, 0xD8, 0x9A, 0x6F, 0xE0, 0x01, 0x5F, 0xC8,
|
||||
0x60, 0xC2, 0x03, 0x18, 0x7E, 0xEF, 0x60, 0xC8, 0x5C, 0xC7, 0xDE, 0x80, 0x84, 0x80, 0x83, 0x93,
|
||||
0x00, 0x48, 0x99, 0x00, 0x18, 0x14, 0x18, 0xD0, 0xE0, 0x4A, 0x6F, 0xEF, 0x18, 0x55, 0x18, 0x11,
|
||||
0x83, 0x52, 0x03, 0x53, 0x11, 0x5C, 0x8A, 0x2F, 0x2A, 0x70, 0xDE, 0x80, 0xDE, 0x4B, 0x86, 0x2F,
|
||||
0x00, 0x00, 0x80, 0xAF, 0xE0, 0x01, 0x5F, 0xC8, 0x60, 0xC2, 0x03, 0x18, 0x08, 0x40, 0x60, 0xC8,
|
||||
0x5C, 0xC7, 0xDE, 0x80, 0x84, 0x80, 0x0F, 0x48, 0x83, 0x93, 0x80, 0x40, 0x98, 0x54, 0x98, 0x10,
|
||||
0xE0, 0x4A, 0x8B, 0x6F, 0xE0, 0x01, 0x5F, 0xC8, 0x60, 0xC2, 0x03, 0x18, 0xAA, 0x6F, 0x60, 0xC8,
|
||||
0x5C, 0xC7, 0xDE, 0x80, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x9A, 0x00, 0x98, 0x95, 0x98, 0x51,
|
||||
0xE0, 0x4A, 0x9B, 0xAF, 0x98, 0x96, 0x98, 0x52, 0x83, 0x52, 0x03, 0x53, 0x91, 0x9C, 0xB6, 0xAF,
|
||||
0x2A, 0x70, 0xDE, 0x80, 0xDE, 0x4B, 0xB2, 0x6F, 0x00, 0x00, 0xAC, 0x6F, 0xE0, 0x01, 0x5F, 0xC8,
|
||||
0x60, 0xC2, 0x03, 0x18, 0x08, 0x40, 0x60, 0xC8, 0x5C, 0xC7, 0xDE, 0x80, 0x84, 0x80, 0x10, 0x88,
|
||||
0x83, 0x93, 0x80, 0x40, 0x18, 0x56, 0x18, 0x12, 0xE0, 0x4A, 0xB7, 0xEF, 0xDE, 0x80, 0xDD, 0xC1,
|
||||
0x5C, 0x48, 0x5E, 0xD8, 0xDD, 0x47, 0x03, 0xD0, 0xDC, 0x0D, 0x5C, 0x48, 0xDE, 0x18, 0xDD, 0x47,
|
||||
0x03, 0xD0, 0xDC, 0x0D, 0x5C, 0x48, 0x5E, 0x19, 0xDD, 0x47, 0x03, 0xD0, 0xDC, 0x0D, 0x5C, 0x48,
|
||||
0xDE, 0x59, 0xDD, 0x47, 0x03, 0xD0, 0xDC, 0x0D, 0x5C, 0x48, 0x5E, 0x1A, 0xDD, 0x47, 0x03, 0xD0,
|
||||
0xDC, 0x0D, 0x5C, 0x48, 0xDE, 0x5A, 0xDD, 0x47, 0x03, 0xD0, 0xDC, 0x0D, 0x5C, 0x48, 0x5E, 0x5B,
|
||||
0xDD, 0x47, 0x03, 0xD0, 0xDC, 0x0D, 0x5C, 0x48, 0xDE, 0x9B, 0xDD, 0x47, 0x5D, 0x88, 0x08, 0x40,
|
||||
0xEF, 0x01, 0x83, 0x93, 0x21, 0x30, 0x84, 0x80, 0x5C, 0xB0, 0x8A, 0x51, 0x11, 0xE0, 0x8A, 0x51,
|
||||
0xA0, 0x30, 0x84, 0x80, 0xC2, 0x70, 0x8A, 0x51, 0x11, 0xE0, 0x83, 0x01, 0x8A, 0x95, 0x5F, 0xAB,
|
||||
0x08, 0xF0, 0x8A, 0xC0, 0x04, 0x88, 0x84, 0x0A, 0x82, 0x47, 0x00, 0xF4, 0x01, 0x34, 0x48, 0x74,
|
||||
0x02, 0x34, 0x3D, 0x34, 0x03, 0x74, 0x33, 0xF4, 0x00, 0xF4, 0xA4, 0xB4, 0x00, 0xF4, 0xF6, 0x74,
|
||||
0x03, 0x74, 0x33, 0xF4, 0x00, 0xF4, 0x52, 0xB4, 0x00, 0xF4, 0x52, 0xB4, 0x00, 0xF4, 0xCD, 0x34,
|
||||
0x00, 0xF4, 0x29, 0xB4, 0x00, 0xF4, 0x29, 0xB4, 0x00, 0xF4, 0x66, 0xF4, 0x00, 0xF4, 0x15, 0xB4,
|
||||
0x00, 0xF4, 0x15, 0xB4, 0x00, 0xF4, 0x29, 0xB4, 0x7F, 0xB4, 0x34, 0xB4, 0x2F, 0x34, 0x2A, 0xB4,
|
||||
0x26, 0xB4, 0x21, 0x74, 0x1A, 0xB4, 0x16, 0xB4, 0x0F, 0xF4, 0x09, 0x74, 0x04, 0x34, 0x02, 0x34,
|
||||
0x01, 0x34, 0x00, 0xF4, 0x00, 0xF4, 0x00, 0xF4, 0x00, 0xF4, 0x03, 0x74, 0x03, 0x74, 0x00, 0xF4,
|
||||
0x00, 0xF4, 0x03, 0x74, 0x03, 0x74, 0x07, 0xB4, 0x01, 0x34, 0x01, 0x34, 0x01, 0x34, 0x07, 0xB4,
|
||||
0x07, 0xB4, 0x00, 0xF4, 0x00, 0xF4, 0x07, 0xB4, 0x07, 0xB4, 0x07, 0xB4, 0x00, 0xF4, 0x07, 0xB4,
|
||||
0x07, 0xB4, 0x07, 0xB4, 0x07, 0xB4, 0x07, 0xB4, 0x07, 0xB4, 0x07, 0xB4, 0x07, 0xB4, 0x07, 0xB4,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xC8, 0x01, 0x02, 0xF0, 0x48, 0xC2,
|
||||
0x03, 0x18, 0x3D, 0x6B, 0x48, 0xC8, 0xB0, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0x48, 0xC8,
|
||||
0xAE, 0xBE, 0x84, 0x80, 0x80, 0x81, 0x48, 0xC8, 0xA8, 0x3E, 0x84, 0x80, 0x80, 0x81, 0x48, 0xC8,
|
||||
0xB2, 0x7E, 0x84, 0x80, 0x80, 0x81, 0x48, 0xC8, 0x23, 0x3E, 0x84, 0x80, 0x80, 0x81, 0x48, 0xC8,
|
||||
0xAC, 0x7E, 0x84, 0x80, 0x80, 0x81, 0xC8, 0x4A, 0x1E, 0x2B, 0x0D, 0x70, 0xAB, 0x81, 0xAB, 0xCA,
|
||||
0xA9, 0x00, 0x03, 0x30, 0xAF, 0x80, 0x0C, 0x30, 0xAD, 0x40, 0x04, 0xF0, 0xB8, 0x00, 0x0F, 0xB0,
|
||||
0xB6, 0x40, 0x28, 0x30, 0xBE, 0x80, 0x50, 0x30, 0xBA, 0x40, 0x5A, 0xB0, 0xBC, 0x40, 0x04, 0xF0,
|
||||
0xB2, 0x00, 0x0E, 0x70, 0x83, 0x96, 0xB4, 0x00, 0x34, 0x70, 0xB6, 0x40, 0x84, 0x30, 0xB5, 0x40,
|
||||
0x83, 0x52, 0x02, 0xF0, 0xC2, 0x01, 0xC2, 0x4A, 0xC1, 0xC0, 0xC0, 0xC1, 0x08, 0x40, 0x9B, 0x81,
|
||||
0x01, 0xF0, 0xA0, 0x80, 0x95, 0x41, 0x96, 0x41, 0x97, 0x81, 0x98, 0x01, 0x99, 0x41, 0x9A, 0x41,
|
||||
0x9B, 0x81, 0x9C, 0x41, 0x9E, 0x81, 0x55, 0xB0, 0x9E, 0x40, 0x9B, 0x81, 0x1C, 0x70, 0xDC, 0x81,
|
||||
0xDC, 0xCA, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x8A, 0x95, 0x1D, 0xE3, 0x8A, 0x95, 0x3D, 0xF0,
|
||||
0x8A, 0x51, 0x2A, 0xE7, 0x8A, 0x95, 0xC9, 0x00, 0xF7, 0xFA, 0x03, 0x9D, 0x82, 0xAB, 0x83, 0x96,
|
||||
0xBF, 0x01, 0x85, 0xEB, 0x83, 0x96, 0xBF, 0x01, 0xBF, 0x4A, 0x3F, 0xC8, 0x03, 0x59, 0x8C, 0xEB,
|
||||
0x8A, 0x51, 0xAE, 0xE4, 0x8A, 0x95, 0x8F, 0x6B, 0x01, 0xF0, 0x83, 0x52, 0x9B, 0x40, 0x8A, 0x51,
|
||||
0x27, 0x60, 0x8A, 0x95, 0x00, 0xB0, 0x8A, 0x51, 0x2A, 0xE7, 0x8A, 0x95, 0xC9, 0x00, 0xFE, 0xF9,
|
||||
0x01, 0x38, 0xC9, 0x00, 0xDC, 0x40, 0x00, 0xB0, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x00, 0xB0,
|
||||
0x8A, 0x51, 0x2A, 0xE7, 0x8A, 0x95, 0xC9, 0x00, 0xEF, 0xF9, 0x10, 0x38, 0xC9, 0x00, 0x49, 0x08,
|
||||
0xDC, 0x40, 0x00, 0xB0, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x1C, 0x54, 0x9C, 0x94, 0x9C, 0xD6,
|
||||
0x35, 0xB0, 0xED, 0x80, 0xED, 0x4B, 0xB2, 0x2B, 0x83, 0x52, 0x03, 0x53, 0x9C, 0x92, 0x9C, 0x17,
|
||||
0x35, 0xB0, 0xED, 0x80, 0xED, 0x4B, 0xBA, 0x6B, 0x83, 0x52, 0x03, 0x53, 0x9C, 0xD3, 0xC8, 0x01,
|
||||
0x02, 0xF0, 0x48, 0xC2, 0x03, 0x18, 0x8D, 0xEC, 0x08, 0xF0, 0xE1, 0x00, 0xAC, 0xB0, 0xE2, 0x00,
|
||||
0x03, 0x30, 0xE3, 0x40, 0x48, 0xC8, 0xE4, 0x00, 0x0D, 0x70, 0x8A, 0x51, 0x19, 0x20, 0x8A, 0x95,
|
||||
0x48, 0xC8, 0x23, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x00, 0xCB, 0xE0, 0xEB, 0x48, 0xC8, 0xA8, 0x3E,
|
||||
0x84, 0x80, 0x00, 0x48, 0xED, 0x80, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x6D, 0x88, 0xE4, 0x2B,
|
||||
0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x29, 0x08, 0x80, 0x40, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80,
|
||||
0x00, 0x48, 0x1F, 0xBE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x95, 0xED, 0x80, 0x48, 0xC8,
|
||||
0x27, 0x7E, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x08, 0xF0, 0xE1, 0x00, 0xB6, 0xF0, 0xE2, 0x00,
|
||||
0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x20, 0x38, 0xE3, 0x40, 0x48, 0xC8, 0xE4, 0x00,
|
||||
0x0D, 0x70, 0x8A, 0x51, 0x19, 0x20, 0x8A, 0x95, 0x48, 0xC8, 0xAC, 0x7E, 0x84, 0x80, 0x83, 0x93,
|
||||
0x00, 0xCB, 0x14, 0x6C, 0x48, 0xC8, 0xAE, 0xBE, 0x84, 0x80, 0x00, 0x48, 0xED, 0x80, 0x48, 0xC8,
|
||||
0x5A, 0x7E, 0x84, 0x80, 0x6D, 0x88, 0x18, 0x6C, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x38, 0x08,
|
||||
0x80, 0x40, 0x06, 0x30, 0xDC, 0x40, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x38, 0x08, 0x00, 0x42,
|
||||
0x8A, 0x51, 0xC6, 0x27, 0x8A, 0x95, 0xED, 0x80, 0x48, 0xC8, 0xAA, 0x7E, 0x84, 0x80, 0x6D, 0x88,
|
||||
0x83, 0x93, 0x80, 0x40, 0x48, 0xC8, 0xAA, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xED, 0x80, 0x48, 0xC8,
|
||||
0x27, 0x7E, 0x84, 0x80, 0x00, 0x48, 0x6D, 0x07, 0xEE, 0x80, 0x48, 0xC8, 0x25, 0x3E, 0x84, 0x80,
|
||||
0x6E, 0x88, 0x80, 0x40, 0x48, 0xC8, 0x25, 0x3E, 0x84, 0x80, 0x7F, 0x70, 0x00, 0x42, 0x03, 0x5C,
|
||||
0x46, 0xAC, 0x48, 0xC8, 0x25, 0x3E, 0x84, 0x80, 0x7F, 0x70, 0x80, 0x40, 0x48, 0x18, 0x4F, 0x2C,
|
||||
0x48, 0xC8, 0x25, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xDC, 0x40, 0x03, 0x30, 0x55, 0xEC, 0x48, 0xC8,
|
||||
0x25, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xDC, 0x40, 0x04, 0xF0, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95,
|
||||
0x48, 0x18, 0x71, 0xEC, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0xED, 0x80,
|
||||
0x01, 0xF0, 0x03, 0xD0, 0xED, 0x4D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0x62, 0xAC, 0x6D, 0x0D,
|
||||
0x02, 0xBE, 0xC9, 0x00, 0xDC, 0x40, 0x01, 0xF0, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x01, 0xF0,
|
||||
0x87, 0xEC, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0xED, 0x80, 0x01, 0xF0,
|
||||
0x03, 0xD0, 0xED, 0x4D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0x79, 0x2C, 0x6D, 0x0D, 0x02, 0xBE,
|
||||
0xC9, 0x00, 0xDC, 0x40, 0x02, 0xF0, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x02, 0xF0, 0xDC, 0x81,
|
||||
0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0xC8, 0x4A, 0xC0, 0xAB, 0xC4, 0x01, 0x08, 0xF0, 0x44, 0xC2,
|
||||
0x03, 0x18, 0xB0, 0xAC, 0x44, 0xC8, 0xDC, 0x40, 0x05, 0x30, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95,
|
||||
0x44, 0xC8, 0xA0, 0xFE, 0x84, 0x80, 0x32, 0x08, 0x83, 0x93, 0x80, 0x40, 0x44, 0xC8, 0xA0, 0xFE,
|
||||
0x84, 0x80, 0x03, 0x14, 0x00, 0xCD, 0xC9, 0x00, 0xDC, 0x40, 0x06, 0x30, 0x8A, 0x51, 0x22, 0xA7,
|
||||
0x8A, 0x95, 0x06, 0x30, 0xDC, 0x81, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0xC4, 0x4A, 0x8E, 0xEC,
|
||||
0x34, 0x70, 0x9E, 0x40, 0x83, 0x52, 0x12, 0x18, 0x1C, 0x9C, 0xBC, 0x2C, 0x1C, 0x10, 0x9B, 0xD4,
|
||||
0x00, 0xB0, 0x8A, 0x51, 0x6A, 0xA1, 0x8A, 0x95, 0x83, 0x52, 0x03, 0x53, 0x12, 0x5C, 0x1C, 0x58,
|
||||
0xC9, 0xEC, 0x00, 0xB0, 0x8A, 0x51, 0x69, 0x60, 0x8A, 0x95, 0x83, 0x52, 0x03, 0x53, 0x1C, 0x54,
|
||||
0x9B, 0x90, 0x92, 0x58, 0x9C, 0xDC, 0xD2, 0xEC, 0x9C, 0x50, 0x9B, 0xD4, 0x01, 0xF0, 0x8A, 0x51,
|
||||
0x6A, 0xA1, 0x8A, 0x95, 0x83, 0x52, 0x03, 0x53, 0x92, 0x9C, 0x9C, 0x98, 0xDF, 0xAC, 0x01, 0xF0,
|
||||
0x8A, 0x51, 0x69, 0x60, 0x8A, 0x95, 0x83, 0x52, 0x03, 0x53, 0x9C, 0x94, 0x9B, 0x90, 0xC4, 0x01,
|
||||
0x08, 0xF0, 0x44, 0xC2, 0x03, 0x18, 0x2E, 0x2D, 0x44, 0xC8, 0xDC, 0x40, 0x05, 0x30, 0x8A, 0x51,
|
||||
0x22, 0xA7, 0x8A, 0x95, 0x24, 0x30, 0x8A, 0x51, 0x2A, 0xE7, 0x8A, 0x95, 0xC5, 0x00, 0x83, 0x96,
|
||||
0x35, 0x42, 0x03, 0x18, 0x04, 0x6D, 0x83, 0x52, 0x44, 0xC8, 0xA0, 0xFE, 0x84, 0x80, 0x83, 0x96,
|
||||
0x34, 0x08, 0x83, 0x93, 0x00, 0x42, 0x03, 0x18, 0x04, 0x6D, 0x83, 0x52, 0x44, 0xC8, 0xA0, 0xFE,
|
||||
0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0x16, 0xED, 0x36, 0x48, 0x83, 0x52, 0x45, 0x02, 0x03, 0x18,
|
||||
0x2C, 0xED, 0x44, 0xC8, 0xA0, 0xFE, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x32, 0x02, 0x03, 0x18,
|
||||
0x2C, 0xED, 0x44, 0xC8, 0xA0, 0xFE, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E, 0xED, 0x80, 0x44, 0xC8,
|
||||
0xA0, 0xFE, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x44, 0xC8, 0xA0, 0xFE, 0x84, 0x80, 0x03, 0x14,
|
||||
0x00, 0xCD, 0xC9, 0x00, 0xDC, 0x40, 0x06, 0x30, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x06, 0x30,
|
||||
0xDC, 0x81, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0xC4, 0x4A, 0xE0, 0xAC, 0x00, 0xB0, 0x14, 0x59,
|
||||
0x80, 0xF0, 0x94, 0x99, 0x40, 0x38, 0x14, 0x18, 0x20, 0x38, 0x94, 0x58, 0x10, 0x38, 0x21, 0xC4,
|
||||
0x9E, 0x40, 0x83, 0x96, 0xC0, 0xC1, 0x83, 0x52, 0x21, 0x30, 0xC8, 0x01, 0x8A, 0x51, 0x2A, 0xE7,
|
||||
0x8A, 0x95, 0xC6, 0x00, 0x20, 0xF0, 0x8A, 0x51, 0x2A, 0xE7, 0x8A, 0x95, 0xC3, 0x00, 0x94, 0x9C,
|
||||
0x9B, 0x6D, 0x48, 0xC8, 0x23, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x88, 0x03, 0x9D, 0x90, 0xAD,
|
||||
0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x2B, 0x42, 0x03, 0x18, 0x90, 0xAD, 0x48, 0xC8,
|
||||
0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E, 0xED, 0x80, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80,
|
||||
0x6D, 0x88, 0x80, 0x40, 0x08, 0xF0, 0xE1, 0x00, 0xB6, 0xF0, 0xE2, 0x00, 0x48, 0xC8, 0x21, 0xFE,
|
||||
0x84, 0x80, 0x00, 0x48, 0x20, 0x38, 0xE3, 0x40, 0x48, 0xC8, 0xE4, 0x00, 0x0D, 0x70, 0x8A, 0x51,
|
||||
0x19, 0x20, 0x8A, 0x95, 0x01, 0xF0, 0xDC, 0x81, 0xDC, 0xCA, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95,
|
||||
0x01, 0xF0, 0xDC, 0x81, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80,
|
||||
0x83, 0x93, 0x00, 0x48, 0x1F, 0xBE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x95, 0xED, 0x80,
|
||||
0x48, 0xC8, 0x27, 0x7E, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x83, 0x96, 0xC0, 0xC1, 0xC0, 0x0A,
|
||||
0x83, 0x52, 0x9C, 0x92, 0x1C, 0x96, 0x05, 0x30, 0xED, 0x80, 0xED, 0x4B, 0x95, 0x2D, 0x83, 0x52,
|
||||
0x03, 0x53, 0x1C, 0x52, 0x71, 0x2E, 0x48, 0xC8, 0xAC, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x88,
|
||||
0x03, 0x9D, 0x15, 0xEE, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x29, 0x46, 0x03, 0x9D,
|
||||
0xAB, 0x6D, 0x3A, 0x48, 0xAC, 0x2D, 0x3C, 0x48, 0xC7, 0x40, 0x46, 0x08, 0x47, 0x42, 0x03, 0x18,
|
||||
0xD0, 0xED, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x36, 0x48, 0x00, 0x42, 0x03, 0x18, 0xD0, 0xED,
|
||||
0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0xED, 0x80, 0x48, 0xC8, 0x5A, 0x7E,
|
||||
0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xED, 0x80,
|
||||
0x01, 0xF0, 0x03, 0xD0, 0xED, 0x4D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0xCA, 0x2D, 0xF2, 0x6D,
|
||||
0x3E, 0x88, 0x46, 0x02, 0x48, 0xC8, 0x03, 0x18, 0x16, 0xEE, 0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48,
|
||||
0x38, 0x02, 0x48, 0xC8, 0x03, 0x18, 0x16, 0xEE, 0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E,
|
||||
0xED, 0x80, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x48, 0xC8, 0x5A, 0x7E,
|
||||
0x84, 0x80, 0x00, 0x48, 0xED, 0x80, 0x01, 0xF0, 0x03, 0xD0, 0xED, 0x4D, 0xFF, 0x7E, 0x03, 0xD0,
|
||||
0x03, 0x9D, 0xED, 0xAD, 0x6D, 0x0D, 0x02, 0xBE, 0xC9, 0x00, 0xDC, 0x40, 0x01, 0xF0, 0x8A, 0x51,
|
||||
0x22, 0xA7, 0x8A, 0x95, 0x01, 0xF0, 0xDC, 0x81, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x83, 0x96,
|
||||
0x06, 0x30, 0xC0, 0xC1, 0xC0, 0x0A, 0x83, 0x52, 0xDC, 0x40, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80,
|
||||
0x38, 0x08, 0x83, 0x93, 0x00, 0x42, 0x8A, 0x51, 0xC6, 0x27, 0x8A, 0x95, 0xED, 0x80, 0x48, 0xC8,
|
||||
0xAA, 0x7E, 0x84, 0x80, 0x6D, 0x88, 0x83, 0x93, 0x80, 0x40, 0x48, 0xC8, 0x23, 0x3E, 0x84, 0x80,
|
||||
0x80, 0x88, 0x03, 0x9D, 0x71, 0x2E, 0x43, 0x08, 0x2D, 0x42, 0x03, 0x18, 0x2C, 0xEE, 0x48, 0xC8,
|
||||
0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x2B, 0x42, 0x03, 0x18, 0x2C, 0xEE, 0x48, 0xC8, 0x21, 0xFE,
|
||||
0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E, 0x3C, 0x2E, 0x2F, 0x88, 0x43, 0x02, 0x03, 0x18, 0x71, 0x2E,
|
||||
0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x29, 0x08, 0x00, 0x42, 0x03, 0x18, 0x71, 0x2E, 0x48, 0xC8,
|
||||
0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0xED, 0x80, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80,
|
||||
0x6D, 0x88, 0x80, 0x40, 0x08, 0xF0, 0xE1, 0x00, 0xB6, 0xF0, 0xE2, 0x00, 0x48, 0xC8, 0x21, 0xFE,
|
||||
0x84, 0x80, 0x00, 0x48, 0x20, 0x38, 0xE3, 0x40, 0x48, 0xC8, 0xE4, 0x00, 0x0D, 0x70, 0x8A, 0x51,
|
||||
0x19, 0x20, 0x8A, 0x95, 0x01, 0xF0, 0xDC, 0x81, 0xDC, 0xCA, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95,
|
||||
0x01, 0xF0, 0xDC, 0x81, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x83, 0x96, 0xC0, 0xC1, 0xC0, 0x0A,
|
||||
0x83, 0x52, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x1F, 0xBE, 0x84, 0x80,
|
||||
0x8A, 0x95, 0x00, 0x60, 0x8A, 0x95, 0xED, 0x80, 0x48, 0xC8, 0x27, 0x7E, 0x84, 0x80, 0x6D, 0x88,
|
||||
0x80, 0x40, 0x83, 0x96, 0x40, 0x0B, 0x9B, 0x6E, 0x83, 0x52, 0x48, 0xC8, 0xAA, 0x7E, 0x84, 0x80,
|
||||
0x83, 0x93, 0x00, 0x48, 0xED, 0x80, 0x48, 0xC8, 0x27, 0x7E, 0x84, 0x80, 0x00, 0x48, 0x6D, 0x07,
|
||||
0xEE, 0x80, 0x48, 0xC8, 0x25, 0x3E, 0x84, 0x80, 0x6E, 0x88, 0x80, 0x40, 0x48, 0xC8, 0x25, 0x3E,
|
||||
0x84, 0x80, 0x7F, 0x70, 0x00, 0x42, 0x48, 0xC8, 0x03, 0x5C, 0x93, 0x2E, 0x25, 0x3E, 0x84, 0x80,
|
||||
0x7F, 0x70, 0x80, 0x40, 0x48, 0xC8, 0x25, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xDC, 0x40, 0x03, 0x30,
|
||||
0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x83, 0x52, 0x23, 0x70, 0xC8, 0x01, 0xC8, 0x4A, 0x8A, 0x51,
|
||||
0x2A, 0xE7, 0x8A, 0x95, 0xC6, 0x00, 0x22, 0x30, 0x8A, 0x51, 0x2A, 0xE7, 0x8A, 0x95, 0xC3, 0x00,
|
||||
0x83, 0x96, 0xC1, 0x01, 0x83, 0x52, 0x94, 0xDD, 0xFF, 0x2E, 0x48, 0xC8, 0x23, 0x3E, 0x84, 0x80,
|
||||
0x83, 0x93, 0x80, 0x88, 0x03, 0x9D, 0xF4, 0x6E, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48,
|
||||
0x2B, 0x42, 0x03, 0x18, 0xF4, 0x6E, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E,
|
||||
0xED, 0x80, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x08, 0xF0, 0xE1, 0x00,
|
||||
0xB6, 0xF0, 0xE2, 0x00, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x20, 0x38, 0xE3, 0x40,
|
||||
0x48, 0xC8, 0xE4, 0x00, 0x0D, 0x70, 0x8A, 0x51, 0x19, 0x20, 0x8A, 0x95, 0x02, 0xF0, 0xDC, 0x81,
|
||||
0xDC, 0xCA, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x02, 0xF0, 0xDC, 0x81, 0x8A, 0x51, 0x22, 0xA7,
|
||||
0x8A, 0x95, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x1F, 0xBE, 0x84, 0x80,
|
||||
0x8A, 0x95, 0x00, 0x60, 0x8A, 0x95, 0xED, 0x80, 0x48, 0xC8, 0x27, 0x7E, 0x84, 0x80, 0x6D, 0x88,
|
||||
0x80, 0x40, 0x83, 0x96, 0xC1, 0x01, 0xC1, 0x4A, 0x83, 0x52, 0x9C, 0xD3, 0x1C, 0xD7, 0x05, 0x30,
|
||||
0xED, 0x80, 0xED, 0x4B, 0xF9, 0xAE, 0x83, 0x52, 0x03, 0x53, 0x1C, 0x93, 0xD5, 0xAF, 0x48, 0xC8,
|
||||
0xAC, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x88, 0x03, 0x9D, 0x79, 0xAF, 0x48, 0xC8, 0x21, 0xFE,
|
||||
0x84, 0x80, 0x00, 0x48, 0x29, 0x46, 0x03, 0x9D, 0x0F, 0x6F, 0x3A, 0x48, 0x10, 0xAF, 0x3C, 0x48,
|
||||
0xC7, 0x40, 0x46, 0x08, 0x47, 0x42, 0x03, 0x18, 0x34, 0x2F, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80,
|
||||
0x36, 0x48, 0x00, 0x42, 0x03, 0x18, 0x34, 0x2F, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48,
|
||||
0x01, 0xBE, 0xED, 0x80, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x48, 0xC8,
|
||||
0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xED, 0x80, 0x01, 0xF0, 0x03, 0xD0, 0xED, 0x4D, 0xFF, 0x7E,
|
||||
0x03, 0xD0, 0x03, 0x9D, 0x2E, 0x6F, 0x56, 0x6F, 0x3E, 0x88, 0x46, 0x02, 0x48, 0xC8, 0x03, 0x18,
|
||||
0x7A, 0xAF, 0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48, 0x38, 0x02, 0x48, 0xC8, 0x03, 0x18, 0x7A, 0xAF,
|
||||
0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E, 0xED, 0x80, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80,
|
||||
0x6D, 0x88, 0x80, 0x40, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xED, 0x80, 0x01, 0xF0,
|
||||
0x03, 0xD0, 0xED, 0x4D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0x51, 0x2F, 0x6D, 0x0D, 0x02, 0xBE,
|
||||
0xC9, 0x00, 0xDC, 0x40, 0x02, 0xF0, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x02, 0xF0, 0xDC, 0x81,
|
||||
0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x83, 0x96, 0x06, 0x30, 0xC1, 0x01, 0xC1, 0x4A, 0x83, 0x52,
|
||||
0xDC, 0x40, 0x48, 0xC8, 0x5A, 0x7E, 0x84, 0x80, 0x38, 0x08, 0x83, 0x93, 0x00, 0x42, 0x8A, 0x51,
|
||||
0xC6, 0x27, 0x8A, 0x95, 0xED, 0x80, 0x48, 0xC8, 0xAA, 0x7E, 0x84, 0x80, 0x6D, 0x88, 0x83, 0x93,
|
||||
0x80, 0x40, 0x48, 0xC8, 0x23, 0x3E, 0x84, 0x80, 0x80, 0x88, 0x03, 0x9D, 0xD5, 0xAF, 0x43, 0x08,
|
||||
0x2D, 0x42, 0x03, 0x18, 0x90, 0xEF, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x2B, 0x42,
|
||||
0x03, 0x18, 0x90, 0xEF, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E, 0xA0, 0xEF,
|
||||
0x2F, 0x88, 0x43, 0x02, 0x03, 0x18, 0xD5, 0xAF, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x29, 0x08,
|
||||
0x00, 0x42, 0x03, 0x18, 0xD5, 0xAF, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x01, 0xBE,
|
||||
0xED, 0x80, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x08, 0xF0, 0xE1, 0x00,
|
||||
0xB6, 0xF0, 0xE2, 0x00, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x20, 0x38, 0xE3, 0x40,
|
||||
0x48, 0xC8, 0xE4, 0x00, 0x0D, 0x70, 0x8A, 0x51, 0x19, 0x20, 0x8A, 0x95, 0x02, 0xF0, 0xDC, 0x81,
|
||||
0xDC, 0xCA, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0x02, 0xF0, 0xDC, 0x81, 0x8A, 0x51, 0x22, 0xA7,
|
||||
0x8A, 0x95, 0x83, 0x96, 0xC1, 0x01, 0xC1, 0x4A, 0x83, 0x52, 0x48, 0xC8, 0x21, 0xFE, 0x84, 0x80,
|
||||
0x83, 0x93, 0x00, 0x48, 0x1F, 0xBE, 0x84, 0x80, 0x8A, 0x95, 0x00, 0x60, 0x8A, 0x95, 0xED, 0x80,
|
||||
0x48, 0xC8, 0x27, 0x7E, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x83, 0x96, 0x41, 0x4B, 0xB2, 0xEC,
|
||||
0x83, 0x52, 0x48, 0xC8, 0xAA, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0xED, 0x80, 0x48, 0xC8,
|
||||
0x27, 0x7E, 0x84, 0x80, 0x00, 0x48, 0x6D, 0x07, 0xEE, 0x80, 0x48, 0xC8, 0x25, 0x3E, 0x84, 0x80,
|
||||
0x6E, 0x88, 0x80, 0x40, 0x48, 0xC8, 0x25, 0x3E, 0x84, 0x80, 0x7F, 0x70, 0x00, 0x42, 0x48, 0xC8,
|
||||
0x03, 0x5C, 0xF7, 0x2F, 0x25, 0x3E, 0x84, 0x80, 0x7F, 0x70, 0x80, 0x40, 0x48, 0xC8, 0x25, 0x3E,
|
||||
0x84, 0x80, 0x00, 0x48, 0xDC, 0x40, 0x04, 0xF0, 0x8A, 0x51, 0x22, 0xA7, 0x8A, 0x95, 0xB2, 0xEC
|
||||
};
|
||||
515
libloragw/src/agc_fw_sx1257.var
Normal file
515
libloragw/src/agc_fw_sx1257.var
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
static uint8_t agc_firmware_sx125x[8192] = {
|
||||
0x8A, 0x51, 0xCF, 0xEF, 0x00, 0xB0, 0x8A, 0xC0, 0x04, 0x88, 0x84, 0x0A, 0x82, 0x47, 0x00, 0xF4,
|
||||
0x0F, 0xF4, 0x0C, 0x74, 0x09, 0x74, 0x09, 0x74, 0x09, 0x74, 0x0C, 0x74, 0x0F, 0xF4, 0x0C, 0x74,
|
||||
0x0F, 0xF4, 0x0C, 0x74, 0x00, 0xF4, 0x06, 0x74, 0x0C, 0x74, 0x12, 0x74, 0x18, 0x74, 0x1E, 0xF4,
|
||||
0x24, 0x74, 0x2A, 0xB4, 0x30, 0x74, 0x36, 0xF4, 0x01, 0x34, 0x01, 0x34, 0x01, 0x34, 0x02, 0x34,
|
||||
0x03, 0x74, 0x04, 0x34, 0x05, 0x74, 0x05, 0x74, 0x06, 0x74, 0x06, 0x74, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0x64, 0xC0, 0x80, 0x81, 0x84, 0x0A,
|
||||
0x04, 0xC6, 0x03, 0x59, 0x00, 0xF4, 0x04, 0xC6, 0xB6, 0x29, 0xDF, 0xC0, 0xDE, 0xC1, 0x5D, 0x88,
|
||||
0x5F, 0x18, 0xDE, 0x47, 0x03, 0xD0, 0xDD, 0x4D, 0x5D, 0x88, 0xDF, 0x58, 0xDE, 0x47, 0x03, 0xD0,
|
||||
0xDD, 0x4D, 0x5D, 0x88, 0x5F, 0x59, 0xDE, 0x47, 0x03, 0xD0, 0xDD, 0x4D, 0x5D, 0x88, 0xDF, 0x99,
|
||||
0xDE, 0x47, 0x03, 0xD0, 0xDD, 0x4D, 0x5D, 0x88, 0x5F, 0x5A, 0xDE, 0x47, 0x03, 0xD0, 0xDD, 0x4D,
|
||||
0x5D, 0x88, 0xDF, 0x9A, 0xDE, 0x47, 0x03, 0xD0, 0xDD, 0x4D, 0x5D, 0x88, 0x5F, 0x9B, 0xDE, 0x47,
|
||||
0x03, 0xD0, 0xDD, 0x4D, 0x5D, 0x88, 0xDF, 0xDB, 0xDE, 0x47, 0x5E, 0x88, 0x08, 0x40, 0xD7, 0xC1,
|
||||
0x02, 0xF0, 0x57, 0x82, 0x03, 0x18, 0x07, 0xAA, 0x57, 0x88, 0x2D, 0x7E, 0x84, 0x80, 0x83, 0x93,
|
||||
0x80, 0x81, 0x57, 0x88, 0x2B, 0x7E, 0x84, 0x80, 0x80, 0x81, 0x57, 0x88, 0x25, 0x3E, 0x84, 0x80,
|
||||
0x80, 0x81, 0x57, 0x88, 0x33, 0x7E, 0x84, 0x80, 0x80, 0x81, 0x57, 0x88, 0xA8, 0x3E, 0x84, 0x80,
|
||||
0x80, 0x81, 0x57, 0x88, 0x29, 0x3E, 0x84, 0x80, 0x80, 0x81, 0xD7, 0x0A, 0xE8, 0xE9, 0x09, 0x30,
|
||||
0xB7, 0xC1, 0xB5, 0x40, 0x10, 0xF0, 0xBB, 0x80, 0x23, 0x70, 0xB9, 0x40, 0x07, 0x70, 0xC7, 0x40,
|
||||
0x0B, 0x70, 0xC5, 0x00, 0x2D, 0xB0, 0xCD, 0x40, 0x64, 0x70, 0xC9, 0x00, 0x73, 0xF0, 0xCB, 0x40,
|
||||
0x04, 0xF0, 0xBF, 0xC0, 0x0E, 0x70, 0xBD, 0x80, 0x34, 0x70, 0xC3, 0x00, 0x84, 0x30, 0xC1, 0xC0,
|
||||
0x08, 0x40, 0x01, 0xF0, 0xA0, 0x80, 0x95, 0x41, 0x96, 0x41, 0x97, 0x81, 0x98, 0x01, 0x99, 0x41,
|
||||
0x9A, 0x41, 0x9B, 0x81, 0x9C, 0x41, 0x9E, 0x81, 0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0xFE, 0xF9, 0x01, 0x38, 0xEF, 0xC0,
|
||||
0x6F, 0xC8, 0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0xEF, 0xF9, 0x10, 0x38, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80,
|
||||
0x00, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x1C, 0x54, 0x9C, 0x94, 0x83, 0x96, 0xAC, 0x41, 0xAD, 0x81, 0x83, 0x52, 0xB3, 0x81, 0xB4, 0x41,
|
||||
0x9B, 0x81, 0x1C, 0x70, 0xDD, 0xC1, 0xDD, 0x0A, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x8A, 0x51, 0xE7, 0x21, 0x8A, 0x51, 0x3D, 0xF0, 0xDD, 0x80,
|
||||
0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0xF7, 0xFA,
|
||||
0x03, 0x9D, 0x7C, 0x2A, 0xCF, 0xC1, 0x7E, 0x6A, 0xCF, 0xC1, 0xCF, 0x0A, 0x4F, 0x88, 0x03, 0x59,
|
||||
0x85, 0xAA, 0x8A, 0x95, 0xB1, 0xA4, 0x8A, 0x51, 0x87, 0xEA, 0x01, 0xF0, 0x9B, 0x40, 0xD7, 0xC1,
|
||||
0x02, 0xF0, 0x57, 0x82, 0x03, 0x18, 0x94, 0xEB, 0x57, 0x88, 0xA8, 0x3E, 0x84, 0x80, 0x83, 0x93,
|
||||
0x00, 0xCB, 0x9C, 0xEA, 0x57, 0x88, 0x25, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xEB, 0x80, 0x57, 0x88,
|
||||
0x23, 0x3E, 0x84, 0x80, 0x6B, 0x88, 0xA0, 0x6A, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x37, 0x88,
|
||||
0x80, 0x40, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51,
|
||||
0x02, 0xA0, 0x8A, 0x51, 0x0F, 0x39, 0xEB, 0x80, 0x03, 0xD0, 0xEB, 0x4D, 0x57, 0x88, 0x23, 0x3E,
|
||||
0x84, 0x80, 0x00, 0x48, 0x15, 0x3E, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0x07, 0xF9,
|
||||
0xEC, 0x40, 0x04, 0xF0, 0x03, 0xD0, 0xEC, 0x0D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0xBB, 0x6A,
|
||||
0x6C, 0xCD, 0x6B, 0x84, 0x01, 0x38, 0xED, 0x80, 0x57, 0x88, 0x21, 0xFE, 0x84, 0x80, 0x6D, 0x88,
|
||||
0x80, 0x40, 0x8C, 0x70, 0x83, 0x96, 0xB5, 0x40, 0x83, 0x52, 0x57, 0x88, 0x21, 0xFE, 0x84, 0x80,
|
||||
0x00, 0x48, 0x83, 0x96, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x57, 0x88, 0xDE, 0x80,
|
||||
0x02, 0xF0, 0x8A, 0x95, 0x15, 0x64, 0x8A, 0x51, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x83, 0x93,
|
||||
0x00, 0x48, 0x0B, 0x3E, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xEB, 0x80, 0x57, 0x88,
|
||||
0x31, 0x3E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x57, 0x88, 0x29, 0x3E, 0x84, 0x80, 0x00, 0xCB,
|
||||
0xFB, 0xAA, 0x57, 0x88, 0x2B, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xEB, 0x80, 0x57, 0x88, 0x59, 0x7E,
|
||||
0x84, 0x80, 0x6B, 0x88, 0xFF, 0xEA, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x47, 0x48, 0x80, 0x40,
|
||||
0x06, 0x30, 0xDD, 0x80, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x47, 0x48, 0x00, 0x42, 0x8A, 0x51,
|
||||
0xBD, 0x21, 0x8A, 0x51, 0xEB, 0x80, 0x57, 0x88, 0x27, 0x7E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40,
|
||||
0x57, 0x88, 0x27, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xEB, 0x80, 0x57, 0x88, 0x31, 0x3E, 0x84, 0x80,
|
||||
0x00, 0x48, 0x6B, 0x07, 0xEC, 0x40, 0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80, 0x6C, 0x48, 0x80, 0x40,
|
||||
0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80, 0x7F, 0x70, 0x00, 0x42, 0x03, 0x5C, 0x2C, 0xEB, 0x57, 0x88,
|
||||
0x2F, 0xBE, 0x84, 0x80, 0x7F, 0x70, 0x80, 0x40, 0x57, 0xD8, 0x62, 0xEB, 0x57, 0x88, 0x2F, 0xBE,
|
||||
0x84, 0x80, 0x00, 0x48, 0xDD, 0x80, 0x03, 0x30, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x57, 0xD8, 0x70, 0xEB, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80,
|
||||
0x83, 0x93, 0x00, 0x48, 0xEB, 0x80, 0x01, 0xF0, 0x03, 0xD0, 0xEB, 0x4D, 0xFF, 0x7E, 0x03, 0xD0,
|
||||
0x03, 0x9D, 0x45, 0xEB, 0x6B, 0x0D, 0x02, 0xBE, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80, 0x01, 0xF0,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0,
|
||||
0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0xD7, 0x0A, 0x88, 0x6A, 0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80, 0x00, 0x48, 0xDD, 0x80, 0x04, 0xF0,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3B, 0x6B,
|
||||
0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0xEB, 0x80, 0x01, 0xF0, 0x03, 0xD0,
|
||||
0xEB, 0x4D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0x78, 0x2B, 0x6B, 0x0D, 0x02, 0xBE, 0xEF, 0xC0,
|
||||
0x6F, 0xC8, 0xDD, 0x80, 0x02, 0xF0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x02, 0xF0, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x60, 0xAB, 0xD1, 0x41, 0x51, 0x08, 0xDD, 0x80, 0x05, 0x30,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x51, 0x08,
|
||||
0xA0, 0xFE, 0x84, 0x80, 0x3F, 0xC8, 0x83, 0x93, 0x80, 0x40, 0x51, 0x08, 0xA0, 0xFE, 0x84, 0x80,
|
||||
0x03, 0x14, 0x00, 0xCD, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80, 0x06, 0x30, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x06, 0x30, 0xDD, 0xC1, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x08, 0xF0, 0xD1, 0x8A,
|
||||
0x51, 0x02, 0x03, 0x5C, 0x95, 0x2B, 0x12, 0x18, 0x1C, 0x9C, 0xCC, 0x2B, 0x1C, 0x10, 0x9B, 0xD4,
|
||||
0x00, 0xB0, 0x8A, 0x95, 0x0F, 0xA2, 0x8A, 0x51, 0x12, 0x5C, 0x1C, 0x58, 0xD5, 0x6B, 0x00, 0xB0,
|
||||
0x8A, 0x95, 0x75, 0xE1, 0x8A, 0x51, 0x1C, 0x54, 0x9B, 0x90, 0x92, 0x58, 0x9C, 0xDC, 0xDE, 0xAB,
|
||||
0x9C, 0x50, 0x9B, 0xD4, 0x01, 0xF0, 0x8A, 0x95, 0x0F, 0xA2, 0x8A, 0x51, 0x92, 0x9C, 0x9C, 0x98,
|
||||
0xE7, 0xAB, 0x01, 0xF0, 0x8A, 0x95, 0x75, 0xE1, 0x8A, 0x51, 0x9C, 0x94, 0x9B, 0x90, 0xD1, 0x41,
|
||||
0x51, 0x08, 0xDD, 0x80, 0x05, 0x30, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x24, 0x30, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xD2, 0x00, 0x52, 0x08, 0x41, 0xC2, 0x03, 0x18, 0x4D, 0xEC, 0x51, 0x08, 0xA0, 0xFE,
|
||||
0x84, 0x80, 0x3D, 0x88, 0x83, 0x93, 0x00, 0x42, 0x03, 0x18, 0x4D, 0xEC, 0x51, 0x08, 0xA0, 0xFE,
|
||||
0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0xEB, 0x80, 0x51, 0x08, 0xA0, 0xFE, 0x84, 0x80, 0x6B, 0x88,
|
||||
0x80, 0x40, 0x51, 0x08, 0xA0, 0xFE, 0x84, 0x80, 0x03, 0x14, 0x00, 0xCD, 0xEF, 0xC0, 0x6F, 0xC8,
|
||||
0xDD, 0x80, 0x06, 0x30, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x06, 0x30, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x08, 0xF0, 0xD1, 0x8A, 0x51, 0x02, 0x03, 0x5C, 0xE8, 0x2B, 0x59, 0xCE,
|
||||
0xF0, 0x39, 0x23, 0x04, 0x9E, 0x40, 0x21, 0x30, 0xD7, 0xC1, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD3, 0x40, 0x20, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD0, 0xC0, 0xD5, 0x81, 0x57, 0x88, 0x29, 0x3E, 0x84, 0x80,
|
||||
0x83, 0x93, 0x80, 0x88, 0x03, 0x59, 0x7E, 0x6C, 0x0D, 0xED, 0x43, 0x08, 0x52, 0x02, 0x03, 0x18,
|
||||
0x2A, 0xAC, 0x51, 0x08, 0xA0, 0xFE, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x3F, 0xC2, 0x03, 0x18,
|
||||
0x2A, 0xAC, 0x51, 0x08, 0xA0, 0xFE, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E, 0xEB, 0x80, 0x51, 0x08,
|
||||
0xA0, 0xFE, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x51, 0x08, 0xA0, 0xFE, 0x84, 0x80, 0x03, 0x14,
|
||||
0x00, 0xCD, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80, 0x06, 0x30, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x06, 0x30, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2A, 0xAC, 0x57, 0x88, 0x23, 0x3E,
|
||||
0x84, 0x80, 0x00, 0x48, 0x37, 0xC6, 0x03, 0x9D, 0x87, 0xEC, 0x49, 0x08, 0x88, 0x6C, 0x4B, 0x48,
|
||||
0xD4, 0x00, 0x53, 0x48, 0x54, 0x02, 0x03, 0x18, 0xC2, 0xAC, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80,
|
||||
0x45, 0x08, 0x00, 0x42, 0x03, 0x18, 0xC2, 0xAC, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x00, 0x48,
|
||||
0x01, 0xBE, 0xEB, 0x80, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x57, 0x88,
|
||||
0x59, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xEB, 0x80, 0x01, 0xF0, 0x03, 0xD0, 0xEB, 0x4D, 0xFF, 0x7E,
|
||||
0x03, 0xD0, 0x03, 0x9D, 0xA6, 0xEC, 0x6B, 0x0D, 0x02, 0xBE, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80,
|
||||
0x01, 0xF0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x01, 0xF0, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0xFA, 0x6C, 0x4D, 0x48, 0x53, 0x42, 0x57, 0x88, 0x03, 0x18, 0x0E, 0xED, 0x59, 0x7E,
|
||||
0x84, 0x80, 0x00, 0x48, 0x47, 0x42, 0x57, 0x88, 0x03, 0x18, 0x0E, 0xED, 0x59, 0x7E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xFF, 0x7E, 0xEB, 0x80, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40,
|
||||
0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xEB, 0x80, 0x01, 0xF0, 0x03, 0xD0, 0xEB, 0x4D,
|
||||
0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0xDF, 0xAC, 0x6B, 0x0D, 0x02, 0xBE, 0xEF, 0xC0, 0x6F, 0xC8,
|
||||
0xDD, 0x80, 0x01, 0xF0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x01, 0xF0, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x06, 0x30, 0xD5, 0x81, 0xD5, 0xCA, 0xDD, 0x80, 0x57, 0x88, 0x59, 0x7E,
|
||||
0x84, 0x80, 0x47, 0x48, 0x83, 0x93, 0x00, 0x42, 0x8A, 0x51, 0xBD, 0x21, 0x8A, 0x51, 0xEB, 0x80,
|
||||
0x57, 0x88, 0x27, 0x7E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x57, 0x88, 0xA8, 0x3E, 0x84, 0x80,
|
||||
0x80, 0x88, 0x03, 0x9D, 0xEE, 0xAD, 0x50, 0xC8, 0x39, 0x42, 0x03, 0x18, 0x78, 0x2D, 0x57, 0x88,
|
||||
0x23, 0x3E, 0x84, 0x80, 0x35, 0x48, 0x00, 0x42, 0x03, 0x18, 0x78, 0x2D, 0x57, 0x88, 0x23, 0x3E,
|
||||
0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0xEB, 0x80, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x6B, 0x88,
|
||||
0x80, 0x40, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51,
|
||||
0x02, 0xA0, 0x8A, 0x51, 0x0F, 0x39, 0xEB, 0x80, 0x03, 0xD0, 0xEB, 0x4D, 0x57, 0x88, 0x23, 0x3E,
|
||||
0x84, 0x80, 0x00, 0x48, 0x15, 0x3E, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0x07, 0xF9,
|
||||
0xEC, 0x40, 0x04, 0xF0, 0x03, 0xD0, 0xEC, 0x0D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0x43, 0xED,
|
||||
0x6C, 0xCD, 0x6B, 0x84, 0x01, 0x38, 0xED, 0x80, 0x57, 0x88, 0x21, 0xFE, 0x84, 0x80, 0x6D, 0x88,
|
||||
0x80, 0x40, 0x8C, 0x70, 0x83, 0x96, 0xB5, 0x40, 0x83, 0x52, 0x57, 0x88, 0x21, 0xFE, 0x84, 0x80,
|
||||
0x00, 0x48, 0x83, 0x96, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x57, 0x88, 0xDE, 0x80,
|
||||
0x02, 0xF0, 0x8A, 0x95, 0x15, 0x64, 0x8A, 0x51, 0x01, 0xF0, 0xDD, 0xC1, 0xDD, 0x0A, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0, 0xDD, 0xC1,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xDC, 0x6D,
|
||||
0x3B, 0x88, 0x50, 0xC2, 0x03, 0x18, 0xEE, 0xAD, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48,
|
||||
0x37, 0x82, 0x03, 0x18, 0xEE, 0xAD, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E,
|
||||
0xEB, 0x80, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x57, 0x88, 0x23, 0x3E,
|
||||
0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0x0F, 0x39,
|
||||
0xEB, 0x80, 0x03, 0xD0, 0xEB, 0x4D, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x15, 0x3E,
|
||||
0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0x07, 0xF9, 0xEC, 0x40, 0x04, 0xF0, 0x03, 0xD0,
|
||||
0xEC, 0x0D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0xA8, 0xED, 0x6C, 0xCD, 0x6B, 0x84, 0x01, 0x38,
|
||||
0xED, 0x80, 0x57, 0x88, 0x21, 0xFE, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x8C, 0x70, 0x83, 0x96,
|
||||
0xB5, 0x40, 0x83, 0x52, 0x57, 0x88, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x83, 0x96, 0xB6, 0x40,
|
||||
0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x57, 0x88, 0xDE, 0x80, 0x02, 0xF0, 0x8A, 0x95, 0x15, 0x64,
|
||||
0x8A, 0x51, 0x01, 0xF0, 0xDD, 0xC1, 0xDD, 0x0A, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xD5, 0x81, 0xD5, 0xCA, 0x57, 0x88, 0x23, 0x3E,
|
||||
0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x0B, 0x3E, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51,
|
||||
0xEB, 0x80, 0x57, 0x88, 0x31, 0x3E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x55, 0xCB, 0x19, 0xEE,
|
||||
0x57, 0x88, 0x27, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xEB, 0x80, 0x57, 0x88, 0x31, 0x3E, 0x84, 0x80,
|
||||
0x00, 0x48, 0x6B, 0x07, 0xEC, 0x40, 0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80, 0x6C, 0x48, 0x80, 0x40,
|
||||
0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80, 0x7F, 0x70, 0x00, 0x42, 0x57, 0x88, 0x03, 0x5C, 0x0D, 0xEE,
|
||||
0x2F, 0xBE, 0x84, 0x80, 0x7F, 0x70, 0x80, 0x40, 0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80, 0x00, 0x48,
|
||||
0xDD, 0x80, 0x03, 0x30, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x23, 0x70, 0xD7, 0xC1, 0xD7, 0x0A, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xD3, 0x40, 0x22, 0x30, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xD0, 0xC0, 0xD6, 0x81, 0x57, 0x88, 0x29, 0x3E, 0x84, 0x80, 0x83, 0x93,
|
||||
0x80, 0x88, 0x03, 0x9D, 0xC2, 0xEE, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x37, 0xC6,
|
||||
0x03, 0x9D, 0x3C, 0x2E, 0x49, 0x08, 0x3D, 0x6E, 0x4B, 0x48, 0xD4, 0x00, 0x53, 0x48, 0x54, 0x02,
|
||||
0x03, 0x18, 0x77, 0xAE, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x45, 0x08, 0x00, 0x42, 0x03, 0x18,
|
||||
0x77, 0xAE, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0xEB, 0x80, 0x57, 0x88,
|
||||
0x59, 0x7E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x00, 0x48,
|
||||
0xEB, 0x80, 0x01, 0xF0, 0x03, 0xD0, 0xEB, 0x4D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0x5B, 0x6E,
|
||||
0x6B, 0x0D, 0x02, 0xBE, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80, 0x02, 0xF0, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x02, 0xF0, 0xDD, 0xC1, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xAF, 0xAE, 0x4D, 0x48,
|
||||
0x53, 0x42, 0x57, 0x88, 0x03, 0x18, 0xC3, 0x2E, 0x59, 0x7E, 0x84, 0x80, 0x00, 0x48, 0x47, 0x42,
|
||||
0x57, 0x88, 0x03, 0x18, 0xC3, 0x2E, 0x59, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E, 0xEB, 0x80,
|
||||
0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xEB, 0x80, 0x01, 0xF0, 0x03, 0xD0, 0xEB, 0x4D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D,
|
||||
0x94, 0xEE, 0x6B, 0x0D, 0x02, 0xBE, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80, 0x02, 0xF0, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x02, 0xF0, 0xDD, 0xC1,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x06, 0x30,
|
||||
0xD6, 0x81, 0xD6, 0xCA, 0xDD, 0x80, 0x57, 0x88, 0x59, 0x7E, 0x84, 0x80, 0x47, 0x48, 0x83, 0x93,
|
||||
0x00, 0x42, 0x8A, 0x51, 0xBD, 0x21, 0x8A, 0x51, 0xEB, 0x80, 0x57, 0x88, 0x27, 0x7E, 0x84, 0x80,
|
||||
0x6B, 0x88, 0x80, 0x40, 0x57, 0x88, 0xA8, 0x3E, 0x84, 0x80, 0x80, 0x88, 0x03, 0x9D, 0xA3, 0x6F,
|
||||
0x50, 0xC8, 0x39, 0x42, 0x03, 0x18, 0x2D, 0x6F, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x35, 0x48,
|
||||
0x00, 0x42, 0x03, 0x18, 0x2D, 0x6F, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x01, 0xBE,
|
||||
0xEB, 0x80, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x57, 0x88, 0x23, 0x3E,
|
||||
0x84, 0x80, 0x00, 0x48, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0x0F, 0x39,
|
||||
0xEB, 0x80, 0x03, 0xD0, 0xEB, 0x4D, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x15, 0x3E,
|
||||
0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0x07, 0xF9, 0xEC, 0x40, 0x04, 0xF0, 0x03, 0xD0,
|
||||
0xEC, 0x0D, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0xF8, 0x6E, 0x6C, 0xCD, 0x6B, 0x84, 0x01, 0x38,
|
||||
0xED, 0x80, 0x57, 0x88, 0x21, 0xFE, 0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x8C, 0x70, 0x83, 0x96,
|
||||
0xB5, 0x40, 0x83, 0x52, 0x57, 0x88, 0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x83, 0x96, 0xB6, 0x40,
|
||||
0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x57, 0x88, 0xDE, 0x80, 0x02, 0xF0, 0x8A, 0x95, 0x15, 0x64,
|
||||
0x8A, 0x51, 0x02, 0xF0, 0xDD, 0xC1, 0xDD, 0x0A, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x02, 0xF0, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x91, 0x2F, 0x3B, 0x88, 0x50, 0xC2, 0x03, 0x18,
|
||||
0xA3, 0x6F, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x37, 0x82, 0x03, 0x18, 0xA3, 0x6F,
|
||||
0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xFF, 0x7E, 0xEB, 0x80, 0x57, 0x88, 0x23, 0x3E,
|
||||
0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x01, 0xBE,
|
||||
0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0x0F, 0x39, 0xEB, 0x80, 0x03, 0xD0, 0xEB, 0x4D,
|
||||
0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x15, 0x3E, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0,
|
||||
0x8A, 0x51, 0x07, 0xF9, 0xEC, 0x40, 0x04, 0xF0, 0x03, 0xD0, 0xEC, 0x0D, 0xFF, 0x7E, 0x03, 0xD0,
|
||||
0x03, 0x9D, 0x5D, 0xAF, 0x6C, 0xCD, 0x6B, 0x84, 0x01, 0x38, 0xED, 0x80, 0x57, 0x88, 0x21, 0xFE,
|
||||
0x84, 0x80, 0x6D, 0x88, 0x80, 0x40, 0x8C, 0x70, 0x83, 0x96, 0xB5, 0x40, 0x83, 0x52, 0x57, 0x88,
|
||||
0x21, 0xFE, 0x84, 0x80, 0x00, 0x48, 0x83, 0x96, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80,
|
||||
0x57, 0x88, 0xDE, 0x80, 0x02, 0xF0, 0x8A, 0x95, 0x15, 0x64, 0x8A, 0x51, 0x02, 0xF0, 0xDD, 0xC1,
|
||||
0xDD, 0x0A, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x02, 0xF0, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0xD6, 0x81, 0xD6, 0xCA, 0x57, 0x88, 0x23, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48,
|
||||
0x0B, 0x3E, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xEB, 0x80, 0x57, 0x88, 0x31, 0x3E,
|
||||
0x84, 0x80, 0x6B, 0x88, 0x80, 0x40, 0x56, 0xCB, 0xC3, 0x2B, 0x57, 0x88, 0x27, 0x7E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xEB, 0x80, 0x57, 0x88, 0x31, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x6B, 0x07, 0xEC, 0x40,
|
||||
0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80, 0x6C, 0x48, 0x80, 0x40, 0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80,
|
||||
0x7F, 0x70, 0x00, 0x42, 0x57, 0x88, 0x03, 0x5C, 0xC2, 0x2F, 0x2F, 0xBE, 0x84, 0x80, 0x7F, 0x70,
|
||||
0x80, 0x40, 0x57, 0x88, 0x2F, 0xBE, 0x84, 0x80, 0x00, 0x48, 0xDD, 0x80, 0x04, 0xF0, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xC3, 0x2B, 0xEE, 0xC1,
|
||||
0x83, 0x93, 0x23, 0x70, 0x84, 0x80, 0x5D, 0xF0, 0x8A, 0x51, 0xB5, 0xE1, 0x8A, 0x51, 0xA0, 0x30,
|
||||
0x84, 0x80, 0xD5, 0xF0, 0x8A, 0x51, 0xB5, 0xE1, 0x83, 0x96, 0x38, 0x70, 0xD5, 0x40, 0x3A, 0xB0,
|
||||
0xD6, 0x40, 0x3C, 0xB0, 0xD7, 0x80, 0x78, 0xB0, 0xD8, 0x00, 0x7A, 0xF0, 0xD9, 0x40, 0x7C, 0xF0,
|
||||
0xDA, 0x40, 0x7D, 0x30, 0xDB, 0x80, 0x7F, 0x70, 0xDC, 0x40, 0xB9, 0xF0, 0xDD, 0x80, 0xBA, 0xF0,
|
||||
0xDE, 0x80, 0xBB, 0x30, 0xDF, 0xC0, 0xFA, 0x30, 0xE0, 0xC0, 0xFB, 0x70, 0xE1, 0x00, 0xFC, 0x30,
|
||||
0xE2, 0x00, 0xFD, 0x70, 0xE3, 0x40, 0xFF, 0xB0, 0xE4, 0x00, 0x83, 0x01, 0x8A, 0x51, 0x21, 0x6A,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xE4, 0x00, 0x64, 0x9C, 0xDD, 0x69,
|
||||
0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0,
|
||||
0x3F, 0x30, 0xEF, 0x45, 0x6F, 0xC8, 0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xE4, 0xB0, 0xE2, 0x00, 0x8F, 0x29, 0x90, 0x69,
|
||||
0xE2, 0xCB, 0x8E, 0xE9, 0x93, 0xE9, 0x00, 0x00, 0x83, 0x52, 0x03, 0x53, 0x64, 0x9C, 0xF2, 0x29,
|
||||
0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0,
|
||||
0x6F, 0xC8, 0xEF, 0xF9, 0x10, 0x38, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x80, 0xF0, 0x83, 0x96,
|
||||
0xB5, 0x40, 0x03, 0x30, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x64, 0x08, 0xDE, 0x80,
|
||||
0x02, 0xF0, 0x15, 0x64, 0x8A, 0x95, 0x04, 0xF0, 0xE3, 0x40, 0x1C, 0x70, 0xE2, 0x00, 0xE2, 0xCB,
|
||||
0xBF, 0xA9, 0xE3, 0x0B, 0xBF, 0xA9, 0x00, 0x00, 0x91, 0x70, 0x83, 0x96, 0x03, 0x53, 0xB5, 0x40,
|
||||
0x83, 0x52, 0x64, 0x08, 0xAE, 0xBE, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x83, 0x96, 0xB6, 0x40,
|
||||
0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x64, 0x08, 0xDE, 0x80, 0x02, 0xF0, 0x15, 0x64, 0x8A, 0x95,
|
||||
0x83, 0x96, 0xAE, 0x1C, 0xAF, 0x18, 0x09, 0x6A, 0x0C, 0x6A, 0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88,
|
||||
0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0xF3, 0x30, 0xEF, 0x45, 0x6F, 0xC8,
|
||||
0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x8C, 0xA9, 0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0xFE, 0xF9, 0x01, 0x38, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80,
|
||||
0x00, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0xAE, 0x29, 0x83, 0x52, 0x1B, 0x92, 0x08, 0x40, 0x83, 0x52, 0x1B, 0xD6, 0x08, 0x40, 0xEA, 0x40,
|
||||
0x6A, 0x98, 0x1A, 0xAA, 0x25, 0x70, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0x21, 0x6A, 0x2A, 0x70, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xE6, 0x40, 0xE9, 0x40, 0x3F, 0x30, 0xE9, 0xC5, 0x88, 0x30, 0x83, 0x96, 0xB5, 0x40,
|
||||
0x83, 0x52, 0x69, 0x48, 0x83, 0x96, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x6A, 0x48,
|
||||
0xDE, 0x80, 0x02, 0xF0, 0x15, 0x64, 0x8A, 0x95, 0x66, 0x48, 0xE3, 0x40, 0x06, 0x30, 0x03, 0xD0,
|
||||
0xE3, 0xCC, 0xFF, 0x7E, 0x03, 0x9D, 0x37, 0x2A, 0x63, 0x48, 0xE9, 0x40, 0x03, 0x30, 0xE9, 0xC5,
|
||||
0x6A, 0x98, 0x68, 0xAA, 0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xEF, 0xC0, 0x69, 0x48, 0xE3, 0x40, 0x03, 0xD0, 0xE3, 0x0D, 0x03, 0xD0, 0xE3, 0x0D,
|
||||
0x6F, 0xC8, 0xF3, 0xB9, 0x63, 0x44, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x6A, 0x98, 0x87, 0xEA,
|
||||
0x26, 0x70, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0x8E, 0xEA,
|
||||
0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0,
|
||||
0x69, 0x48, 0xE3, 0x40, 0x06, 0x30, 0x03, 0xD0, 0xE3, 0x0D, 0xFF, 0x7E, 0x03, 0x9D, 0x73, 0x2A,
|
||||
0x6F, 0xC8, 0x3F, 0xB9, 0x63, 0x44, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x5E, 0x2A, 0x2B, 0xB0,
|
||||
0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xE9, 0x40, 0x07, 0x70,
|
||||
0xE9, 0xC5, 0x06, 0x30, 0x69, 0x42, 0x03, 0x5C, 0xA7, 0x2A, 0x8A, 0x70, 0x83, 0x96, 0xB5, 0x40,
|
||||
0x6A, 0xB0, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x6A, 0x48, 0xDE, 0x80, 0x02, 0xF0,
|
||||
0x15, 0x64, 0x8A, 0x95, 0x8B, 0xB0, 0x83, 0x96, 0xB5, 0x40, 0x04, 0xF0, 0xC0, 0x6A, 0x69, 0x48,
|
||||
0x05, 0xBA, 0x8A, 0x70, 0x03, 0x9D, 0xB1, 0xEA, 0x83, 0x96, 0xB5, 0x40, 0x20, 0xF0, 0xB6, 0x40,
|
||||
0xB4, 0xEA, 0x83, 0x96, 0xB5, 0x40, 0xB6, 0x81, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x6A, 0x48,
|
||||
0xDE, 0x80, 0x02, 0xF0, 0x15, 0x64, 0x8A, 0x95, 0x8B, 0xB0, 0x83, 0x96, 0xB5, 0x40, 0x05, 0x30,
|
||||
0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x6A, 0x48, 0xDE, 0x80, 0x02, 0xF0, 0x15, 0x64,
|
||||
0x8A, 0x95, 0x6A, 0x98, 0xE3, 0x2A, 0x27, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xE5, 0x40, 0x28, 0x30, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xE9, 0x40, 0x29, 0x70, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xFA, 0x6A, 0x2C, 0x70, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xE5, 0x40, 0x2D, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xE9, 0x40, 0x2E, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xE7, 0x80, 0x69, 0x48, 0xE3, 0x40, 0x07, 0x70, 0x03, 0xD0, 0xE3, 0xCC,
|
||||
0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0xFF, 0xEA, 0x65, 0xCD, 0x63, 0x44, 0xE8, 0x00, 0x84, 0x30,
|
||||
0x83, 0x96, 0xB5, 0x40, 0x83, 0x52, 0x68, 0x08, 0x83, 0x96, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52,
|
||||
0xDD, 0x80, 0x6A, 0x48, 0xDE, 0x80, 0x02, 0xF0, 0x15, 0x64, 0x8A, 0x95, 0x67, 0x88, 0xE3, 0x40,
|
||||
0x07, 0x70, 0x03, 0xD0, 0xE3, 0xCC, 0xFF, 0x7E, 0x03, 0xD0, 0x03, 0x9D, 0x1A, 0xEB, 0x69, 0xCD,
|
||||
0x63, 0x44, 0xE8, 0x00, 0x85, 0x70, 0x83, 0x96, 0xB5, 0x40, 0x83, 0x52, 0x68, 0x08, 0x83, 0x96,
|
||||
0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x6A, 0x48, 0xDE, 0x80, 0x02, 0xF0, 0x15, 0x64,
|
||||
0x8A, 0x95, 0x03, 0xD0, 0x67, 0x0D, 0xE8, 0x00, 0x86, 0x70, 0x83, 0x96, 0xB5, 0x40, 0x83, 0x52,
|
||||
0x68, 0x08, 0x83, 0x96, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80, 0x6A, 0x48, 0xDE, 0x80,
|
||||
0x02, 0xF0, 0x15, 0x64, 0x8A, 0x95, 0x6A, 0x48, 0x2D, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x88,
|
||||
0x03, 0x59, 0x4F, 0x6B, 0x6A, 0x48, 0x5B, 0xBE, 0x84, 0x80, 0x03, 0x30, 0x53, 0x2B, 0x6A, 0x48,
|
||||
0x5B, 0xBE, 0x84, 0x80, 0x01, 0xF0, 0x80, 0x40, 0x80, 0xF0, 0x83, 0x96, 0xB5, 0x40, 0x83, 0x52,
|
||||
0x6A, 0x48, 0x5B, 0xBE, 0x84, 0x80, 0x00, 0x48, 0x04, 0x38, 0x83, 0x96, 0xB6, 0x40, 0xB5, 0xF0,
|
||||
0x83, 0x52, 0xDD, 0x80, 0x6A, 0x48, 0xDE, 0x80, 0x02, 0xF0, 0x15, 0x64, 0x8A, 0x95, 0x03, 0x30,
|
||||
0xE4, 0x00, 0x7D, 0x30, 0xE3, 0x40, 0xE3, 0x0B, 0x6B, 0x6B, 0xE4, 0xCB, 0x6B, 0x6B, 0x83, 0x52,
|
||||
0x03, 0x53, 0x6A, 0xDC, 0x87, 0x2B, 0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0x12, 0x6F, 0xC8, 0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x9A, 0x2B, 0x00, 0xB0,
|
||||
0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xD0,
|
||||
0x6F, 0xC8, 0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x05, 0x30, 0xE3, 0x40, 0xE3, 0x0B, 0x9C, 0x2B, 0x83, 0x52, 0x03, 0x53,
|
||||
0x6A, 0xDC, 0xFC, 0xAB, 0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0xDF, 0xF9, 0x20, 0x38, 0xEF, 0xC0, 0x6F, 0xC8, 0xDD, 0x80,
|
||||
0x00, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x15, 0x70, 0xE4, 0x00, 0xC6, 0xB0, 0xE3, 0x40, 0xE3, 0x0B, 0xBC, 0x6B, 0xE4, 0xCB, 0xBC, 0x6B,
|
||||
0x00, 0x00, 0x80, 0xF0, 0x83, 0x96, 0x03, 0x53, 0xB5, 0x40, 0x83, 0x52, 0x6A, 0x48, 0x5B, 0xBE,
|
||||
0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x0C, 0x78, 0x83, 0x96, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52,
|
||||
0xDD, 0x80, 0x6A, 0x48, 0xDE, 0x80, 0x02, 0xF0, 0x15, 0x64, 0x8A, 0x95, 0x04, 0xF0, 0xE4, 0x00,
|
||||
0x1C, 0x70, 0xE3, 0x40, 0xE3, 0x0B, 0xDA, 0x6B, 0xE4, 0xCB, 0xDA, 0x6B, 0x00, 0x00, 0x11, 0x30,
|
||||
0x83, 0x96, 0x03, 0x53, 0xB5, 0x40, 0x55, 0xB0, 0xB6, 0x40, 0xB5, 0xF0, 0x83, 0x52, 0xDD, 0x80,
|
||||
0x6A, 0x48, 0xDE, 0x80, 0x02, 0xF0, 0x4E, 0xA4, 0x8A, 0x95, 0x6A, 0x48, 0xAE, 0xBE, 0x84, 0x80,
|
||||
0x83, 0x96, 0x35, 0x48, 0x83, 0x93, 0x80, 0x40, 0x83, 0x52, 0x6A, 0x48, 0xAE, 0xBE, 0x84, 0x80,
|
||||
0x00, 0xDC, 0x13, 0xAC, 0x9B, 0xD2, 0x08, 0x40, 0x00, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0xFD, 0xF9, 0x02, 0x38, 0xEF, 0xC0,
|
||||
0x6F, 0xC8, 0xDD, 0x80, 0x00, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0xB8, 0x2B, 0x9B, 0x16, 0x08, 0x40, 0xE0, 0xC0, 0x5E, 0xD8, 0x33, 0xEC,
|
||||
0xE1, 0x41, 0x60, 0xC8, 0x61, 0x02, 0x03, 0x18, 0x28, 0x6C, 0x61, 0x08, 0x5D, 0x07, 0xDF, 0xC0,
|
||||
0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x99, 0x00, 0x18, 0x14, 0x18, 0xD0, 0xE1, 0x8A, 0x19, 0xAC,
|
||||
0x18, 0x55, 0x18, 0x11, 0x83, 0x52, 0x03, 0x53, 0x11, 0x5C, 0x08, 0x40, 0x05, 0x30, 0xDF, 0xC0,
|
||||
0xDF, 0x8B, 0x30, 0x6C, 0x2A, 0xAC, 0xE1, 0x41, 0x60, 0xC8, 0x61, 0x02, 0x03, 0x18, 0x43, 0xAC,
|
||||
0x61, 0x08, 0x5D, 0x07, 0xDF, 0xC0, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x9A, 0x00, 0x98, 0x95,
|
||||
0x98, 0x51, 0xE1, 0x8A, 0x34, 0xAC, 0x98, 0x96, 0x98, 0x52, 0x83, 0x52, 0x03, 0x53, 0x91, 0x9C,
|
||||
0x08, 0x40, 0x05, 0x30, 0xDF, 0xC0, 0xDF, 0x8B, 0x4B, 0xEC, 0x45, 0xAC, 0xE0, 0xC0, 0x10, 0xF0,
|
||||
0x60, 0xC2, 0x03, 0x5C, 0x55, 0xEC, 0x10, 0xF0, 0x56, 0xEC, 0x60, 0xC8, 0xE1, 0x00, 0x5E, 0xD8,
|
||||
0x85, 0xAC, 0xE2, 0x41, 0x61, 0x08, 0x62, 0x02, 0x03, 0x18, 0x69, 0xEC, 0x62, 0x08, 0x5D, 0x07,
|
||||
0xDF, 0xC0, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x99, 0x00, 0x18, 0x14, 0x18, 0xD0, 0xE2, 0x8A,
|
||||
0x5A, 0xEC, 0x18, 0x55, 0x18, 0x11, 0x83, 0x52, 0x03, 0x53, 0x11, 0x5C, 0x75, 0x2C, 0x2A, 0x70,
|
||||
0xDF, 0xC0, 0xDF, 0x8B, 0x71, 0xEC, 0x00, 0x00, 0x6B, 0x2C, 0xE2, 0x41, 0x61, 0x08, 0x62, 0x02,
|
||||
0x03, 0x18, 0x08, 0x40, 0x62, 0x08, 0x5D, 0x07, 0xDF, 0xC0, 0x84, 0x80, 0x0F, 0x48, 0x83, 0x93,
|
||||
0x80, 0x40, 0x98, 0x54, 0x98, 0x10, 0xE2, 0x8A, 0x76, 0x2C, 0xE2, 0x41, 0x61, 0x08, 0x62, 0x02,
|
||||
0x03, 0x18, 0x95, 0xEC, 0x62, 0x08, 0x5D, 0x07, 0xDF, 0xC0, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48,
|
||||
0x9A, 0x00, 0x98, 0x95, 0x98, 0x51, 0xE2, 0x8A, 0x86, 0xAC, 0x98, 0x96, 0x98, 0x52, 0x83, 0x52,
|
||||
0x03, 0x53, 0x91, 0x9C, 0xA1, 0xAC, 0x2A, 0x70, 0xDF, 0xC0, 0xDF, 0x8B, 0x9D, 0x2C, 0x00, 0x00,
|
||||
0x97, 0x2C, 0xE2, 0x41, 0x61, 0x08, 0x62, 0x02, 0x03, 0x18, 0x08, 0x40, 0x62, 0x08, 0x5D, 0x07,
|
||||
0xDF, 0xC0, 0x84, 0x80, 0x10, 0x88, 0x83, 0x93, 0x80, 0x40, 0x18, 0x56, 0x18, 0x12, 0xE2, 0x8A,
|
||||
0xA2, 0xAC, 0x55, 0xB0, 0x9B, 0x40, 0xD7, 0xC1, 0x02, 0xF0, 0x57, 0x82, 0x03, 0x18, 0xC9, 0x2D,
|
||||
0x57, 0x88, 0x01, 0xBE, 0x9B, 0x40, 0x57, 0x88, 0x33, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81,
|
||||
0x57, 0x88, 0x33, 0x7E, 0x84, 0x80, 0x80, 0x88, 0x03, 0x9D, 0xEC, 0x2C, 0x3C, 0xB0, 0xDD, 0x80,
|
||||
0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x57, 0xD8, 0xDC, 0x2C,
|
||||
0x57, 0x88, 0x33, 0x7E, 0x84, 0x80, 0x6F, 0xC8, 0xDF, 0xC0, 0x07, 0x70, 0x03, 0xD0, 0xDF, 0x4C,
|
||||
0xFF, 0x7E, 0x03, 0x9D, 0xD6, 0x2C, 0xE7, 0x6C, 0x57, 0x88, 0x33, 0x7E, 0x84, 0x80, 0x6F, 0xC8,
|
||||
0xDF, 0xC0, 0x05, 0x30, 0x03, 0xD0, 0xDF, 0x4C, 0xFF, 0x7E, 0x03, 0x9D, 0xE2, 0xEC, 0x5F, 0xC8,
|
||||
0x01, 0x79, 0x83, 0x93, 0x80, 0x40, 0xC0, 0x6C, 0x3D, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0x03, 0x59, 0xF9, 0x6C, 0x6F, 0x4B,
|
||||
0x18, 0xAD, 0x57, 0x88, 0x2D, 0x7E, 0x84, 0x80, 0x6F, 0xC8, 0x83, 0x93, 0x80, 0x40, 0x57, 0x88,
|
||||
0x2D, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xDD, 0x80, 0x1A, 0x70, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3E, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0x03, 0x9D, 0x2B, 0x2D, 0x49, 0xED,
|
||||
0x57, 0x88, 0x2D, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0x57, 0x88, 0x2D, 0x7E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xDD, 0x80, 0x1A, 0x70, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x0C, 0xAD, 0x10, 0xF0, 0x6F, 0xC2, 0x03, 0x18, 0x49, 0xED, 0x57, 0x88,
|
||||
0x2B, 0x7E, 0x84, 0x80, 0x6F, 0xC8, 0x83, 0x93, 0x80, 0x40, 0x57, 0x88, 0x2B, 0x7E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x57, 0x88, 0x29, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0x80, 0xCA,
|
||||
0x76, 0x6D, 0x6F, 0xC8, 0xFF, 0x3A, 0x03, 0x9D, 0x5E, 0x6D, 0x57, 0x88, 0x2B, 0x7E, 0x84, 0x80,
|
||||
0x07, 0x70, 0x83, 0x93, 0x80, 0x40, 0xFF, 0xB0, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x71, 0x2D, 0x57, 0x88, 0x2B, 0x7E,
|
||||
0x84, 0x80, 0x07, 0x70, 0x83, 0x93, 0x80, 0x40, 0x57, 0x88, 0x2B, 0x7E, 0x84, 0x80, 0x00, 0x48,
|
||||
0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x57, 0x88, 0x29, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0x3F, 0x30, 0xDD, 0x80,
|
||||
0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x0A, 0x30, 0x6F, 0xC2,
|
||||
0x03, 0x18, 0x9C, 0x2D, 0x57, 0x88, 0x25, 0x3E, 0x84, 0x80, 0x6F, 0xC8, 0x83, 0x93, 0x80, 0x40,
|
||||
0x57, 0x88, 0x25, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x57, 0x88, 0xA8, 0x3E, 0x84, 0x80,
|
||||
0x83, 0x93, 0x80, 0x81, 0x80, 0xCA, 0xC7, 0x6D, 0x6F, 0xC8, 0xFF, 0x3A, 0x03, 0x9D, 0xB0, 0xED,
|
||||
0x57, 0x88, 0x25, 0x3E, 0x84, 0x80, 0xFF, 0xB0, 0x83, 0x93, 0x80, 0x81, 0xDD, 0x80, 0x1C, 0x70,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xC2, 0xED,
|
||||
0x57, 0x88, 0x25, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0x57, 0x88, 0x25, 0x3E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x57, 0x88, 0xA8, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0xD7, 0x0A,
|
||||
0xB4, 0xEC, 0x03, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0x03, 0xBA, 0x03, 0x9D, 0xCB, 0x6D, 0x3E, 0xF0,
|
||||
0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xB6, 0x40, 0x3F, 0x30,
|
||||
0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xB8, 0x00, 0x36, 0x42,
|
||||
0x03, 0x5C, 0x07, 0xEE, 0x0A, 0x30, 0x36, 0x42, 0x03, 0x18, 0x07, 0xEE, 0x36, 0x48, 0xDD, 0x80,
|
||||
0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x38, 0x08, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x36, 0x48, 0xB5, 0x40, 0x38, 0x08, 0xB7, 0x80, 0x1D, 0x2E, 0x09, 0x30,
|
||||
0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x1C, 0x70, 0xDD, 0xC1, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x09, 0x30, 0xB5, 0x40, 0xB7, 0xC1, 0x04, 0xF0, 0x9B, 0x40, 0x3C, 0xB0,
|
||||
0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8,
|
||||
0x04, 0x7A, 0x03, 0x9D, 0x1F, 0x6E, 0x3E, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xBA, 0x40, 0x3F, 0x30, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xBC, 0x40, 0x3A, 0x42, 0x03, 0x5C, 0x5A, 0x2E, 0x02, 0xF0, 0x3C, 0x42,
|
||||
0x03, 0x5C, 0x5A, 0x2E, 0x3A, 0x48, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3C, 0x48, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3A, 0x48, 0xB9, 0x40,
|
||||
0x3C, 0x48, 0x71, 0x2E, 0x23, 0x70, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x10, 0xF0, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x23, 0x70, 0xB9, 0x40,
|
||||
0x10, 0xF0, 0xBB, 0x80, 0x05, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0x05, 0xBA, 0x03, 0x9D, 0x74, 0x2E,
|
||||
0x3E, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC6, 0x00,
|
||||
0x3F, 0x30, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC8, 0xC0,
|
||||
0x46, 0x02, 0x03, 0x5C, 0xB2, 0x2E, 0x10, 0xF0, 0x46, 0x02, 0x03, 0x18, 0xB2, 0x2E, 0x48, 0xC8,
|
||||
0x03, 0x59, 0xB2, 0x2E, 0x46, 0x08, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x48, 0xC8, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x46, 0x08, 0xC5, 0x00,
|
||||
0x48, 0xC8, 0xC9, 0x2E, 0x0B, 0x70, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00,
|
||||
0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x07, 0x70, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80,
|
||||
0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x0B, 0x70, 0xC5, 0x00,
|
||||
0x07, 0x70, 0xC7, 0x40, 0x06, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0x06, 0xBA, 0x03, 0x9D, 0xCC, 0x2E,
|
||||
0x3D, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xCC, 0x00,
|
||||
0x3E, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xCA, 0x00,
|
||||
0x3F, 0x30, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xCE, 0x40,
|
||||
0x4A, 0x08, 0x4C, 0x02, 0x03, 0x5C, 0x1F, 0xAF, 0x4E, 0x48, 0x4A, 0x02, 0x03, 0x5C, 0x1F, 0xAF,
|
||||
0x4E, 0x48, 0x03, 0x59, 0x1F, 0xAF, 0x4C, 0x08, 0xDD, 0x80, 0x1A, 0x70, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x4A, 0x08, 0xDD, 0x80, 0x1B, 0xB0,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x4E, 0x48,
|
||||
0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x4C, 0x08, 0xCB, 0x40, 0x4A, 0x08, 0xC9, 0x00, 0x4E, 0x48, 0x42, 0xEF, 0x73, 0xF0,
|
||||
0xDD, 0x80, 0x1A, 0x70, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x64, 0x70, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2D, 0xB0, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x73, 0xF0, 0xCB, 0x40, 0x64, 0x70,
|
||||
0xC9, 0x00, 0x2D, 0xB0, 0xCD, 0x40, 0x07, 0x70, 0x9B, 0x40, 0x3C, 0xB0, 0xDD, 0x80, 0x5D, 0x88,
|
||||
0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0x07, 0xFA, 0x03, 0x9D,
|
||||
0x45, 0x2F, 0x3E, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xBE, 0x80, 0x3F, 0x30, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xC0, 0x80, 0x3E, 0x82, 0x03, 0x5C, 0x83, 0x2F, 0x10, 0xF0, 0x3E, 0x82, 0x03, 0x18, 0x83, 0x2F,
|
||||
0x40, 0x88, 0x03, 0x59, 0x83, 0x2F, 0x3E, 0x88, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x40, 0x88, 0xDD, 0x80, 0x1C, 0x70,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3E, 0x88,
|
||||
0xBD, 0x80, 0x40, 0x88, 0x9A, 0x6F, 0x0E, 0x70, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x04, 0xF0, 0xDD, 0x80, 0x1C, 0x70,
|
||||
0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x0E, 0x70,
|
||||
0xBD, 0x80, 0x04, 0xF0, 0xBF, 0xC0, 0x08, 0xF0, 0x9B, 0x40, 0x3C, 0xB0, 0xDD, 0x80, 0x5D, 0x88,
|
||||
0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0x08, 0x7A, 0x03, 0x9D,
|
||||
0x9D, 0xAF, 0x3E, 0xF0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xC2, 0xC0, 0x3F, 0x30, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xC4, 0xC0, 0x42, 0xC8, 0x44, 0xC2, 0x03, 0x18, 0xD9, 0xAF, 0x02, 0xF0, 0x44, 0xC2, 0x03, 0x5C,
|
||||
0xD9, 0xAF, 0x42, 0xC8, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x44, 0xC8, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x42, 0xC8, 0xC1, 0xC0, 0x44, 0xC8,
|
||||
0xF0, 0x6F, 0x84, 0x30, 0xDD, 0x80, 0x1B, 0xB0, 0xDE, 0x80, 0x5D, 0x88, 0x96, 0x00, 0x5E, 0x88,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x34, 0x70, 0xDD, 0x80, 0x1C, 0x70, 0xDE, 0x80, 0x5D, 0x88,
|
||||
0x96, 0x00, 0x5E, 0x88, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x84, 0x30, 0xC1, 0xC0, 0x34, 0x70,
|
||||
0xC3, 0x00, 0x09, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0xDD, 0x80, 0x5D, 0x88, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xEF, 0xC0, 0x6F, 0xC8, 0x09, 0xBA, 0x03, 0x59, 0x08, 0x40, 0xF3, 0xEF
|
||||
};
|
||||
|
||||
515
libloragw/src/arb_fw.var
Normal file
515
libloragw/src/arb_fw.var
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
static uint8_t arb_firmware[8192] = {
|
||||
0x8A, 0x51, 0xE9, 0xAF, 0x00, 0xB0, 0x8A, 0xC0, 0x04, 0x88, 0x84, 0x0A, 0x82, 0x47, 0x00, 0xF4,
|
||||
0x01, 0x34, 0x02, 0x34, 0x04, 0x34, 0x08, 0x34, 0x10, 0x34, 0x20, 0x34, 0x40, 0x34, 0x80, 0x34,
|
||||
0x01, 0x34, 0x02, 0x34, 0x04, 0x34, 0x08, 0x34, 0x10, 0x34, 0x20, 0x34, 0x40, 0x34, 0x80, 0x34,
|
||||
0x00, 0xF4, 0x00, 0xF4, 0x00, 0xF4, 0x00, 0xF4, 0x00, 0xF4, 0x01, 0x34, 0x03, 0x74, 0x07, 0xB4,
|
||||
0x0F, 0xF4, 0x1F, 0x34, 0x3F, 0x74, 0x7F, 0xB4, 0xFF, 0xF4, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0x64, 0xC0, 0x80, 0x81, 0x84, 0x0A, 0x04, 0xC6,
|
||||
0x03, 0x59, 0x00, 0xF4, 0x04, 0xC6, 0xF5, 0xAB, 0x95, 0x41, 0x96, 0x41, 0x97, 0x81, 0x98, 0x01,
|
||||
0x99, 0x41, 0x9A, 0x41, 0x9B, 0x81, 0x9C, 0x41, 0x9E, 0x81, 0xDC, 0x81, 0x10, 0xF0, 0x5C, 0x42,
|
||||
0x03, 0x18, 0x25, 0xAC, 0x5C, 0x48, 0x22, 0xFE, 0x84, 0x80, 0x80, 0x81, 0x5C, 0x48, 0xB0, 0x3E,
|
||||
0x84, 0x80, 0x80, 0x81, 0x5C, 0x48, 0xD0, 0x3E, 0x84, 0x80, 0x80, 0x81, 0x5C, 0x48, 0xA0, 0xFE,
|
||||
0x84, 0x80, 0x80, 0x81, 0x5C, 0x48, 0xC0, 0xFE, 0x84, 0x80, 0x80, 0x81, 0x5C, 0x48, 0xE0, 0x3E,
|
||||
0x84, 0x80, 0xFF, 0xB0, 0x80, 0x40, 0xDC, 0xCA, 0x06, 0x6C, 0xC6, 0x41, 0xC7, 0x81, 0xC9, 0x41,
|
||||
0xC4, 0x01, 0xC8, 0x01, 0x6C, 0x50, 0xEC, 0x90, 0xA1, 0x01, 0xDC, 0x81, 0x40, 0xF0, 0x5C, 0x42,
|
||||
0x03, 0x18, 0x3A, 0xEC, 0x5C, 0x48, 0xA0, 0xFE, 0x84, 0x80, 0xFF, 0xB0, 0x83, 0xD7, 0x80, 0x40,
|
||||
0xDC, 0xCA, 0x2E, 0xEC, 0xC5, 0x41, 0x08, 0xF0, 0x45, 0x02, 0x03, 0x18, 0x08, 0x40, 0x45, 0x08,
|
||||
0x3A, 0x7E, 0x84, 0x80, 0x83, 0x93, 0x80, 0x81, 0x45, 0x08, 0x32, 0x3E, 0x84, 0x80, 0x80, 0x81,
|
||||
0xC5, 0x8A, 0x3B, 0x2C, 0x01, 0xF0, 0xA0, 0x80, 0x8A, 0x51, 0xFC, 0x63, 0x8A, 0x51, 0x03, 0x30,
|
||||
0x9E, 0x40, 0x02, 0xF0, 0x9E, 0x40, 0x01, 0xF0, 0x9E, 0x40, 0x9E, 0x81, 0x9B, 0x81, 0xE1, 0x41,
|
||||
0xE1, 0x8A, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x2A, 0x70, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xDF, 0xC0, 0x5F, 0xC8, 0xF7, 0xFA, 0x03, 0x9D, 0x70, 0xAC, 0xEB, 0xC1, 0x72, 0xEC,
|
||||
0xEB, 0xC1, 0xEB, 0x0A, 0x6B, 0x88, 0x03, 0x59, 0xE2, 0xEC, 0x01, 0xF0, 0x9B, 0x40, 0x29, 0x70,
|
||||
0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xDF, 0xC0, 0x5F, 0x4B, 0x77, 0x6C, 0x28, 0x30, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08,
|
||||
0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xCA, 0x00, 0x0D, 0x70, 0x4A, 0x02, 0x03, 0x18,
|
||||
0xD6, 0x2C, 0x05, 0x30, 0x4A, 0x02, 0xD5, 0x81, 0x03, 0x5C, 0xD7, 0x6C, 0xD5, 0xCA, 0x4A, 0x08,
|
||||
0xE1, 0x00, 0x01, 0xF0, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x2A, 0x70, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xD6, 0x40, 0x10, 0xF0, 0x56, 0x42, 0x03, 0x5C, 0xB1, 0xEC, 0x10, 0xF0,
|
||||
0xD6, 0x40, 0xF0, 0xB0, 0xD6, 0x0E, 0xD6, 0xC5, 0x56, 0x48, 0xE1, 0x00, 0x03, 0x30, 0xE2, 0x00,
|
||||
0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2B, 0xB0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xE0, 0xC0,
|
||||
0x01, 0xF0, 0xE0, 0x45, 0x60, 0xC8, 0xE1, 0x00, 0x04, 0xF0, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00,
|
||||
0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x9B, 0x81, 0xEB, 0x6C, 0xD5, 0x81, 0xFF, 0xB0,
|
||||
0xE1, 0x00, 0x01, 0xF0, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0xA1, 0xAC, 0x07, 0x70, 0xD5, 0x81, 0xD5, 0xCA, 0xCA, 0x00, 0x30, 0x30, 0xD6, 0x40,
|
||||
0x01, 0xF0, 0xE0, 0x01, 0x9B, 0x40, 0x0E, 0x58, 0xEB, 0x6C, 0x25, 0x70, 0x83, 0x52, 0x03, 0x53,
|
||||
0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD7, 0x80, 0x07, 0x70,
|
||||
0xD7, 0x05, 0x57, 0x88, 0xC5, 0x00, 0x08, 0xF0, 0x45, 0x02, 0x03, 0x18, 0xEB, 0x6C, 0x45, 0x08,
|
||||
0x8A, 0x51, 0x07, 0xA5, 0x8A, 0x51, 0x0E, 0x58, 0xEB, 0x6C, 0xC5, 0x8A, 0xFB, 0xAC, 0xEA, 0x40,
|
||||
0xE1, 0x00, 0x00, 0xB0, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x8E, 0xDC, 0x08, 0x40, 0x18, 0x14, 0x05, 0x30, 0xE8, 0x00, 0xE8, 0xCB, 0x16, 0xED,
|
||||
0x21, 0x30, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xC6, 0x00, 0x22, 0x30, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC7, 0x40, 0x24, 0x30, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00,
|
||||
0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC9, 0x00, 0x20, 0xF0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC4, 0xC0,
|
||||
0x23, 0x70, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xC8, 0xC0, 0x18, 0xD0, 0x55, 0xCB, 0x56, 0x2D, 0x48, 0xC8, 0xE8, 0x00, 0xE9, 0x81,
|
||||
0xE8, 0x1B, 0xE9, 0xC3, 0x4A, 0x46, 0x69, 0x44, 0x03, 0x59, 0x60, 0xAD, 0x0A, 0x30, 0x49, 0x02,
|
||||
0x03, 0x5C, 0x8D, 0x2D, 0x44, 0xC8, 0x80, 0x7A, 0x78, 0x7E, 0x03, 0x5C, 0x81, 0xAD, 0x8D, 0x2D,
|
||||
0x44, 0xC8, 0x80, 0x7A, 0x78, 0x7E, 0x03, 0x5C, 0xC4, 0xDB, 0x56, 0x2D, 0x44, 0xC8, 0x3A, 0x7E,
|
||||
0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x01, 0xBE, 0xE8, 0x00, 0x44, 0xC8, 0x3A, 0x7E, 0x84, 0x80,
|
||||
0x68, 0x08, 0x80, 0x40, 0x44, 0xC8, 0x3A, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xE1, 0x00, 0x44, 0xC8,
|
||||
0x01, 0xBE, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x56, 0x2D, 0xC4, 0xDB, 0x8D, 0x2D, 0x48, 0xC8, 0x80, 0x7A, 0x73, 0xBE, 0x03, 0x18, 0x8D, 0x2D,
|
||||
0x48, 0xC8, 0x80, 0x7A, 0x7B, 0xFE, 0x03, 0x18, 0x8F, 0x6D, 0x6C, 0xD5, 0x30, 0xAE, 0x6C, 0x91,
|
||||
0x48, 0xC8, 0x11, 0xFE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xC7, 0xC5, 0x48, 0xC8,
|
||||
0xE8, 0x00, 0x03, 0xD0, 0xE8, 0xCD, 0x03, 0xD0, 0xE8, 0xCD, 0x03, 0xD0, 0xE8, 0xCD, 0x44, 0xC8,
|
||||
0x68, 0x87, 0xD8, 0x7E, 0xDE, 0x80, 0xA0, 0xFE, 0x84, 0x80, 0x83, 0xD7, 0x00, 0x48, 0xDC, 0x40,
|
||||
0x3E, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xC2, 0xC0, 0x3F, 0x30, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC3, 0x00, 0x6C, 0x91, 0xDC, 0x81, 0x08, 0xF0, 0x5C, 0x42,
|
||||
0x03, 0x18, 0xF5, 0xAD, 0x5C, 0x48, 0xE0, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x5E, 0xC6,
|
||||
0x03, 0x9D, 0xF1, 0x6D, 0x5C, 0x48, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51,
|
||||
0x42, 0x05, 0x03, 0x59, 0xF1, 0x6D, 0x46, 0x08, 0xE1, 0x00, 0x5C, 0x48, 0xB0, 0x3E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xE2, 0x00, 0x5C, 0x48, 0x22, 0xFE, 0x84, 0x80, 0x00, 0x48, 0xE3, 0x40, 0x56, 0x48,
|
||||
0xE4, 0x00, 0x48, 0xC8, 0xE5, 0x40, 0x47, 0x48, 0x52, 0xE7, 0x8A, 0x51, 0xE8, 0x00, 0x68, 0x4C,
|
||||
0x03, 0x5C, 0xEE, 0xAD, 0x83, 0x52, 0x03, 0x53, 0x6C, 0xD5, 0xF1, 0x6D, 0x83, 0x52, 0x03, 0x53,
|
||||
0x6C, 0x91, 0x6C, 0xD9, 0xF5, 0xAD, 0xDC, 0xCA, 0xBE, 0xAD, 0x6C, 0xD9, 0x30, 0xAE, 0x08, 0xF0,
|
||||
0xDC, 0x40, 0x10, 0xF0, 0x5C, 0x42, 0x03, 0x18, 0x30, 0xAE, 0x5C, 0x48, 0xE0, 0x3E, 0x84, 0x80,
|
||||
0x83, 0x93, 0x00, 0x48, 0x5E, 0xC6, 0x03, 0x9D, 0x2C, 0xEE, 0x5C, 0x48, 0x01, 0xBE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0x43, 0x45, 0x03, 0x59, 0x2C, 0xEE, 0x46, 0x08, 0xE1, 0x00,
|
||||
0x5C, 0x48, 0xB0, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xE2, 0x00, 0x5C, 0x48, 0x22, 0xFE, 0x84, 0x80,
|
||||
0x00, 0x48, 0xE3, 0x40, 0x56, 0x48, 0xE4, 0x00, 0x48, 0xC8, 0xE5, 0x40, 0x47, 0x48, 0x52, 0xE7,
|
||||
0x8A, 0x51, 0xE8, 0x00, 0x68, 0x4C, 0x03, 0x5C, 0x29, 0xEE, 0x83, 0x52, 0x03, 0x53, 0x6C, 0xD5,
|
||||
0x2C, 0xEE, 0x83, 0x52, 0x03, 0x53, 0x6C, 0x91, 0x6C, 0xD9, 0x30, 0xAE, 0xDC, 0xCA, 0xF9, 0xAD,
|
||||
0x6C, 0xD9, 0x08, 0x40, 0x48, 0xC8, 0x80, 0x7A, 0x77, 0xFE, 0x03, 0x5C, 0x3B, 0x6E, 0x60, 0xC8,
|
||||
0x01, 0xBE, 0xDD, 0x80, 0x3D, 0x6E, 0xDD, 0xC1, 0xDD, 0x0A, 0xDB, 0xC1, 0x5D, 0x88, 0x5B, 0x82,
|
||||
0x03, 0x18, 0x08, 0x40, 0x11, 0x30, 0xDC, 0x40, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xE1, 0x00,
|
||||
0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD8, 0x00, 0x3D, 0xF0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xE1, 0x00, 0x61, 0x08, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD9, 0x40,
|
||||
0x48, 0xC8, 0x80, 0x7A, 0x75, 0xBE, 0x03, 0x5C, 0x65, 0x2E, 0x58, 0x08, 0x80, 0x7A, 0x70, 0x3E,
|
||||
0x03, 0x5C, 0xD8, 0x1B, 0x75, 0x6E, 0x58, 0x08, 0x6C, 0x2E, 0x59, 0x48, 0x80, 0x7A, 0x70, 0x3E,
|
||||
0x03, 0x5C, 0xD9, 0x5B, 0x6E, 0x6E, 0x59, 0x48, 0xDC, 0x40, 0x75, 0x6E, 0x58, 0x08, 0x80, 0x7A,
|
||||
0x70, 0x3E, 0x03, 0x18, 0x75, 0x6E, 0xD8, 0x5F, 0x63, 0x2E, 0x10, 0xF0, 0x5C, 0x42, 0x03, 0x18,
|
||||
0x50, 0xEF, 0x5C, 0x48, 0x22, 0xFE, 0x84, 0x80, 0x46, 0x08, 0x83, 0x93, 0x80, 0x40, 0x5C, 0x48,
|
||||
0xB0, 0x3E, 0x84, 0x80, 0x47, 0x48, 0x80, 0x40, 0x5C, 0x48, 0xD0, 0x3E, 0x84, 0x80, 0x49, 0x08,
|
||||
0x80, 0x40, 0x5C, 0x48, 0xA0, 0xFE, 0x84, 0x80, 0x44, 0xC8, 0x80, 0x40, 0x5C, 0x48, 0xC0, 0xFE,
|
||||
0x84, 0x80, 0x48, 0xC8, 0x80, 0x40, 0x5C, 0x48, 0xE0, 0x3E, 0x84, 0x80, 0x5E, 0x88, 0x80, 0x40,
|
||||
0x5E, 0x88, 0xA0, 0xFE, 0x84, 0x80, 0x5C, 0x48, 0x83, 0xD7, 0x80, 0x40, 0x48, 0xC8, 0xE1, 0x00,
|
||||
0x17, 0xB0, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x44, 0xC8, 0xE1, 0x00, 0x18, 0x30, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x46, 0x08, 0xE1, 0x00, 0x19, 0x70, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00,
|
||||
0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x47, 0x48, 0xE1, 0x00, 0x1A, 0x70, 0xE2, 0x00,
|
||||
0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x5C, 0x48, 0xE1, 0x00,
|
||||
0x16, 0x70, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x49, 0x08, 0xE1, 0x00, 0x1B, 0xB0, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x5B, 0x88, 0xE1, 0x00, 0x11, 0x30, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00,
|
||||
0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x08, 0xF0, 0x5C, 0x42, 0x5C, 0x48, 0x03, 0x18,
|
||||
0x12, 0xEF, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xE1, 0x00, 0x12, 0x30,
|
||||
0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x05, 0x30,
|
||||
0xE8, 0x00, 0xE8, 0xCB, 0xF9, 0xAE, 0x83, 0x52, 0x12, 0x30, 0x03, 0x53, 0xE1, 0x41, 0xE2, 0x00,
|
||||
0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x55, 0xCB, 0x50, 0xEF,
|
||||
0x48, 0xC8, 0xE8, 0x00, 0xE9, 0x81, 0xE8, 0x1B, 0xE9, 0xC3, 0x4A, 0x46, 0x69, 0x44, 0x03, 0x59,
|
||||
0x30, 0xEF, 0x50, 0xEF, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xE1, 0x00,
|
||||
0x13, 0x70, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x05, 0x30, 0xE8, 0x00, 0xE8, 0xCB, 0x22, 0xEF, 0x83, 0x52, 0x13, 0x70, 0x03, 0x53, 0xE1, 0x41,
|
||||
0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x06, 0xEF,
|
||||
0x44, 0xC8, 0x80, 0x7A, 0x78, 0x7E, 0x03, 0x5C, 0xC4, 0xDB, 0x50, 0xEF, 0x44, 0xC8, 0x32, 0x3E,
|
||||
0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0x01, 0xBE, 0xE8, 0x00, 0x44, 0xC8, 0x32, 0x3E, 0x84, 0x80,
|
||||
0x68, 0x08, 0x80, 0x40, 0x44, 0xC8, 0x32, 0x3E, 0x84, 0x80, 0x00, 0x48, 0xE1, 0x00, 0x44, 0xC8,
|
||||
0x09, 0xFE, 0xE2, 0x00, 0x61, 0x08, 0x96, 0x00, 0x62, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0xDB, 0x0A, 0x3E, 0x6E, 0xE7, 0x80, 0x62, 0x02, 0x62, 0x08, 0x03, 0x18, 0x9D, 0xAF, 0x67, 0x82,
|
||||
0xD0, 0xC0, 0x63, 0x48, 0x61, 0x02, 0x03, 0x5C, 0x61, 0x2F, 0x63, 0x48, 0x61, 0x02, 0xCC, 0x00,
|
||||
0x68, 0x2F, 0x61, 0x08, 0x63, 0x42, 0xCC, 0x00, 0xFF, 0xB0, 0xD0, 0x87, 0xCC, 0x86, 0xCC, 0x8A,
|
||||
0x65, 0x48, 0x11, 0xFE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xE6, 0x40, 0x67, 0x88,
|
||||
0x66, 0x42, 0xD2, 0x00, 0x61, 0x49, 0xCE, 0x40, 0x62, 0x08, 0x52, 0x87, 0xD1, 0x00, 0x4E, 0x89,
|
||||
0xE6, 0x40, 0x63, 0x48, 0x66, 0x42, 0x03, 0x5C, 0x80, 0xAF, 0x63, 0x48, 0x4E, 0xC7, 0x84, 0xEF,
|
||||
0xD1, 0x8A, 0x4E, 0x89, 0xCD, 0x40, 0x63, 0x42, 0xCD, 0x40, 0x50, 0xC8, 0x51, 0x02, 0x03, 0x5C,
|
||||
0xD3, 0xAF, 0x51, 0x08, 0x50, 0xC2, 0x03, 0x5C, 0x91, 0x2F, 0x4D, 0x48, 0x4C, 0x02, 0x03, 0x18,
|
||||
0xD3, 0xAF, 0xDA, 0x81, 0x5A, 0x48, 0x03, 0x59, 0x99, 0x6F, 0x51, 0x08, 0xCF, 0x80, 0x4D, 0x48,
|
||||
0xE0, 0x2F, 0x50, 0xC8, 0xCF, 0x80, 0x4C, 0x08, 0xE0, 0x2F, 0x67, 0x82, 0x03, 0x18, 0xD6, 0xAF,
|
||||
0x67, 0x88, 0x62, 0x02, 0xD0, 0xC0, 0x61, 0x08, 0x63, 0x42, 0x03, 0x5C, 0xAB, 0xAF, 0x61, 0x08,
|
||||
0x63, 0x42, 0xCC, 0x00, 0xB2, 0x6F, 0x63, 0x48, 0x61, 0x02, 0xCC, 0x00, 0xFF, 0xB0, 0xD0, 0x87,
|
||||
0xCC, 0x86, 0xCC, 0x8A, 0x65, 0x48, 0x11, 0xFE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51,
|
||||
0xE6, 0x40, 0x62, 0x08, 0x66, 0x42, 0xD2, 0x00, 0x63, 0x89, 0xCE, 0x40, 0x67, 0x88, 0x52, 0x87,
|
||||
0xD1, 0x00, 0x4E, 0x89, 0xE6, 0x40, 0x61, 0x08, 0x66, 0x42, 0x03, 0x5C, 0xCA, 0x6F, 0x61, 0x08,
|
||||
0x4E, 0xC7, 0xCE, 0xAF, 0xD1, 0x8A, 0x4E, 0x89, 0xCD, 0x40, 0x61, 0x02, 0xCD, 0x40, 0x50, 0xC8,
|
||||
0x51, 0x02, 0x03, 0x18, 0x89, 0x2F, 0xDA, 0x81, 0xDA, 0xCA, 0x92, 0x2F, 0xCF, 0xC1, 0x63, 0x48,
|
||||
0x61, 0x02, 0x03, 0x5C, 0xDE, 0xEF, 0x63, 0x48, 0x61, 0x02, 0xE0, 0x2F, 0x61, 0x08, 0x63, 0x42,
|
||||
0xCB, 0x40, 0xCF, 0xC8, 0x03, 0x9D, 0x00, 0xF4, 0x64, 0x08, 0x4B, 0x42, 0x03, 0x5C, 0x01, 0x34,
|
||||
0x00, 0xF4, 0xEC, 0x81, 0x83, 0x93, 0x22, 0x30, 0x84, 0x80, 0x61, 0x70, 0x8A, 0x51, 0xF4, 0x23,
|
||||
0x8A, 0x51, 0xA0, 0x30, 0x84, 0x80, 0xF0, 0xB0, 0x8A, 0x51, 0xF4, 0x23, 0x8A, 0x51, 0x83, 0xD7,
|
||||
0xA0, 0x30, 0x84, 0x80, 0xE0, 0x70, 0x8A, 0x51, 0xF4, 0x23, 0x83, 0x01, 0x8A, 0x51, 0x4A, 0xAC,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF
|
||||
};
|
||||
|
||||
515
libloragw/src/cal_fw.var
Normal file
515
libloragw/src/cal_fw.var
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
static uint8_t cal_firmware_sx125x[8192] = {
|
||||
0x8A, 0x51, 0xF0, 0x6F, 0x00, 0xB0, 0x8A, 0xC0, 0x04, 0x88, 0x84, 0x0A, 0x82, 0x47, 0x00, 0xF4,
|
||||
0x40, 0x34, 0x2B, 0xF4, 0x1C, 0xB4, 0x13, 0xB4, 0x0D, 0xB4, 0x08, 0x34, 0x06, 0x74, 0x04, 0x34,
|
||||
0x02, 0x34, 0x10, 0x34, 0x0B, 0xB4, 0x07, 0xB4, 0x05, 0x74, 0x03, 0x74, 0x02, 0x34, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0x64, 0xC0,
|
||||
0x80, 0x81, 0x84, 0x0A, 0x04, 0xC6, 0x03, 0x59, 0x00, 0xF4, 0x04, 0xC6, 0x30, 0x69, 0xB1, 0x00,
|
||||
0x04, 0xF0, 0xA2, 0xC0, 0x10, 0xF0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x2A, 0x08, 0xA2, 0xC0, 0x14, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2B, 0x48, 0xA2, 0xC0, 0x15, 0x70, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2C, 0x08, 0xA2, 0xC0,
|
||||
0x11, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x2D, 0x48, 0xA2, 0xC0, 0x12, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x29, 0x08, 0xA2, 0xC0, 0x13, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x31, 0x58, 0xB5, 0x29, 0x2E, 0x48, 0xB0, 0xC0,
|
||||
0x01, 0xF0, 0xD7, 0xA7, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC3, 0x39, 0x30, 0xC4, 0xA2, 0xC0, 0x01, 0xF0, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD3, 0x67,
|
||||
0x8A, 0x51, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x01, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xA2, 0xC0, 0x01, 0xF0, 0xA2, 0x10, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xB4, 0x41, 0x1B, 0xEA, 0x2E, 0x48, 0xB0, 0xC0, 0x02, 0xF0,
|
||||
0xD7, 0xA7, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xC3, 0x39, 0x30, 0xC4, 0xA2, 0xC0, 0x02, 0xF0, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x02, 0xF0, 0x83, 0x52, 0x03, 0x53,
|
||||
0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xCF, 0xA7, 0x8A, 0x51,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x02, 0xF0,
|
||||
0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xA2, 0xC0, 0x02, 0xF0, 0xA2, 0x10, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0xB3, 0x29, 0x2F, 0x88, 0xA4, 0xC0, 0x32, 0x70, 0x2D, 0x27, 0x8A, 0x51,
|
||||
0x32, 0x08, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x33, 0x48, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x07, 0x70, 0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xB4, 0x00,
|
||||
0x06, 0xBA, 0x03, 0x59, 0x0E, 0xAA, 0x34, 0x08, 0x07, 0xFA, 0x03, 0x59, 0x2F, 0x2A, 0x06, 0x30,
|
||||
0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xB4, 0x00, 0x06, 0xBA, 0x03, 0x59, 0xF3, 0x69, 0x21, 0x6A, 0x10, 0xF0,
|
||||
0xA2, 0x01, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x08, 0x40, 0xB3, 0x40, 0x04, 0xF0, 0xA2, 0xC0, 0x10, 0xF0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2D, 0x48, 0xA2, 0xC0, 0x14, 0x30, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2E, 0x48, 0xA2, 0xC0,
|
||||
0x15, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x2C, 0x08, 0xA2, 0xC0, 0x13, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x30, 0xC8, 0x20, 0x38, 0xD5, 0x40, 0xA2, 0xC0, 0x18, 0x30, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0, 0xB9, 0x81,
|
||||
0xC2, 0x01, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xFF, 0x3A, 0x01, 0xBE, 0xBA, 0x40,
|
||||
0x01, 0xF0, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xFF, 0x3A, 0x01, 0xBE, 0xC3, 0x00,
|
||||
0x01, 0xF0, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xFF, 0x3A, 0x01, 0xBE, 0xBB, 0x80,
|
||||
0x01, 0xF0, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xC4, 0xC0, 0x01, 0xF0, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xBC, 0x40, 0x01, 0xF0, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0,
|
||||
0x8A, 0x51, 0xFF, 0x3A, 0x01, 0xBE, 0xC5, 0x00, 0x01, 0xF0, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0,
|
||||
0x8A, 0x51, 0xBD, 0x80, 0x01, 0xF0, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xC6, 0x00,
|
||||
0x0B, 0x70, 0xD7, 0x80, 0x57, 0x88, 0xB4, 0x00, 0x33, 0x98, 0x06, 0xAB, 0x57, 0x88, 0xB1, 0x00,
|
||||
0x01, 0xF0, 0xE1, 0x27, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC3, 0x39, 0x31, 0x04, 0xA2, 0xC0, 0x01, 0xF0, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD3, 0x67,
|
||||
0x8A, 0x51, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x01, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xA2, 0xC0, 0x01, 0xF0, 0xA2, 0x10, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x39, 0x48, 0xA2, 0xC0, 0x11, 0x30, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x42, 0xC8, 0xA2, 0xC0, 0x12, 0x30,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x30, 0xC8,
|
||||
0xA4, 0xC0, 0x4B, 0xB0, 0x2D, 0x27, 0x8A, 0x51, 0xD6, 0x81, 0x69, 0x2B, 0x57, 0x88, 0xB1, 0x00,
|
||||
0x02, 0xF0, 0xE1, 0x27, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC3, 0x39, 0x31, 0x04, 0xA2, 0xC0, 0x02, 0xF0, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x02, 0xF0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xCF, 0xA7,
|
||||
0x8A, 0x51, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x02, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xA2, 0xC0, 0x02, 0xF0, 0xA2, 0x10, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xEB, 0x6A, 0x56, 0x48, 0xCA, 0x27, 0x8A, 0x51, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xB1, 0x27, 0x8A, 0x51,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x30, 0xC8,
|
||||
0xA4, 0xC0, 0x51, 0x70, 0x2D, 0x27, 0x8A, 0x51, 0x4B, 0xB0, 0xA1, 0xC0, 0x51, 0x70, 0x79, 0x67,
|
||||
0x8A, 0x51, 0xCD, 0x40, 0x4D, 0x48, 0x03, 0x59, 0x69, 0x2B, 0x51, 0x08, 0xCB, 0x40, 0x52, 0x08,
|
||||
0xCC, 0x00, 0x05, 0x30, 0xD6, 0xCA, 0x56, 0x42, 0x03, 0x5C, 0x44, 0xAB, 0x2F, 0x88, 0xD1, 0x00,
|
||||
0x51, 0x70, 0xD2, 0x41, 0xA1, 0xC0, 0x4B, 0xB0, 0x79, 0x67, 0x8A, 0x51, 0xCD, 0x40, 0x4D, 0x48,
|
||||
0x03, 0x9D, 0x7F, 0xEB, 0x07, 0x70, 0xD7, 0x03, 0x57, 0x82, 0x03, 0x18, 0xAA, 0xEA, 0x4B, 0x48,
|
||||
0xB7, 0x80, 0x4C, 0x08, 0xB8, 0x00, 0xD3, 0x81, 0xD4, 0x41, 0xD7, 0xC1, 0x53, 0x48, 0xB9, 0x40,
|
||||
0x54, 0x08, 0xC2, 0xC0, 0x57, 0x88, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51,
|
||||
0xA1, 0xC0, 0x53, 0x48, 0xDD, 0x66, 0x83, 0x52, 0x03, 0x53, 0xBA, 0x40, 0x57, 0x88, 0x01, 0xBE,
|
||||
0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xA1, 0xC0, 0x54, 0x08, 0xDD, 0x66, 0x83, 0x52,
|
||||
0x03, 0x53, 0xC3, 0x00, 0x57, 0x88, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51,
|
||||
0xA1, 0xC0, 0x53, 0x48, 0xDD, 0x66, 0x83, 0x52, 0x03, 0x53, 0xBB, 0x80, 0x57, 0x88, 0x01, 0xBE,
|
||||
0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xEB, 0xA7, 0x8A, 0x51, 0xDD, 0x66, 0x83, 0x52,
|
||||
0x03, 0x53, 0xC4, 0xC0, 0x57, 0x88, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51,
|
||||
0xDC, 0x67, 0x8A, 0x51, 0xDD, 0x66, 0x83, 0x52, 0x03, 0x53, 0xBC, 0x40, 0x57, 0x88, 0x01, 0xBE,
|
||||
0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xA1, 0xC0, 0x54, 0x08, 0xDD, 0x66, 0x83, 0x52,
|
||||
0x03, 0x53, 0xC5, 0x00, 0x57, 0x88, 0x01, 0xBE, 0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51,
|
||||
0xDC, 0x67, 0x8A, 0x51, 0xDD, 0x66, 0x83, 0x52, 0x03, 0x53, 0xBD, 0x80, 0x57, 0x88, 0x01, 0xBE,
|
||||
0x84, 0x80, 0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x51, 0xEB, 0xA7, 0x8A, 0x51, 0xDD, 0x66, 0x8A, 0x51,
|
||||
0x83, 0x52, 0x03, 0x53, 0xC6, 0x00, 0x39, 0x48, 0xA2, 0xC0, 0x11, 0x30, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x42, 0xC8, 0xA2, 0xC0, 0x12, 0x30,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x30, 0xC8,
|
||||
0xA4, 0xC0, 0x4F, 0xF0, 0x2D, 0x27, 0x8A, 0x51, 0x05, 0x30, 0xCE, 0x81, 0xA1, 0xC0, 0x57, 0x88,
|
||||
0x96, 0x27, 0x8A, 0x51, 0xA0, 0xFE, 0x84, 0x80, 0x4F, 0x88, 0xE6, 0x67, 0x8A, 0x51, 0x96, 0x27,
|
||||
0x8A, 0x51, 0xA0, 0xFE, 0x84, 0x80, 0x50, 0xC8, 0x83, 0xD7, 0x80, 0x40, 0xD6, 0x81, 0x05, 0x30,
|
||||
0xD6, 0xCA, 0x56, 0x42, 0x03, 0x18, 0x5A, 0xEC, 0x56, 0x48, 0x39, 0x7E, 0x84, 0x80, 0x83, 0x93,
|
||||
0x00, 0x48, 0xA2, 0xC0, 0x11, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0xB1, 0x27, 0x8A, 0x51, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x30, 0xC8, 0xA4, 0xC0, 0x51, 0x70, 0x2D, 0x27, 0x8A, 0x51,
|
||||
0x51, 0x70, 0xA1, 0xC0, 0x4F, 0xF0, 0x79, 0x67, 0x8A, 0x51, 0xCD, 0x40, 0x4D, 0x48, 0x03, 0x59,
|
||||
0x44, 0x6C, 0x51, 0x08, 0xBE, 0xA7, 0x8A, 0x51, 0x05, 0x30, 0xA1, 0xC0, 0x57, 0x88, 0x96, 0x27,
|
||||
0x8A, 0x51, 0xA0, 0xFE, 0x56, 0xC7, 0xB1, 0x00, 0x84, 0x80, 0x51, 0x08, 0xE6, 0x67, 0x8A, 0x51,
|
||||
0x96, 0x27, 0x8A, 0x51, 0xA0, 0xFE, 0x56, 0xC7, 0xB1, 0x00, 0x84, 0x80, 0x52, 0x08, 0x83, 0xD7,
|
||||
0x80, 0x40, 0x17, 0xEC, 0x57, 0x88, 0xE0, 0x3E, 0x84, 0x80, 0x4E, 0x48, 0x83, 0x93, 0x80, 0x40,
|
||||
0x4E, 0x48, 0x39, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xD3, 0x40, 0xC4, 0xE7, 0x8A, 0x51, 0x09, 0x30,
|
||||
0xD7, 0x0A, 0x57, 0x82, 0x03, 0x5C, 0x86, 0xEB, 0xA1, 0x01, 0xA1, 0x43, 0x53, 0x48, 0xDD, 0x66,
|
||||
0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xB9, 0x40, 0xA1, 0x01, 0xA1, 0x43, 0x54, 0x08, 0xDD, 0x66,
|
||||
0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xC2, 0xC0, 0xA1, 0x01, 0xA1, 0x43, 0x53, 0x48, 0xDD, 0x66,
|
||||
0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xBA, 0x40, 0x54, 0x08, 0xC3, 0x00, 0xA1, 0x01, 0xA1, 0x43,
|
||||
0x53, 0x48, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xBB, 0x80, 0xA1, 0x01, 0xA1, 0x4A,
|
||||
0x54, 0x08, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xC4, 0xC0, 0x53, 0x48, 0xBC, 0x40,
|
||||
0xA1, 0x01, 0xA1, 0x43, 0x54, 0x08, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xC5, 0x00,
|
||||
0x53, 0x48, 0xBD, 0x80, 0x54, 0x08, 0xC6, 0x00, 0x53, 0x48, 0xBE, 0x80, 0xA1, 0x01, 0xA1, 0x4A,
|
||||
0x54, 0x08, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xC7, 0x40, 0xA1, 0x01, 0xA1, 0x4A,
|
||||
0x53, 0x48, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xBF, 0xC0, 0xA1, 0x01, 0xA1, 0x43,
|
||||
0x54, 0x08, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xC8, 0xC0, 0xA1, 0x01, 0xA1, 0x4A,
|
||||
0x53, 0x48, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xC0, 0x80, 0x54, 0x08, 0xC9, 0x00,
|
||||
0xA1, 0x01, 0xA1, 0x4A, 0x53, 0x48, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xC1, 0xC0,
|
||||
0xA1, 0x01, 0xA1, 0x4A, 0x54, 0x08, 0xDD, 0x66, 0x8A, 0x51, 0x83, 0x52, 0x03, 0x53, 0xCA, 0x00,
|
||||
0xCE, 0x81, 0x39, 0x48, 0xA2, 0xC0, 0x11, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x42, 0xC8, 0xA2, 0xC0, 0x12, 0x30, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x30, 0xC8, 0xA4, 0xC0, 0x4F, 0xF0,
|
||||
0x2D, 0x27, 0x8A, 0x51, 0xD6, 0x81, 0x09, 0x30, 0xD6, 0xCA, 0x56, 0x42, 0x03, 0x18, 0x1D, 0x2D,
|
||||
0x56, 0x48, 0xCA, 0x27, 0x8A, 0x51, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0xB1, 0x27, 0x8A, 0x51, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x30, 0xC8, 0xA4, 0xC0, 0x51, 0x70, 0x2D, 0x27, 0x8A, 0x51,
|
||||
0x51, 0x70, 0xA1, 0xC0, 0x4F, 0xF0, 0x79, 0x67, 0x8A, 0x51, 0xCD, 0x40, 0x4D, 0x48, 0x03, 0x59,
|
||||
0xF3, 0x6C, 0x51, 0x08, 0xBE, 0xA7, 0x8A, 0x51, 0xF3, 0x6C, 0x4E, 0x48, 0x39, 0x7E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xD3, 0x40, 0xC4, 0xE7, 0x8A, 0x51, 0x53, 0x48, 0xA2, 0xC0, 0x11, 0x30, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x54, 0x08, 0xA2, 0xC0,
|
||||
0x12, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x4F, 0x88, 0xB5, 0x40, 0x50, 0xC8, 0xB6, 0x40, 0x2F, 0x88, 0xA2, 0xC0, 0x19, 0x70, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x34, 0x08, 0xA2, 0xC0,
|
||||
0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x37, 0x88, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x38, 0x08, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x06, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD5, 0x40,
|
||||
0x9E, 0x40, 0x55, 0x48, 0x06, 0xBA, 0x03, 0x9D, 0x66, 0x2D, 0x35, 0x48, 0xA2, 0xC0, 0x19, 0x70,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x36, 0x48,
|
||||
0xA2, 0xC0, 0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x53, 0x48, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x54, 0x08, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x07, 0x70, 0x9B, 0x40, 0x3C, 0xB0,
|
||||
0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xD5, 0x40, 0x9E, 0x40, 0x55, 0x48, 0x07, 0xFA, 0x03, 0x9D, 0x9F, 0xAD, 0x83, 0x96, 0x60, 0xC8,
|
||||
0x83, 0x52, 0xA2, 0xC0, 0x19, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x83, 0x96, 0x61, 0x08, 0x83, 0x52, 0xA2, 0xC0, 0x1A, 0x70, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x83, 0x96, 0x62, 0x08,
|
||||
0x83, 0x52, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x83, 0x96, 0x63, 0x48, 0x83, 0x52, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x08, 0xF0, 0x9B, 0x40,
|
||||
0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xD5, 0x40, 0x9E, 0x40, 0x55, 0x48, 0x08, 0x7A, 0x03, 0x9D, 0xE0, 0xED, 0x83, 0x96,
|
||||
0x64, 0x08, 0x83, 0x52, 0xA2, 0xC0, 0x19, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x83, 0x96, 0x65, 0x48, 0x83, 0x52, 0xA2, 0xC0, 0x1A, 0x70,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x83, 0x96,
|
||||
0x66, 0x48, 0x83, 0x52, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x83, 0x96, 0x67, 0x88, 0x83, 0x52, 0xA2, 0xC0, 0x1C, 0x70,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x09, 0x30,
|
||||
0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xD5, 0x40, 0x9E, 0x40, 0x55, 0x48, 0x09, 0xBA, 0x03, 0x9D, 0x21, 0xAE,
|
||||
0x83, 0x96, 0x68, 0x08, 0x83, 0x52, 0xA2, 0xC0, 0x19, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x83, 0x96, 0x69, 0x48, 0x83, 0x52, 0xA2, 0xC0,
|
||||
0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x83, 0x96, 0x6A, 0x48, 0x83, 0x52, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x83, 0x96, 0x6B, 0x88, 0x83, 0x52, 0xA2, 0xC0,
|
||||
0x1C, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x0A, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD5, 0x40, 0x9E, 0x40, 0x55, 0x48, 0x0A, 0xBA, 0x03, 0x9D,
|
||||
0x62, 0xEE, 0xD7, 0xC1, 0x03, 0xD0, 0x57, 0x0D, 0xA0, 0xFE, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48,
|
||||
0xA2, 0xC0, 0x19, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x03, 0xD0, 0x57, 0x0D, 0xA0, 0xFE, 0x84, 0x80, 0x83, 0xD7, 0x00, 0x48, 0xA2, 0xC0,
|
||||
0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x03, 0xD0, 0x57, 0x0D, 0xA1, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0xA2, 0xC0, 0x1B, 0xB0,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x03, 0xD0,
|
||||
0x57, 0x0D, 0xA1, 0x3E, 0x84, 0x80, 0x83, 0xD7, 0x00, 0x48, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x57, 0x88, 0x0C, 0xFE,
|
||||
0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xA4, 0xE7, 0x8A, 0x51, 0x03, 0x9D, 0xB1, 0x2E, 0x14, 0x30, 0xD7, 0x0A,
|
||||
0x57, 0x82, 0x03, 0x5C, 0x73, 0x6E, 0x57, 0x88, 0x0C, 0xFE, 0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xA4, 0xE7,
|
||||
0x8A, 0x51, 0x03, 0x9D, 0xC6, 0x2E, 0x10, 0xF0, 0xA2, 0x01, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x08, 0x40, 0xAB, 0x40, 0xAB, 0x9F, 0x09, 0xEF,
|
||||
0xA1, 0x1F, 0x04, 0xAF, 0x2B, 0x48, 0xA2, 0xC0, 0xA3, 0x41, 0xA2, 0xDB, 0xA3, 0x83, 0x80, 0xF0,
|
||||
0xA4, 0xC0, 0xFF, 0xB0, 0xA5, 0x00, 0x22, 0xC8, 0x24, 0xC2, 0xA6, 0x00, 0x23, 0x08, 0x03, 0x5C,
|
||||
0x23, 0x4A, 0x25, 0x02, 0xA7, 0x40, 0x21, 0xC8, 0xA8, 0xC0, 0xA9, 0x41, 0xA8, 0xDB, 0xA9, 0x83,
|
||||
0x29, 0x08, 0x80, 0x7A, 0xAA, 0x00, 0x27, 0x48, 0x80, 0x7A, 0x2A, 0x02, 0x03, 0x9D, 0x02, 0xAF,
|
||||
0x26, 0x08, 0x28, 0xC2, 0x03, 0x5C, 0x80, 0x34, 0x83, 0x52, 0x03, 0x53, 0x21, 0xC8, 0x2B, 0xC7,
|
||||
0x08, 0x40, 0x21, 0xC8, 0x80, 0x7A, 0x7F, 0x3E, 0x03, 0x5C, 0x04, 0xAF, 0x21, 0xC8, 0xA2, 0xC0,
|
||||
0xA3, 0x41, 0xA2, 0xDB, 0xA3, 0x83, 0x2B, 0x48, 0xA4, 0xC0, 0xA5, 0x41, 0xA4, 0xDB, 0xA5, 0x83,
|
||||
0x7F, 0x70, 0xA6, 0x00, 0x24, 0xC8, 0x26, 0x02, 0xA7, 0x40, 0x25, 0x49, 0x03, 0x18, 0x01, 0xBE,
|
||||
0xA8, 0xC0, 0x80, 0x7A, 0xA9, 0x00, 0x23, 0x08, 0x80, 0x7A, 0x29, 0x02, 0x03, 0x9D, 0x2A, 0x2F,
|
||||
0x22, 0xC8, 0x27, 0x42, 0x03, 0x5C, 0x7F, 0xB4, 0x04, 0xAF, 0xA8, 0xC0, 0x24, 0xC8, 0x20, 0x38,
|
||||
0xA7, 0x40, 0xA2, 0xC0, 0x18, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x05, 0x30, 0xA5, 0x00, 0xA5, 0xCB, 0x3C, 0x6F, 0x83, 0x52, 0x03, 0x53,
|
||||
0x24, 0xC8, 0x30, 0x78, 0xA7, 0x40, 0xA2, 0xC0, 0x18, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x05, 0x30, 0xA5, 0x00, 0xA5, 0xCB, 0x4E, 0x6F,
|
||||
0x39, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xA6, 0x00, 0x55, 0xB0, 0x9E, 0x40, 0x26, 0x9C, 0x50, 0xEF, 0x28, 0xC8, 0x84, 0x80,
|
||||
0x3A, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0x83, 0x93, 0x80, 0x40, 0x28, 0x0A, 0x84, 0x80, 0x3B, 0xF0, 0x83, 0x52, 0x03, 0x53,
|
||||
0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0x83, 0x93, 0x80, 0x40,
|
||||
0x08, 0x40, 0xA4, 0xC0, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0xA2, 0xC0, 0x21, 0xC8, 0xB8, 0x27,
|
||||
0x8A, 0x51, 0x03, 0x5C, 0x01, 0x34, 0x21, 0xC8, 0x84, 0x80, 0x00, 0x48, 0xA2, 0xC0, 0x24, 0xC8,
|
||||
0xB8, 0x27, 0x8A, 0x51, 0x03, 0x5C, 0x00, 0xF4, 0x24, 0x0A, 0x84, 0x80, 0x00, 0x48, 0xA2, 0xC0,
|
||||
0x21, 0x0A, 0xB8, 0x27, 0x8A, 0x51, 0x03, 0x5C, 0x01, 0x34, 0x00, 0xF4, 0xA3, 0x00, 0xA2, 0x01,
|
||||
0x21, 0xC8, 0x23, 0x58, 0xA2, 0x87, 0x03, 0xD0, 0xA1, 0x8D, 0x03, 0xD0, 0xA3, 0x8C, 0xA3, 0x48,
|
||||
0x03, 0x9D, 0x98, 0x2F, 0x22, 0xC8, 0x08, 0x40, 0xD5, 0x40, 0x9E, 0x40, 0x57, 0x88, 0x0C, 0xFE,
|
||||
0xB1, 0x00, 0x00, 0xB0, 0x03, 0x18, 0x01, 0xF0, 0xB2, 0x00, 0x55, 0x48, 0x31, 0x46, 0x32, 0x04,
|
||||
0x08, 0x40, 0x56, 0x48, 0x42, 0xFE, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48, 0xA2, 0xC0, 0x12, 0x74,
|
||||
0x84, 0x80, 0x00, 0x48, 0xA3, 0x00, 0x22, 0xC8, 0x23, 0x02, 0x08, 0x40, 0xCF, 0x80, 0x52, 0x08,
|
||||
0xD0, 0xC0, 0x56, 0x48, 0xCE, 0x40, 0x08, 0x40, 0x4E, 0x48, 0x42, 0xFE, 0x84, 0x80, 0x00, 0x48,
|
||||
0xD4, 0x00, 0x08, 0x40, 0x39, 0x7E, 0x84, 0x80, 0x00, 0x48, 0xA2, 0xC0, 0x11, 0x74, 0xFD, 0xF9,
|
||||
0x02, 0x38, 0xA2, 0xC0, 0x02, 0x34, 0xFD, 0xF9, 0x02, 0x38, 0xA2, 0xC0, 0x01, 0x34, 0x03, 0xD0,
|
||||
0xB0, 0x8D, 0x03, 0xD0, 0xB0, 0x8D, 0x08, 0x40, 0xFF, 0x3A, 0x01, 0xBE, 0xA1, 0xC0, 0x53, 0x48,
|
||||
0x08, 0x40, 0x03, 0xD0, 0xB1, 0xCD, 0x03, 0xD0, 0xB1, 0xCD, 0x08, 0x40, 0x80, 0x40, 0x05, 0x30,
|
||||
0xA1, 0xC0, 0x57, 0x88, 0x08, 0x40, 0xFF, 0x3A, 0x01, 0xBE, 0xA1, 0xC0, 0x54, 0x08, 0x08, 0x40,
|
||||
0xA0, 0x30, 0x83, 0x93, 0x84, 0x80, 0xF0, 0xB0, 0x8A, 0x51, 0x2F, 0xE1, 0x8A, 0x51, 0xA0, 0x30,
|
||||
0x83, 0xD7, 0x84, 0x80, 0xE0, 0x70, 0x8A, 0x51, 0x2F, 0xE1, 0x83, 0x01, 0x8A, 0x95, 0xD5, 0x2A,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF,
|
||||
0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0xFF, 0xBF, 0x01, 0xF0, 0xA0, 0x80, 0x95, 0x41,
|
||||
0x96, 0x41, 0x97, 0x81, 0x98, 0x01, 0x99, 0x41, 0x9A, 0x41, 0x9B, 0x81, 0x9C, 0x41, 0x9E, 0x81,
|
||||
0x9B, 0x81, 0x1C, 0x70, 0xA2, 0x01, 0xA2, 0x4A, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0, 0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53,
|
||||
0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xE5, 0x40, 0x65, 0x48,
|
||||
0x03, 0x59, 0xED, 0x6A, 0x9B, 0x81, 0x10, 0xF0, 0xA2, 0x01, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0,
|
||||
0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xE5, 0x40, 0x9E, 0x40, 0x65, 0xCB,
|
||||
0x04, 0x6B, 0x3D, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xE2, 0x00, 0xA2, 0xC0, 0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3E, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0,
|
||||
0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xE3, 0x40, 0xA2, 0xC0, 0x1B, 0xB0,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3F, 0x30,
|
||||
0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xE4, 0x00, 0x03, 0x30, 0xE4, 0x85, 0x64, 0x08, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0, 0x9E, 0x40, 0x9B, 0x40,
|
||||
0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xE5, 0x40, 0x9E, 0x40, 0x65, 0x48, 0x02, 0x7A, 0x03, 0x9D, 0x50, 0xAB, 0x3D, 0xF0,
|
||||
0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xDF, 0xC0, 0xA2, 0xC0, 0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x3E, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xE0, 0xC0, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x02, 0xF0, 0x9E, 0x40, 0x9B, 0x40,
|
||||
0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xE5, 0x40, 0x9E, 0x40, 0x65, 0x48, 0x03, 0xBA, 0x03, 0x9D, 0x88, 0xAB, 0x3D, 0xF0,
|
||||
0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xDC, 0x40, 0xA2, 0xC0, 0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x3E, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00,
|
||||
0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xDD, 0x80, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x03, 0x30, 0x9E, 0x40, 0x9B, 0x40,
|
||||
0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xE5, 0x40, 0x9E, 0x40, 0x65, 0x48, 0x04, 0x7A, 0x03, 0x9D, 0xC0, 0xAB, 0x9E, 0x81,
|
||||
0x9B, 0x81, 0x3D, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4,
|
||||
0x97, 0x90, 0x0D, 0x08, 0xDE, 0x80, 0xA2, 0xC0, 0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3E, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0,
|
||||
0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xE1, 0x00, 0xA2, 0xC0, 0x1B, 0xB0,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xE2, 0x48,
|
||||
0x03, 0x9D, 0x02, 0x2C, 0x63, 0x48, 0x56, 0xA4, 0x00, 0xB0, 0x8A, 0x95, 0x5C, 0xA4, 0x8A, 0x95,
|
||||
0x11, 0x30, 0x3B, 0x2C, 0x62, 0x8B, 0x0C, 0x6C, 0x63, 0x48, 0x56, 0xA4, 0x01, 0xF0, 0x8A, 0x95,
|
||||
0x5C, 0xA4, 0x8A, 0x95, 0x22, 0x30, 0x3B, 0x2C, 0x62, 0x08, 0x02, 0x7A, 0x03, 0x9D, 0x18, 0x6C,
|
||||
0x63, 0x48, 0x4C, 0x64, 0x00, 0xB0, 0x8A, 0x51, 0x39, 0xA2, 0x8A, 0x95, 0x33, 0xB0, 0x3B, 0x2C,
|
||||
0x62, 0x08, 0x03, 0xBA, 0x03, 0x9D, 0x24, 0x6C, 0x63, 0x48, 0x4C, 0x64, 0x01, 0xF0, 0x8A, 0x51,
|
||||
0x39, 0xA2, 0x8A, 0x95, 0x44, 0x30, 0x3B, 0x2C, 0x62, 0x08, 0x04, 0x7A, 0x03, 0x9D, 0x30, 0x6C,
|
||||
0x63, 0x48, 0x3E, 0xE4, 0x00, 0xB0, 0x8A, 0x51, 0x37, 0xE1, 0x8A, 0x95, 0x55, 0xB0, 0x3B, 0x2C,
|
||||
0x62, 0x08, 0x05, 0xBA, 0x03, 0x9D, 0x04, 0x6B, 0x63, 0x48, 0x3E, 0xE4, 0x01, 0xF0, 0x8A, 0x51,
|
||||
0x37, 0xE1, 0x8A, 0x95, 0x66, 0xB0, 0x9B, 0x40, 0x9E, 0x40, 0x04, 0x6B, 0xA9, 0x00, 0x5F, 0xC8,
|
||||
0xAA, 0x00, 0x60, 0xC8, 0xAB, 0x40, 0x5C, 0x48, 0xAC, 0x00, 0x5D, 0x88, 0xAD, 0x40, 0x5E, 0x88,
|
||||
0xAE, 0x40, 0x64, 0x08, 0xAF, 0x80, 0x08, 0x40, 0xAC, 0x00, 0x5F, 0xC8, 0xAD, 0x40, 0x60, 0xC8,
|
||||
0xAE, 0x40, 0x61, 0x08, 0xAF, 0x80, 0x64, 0x08, 0xB0, 0xC0, 0x08, 0x40, 0xA9, 0x00, 0x61, 0x08,
|
||||
0xAA, 0x00, 0x64, 0x08, 0xAB, 0x40, 0x08, 0x40, 0xB3, 0x40, 0x04, 0xF0, 0xA2, 0xC0, 0x10, 0xF0,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x29, 0x08,
|
||||
0xA2, 0xC0, 0x13, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x14, 0x30, 0xA2, 0x01, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x15, 0x70, 0xA2, 0x01, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2A, 0x08, 0xD6, 0x40, 0x0B, 0x70, 0xD7, 0xC1, 0xDB, 0x80,
|
||||
0x5B, 0x88, 0xB4, 0x00, 0x33, 0x98, 0xE0, 0xAC, 0x5B, 0x88, 0xAC, 0x00, 0x01, 0xF0, 0xFB, 0xE7,
|
||||
0x8A, 0x95, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0xC3, 0x39, 0x2C, 0x04, 0xA2, 0xC0, 0x01, 0xF0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0,
|
||||
0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0x8A, 0x51, 0xD3, 0x67, 0x8A, 0x95,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x01, 0xF0,
|
||||
0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08,
|
||||
0xA2, 0xC0, 0x01, 0xF0, 0xA2, 0x10, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x2B, 0x48, 0xA4, 0xC0, 0x53, 0xB0, 0x8A, 0x51, 0x2D, 0x27, 0x8A, 0x95,
|
||||
0x56, 0xB0, 0xA1, 0xC0, 0x53, 0xB0, 0x8A, 0x51, 0x79, 0x67, 0x8A, 0x95, 0xD0, 0xC0, 0x50, 0xC8,
|
||||
0x03, 0x9D, 0x1F, 0x6D, 0x07, 0x70, 0xDB, 0x03, 0x5B, 0x82, 0x03, 0x5C, 0x1F, 0x6D, 0x88, 0x6C,
|
||||
0x5B, 0x88, 0xAC, 0x00, 0x02, 0xF0, 0xFB, 0xE7, 0x8A, 0x95, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0,
|
||||
0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xC3, 0x39, 0x2C, 0x04, 0xA2, 0xC0,
|
||||
0x02, 0xF0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x02, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90,
|
||||
0x0D, 0x08, 0x8A, 0x51, 0xCF, 0xA7, 0x8A, 0x95, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x02, 0xF0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8,
|
||||
0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xA2, 0xC0, 0x02, 0xF0, 0xA2, 0x10, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xCA, 0xEC, 0x53, 0x48,
|
||||
0xB5, 0x40, 0x54, 0x08, 0xB6, 0x40, 0xF3, 0xA7, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2B, 0x48, 0xA4, 0xC0, 0x56, 0xB0, 0x8A, 0x51, 0x2D, 0x27,
|
||||
0x8A, 0x95, 0x56, 0x48, 0xB9, 0x40, 0x57, 0x88, 0xBA, 0x40, 0x29, 0x08, 0xFE, 0xFC, 0xAD, 0x40,
|
||||
0x29, 0x49, 0xAE, 0x40, 0x29, 0x08, 0x01, 0x7C, 0xAF, 0x80, 0x29, 0x08, 0x02, 0x7C, 0xB0, 0xC0,
|
||||
0x14, 0x30, 0xA2, 0x01, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x15, 0x70, 0xA2, 0x01, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x2D, 0x48, 0xA2, 0xC0, 0x13, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2B, 0x48, 0xA4, 0xC0, 0x53, 0xB0, 0x8A, 0x51,
|
||||
0x2D, 0x27, 0x8A, 0x95, 0xDB, 0xC1, 0xDB, 0x0A, 0x5B, 0x88, 0x2D, 0x7E, 0x84, 0x80, 0x00, 0x48,
|
||||
0xA2, 0xC0, 0x13, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x2B, 0x48, 0xA4, 0xC0, 0x56, 0xB0, 0x8A, 0x51, 0x2D, 0x27, 0x8A, 0x95, 0x53, 0xB0,
|
||||
0xA1, 0xC0, 0x56, 0xB0, 0x8A, 0x51, 0x79, 0x67, 0x8A, 0x95, 0xD0, 0xC0, 0x50, 0xC8, 0x03, 0x59,
|
||||
0x85, 0xED, 0x56, 0x48, 0xD3, 0x40, 0x57, 0x88, 0xD4, 0x00, 0x04, 0xF0, 0xDB, 0x0A, 0x5B, 0x82,
|
||||
0x03, 0x5C, 0x64, 0xED, 0x53, 0x48, 0xB7, 0x80, 0x54, 0x08, 0xB8, 0x00, 0xF3, 0xA7, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xD8, 0x41, 0xD9, 0x81,
|
||||
0xDB, 0xC1, 0x58, 0x08, 0xBD, 0x80, 0x59, 0x48, 0xC6, 0x00, 0x5B, 0x88, 0x0A, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x95, 0x58, 0x87, 0xBE, 0x80, 0x5B, 0x88, 0x0A, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x95, 0x59, 0xC7, 0xC7, 0x40, 0x5B, 0x88, 0x0A, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x95, 0x58, 0x87, 0xBF, 0xC0, 0x5B, 0x88, 0x0A, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x95, 0x59, 0x42, 0xC8, 0xC0, 0x5B, 0x88, 0x0A, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x95, 0x58, 0x02, 0xC0, 0x80, 0x5B, 0x88, 0x0A, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x95, 0x59, 0xC7, 0xC9, 0x00, 0x5B, 0x88, 0x0A, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x95, 0x58, 0x02, 0xC1, 0xC0, 0x5B, 0x88, 0x0A, 0xFE, 0x84, 0x80,
|
||||
0x8A, 0x51, 0x02, 0xA0, 0x8A, 0x95, 0x59, 0x42, 0xCA, 0x00, 0xE1, 0x27, 0x8A, 0x95, 0x97, 0x67,
|
||||
0x8A, 0x95, 0xDA, 0x67, 0x8A, 0x95, 0x97, 0x67, 0x8A, 0x95, 0xF7, 0xE7, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x46, 0x08, 0xA2, 0xC0, 0x15, 0x70,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2B, 0x48,
|
||||
0xA4, 0xC0, 0x51, 0x70, 0x8A, 0x51, 0x2D, 0x27, 0x8A, 0x95, 0xCF, 0xC1, 0xDA, 0x81, 0x05, 0x30,
|
||||
0xDA, 0xCA, 0x5A, 0x42, 0x03, 0x18, 0x32, 0xEE, 0x1F, 0xF0, 0xCB, 0x67, 0x8A, 0x95, 0x97, 0x67,
|
||||
0x8A, 0x95, 0xAE, 0x67, 0x8A, 0x95, 0x97, 0x67, 0x8A, 0x95, 0xBE, 0xA7, 0x8A, 0x95, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xD3, 0x67, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2B, 0x48, 0xA4, 0xC0,
|
||||
0x56, 0xB0, 0x8A, 0x51, 0x2D, 0x27, 0x8A, 0x95, 0x56, 0xB0, 0xA1, 0xC0, 0x51, 0x70, 0x8A, 0x51,
|
||||
0x79, 0x67, 0x8A, 0x95, 0xD0, 0xC0, 0x50, 0xC8, 0x03, 0x59, 0xFF, 0x2D, 0x56, 0x48, 0xE7, 0xA7,
|
||||
0x8A, 0x95, 0xFF, 0x2D, 0x4F, 0x88, 0x3D, 0xBE, 0x84, 0x80, 0x00, 0x48, 0xD8, 0x00, 0xED, 0xA7,
|
||||
0x8A, 0x95, 0x06, 0x30, 0xDB, 0x0A, 0x5B, 0x82, 0x58, 0x08, 0x03, 0x5C, 0x9A, 0x2D, 0xFF, 0x7E,
|
||||
0xBD, 0x80, 0x59, 0x48, 0xFF, 0x7E, 0xC6, 0x00, 0x58, 0x08, 0xFF, 0x7E, 0xBE, 0x80, 0x59, 0x48,
|
||||
0xC7, 0x40, 0x58, 0x08, 0xFF, 0x7E, 0xBF, 0xC0, 0x59, 0x48, 0x01, 0xBE, 0xC8, 0xC0, 0x58, 0x08,
|
||||
0xC0, 0x80, 0x59, 0x48, 0xFF, 0x7E, 0xC9, 0x00, 0x58, 0x08, 0xC1, 0xC0, 0x59, 0x48, 0xCA, 0x00,
|
||||
0x58, 0x08, 0xC2, 0xC0, 0x59, 0x48, 0x01, 0xBE, 0xCB, 0x40, 0x58, 0x08, 0x01, 0xBE, 0xC3, 0x00,
|
||||
0x59, 0x48, 0xFF, 0x7E, 0xCC, 0x00, 0x58, 0x08, 0x01, 0xBE, 0xC4, 0xC0, 0x59, 0x48, 0xCD, 0x40,
|
||||
0x58, 0x08, 0x01, 0xBE, 0xC5, 0x00, 0x59, 0x48, 0x01, 0xBE, 0xCE, 0x40, 0xE1, 0x27, 0x8A, 0x95,
|
||||
0x97, 0x67, 0x8A, 0x95, 0xDA, 0x67, 0x8A, 0x95, 0x97, 0x67, 0x8A, 0x95, 0xF7, 0xE7, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x46, 0x08, 0xA2, 0xC0,
|
||||
0x15, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x2B, 0x48, 0xA4, 0xC0, 0x51, 0x70, 0x8A, 0x51, 0x2D, 0x27, 0x8A, 0x95, 0xCF, 0xC1, 0xDA, 0x81,
|
||||
0x09, 0x30, 0xDA, 0xCA, 0x5A, 0x42, 0x03, 0x18, 0xC3, 0x2E, 0x1F, 0xF0, 0xCB, 0x67, 0x8A, 0x95,
|
||||
0x97, 0x67, 0x8A, 0x95, 0xAE, 0x67, 0x8A, 0x95, 0x97, 0x67, 0x8A, 0x95, 0xBE, 0xA7, 0x8A, 0x95,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0xD3, 0x67,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x2B, 0x48,
|
||||
0xA4, 0xC0, 0x56, 0xB0, 0x8A, 0x51, 0x2D, 0x27, 0x8A, 0x95, 0x56, 0xB0, 0xA1, 0xC0, 0x51, 0x70,
|
||||
0x8A, 0x51, 0x79, 0x67, 0x8A, 0x95, 0xD0, 0xC0, 0x50, 0xC8, 0x03, 0x59, 0x90, 0xAE, 0x56, 0x48,
|
||||
0xE7, 0xA7, 0x8A, 0x95, 0x90, 0xAE, 0x4F, 0x88, 0x3D, 0xBE, 0x84, 0x80, 0x00, 0x48, 0xD8, 0x00,
|
||||
0xED, 0xA7, 0x8A, 0x95, 0x51, 0x08, 0xBB, 0x80, 0x52, 0x08, 0xBC, 0x40, 0x58, 0x08, 0xA2, 0xC0,
|
||||
0x14, 0x30, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x59, 0x48, 0xA2, 0xC0, 0x15, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x2A, 0x08, 0xA2, 0xC0, 0x19, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x34, 0x08, 0xA2, 0xC0, 0x1A, 0x70, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x35, 0x48, 0xA2, 0xC0,
|
||||
0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x36, 0x48, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x06, 0x30, 0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53, 0xA1, 0xC0,
|
||||
0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD5, 0x40, 0x9E, 0x40, 0x55, 0x48,
|
||||
0x06, 0xBA, 0x03, 0x9D, 0x0C, 0xEF, 0x39, 0x48, 0xA2, 0xC0, 0x19, 0x70, 0xA3, 0x00, 0x22, 0xC8,
|
||||
0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3A, 0x48, 0xA2, 0xC0, 0x1A, 0x70,
|
||||
0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x58, 0x08,
|
||||
0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94,
|
||||
0x17, 0x50, 0x59, 0x48, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08,
|
||||
0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x07, 0x70, 0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52, 0x03, 0x53,
|
||||
0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD5, 0x40, 0x9E, 0x40,
|
||||
0x55, 0x48, 0x07, 0xFA, 0x03, 0x9D, 0x45, 0x2F, 0x3B, 0x88, 0xA2, 0xC0, 0x19, 0x70, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x3C, 0x48, 0xA2, 0xC0,
|
||||
0x1A, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50,
|
||||
0x37, 0x88, 0xA2, 0xC0, 0x1B, 0xB0, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00,
|
||||
0x17, 0x94, 0x17, 0x50, 0x38, 0x08, 0xA2, 0xC0, 0x1C, 0x70, 0xA3, 0x00, 0x22, 0xC8, 0x96, 0x00,
|
||||
0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x08, 0xF0, 0x9B, 0x40, 0x3C, 0xB0, 0x83, 0x52,
|
||||
0x03, 0x53, 0xA1, 0xC0, 0x21, 0xC8, 0x95, 0x00, 0x97, 0xD4, 0x97, 0x90, 0x0D, 0x08, 0xD5, 0x40,
|
||||
0x9E, 0x40, 0x55, 0x48, 0x08, 0x7A, 0x03, 0x9D, 0x7E, 0xEF, 0x10, 0xF0, 0xA2, 0x01, 0xA3, 0x00,
|
||||
0x22, 0xC8, 0x96, 0x00, 0x23, 0x08, 0x95, 0x00, 0x17, 0x94, 0x17, 0x50, 0x08, 0x40, 0xA4, 0xC0,
|
||||
0x21, 0xC8, 0x80, 0x7A, 0xA3, 0x00, 0x24, 0xC8, 0x80, 0x7A, 0xA3, 0x42, 0x03, 0x18, 0xA2, 0x2F,
|
||||
0x21, 0xC8, 0x08, 0x40, 0x24, 0xC8, 0x80, 0x7A, 0xA3, 0x00, 0x22, 0xC8, 0x80, 0x7A, 0xA3, 0x42,
|
||||
0x03, 0x18, 0xAC, 0x6F, 0x22, 0xC8, 0x08, 0x40, 0x24, 0xC8, 0x08, 0x40, 0xAC, 0x00, 0x5A, 0x48,
|
||||
0x3D, 0xBE, 0x84, 0x80, 0x2C, 0x08, 0x83, 0x93, 0x80, 0x40, 0x1F, 0xF0, 0xA1, 0xC0, 0xE0, 0x70,
|
||||
0xA2, 0xC0, 0x5A, 0x48, 0x46, 0x3E, 0x84, 0x80, 0x00, 0x48, 0x08, 0x40, 0xAC, 0x00, 0x5A, 0x48,
|
||||
0x46, 0x3E, 0x84, 0x80, 0x2C, 0x08, 0x83, 0x93, 0x80, 0x40, 0x5A, 0x48, 0x3D, 0xBE, 0x84, 0x80,
|
||||
0x00, 0x48, 0xA2, 0xC0, 0x14, 0x74, 0xA1, 0xC0, 0xE0, 0x70, 0xA2, 0xC0, 0x5A, 0x48, 0x3D, 0xBE,
|
||||
0x84, 0x80, 0x00, 0x48, 0x08, 0x40, 0x5A, 0x48, 0x46, 0x3E, 0x84, 0x80, 0x83, 0x93, 0x00, 0x48,
|
||||
0xA2, 0xC0, 0x15, 0xB4, 0xBD, 0x80, 0x1F, 0xF0, 0xA1, 0xC0, 0xE0, 0x70, 0xA2, 0xC0, 0x46, 0x08,
|
||||
0x08, 0x40, 0x1F, 0xF0, 0xA1, 0xC0, 0xE0, 0x70, 0xA2, 0xC0, 0x3D, 0x88, 0x08, 0x40, 0xD1, 0x00,
|
||||
0x57, 0x88, 0xD2, 0x00, 0x5A, 0x48, 0xCF, 0x80, 0x08, 0x40, 0x4F, 0x88, 0x46, 0x3E, 0x84, 0x80,
|
||||
0x00, 0x48, 0xD9, 0x40, 0x08, 0x40, 0x29, 0x43, 0xFF, 0x3A, 0xA2, 0xC0, 0x13, 0xB4, 0xC6, 0x00,
|
||||
0x3D, 0x88, 0xA2, 0xC0, 0x14, 0x74, 0x03, 0xD0, 0xAC, 0xCD, 0x03, 0xD0, 0xAC, 0xCD, 0x08, 0x40
|
||||
};
|
||||
|
||||
60
libloragw/src/loragw_aux.c
Normal file
60
libloragw/src/loragw_aux.c
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
LoRa concentrator HAL auxiliary functions
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
#include <time.h> /* clock_nanosleep */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#if DEBUG_AUX == 1
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
|
||||
#else
|
||||
#define DEBUG_MSG(str)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
/* This implementation is POSIX-pecific and require a fix to be compatible with C99 */
|
||||
void wait_ms(unsigned long a) {
|
||||
struct timespec dly;
|
||||
struct timespec rem;
|
||||
|
||||
dly.tv_sec = a / 1000;
|
||||
dly.tv_nsec = ((long)a % 1000) * 1000000;
|
||||
|
||||
DEBUG_PRINTF("NOTE dly: %ld sec %ld ns\n", dly.tv_sec, dly.tv_nsec);
|
||||
|
||||
if((dly.tv_sec > 0) || ((dly.tv_sec == 0) && (dly.tv_nsec > 100000))) {
|
||||
clock_nanosleep(CLOCK_MONOTONIC, 0, &dly, &rem);
|
||||
DEBUG_PRINTF("NOTE remain: %ld sec %ld ns\n", rem.tv_sec, rem.tv_nsec);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
1044
libloragw/src/loragw_cal.c
Normal file
1044
libloragw/src/loragw_cal.c
Normal file
File diff suppressed because it is too large
Load diff
201
libloragw/src/loragw_debug.c
Normal file
201
libloragw/src/loragw_debug.c
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
LoRa concentrator debug functions
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdbool.h> /* bool type */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
#include <string.h> /* memcmp */
|
||||
#include <time.h>
|
||||
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_debug.h"
|
||||
|
||||
#include "tinymt32.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEBUG CONSTANTS ------------------------------------------------------ */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS & TYPES -------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
static tinymt32_t tinymt;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
void dbg_init_random(void) {
|
||||
tinymt.mat1 = 0x8f7011ee;
|
||||
tinymt.mat2 = 0xfc78ff1f;
|
||||
tinymt.tmat = 0x3793fdff;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
void dbg_init_gpio(void) {
|
||||
/* Select GPIO_6 to be controlled by HOST */
|
||||
lgw_reg_w(SX1302_REG_GPIO_GPIO_SEL_6_SELECTION, 0);
|
||||
/* Configure it as an OUTPUT */
|
||||
lgw_reg_w(SX1302_REG_GPIO_GPIO_DIR_L_DIRECTION, 0xFF);
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
void dbg_toggle_gpio(void) {
|
||||
/* Set GPIO_6 to high */
|
||||
lgw_reg_w(SX1302_REG_GPIO_GPIO_OUT_L_OUT_VALUE, 64);
|
||||
/* Set GPIO_6 to low */
|
||||
lgw_reg_w(SX1302_REG_GPIO_GPIO_OUT_L_OUT_VALUE, 0);
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
void dbg_log_buffer_to_file(FILE * file, uint8_t * buffer, uint16_t size) {
|
||||
int i;
|
||||
char stat_timestamp[24];
|
||||
time_t t;
|
||||
|
||||
t = time(NULL);
|
||||
strftime(stat_timestamp, sizeof stat_timestamp, "%F %T %Z", gmtime(&t));
|
||||
fprintf(file, "---------(%s)------------\n", stat_timestamp);
|
||||
for (i = 0; i < size; i++) {
|
||||
fprintf(file, "%02X ", buffer[i]);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
|
||||
fflush(file);
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
void dbg_log_payload_diff_to_file(FILE * file, uint8_t * buffer1, uint8_t * buffer2, uint16_t size) {
|
||||
int i, j;
|
||||
uint16_t nb_bits_diff = 0;
|
||||
uint8_t debug_payload_diff[255];
|
||||
|
||||
fprintf(file, "Diff: ");
|
||||
/* bit comparison of payloads */
|
||||
for (j = 0; j < size; j++) {
|
||||
debug_payload_diff[j] = buffer1[j] ^ buffer2[j];
|
||||
fprintf(file, "%02X ", debug_payload_diff[j]);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
|
||||
/* count number of bits flipped, and display bit by bit */
|
||||
for (j = 0; j < size; j++) {
|
||||
for (i = 7; i >= 0; i--) {
|
||||
fprintf(file, "%u", TAKE_N_BITS_FROM(debug_payload_diff[j], i, 1));
|
||||
if (TAKE_N_BITS_FROM(debug_payload_diff[j], i, 1) == 1) {
|
||||
nb_bits_diff += 1;
|
||||
}
|
||||
}
|
||||
fprintf(file, " ");
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "%u bits flipped\n", nb_bits_diff);
|
||||
|
||||
fflush(file);
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
void dbg_generate_random_payload(uint32_t pkt_cnt, uint8_t * buffer_expected, uint8_t size) {
|
||||
int k;
|
||||
|
||||
/* construct payload we should get for this packet counter */
|
||||
tinymt32_init(&tinymt, (int)pkt_cnt);
|
||||
buffer_expected[4] = (uint8_t)(pkt_cnt >> 24);
|
||||
buffer_expected[5] = (uint8_t)(pkt_cnt >> 16);
|
||||
buffer_expected[6] = (uint8_t)(pkt_cnt >> 8);
|
||||
buffer_expected[7] = (uint8_t)(pkt_cnt >> 0);
|
||||
tinymt32_generate_uint32(&tinymt); /* dummy: for sync with random size generation */
|
||||
for (k = 8; k < (int)size; k++) {
|
||||
buffer_expected[k] = (uint8_t)tinymt32_generate_uint32(&tinymt);
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int dbg_check_payload(struct lgw_conf_debug_s * context, FILE * file, uint8_t * payload_received, uint8_t size, uint8_t ref_payload_idx, uint8_t sf) {
|
||||
int k;
|
||||
uint32_t debug_payload_cnt;
|
||||
|
||||
/* If the 4 first bytes of received payload match with the expected ones, go on with comparison */
|
||||
if (memcmp((void*)payload_received, (void*)(context->ref_payload[ref_payload_idx].payload), 4) == 0) {
|
||||
/* get counter to initialize random seed */
|
||||
debug_payload_cnt = (unsigned int)(payload_received[4] << 24) | (unsigned int)(payload_received[5] << 16) | (unsigned int)(payload_received[6] << 8) | (unsigned int)(payload_received[7] << 0);
|
||||
|
||||
/* check if we missed some packets */
|
||||
if (debug_payload_cnt > (context->ref_payload[ref_payload_idx].prev_cnt + 1)) {
|
||||
printf("ERROR: 0x%08X missed %u pkt before %u (SF%u, size:%u)\n", context->ref_payload[ref_payload_idx].id, debug_payload_cnt - context->ref_payload[ref_payload_idx].prev_cnt - 1, debug_payload_cnt, sf, size);
|
||||
if (file != NULL) {
|
||||
fprintf(file, "ERROR: 0x%08X missed %u pkt before %u (SF%u, size:%u)\n", context->ref_payload[ref_payload_idx].id, debug_payload_cnt - context->ref_payload[ref_payload_idx].prev_cnt - 1, debug_payload_cnt, sf, size);
|
||||
fflush(file);
|
||||
}
|
||||
} else if (debug_payload_cnt < context->ref_payload[ref_payload_idx].prev_cnt) {
|
||||
if (file != NULL) {
|
||||
fprintf(file, "INFO: 0x%08X got missing pkt %u (SF%u, size:%u) ?\n", context->ref_payload[ref_payload_idx].id, debug_payload_cnt, sf, size);
|
||||
fflush(file);
|
||||
}
|
||||
} else {
|
||||
#if 0
|
||||
if (file != NULL) {
|
||||
fprintf(file, "0x%08X %u (SF%u, size:%u)\n", context.ref_payload[ref_payload_idx].id, debug_payload_cnt, sf, size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
context->ref_payload[ref_payload_idx].prev_cnt = debug_payload_cnt;
|
||||
|
||||
/* generate the random payload which is expected for this packet count */
|
||||
dbg_generate_random_payload(debug_payload_cnt, context->ref_payload[ref_payload_idx].payload, size);
|
||||
|
||||
/* compare expected with received */
|
||||
if (memcmp((void *)payload_received, (void *)(context->ref_payload[ref_payload_idx].payload), size) != 0) {
|
||||
if (file != NULL) {
|
||||
fprintf(file, "RECEIVED:");
|
||||
for (k = 0; k < (int)size; k++) {
|
||||
fprintf(file, "%02X ", payload_received[k]);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
fprintf(file, "EXPECTED:");
|
||||
for (k = 0; k < (int)size; k++) {
|
||||
fprintf(file, "%02X ", context->ref_payload[ref_payload_idx].payload[k]);
|
||||
}
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
return 1; /* matches */
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* ignored */
|
||||
}
|
||||
837
libloragw/src/loragw_gps.c
Normal file
837
libloragw/src/loragw_gps.c
Normal file
|
|
@ -0,0 +1,837 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Library of functions to manage a GNSS module (typically GPS) for accurate
|
||||
timestamping of packets and synchronisation of gateways.
|
||||
A limited set of module brands/models are supported.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#define _GNU_SOURCE /* needed for qsort_r to be defined */
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdbool.h> /* bool type */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
#include <string.h> /* memcpy */
|
||||
#include <errno.h>
|
||||
|
||||
#include <time.h> /* struct timespec */
|
||||
#include <fcntl.h> /* open */
|
||||
#include <termios.h> /* tcflush */
|
||||
#include <math.h> /* modf */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "loragw_gps.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#if DEBUG_GPS == 1
|
||||
#define DEBUG_MSG(args...) fprintf(stderr, args)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
|
||||
#define DEBUG_ARRAY(a,b,c) for(a=0;a<b;++a) fprintf(stderr,"%x.",c[a]);fprintf(stderr,"end\n")
|
||||
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_GPS_ERROR;}
|
||||
#else
|
||||
#define DEBUG_MSG(args...)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#define DEBUG_ARRAY(a,b,c) for(a=0;a!=0;){}
|
||||
#define CHECK_NULL(a) if(a==NULL){return LGW_GPS_ERROR;}
|
||||
#endif
|
||||
#define TRACE() fprintf(stderr, "@ %s %d\n", __FUNCTION__, __LINE__);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define TS_CPS 1E6 /* count-per-second of the timestamp counter */
|
||||
#define PLUS_10PPM 1.00001
|
||||
#define MINUS_10PPM 0.99999
|
||||
#define DEFAULT_BAUDRATE B9600
|
||||
|
||||
#define UBX_MSG_NAVTIMEGPS_LEN 16
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
|
||||
/* result of the NMEA parsing */
|
||||
static short gps_yea = 0; /* year (2 or 4 digits) */
|
||||
static short gps_mon = 0; /* month (1-12) */
|
||||
static short gps_day = 0; /* day of the month (1-31) */
|
||||
static short gps_hou = 0; /* hours (0-23) */
|
||||
static short gps_min = 0; /* minutes (0-59) */
|
||||
static short gps_sec = 0; /* seconds (0-60)(60 is for leap second) */
|
||||
static float gps_fra = 0.0; /* fractions of seconds (<1) */
|
||||
static bool gps_time_ok = false;
|
||||
static int16_t gps_week = 0; /* GPS week number of the navigation epoch */
|
||||
static uint32_t gps_iTOW = 0; /* GPS time of week in milliseconds */
|
||||
static int32_t gps_fTOW = 0; /* Fractional part of iTOW (+/-500000) in nanosec */
|
||||
|
||||
static short gps_dla = 0; /* degrees of latitude */
|
||||
static double gps_mla = 0.0; /* minutes of latitude */
|
||||
static char gps_ola = 0; /* orientation (N-S) of latitude */
|
||||
static short gps_dlo = 0; /* degrees of longitude */
|
||||
static double gps_mlo = 0.0; /* minutes of longitude */
|
||||
static char gps_olo = 0; /* orientation (E-W) of longitude */
|
||||
static short gps_alt = 0; /* altitude */
|
||||
static bool gps_pos_ok = false;
|
||||
|
||||
static char gps_mod = 'N'; /* GPS mode (N no fix, A autonomous, D differential) */
|
||||
static short gps_sat = 0; /* number of satellites used for fix */
|
||||
|
||||
static struct termios ttyopt_restore;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
|
||||
|
||||
static int nmea_checksum(const char *nmea_string, int buff_size, char *checksum);
|
||||
|
||||
static char nibble_to_hexchar(uint8_t a);
|
||||
|
||||
static bool validate_nmea_checksum(const char *serial_buff, int buff_size);
|
||||
|
||||
static bool match_label(const char *s, char *label, int size, char wildcard);
|
||||
|
||||
static int str_chop(char *s, int buff_size, char separator, int *idx_ary, int max_idx);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
|
||||
|
||||
/*
|
||||
Calculate the checksum for a NMEA string
|
||||
Skip the first '$' if necessary and calculate checksum until '*' character is
|
||||
reached (or buff_size exceeded).
|
||||
Checksum must point to a 2-byte (or more) char array.
|
||||
Return position of the checksum in the string
|
||||
*/
|
||||
static int nmea_checksum(const char *nmea_string, int buff_size, char *checksum) {
|
||||
int i = 0;
|
||||
uint8_t check_num = 0;
|
||||
|
||||
/* check input parameters */
|
||||
if ((nmea_string == NULL) || (checksum == NULL) || (buff_size <= 1)) {
|
||||
DEBUG_MSG("Invalid parameters for nmea_checksum\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* skip the first '$' if necessary */
|
||||
if (nmea_string[i] == '$') {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
/* xor until '*' or max length is reached */
|
||||
while (nmea_string[i] != '*') {
|
||||
check_num ^= nmea_string[i];
|
||||
i += 1;
|
||||
if (i >= buff_size) {
|
||||
DEBUG_MSG("Maximum length reached for nmea_checksum\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert checksum value to 2 hexadecimal characters */
|
||||
checksum[0] = nibble_to_hexchar(check_num / 16); /* upper nibble */
|
||||
checksum[1] = nibble_to_hexchar(check_num % 16); /* lower nibble */
|
||||
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
static char nibble_to_hexchar(uint8_t a) {
|
||||
if (a < 10) {
|
||||
return '0' + a;
|
||||
} else if (a < 16) {
|
||||
return 'A' + (a-10);
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/*
|
||||
Calculate the checksum of a NMEA frame and compare it to the checksum that is
|
||||
present at the end of it.
|
||||
Return true if it matches
|
||||
*/
|
||||
static bool validate_nmea_checksum(const char *serial_buff, int buff_size) {
|
||||
int checksum_index;
|
||||
char checksum[2]; /* 2 characters to calculate NMEA checksum */
|
||||
|
||||
checksum_index = nmea_checksum(serial_buff, buff_size, checksum);
|
||||
|
||||
/* could we calculate a verification checksum ? */
|
||||
if (checksum_index < 0) {
|
||||
DEBUG_MSG("ERROR: IMPOSSIBLE TO PARSE NMEA SENTENCE\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check if there are enough char in the serial buffer to read checksum */
|
||||
if (checksum_index >= (buff_size - 2)) {
|
||||
DEBUG_MSG("ERROR: IMPOSSIBLE TO READ NMEA SENTENCE CHECKSUM\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check the checksum per se */
|
||||
if ((serial_buff[checksum_index] == checksum[0]) && (serial_buff[checksum_index+1] == checksum[1])) {
|
||||
return true;
|
||||
} else {
|
||||
DEBUG_MSG("ERROR: NMEA CHECKSUM %c%c DOESN'T MATCH VERIFICATION CHECKSUM %c%c\n", serial_buff[checksum_index], serial_buff[checksum_index+1], checksum[0], checksum[1]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/*
|
||||
Return true if the "label" string (can contain wildcard characters) matches
|
||||
the begining of the "s" string
|
||||
*/
|
||||
static bool match_label(const char *s, char *label, int size, char wildcard) {
|
||||
int i;
|
||||
|
||||
for (i=0; i < size; i++) {
|
||||
if (label[i] == wildcard) continue;
|
||||
if (label[i] != s[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/*
|
||||
Chop a string into smaller strings
|
||||
Replace every separator in the input character buffer by a null character so
|
||||
that all s[index] are valid strings.
|
||||
Populate an array of integer 'idx_ary' representing indexes of token in the
|
||||
string.
|
||||
buff_size and max_idx are there to prevent segfaults.
|
||||
Return the number of token found (number of idx_ary filled).
|
||||
*/
|
||||
int str_chop(char *s, int buff_size, char separator, int *idx_ary, int max_idx) {
|
||||
int i = 0; /* index in the string */
|
||||
int j = 0; /* index in the result array */
|
||||
|
||||
if ((s == NULL) || (buff_size < 0) || (separator == 0) || (idx_ary == NULL) || (max_idx < 0)) {
|
||||
/* unsafe to do anything */
|
||||
return -1;
|
||||
}
|
||||
if ((buff_size == 0) || (max_idx == 0)) {
|
||||
/* nothing to do */
|
||||
return 0;
|
||||
}
|
||||
s[buff_size - 1] = 0; /* add string terminator at the end of the buffer, just to be sure */
|
||||
idx_ary[j] = 0;
|
||||
j += 1;
|
||||
/* loop until string terminator is reached */
|
||||
while (s[i] != 0) {
|
||||
if (s[i] == separator) {
|
||||
s[i] = 0; /* replace separator by string terminator */
|
||||
if (j >= max_idx) { /* no more room in the index array */
|
||||
return j;
|
||||
}
|
||||
idx_ary[j] = i+1; /* next token start after replaced separator */
|
||||
++j;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
int lgw_gps_enable(char *tty_path, char *gps_family, speed_t target_brate, int *fd_ptr) {
|
||||
int i;
|
||||
struct termios ttyopt; /* serial port options */
|
||||
int gps_tty_dev; /* file descriptor to the serial port of the GNSS module */
|
||||
uint8_t ubx_cmd_timegps[UBX_MSG_NAVTIMEGPS_LEN] = {
|
||||
0xB5, 0x62, /* UBX Sync Chars */
|
||||
0x06, 0x01, /* CFG-MSG Class/ID */
|
||||
0x08, 0x00, /* Payload length */
|
||||
0x01, 0x20, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, /* Enable NAV-TIMEGPS output on serial */
|
||||
0x32, 0x94 }; /* Checksum */
|
||||
ssize_t num_written;
|
||||
|
||||
/* check input parameters */
|
||||
CHECK_NULL(tty_path);
|
||||
CHECK_NULL(fd_ptr);
|
||||
|
||||
/* open TTY device */
|
||||
gps_tty_dev = open(tty_path, O_RDWR | O_NOCTTY);
|
||||
if (gps_tty_dev <= 0) {
|
||||
DEBUG_MSG("ERROR: TTY PORT FAIL TO OPEN, CHECK PATH AND ACCESS RIGHTS\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
*fd_ptr = gps_tty_dev;
|
||||
|
||||
/* manage the different GPS modules families */
|
||||
if (gps_family == NULL) {
|
||||
DEBUG_MSG("WARNING: this version of GPS module may not be supported\n");
|
||||
} else if (strncmp(gps_family, "ubx7", 4) != 0) {
|
||||
/* The current implementation relies on proprietary messages from U-Blox */
|
||||
/* GPS modules (UBX, NAV-TIMEGPS...) and has only be tested with a u-blox 7. */
|
||||
/* Those messages allow to get NATIVE GPS time (no leap seconds) required */
|
||||
/* for class-B handling and GPS synchronization */
|
||||
/* see lgw_parse_ubx() function for details */
|
||||
DEBUG_MSG("WARNING: this version of GPS module may not be supported\n");
|
||||
}
|
||||
|
||||
/* manage the target bitrate */
|
||||
if (target_brate != 0) {
|
||||
DEBUG_MSG("WARNING: target_brate parameter ignored for now\n"); // TODO
|
||||
}
|
||||
|
||||
/* get actual serial port configuration */
|
||||
i = tcgetattr(gps_tty_dev, &ttyopt);
|
||||
if (i != 0) {
|
||||
DEBUG_MSG("ERROR: IMPOSSIBLE TO GET TTY PORT CONFIGURATION\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
|
||||
/* Save current serial port configuration for restoring later */
|
||||
memcpy(&ttyopt_restore, &ttyopt, sizeof ttyopt);
|
||||
|
||||
/* update baudrates */
|
||||
cfsetispeed(&ttyopt, DEFAULT_BAUDRATE);
|
||||
cfsetospeed(&ttyopt, DEFAULT_BAUDRATE);
|
||||
|
||||
/* update terminal parameters */
|
||||
/* The following configuration should allow to:
|
||||
- Get ASCII NMEA messages
|
||||
- Get UBX binary messages
|
||||
- Send UBX binary commands
|
||||
Note: as binary data have to be read/written, we need to disable
|
||||
various character processing to avoid loosing data */
|
||||
/* Control Modes */
|
||||
ttyopt.c_cflag |= CLOCAL; /* local connection, no modem control */
|
||||
ttyopt.c_cflag |= CREAD; /* enable receiving characters */
|
||||
ttyopt.c_cflag |= CS8; /* 8 bit frames */
|
||||
ttyopt.c_cflag &= ~PARENB; /* no parity */
|
||||
ttyopt.c_cflag &= ~CSTOPB; /* one stop bit */
|
||||
/* Input Modes */
|
||||
ttyopt.c_iflag |= IGNPAR; /* ignore bytes with parity errors */
|
||||
ttyopt.c_iflag &= ~ICRNL; /* do not map CR to NL on input*/
|
||||
ttyopt.c_iflag &= ~IGNCR; /* do not ignore carriage return on input */
|
||||
ttyopt.c_iflag &= ~IXON; /* disable Start/Stop output control */
|
||||
ttyopt.c_iflag &= ~IXOFF; /* do not send Start/Stop characters */
|
||||
/* Output Modes */
|
||||
ttyopt.c_oflag = 0; /* disable everything on output as we only write binary */
|
||||
/* Local Modes */
|
||||
ttyopt.c_lflag &= ~ICANON; /* disable canonical input - cannot use with binary input */
|
||||
ttyopt.c_lflag &= ~ISIG; /* disable check for INTR, QUIT, SUSP special characters */
|
||||
ttyopt.c_lflag &= ~IEXTEN; /* disable any special control character */
|
||||
ttyopt.c_lflag &= ~ECHO; /* do not echo back every character typed */
|
||||
ttyopt.c_lflag &= ~ECHOE; /* does not erase the last character in current line */
|
||||
ttyopt.c_lflag &= ~ECHOK; /* do not echo NL after KILL character */
|
||||
|
||||
/* settings for non-canonical mode
|
||||
read will block for until the lesser of VMIN or requested chars have been received */
|
||||
ttyopt.c_cc[VMIN] = LGW_GPS_MIN_MSG_SIZE;
|
||||
ttyopt.c_cc[VTIME] = 0;
|
||||
|
||||
/* set new serial ports parameters */
|
||||
i = tcsetattr(gps_tty_dev, TCSANOW, &ttyopt);
|
||||
if (i != 0){
|
||||
DEBUG_MSG("ERROR: IMPOSSIBLE TO UPDATE TTY PORT CONFIGURATION\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
tcflush(gps_tty_dev, TCIOFLUSH);
|
||||
|
||||
/* Send UBX CFG NAV-TIMEGPS message to tell GPS module to output native GPS time */
|
||||
/* This is a binary message, serial port has to be properly configured to handle this */
|
||||
num_written = write (gps_tty_dev, ubx_cmd_timegps, UBX_MSG_NAVTIMEGPS_LEN);
|
||||
if (num_written != UBX_MSG_NAVTIMEGPS_LEN) {
|
||||
DEBUG_MSG("ERROR: Failed to write on serial port (written=%d)\n", (int) num_written);
|
||||
}
|
||||
|
||||
/* get timezone info */
|
||||
tzset();
|
||||
|
||||
/* initialize global variables */
|
||||
gps_time_ok = false;
|
||||
gps_pos_ok = false;
|
||||
gps_mod = 'N';
|
||||
|
||||
return LGW_GPS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_gps_disable(int fd) {
|
||||
int i;
|
||||
|
||||
/* restore serial ports parameters */
|
||||
i = tcsetattr(fd, TCSANOW, &ttyopt_restore);
|
||||
if (i != 0){
|
||||
DEBUG_MSG("ERROR: IMPOSSIBLE TO RESTORE TTY PORT CONFIGURATION - %s\n", strerror(errno));
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
||||
i = close(fd);
|
||||
if (i != 0) {
|
||||
DEBUG_PRINTF("ERROR: TTY PORT FAIL TO CLOSE - %s\n", strerror(errno));
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
|
||||
return LGW_GPS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
enum gps_msg lgw_parse_ubx(const char *serial_buff, size_t buff_size, size_t *msg_size) {
|
||||
bool valid = 0; /* iTOW, fTOW and week validity */
|
||||
unsigned int payload_length;
|
||||
uint8_t ck_a, ck_b;
|
||||
uint8_t ck_a_rcv, ck_b_rcv;
|
||||
unsigned int i;
|
||||
|
||||
*msg_size = 0; /* ensure msg_size alway receives a value */
|
||||
|
||||
/* check input parameters */
|
||||
if (serial_buff == NULL) {
|
||||
return IGNORED;
|
||||
}
|
||||
if (buff_size < 8) {
|
||||
DEBUG_MSG("ERROR: TOO SHORT TO BE A VALID UBX MESSAGE\n");
|
||||
return IGNORED;
|
||||
}
|
||||
|
||||
/* display received serial data and checksum */
|
||||
DEBUG_MSG("Note: parsing UBX frame> ");
|
||||
for (i=0; i<buff_size; i++) {
|
||||
DEBUG_MSG("%02x ", serial_buff[i]);
|
||||
}
|
||||
DEBUG_MSG("\n");
|
||||
|
||||
/* Check for UBX sync chars 0xB5 0x62 */
|
||||
if ((serial_buff[0] == (char)0xB5) && (serial_buff[1] == (char)0x62)) {
|
||||
|
||||
/* Get payload length to compute message size */
|
||||
payload_length = (uint8_t)serial_buff[4];
|
||||
payload_length |= (uint8_t)serial_buff[5] << 8;
|
||||
*msg_size = 6 + payload_length + 2; /* header + payload + checksum */
|
||||
|
||||
/* check for complete message in buffer */
|
||||
if(*msg_size <= buff_size) {
|
||||
/* Validate checksum of message */
|
||||
ck_a_rcv = serial_buff[*msg_size-2]; /* received checksum */
|
||||
ck_b_rcv = serial_buff[*msg_size-1]; /* received checksum */
|
||||
/* Use 8-bit Fletcher Algorithm to compute checksum of actual payload */
|
||||
ck_a = 0; ck_b = 0;
|
||||
for (i=0; i<(4 + payload_length); i++) {
|
||||
ck_a = ck_a + serial_buff[i+2];
|
||||
ck_b = ck_b + ck_a;
|
||||
}
|
||||
|
||||
/* Compare checksums and parse if OK */
|
||||
if ((ck_a == ck_a_rcv) && (ck_b == ck_b_rcv)) {
|
||||
/* Check for Class 0x01 (NAV) and ID 0x20 (NAV-TIMEGPS) */
|
||||
if ((serial_buff[2] == 0x01) && (serial_buff[3] == 0x20)) {
|
||||
/* Check validity of information */
|
||||
valid = serial_buff[17] & 0x3; /* towValid, weekValid */
|
||||
if (valid) {
|
||||
/* Parse buffer to extract GPS time */
|
||||
/* Warning: payload byte ordering is Little Endian */
|
||||
gps_iTOW = (uint8_t)serial_buff[6];
|
||||
gps_iTOW |= (uint8_t)serial_buff[7] << 8;
|
||||
gps_iTOW |= (uint8_t)serial_buff[8] << 16;
|
||||
gps_iTOW |= (uint8_t)serial_buff[9] << 24; /* GPS time of week, in ms */
|
||||
|
||||
gps_fTOW = (uint8_t)serial_buff[10];
|
||||
gps_fTOW |= (uint8_t)serial_buff[11] << 8;
|
||||
gps_fTOW |= (uint8_t)serial_buff[12] << 16;
|
||||
gps_fTOW |= (uint8_t)serial_buff[13] << 24; /* Fractional part of iTOW, in ns */
|
||||
|
||||
gps_week = (uint8_t)serial_buff[14];
|
||||
gps_week |= (uint8_t)serial_buff[15] << 8; /* GPS week number */
|
||||
|
||||
gps_time_ok = true;
|
||||
#if 0
|
||||
/* For debug */
|
||||
{
|
||||
short ubx_gps_hou = 0; /* hours (0-23) */
|
||||
short ubx_gps_min = 0; /* minutes (0-59) */
|
||||
short ubx_gps_sec = 0; /* seconds (0-59) */
|
||||
|
||||
/* Format GPS time in hh:mm:ss based on iTOW */
|
||||
ubx_gps_sec = (gps_iTOW / 1000) % 60;
|
||||
ubx_gps_min = (gps_iTOW / 1000 / 60) % 60;
|
||||
ubx_gps_hou = (gps_iTOW / 1000 / 60 / 60) % 24;
|
||||
printf(" GPS time = %02d:%02d:%02d\n", ubx_gps_hou, ubx_gps_min, ubx_gps_sec);
|
||||
}
|
||||
#endif
|
||||
} else { /* valid */
|
||||
gps_time_ok = false;
|
||||
}
|
||||
|
||||
return UBX_NAV_TIMEGPS;
|
||||
} else if ((serial_buff[2] == 0x05) && (serial_buff[3] == 0x00)) {
|
||||
DEBUG_MSG("NOTE: UBX ACK-NAK received\n");
|
||||
return IGNORED;
|
||||
} else if ((serial_buff[2] == 0x05) && (serial_buff[3] == 0x01)) {
|
||||
DEBUG_MSG("NOTE: UBX ACK-ACK received\n");
|
||||
return IGNORED;
|
||||
} else { /* not a supported message */
|
||||
DEBUG_MSG("ERROR: UBX message is not supported (%02x %02x)\n", serial_buff[2], serial_buff[3]);
|
||||
return IGNORED;
|
||||
}
|
||||
} else { /* checksum failed */
|
||||
DEBUG_MSG("ERROR: UBX message is corrupted, checksum failed\n");
|
||||
return INVALID;
|
||||
}
|
||||
} else { /* message contains less bytes than indicated by header */
|
||||
DEBUG_MSG("ERROR: UBX message incomplete\n");
|
||||
return INCOMPLETE;
|
||||
}
|
||||
} else { /* Not a UBX message */
|
||||
/* Ignore messages which are not UBX ones for now */
|
||||
return IGNORED;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
enum gps_msg lgw_parse_nmea(const char *serial_buff, int buff_size) {
|
||||
int i, j, k;
|
||||
int str_index[30]; /* string index from the string chopping */
|
||||
int nb_fields; /* number of strings detected by string chopping */
|
||||
char parser_buf[256]; /* parsing modifies buffer so need a local copy */
|
||||
|
||||
/* check input parameters */
|
||||
if (serial_buff == NULL) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
if(buff_size > (int)(sizeof(parser_buf) - 1)) {
|
||||
DEBUG_MSG("Note: input string to big for parsing\n");
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
/* look for some NMEA sentences in particular */
|
||||
if (buff_size < 8) {
|
||||
DEBUG_MSG("ERROR: TOO SHORT TO BE A VALID NMEA SENTENCE\n");
|
||||
return UNKNOWN;
|
||||
} else if (!validate_nmea_checksum(serial_buff, buff_size)) {
|
||||
DEBUG_MSG("Warning: invalid NMEA sentence (bad checksum)\n");
|
||||
return INVALID;
|
||||
} else if (match_label(serial_buff, "$G?RMC", 6, '?')) {
|
||||
/*
|
||||
NMEA sentence format: $xxRMC,time,status,lat,NS,long,EW,spd,cog,date,mv,mvEW,posMode*cs<CR><LF>
|
||||
Valid fix: $GPRMC,083559.34,A,4717.11437,N,00833.91522,E,0.004,77.52,091202,,,A*00
|
||||
No fix: $GPRMC,,V,,,,,,,,,,N*00
|
||||
*/
|
||||
memcpy(parser_buf, serial_buff, buff_size);
|
||||
parser_buf[buff_size] = '\0';
|
||||
nb_fields = str_chop(parser_buf, buff_size, ',', str_index, ARRAY_SIZE(str_index));
|
||||
if (nb_fields != 13) {
|
||||
DEBUG_MSG("Warning: invalid RMC sentence (number of fields)\n");
|
||||
return IGNORED;
|
||||
}
|
||||
/* parse GPS status */
|
||||
gps_mod = *(parser_buf + str_index[12]); /* get first character, no need to bother with sscanf */
|
||||
if ((gps_mod != 'N') && (gps_mod != 'A') && (gps_mod != 'D')) {
|
||||
gps_mod = 'N';
|
||||
}
|
||||
/* parse complete time */
|
||||
i = sscanf(parser_buf + str_index[1], "%2hd%2hd%2hd%4f", &gps_hou, &gps_min, &gps_sec, &gps_fra);
|
||||
j = sscanf(parser_buf + str_index[9], "%2hd%2hd%2hd", &gps_day, &gps_mon, &gps_yea);
|
||||
if ((i == 4) && (j == 3)) {
|
||||
if ((gps_mod == 'A') || (gps_mod == 'D')) {
|
||||
gps_time_ok = true;
|
||||
DEBUG_MSG("Note: Valid RMC sentence, GPS locked, date: 20%02d-%02d-%02dT%02d:%02d:%06.3fZ\n", gps_yea, gps_mon, gps_day, gps_hou, gps_min, gps_fra + (float)gps_sec);
|
||||
} else {
|
||||
gps_time_ok = false;
|
||||
DEBUG_MSG("Note: Valid RMC sentence, no satellite fix, estimated date: 20%02d-%02d-%02dT%02d:%02d:%06.3fZ\n", gps_yea, gps_mon, gps_day, gps_hou, gps_min, gps_fra + (float)gps_sec);
|
||||
}
|
||||
} else {
|
||||
/* could not get a valid hour AND date */
|
||||
gps_time_ok = false;
|
||||
DEBUG_MSG("Note: Valid RMC sentence, mode %c, no date\n", gps_mod);
|
||||
}
|
||||
return NMEA_RMC;
|
||||
} else if (match_label(serial_buff, "$G?GGA", 6, '?')) {
|
||||
/*
|
||||
NMEA sentence format: $xxGGA,time,lat,NS,long,EW,quality,numSV,HDOP,alt,M,sep,M,diffAge,diffStation*cs<CR><LF>
|
||||
Valid fix: $GPGGA,092725.00,4717.11399,N,00833.91590,E,1,08,1.01,499.6,M,48.0,M,,*5B
|
||||
*/
|
||||
memcpy(parser_buf, serial_buff, buff_size);
|
||||
parser_buf[buff_size] = '\0';
|
||||
nb_fields = str_chop(parser_buf, buff_size, ',', str_index, ARRAY_SIZE(str_index));
|
||||
if (nb_fields != 15) {
|
||||
DEBUG_MSG("Warning: invalid GGA sentence (number of fields)\n");
|
||||
return IGNORED;
|
||||
}
|
||||
/* parse number of satellites used for fix */
|
||||
sscanf(parser_buf + str_index[7], "%hd", &gps_sat);
|
||||
/* parse 3D coordinates */
|
||||
i = sscanf(parser_buf + str_index[2], "%2hd%10lf", &gps_dla, &gps_mla);
|
||||
gps_ola = *(parser_buf + str_index[3]);
|
||||
j = sscanf(parser_buf + str_index[4], "%3hd%10lf", &gps_dlo, &gps_mlo);
|
||||
gps_olo = *(parser_buf + str_index[5]);
|
||||
k = sscanf(parser_buf + str_index[9], "%hd", &gps_alt);
|
||||
if ((i == 2) && (j == 2) && (k == 1) && ((gps_ola=='N')||(gps_ola=='S')) && ((gps_olo=='E')||(gps_olo=='W'))) {
|
||||
gps_pos_ok = true;
|
||||
DEBUG_MSG("Note: Valid GGA sentence, %d sat, lat %02ddeg %06.3fmin %c, lon %03ddeg%06.3fmin %c, alt %d\n", gps_sat, gps_dla, gps_mla, gps_ola, gps_dlo, gps_mlo, gps_olo, gps_alt);
|
||||
} else {
|
||||
/* could not get a valid latitude, longitude AND altitude */
|
||||
gps_pos_ok = false;
|
||||
DEBUG_MSG("Note: Valid GGA sentence, %d sat, no coordinates\n", gps_sat);
|
||||
}
|
||||
return NMEA_GGA;
|
||||
} else {
|
||||
DEBUG_MSG("Note: ignored NMEA sentence\n"); /* quite verbose */
|
||||
return IGNORED;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_gps_get(struct timespec *utc, struct timespec *gps_time, struct coord_s *loc, struct coord_s *err) {
|
||||
struct tm x;
|
||||
time_t y;
|
||||
double intpart, fractpart;
|
||||
|
||||
if (utc != NULL) {
|
||||
if (!gps_time_ok) {
|
||||
DEBUG_MSG("ERROR: NO VALID TIME TO RETURN\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
memset(&x, 0, sizeof(x));
|
||||
if (gps_yea < 100) { /* 2-digits year, 20xx */
|
||||
x.tm_year = gps_yea + 100; /* 100 years offset to 1900 */
|
||||
} else { /* 4-digits year, Gregorian calendar */
|
||||
x.tm_year = gps_yea - 1900;
|
||||
}
|
||||
x.tm_mon = gps_mon - 1; /* tm_mon is [0,11], gps_mon is [1,12] */
|
||||
x.tm_mday = gps_day;
|
||||
x.tm_hour = gps_hou;
|
||||
x.tm_min = gps_min;
|
||||
x.tm_sec = gps_sec;
|
||||
y = mktime(&x) - timezone; /* need to substract timezone bc mktime assumes time vector is local time */
|
||||
if (y == (time_t)(-1)) {
|
||||
DEBUG_MSG("ERROR: FAILED TO CONVERT BROKEN-DOWN TIME\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
utc->tv_sec = y;
|
||||
utc->tv_nsec = (int32_t)(gps_fra * 1e9);
|
||||
}
|
||||
if (gps_time != NULL) {
|
||||
if (!gps_time_ok) {
|
||||
DEBUG_MSG("ERROR: NO VALID TIME TO RETURN\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
fractpart = modf(((double)gps_iTOW / 1E3) + ((double)gps_fTOW / 1E9), &intpart);
|
||||
/* Number of seconds since beginning on current GPS week */
|
||||
gps_time->tv_sec = (time_t)intpart;
|
||||
/* Number of seconds since GPS epoch 06.Jan.1980 */
|
||||
gps_time->tv_sec += (time_t)gps_week * 604800; /* day*hours*minutes*secondes: 7*24*60*60; */
|
||||
/* Fractional part in nanoseconds */
|
||||
gps_time->tv_nsec = (long)(fractpart * 1E9);
|
||||
}
|
||||
if (loc != NULL) {
|
||||
if (!gps_pos_ok) {
|
||||
DEBUG_MSG("ERROR: NO VALID POSITION TO RETURN\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
loc->lat = ((double)gps_dla + (gps_mla/60.0)) * ((gps_ola == 'N')?1.0:-1.0);
|
||||
loc->lon = ((double)gps_dlo + (gps_mlo/60.0)) * ((gps_olo == 'E')?1.0:-1.0);
|
||||
loc->alt = gps_alt;
|
||||
}
|
||||
if (err != NULL) {
|
||||
DEBUG_MSG("Warning: localization error processing not implemented yet\n");
|
||||
err->lat = 0.0;
|
||||
err->lon = 0.0;
|
||||
err->alt = 0;
|
||||
}
|
||||
|
||||
return LGW_GPS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_gps_sync(struct tref *ref, uint32_t count_us, struct timespec utc, struct timespec gps_time) {
|
||||
double cnt_diff; /* internal concentrator time difference (in seconds) */
|
||||
double utc_diff; /* UTC time difference (in seconds) */
|
||||
double slope; /* time slope between new reference and old reference (for sanity check) */
|
||||
|
||||
bool aber_n0; /* is the update value for synchronization aberrant or not ? */
|
||||
static bool aber_min1 = false; /* keep track of whether value at sync N-1 was aberrant or not */
|
||||
static bool aber_min2 = false; /* keep track of whether value at sync N-2 was aberrant or not */
|
||||
|
||||
CHECK_NULL(ref);
|
||||
|
||||
/* calculate the slope */
|
||||
|
||||
cnt_diff = (double)(count_us - ref->count_us) / (double)(TS_CPS); /* uncorrected by xtal_err */
|
||||
utc_diff = (double)(utc.tv_sec - (ref->utc).tv_sec) + (1E-9 * (double)(utc.tv_nsec - (ref->utc).tv_nsec));
|
||||
|
||||
/* detect aberrant points by measuring if slope limits are exceeded */
|
||||
if (utc_diff != 0) { // prevent divide by zero
|
||||
slope = cnt_diff/utc_diff;
|
||||
if ((slope > PLUS_10PPM) || (slope < MINUS_10PPM)) {
|
||||
DEBUG_MSG("Warning: correction range exceeded\n");
|
||||
aber_n0 = true;
|
||||
} else {
|
||||
aber_n0 = false;
|
||||
}
|
||||
} else {
|
||||
DEBUG_MSG("Warning: aberrant UTC value for synchronization\n");
|
||||
aber_n0 = true;
|
||||
}
|
||||
|
||||
/* watch if the 3 latest sync point were aberrant or not */
|
||||
if (aber_n0 == false) {
|
||||
/* value no aberrant -> sync with smoothed slope */
|
||||
ref->systime = time(NULL);
|
||||
ref->count_us = count_us;
|
||||
ref->utc.tv_sec = utc.tv_sec;
|
||||
ref->utc.tv_nsec = utc.tv_nsec;
|
||||
ref->gps.tv_sec = gps_time.tv_sec;
|
||||
ref->gps.tv_nsec = gps_time.tv_nsec;
|
||||
ref->xtal_err = slope;
|
||||
aber_min2 = aber_min1;
|
||||
aber_min1 = aber_n0;
|
||||
return LGW_GPS_SUCCESS;
|
||||
} else if (aber_n0 && aber_min1 && aber_min2) {
|
||||
/* 3 successive aberrant values -> sync reset (keep xtal_err) */
|
||||
ref->systime = time(NULL);
|
||||
ref->count_us = count_us;
|
||||
ref->utc.tv_sec = utc.tv_sec;
|
||||
ref->utc.tv_nsec = utc.tv_nsec;
|
||||
ref->gps.tv_sec = gps_time.tv_sec;
|
||||
ref->gps.tv_nsec = gps_time.tv_nsec;
|
||||
/* reset xtal_err only if the present value is out of range */
|
||||
if ((ref->xtal_err > PLUS_10PPM) || (ref->xtal_err < MINUS_10PPM)) {
|
||||
ref->xtal_err = 1.0;
|
||||
}
|
||||
DEBUG_MSG("Warning: 3 successive aberrant sync attempts, sync reset\n");
|
||||
aber_min2 = aber_min1;
|
||||
aber_min1 = aber_n0;
|
||||
return LGW_GPS_SUCCESS;
|
||||
} else {
|
||||
/* only 1 or 2 successive aberrant values -> ignore and return an error */
|
||||
aber_min2 = aber_min1;
|
||||
aber_min1 = aber_n0;
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
|
||||
return LGW_GPS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_cnt2utc(struct tref ref, uint32_t count_us, struct timespec *utc) {
|
||||
double delta_sec;
|
||||
double intpart, fractpart;
|
||||
long tmp;
|
||||
|
||||
CHECK_NULL(utc);
|
||||
if ((ref.systime == 0) || (ref.xtal_err > PLUS_10PPM) || (ref.xtal_err < MINUS_10PPM)) {
|
||||
DEBUG_MSG("ERROR: INVALID REFERENCE FOR CNT -> UTC CONVERSION\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
|
||||
/* calculate delta in seconds between reference count_us and target count_us */
|
||||
delta_sec = (double)(count_us - ref.count_us) / (TS_CPS * ref.xtal_err);
|
||||
|
||||
/* now add that delta to reference UTC time */
|
||||
fractpart = modf (delta_sec , &intpart);
|
||||
tmp = ref.utc.tv_nsec + (long)(fractpart * 1E9);
|
||||
if (tmp < (long)1E9) { /* the nanosecond part doesn't overflow */
|
||||
utc->tv_sec = ref.utc.tv_sec + (time_t)intpart;
|
||||
utc->tv_nsec = tmp;
|
||||
} else { /* must carry one second */
|
||||
utc->tv_sec = ref.utc.tv_sec + (time_t)intpart + 1;
|
||||
utc->tv_nsec = tmp - (long)1E9;
|
||||
}
|
||||
|
||||
return LGW_GPS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_utc2cnt(struct tref ref, struct timespec utc, uint32_t *count_us) {
|
||||
double delta_sec;
|
||||
|
||||
CHECK_NULL(count_us);
|
||||
if ((ref.systime == 0) || (ref.xtal_err > PLUS_10PPM) || (ref.xtal_err < MINUS_10PPM)) {
|
||||
DEBUG_MSG("ERROR: INVALID REFERENCE FOR UTC -> CNT CONVERSION\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
|
||||
/* calculate delta in seconds between reference utc and target utc */
|
||||
delta_sec = (double)(utc.tv_sec - ref.utc.tv_sec);
|
||||
delta_sec += 1E-9 * (double)(utc.tv_nsec - ref.utc.tv_nsec);
|
||||
|
||||
/* now convert that to internal counter tics and add that to reference counter value */
|
||||
*count_us = ref.count_us + (uint32_t)(delta_sec * TS_CPS * ref.xtal_err);
|
||||
|
||||
return LGW_GPS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_cnt2gps(struct tref ref, uint32_t count_us, struct timespec *gps_time) {
|
||||
double delta_sec;
|
||||
double intpart, fractpart;
|
||||
long tmp;
|
||||
|
||||
CHECK_NULL(gps_time);
|
||||
if ((ref.systime == 0) || (ref.xtal_err > PLUS_10PPM) || (ref.xtal_err < MINUS_10PPM)) {
|
||||
DEBUG_MSG("ERROR: INVALID REFERENCE FOR CNT -> GPS CONVERSION\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
|
||||
/* calculate delta in milliseconds between reference count_us and target count_us */
|
||||
delta_sec = (double)(count_us - ref.count_us) / (TS_CPS * ref.xtal_err);
|
||||
|
||||
/* now add that delta to reference GPS time */
|
||||
fractpart = modf (delta_sec , &intpart);
|
||||
tmp = ref.gps.tv_nsec + (long)(fractpart * 1E9);
|
||||
if (tmp < (long)1E9) { /* the nanosecond part doesn't overflow */
|
||||
gps_time->tv_sec = ref.gps.tv_sec + (time_t)intpart;
|
||||
gps_time->tv_nsec = tmp;
|
||||
} else { /* must carry one second */
|
||||
gps_time->tv_sec = ref.gps.tv_sec + (time_t)intpart + 1;
|
||||
gps_time->tv_nsec = tmp - (long)1E9;
|
||||
}
|
||||
|
||||
return LGW_GPS_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_gps2cnt(struct tref ref, struct timespec gps_time, uint32_t *count_us) {
|
||||
double delta_sec;
|
||||
|
||||
CHECK_NULL(count_us);
|
||||
if ((ref.systime == 0) || (ref.xtal_err > PLUS_10PPM) || (ref.xtal_err < MINUS_10PPM)) {
|
||||
DEBUG_MSG("ERROR: INVALID REFERENCE FOR GPS -> CNT CONVERSION\n");
|
||||
return LGW_GPS_ERROR;
|
||||
}
|
||||
|
||||
/* calculate delta in seconds between reference gps time and target gps time */
|
||||
delta_sec = (double)(gps_time.tv_sec - ref.gps.tv_sec);
|
||||
delta_sec += 1E-9 * (double)(gps_time.tv_nsec - ref.gps.tv_nsec);
|
||||
|
||||
/* now convert that to internal counter tics and add that to reference counter value */
|
||||
*count_us = ref.count_us + (uint32_t)(delta_sec * TS_CPS * ref.xtal_err);
|
||||
|
||||
return LGW_GPS_SUCCESS;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
1048
libloragw/src/loragw_hal.c
Normal file
1048
libloragw/src/loragw_hal.c
Normal file
File diff suppressed because it is too large
Load diff
156
libloragw/src/loragw_i2c.c
Normal file
156
libloragw/src/loragw_i2c.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Host specific functions to address the LoRa concentrator I2C peripherals.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
#include <stdlib.h> /* malloc free */
|
||||
#include <unistd.h> /* lseek, close */
|
||||
#include <fcntl.h> /* open */
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
|
||||
#include "loragw_i2c.h"
|
||||
#include "loragw_aux.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#if DEBUG_I2C == 1
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
|
||||
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_SPI_ERROR;}
|
||||
#else
|
||||
#define DEBUG_MSG(str)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#define CHECK_NULL(a) if(a==NULL){return LGW_SPI_ERROR;}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
int i2c_linuxdev_open(const char *path, uint8_t device_addr, int *i2c_fd) {
|
||||
int dev;
|
||||
|
||||
/* Check input variables */
|
||||
if (path == NULL) {
|
||||
DEBUG_MSG("ERROR: null pointer path");
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
if (i2c_fd == NULL) {
|
||||
DEBUG_MSG("ERROR: null pointer i2c_fd");
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
/* Open I2C device */
|
||||
dev = open(path, O_RDWR);
|
||||
if (dev < 0) {
|
||||
DEBUG_PRINTF("ERROR: Failed to open I2C %s - %s", path, strerror(errno));
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
/* Setting I2C device mode to slave */
|
||||
if (ioctl(dev, I2C_SLAVE, device_addr) < 0) {
|
||||
DEBUG_PRINTF("ERROR: Failed to acquire bus access and/or talk to slave - %s\n", strerror(errno));
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
DEBUG_MSG("INFO: I2C port opened successfully");
|
||||
*i2c_fd = dev; /* return file descriptor index */
|
||||
|
||||
return LGW_I2C_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int i2c_linuxdev_read(int i2c_fd, uint8_t device_addr, uint8_t reg_addr, uint8_t *data) {
|
||||
uint8_t *inbuff, outbuff;
|
||||
struct i2c_rdwr_ioctl_data packets;
|
||||
struct i2c_msg messages[2];
|
||||
|
||||
outbuff = reg_addr;
|
||||
messages[0].addr = device_addr;
|
||||
messages[0].flags= 0;
|
||||
messages[0].len = sizeof(outbuff);
|
||||
messages[0].buf = &outbuff;
|
||||
|
||||
inbuff = data;
|
||||
messages[1].addr = device_addr;
|
||||
messages[1].flags = I2C_M_RD;
|
||||
messages[1].len = sizeof(*inbuff);
|
||||
messages[1].buf = inbuff;
|
||||
|
||||
packets.msgs = messages;
|
||||
packets.nmsgs = 2;
|
||||
|
||||
if (ioctl(i2c_fd, I2C_RDWR, &packets) < 0) {
|
||||
DEBUG_PRINTF("ERROR: Read from I2C Device failed (%d, 0x%02x, 0x%02x) - %s", i2c_fd, device_addr, reg_addr, strerror(errno));
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
return LGW_I2C_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int i2c_linuxdev_write(int i2c_fd, uint8_t device_addr, uint8_t reg_addr, uint8_t data) {
|
||||
unsigned char buff[2];
|
||||
struct i2c_rdwr_ioctl_data packets;
|
||||
struct i2c_msg messages[1];
|
||||
|
||||
buff[0] = reg_addr;
|
||||
buff[1] = data;
|
||||
|
||||
messages[0].addr = device_addr;
|
||||
messages[0].flags = 0;
|
||||
messages[0].len = sizeof(buff);
|
||||
messages[0].buf = buff;
|
||||
|
||||
packets.msgs = messages;
|
||||
packets.nmsgs = 1;
|
||||
|
||||
if (ioctl(i2c_fd, I2C_RDWR, &packets) < 0) {
|
||||
DEBUG_PRINTF("ERROR: Write to I2C Device failed (%d, 0x%02x, 0x%02x) - %s", i2c_fd, device_addr, reg_addr, strerror(errno));
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
return LGW_I2C_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int i2c_linuxdev_close(int i2c_fd) {
|
||||
int i;
|
||||
|
||||
i = close(i2c_fd);
|
||||
if (i == 0) {
|
||||
DEBUG_MSG("INFO: I2C port closed successfully");
|
||||
return LGW_I2C_SUCCESS;
|
||||
} else {
|
||||
DEBUG_PRINTF("ERROR: Failed to close I2C - %s", strerror(errno));
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
1501
libloragw/src/loragw_reg.c
Normal file
1501
libloragw/src/loragw_reg.c
Normal file
File diff suppressed because it is too large
Load diff
352
libloragw/src/loragw_spi.c
Normal file
352
libloragw/src/loragw_spi.c
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Host specific functions to address the LoRa concentrator registers through
|
||||
a SPI interface.
|
||||
Single-byte read/write and burst read/write.
|
||||
Could be used with multiple SPI ports in parallel (explicit file descriptor)
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
#include <stdlib.h> /* malloc free */
|
||||
#include <unistd.h> /* lseek, close */
|
||||
#include <fcntl.h> /* open */
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "loragw_spi.h"
|
||||
#include "loragw_aux.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#if DEBUG_SPI == 1
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
|
||||
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_SPI_ERROR;}
|
||||
#else
|
||||
#define DEBUG_MSG(str)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#define CHECK_NULL(a) if(a==NULL){return LGW_SPI_ERROR;}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define READ_ACCESS 0x00
|
||||
#define WRITE_ACCESS 0x80
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
/* SPI initialization and configuration */
|
||||
int lgw_spi_open(const char * spidev_path, void **spi_target_ptr) {
|
||||
int *spi_device = NULL;
|
||||
int dev;
|
||||
int a=0, b=0;
|
||||
int i;
|
||||
|
||||
/* check input variables */
|
||||
CHECK_NULL(spi_target_ptr); /* cannot be null, must point on a void pointer (*spi_target_ptr can be null) */
|
||||
|
||||
/* allocate memory for the device descriptor */
|
||||
spi_device = malloc(sizeof(int));
|
||||
if (spi_device == NULL) {
|
||||
DEBUG_MSG("ERROR: MALLOC FAIL\n");
|
||||
return LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
/* open SPI device */
|
||||
dev = open(spidev_path, O_RDWR);
|
||||
if (dev < 0) {
|
||||
DEBUG_PRINTF("ERROR: failed to open SPI device %s\n", spidev_path);
|
||||
return LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
/* setting SPI mode to 'mode 0' */
|
||||
i = SPI_MODE_0;
|
||||
a = ioctl(dev, SPI_IOC_WR_MODE, &i);
|
||||
b = ioctl(dev, SPI_IOC_RD_MODE, &i);
|
||||
if ((a < 0) || (b < 0)) {
|
||||
DEBUG_MSG("ERROR: SPI PORT FAIL TO SET IN MODE 0\n");
|
||||
close(dev);
|
||||
free(spi_device);
|
||||
return LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
/* setting SPI max clk (in Hz) */
|
||||
i = SPI_SPEED;
|
||||
a = ioctl(dev, SPI_IOC_WR_MAX_SPEED_HZ, &i);
|
||||
b = ioctl(dev, SPI_IOC_RD_MAX_SPEED_HZ, &i);
|
||||
if ((a < 0) || (b < 0)) {
|
||||
DEBUG_MSG("ERROR: SPI PORT FAIL TO SET MAX SPEED\n");
|
||||
close(dev);
|
||||
free(spi_device);
|
||||
return LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
/* setting SPI to MSB first */
|
||||
i = 0;
|
||||
a = ioctl(dev, SPI_IOC_WR_LSB_FIRST, &i);
|
||||
b = ioctl(dev, SPI_IOC_RD_LSB_FIRST, &i);
|
||||
if ((a < 0) || (b < 0)) {
|
||||
DEBUG_MSG("ERROR: SPI PORT FAIL TO SET MSB FIRST\n");
|
||||
close(dev);
|
||||
free(spi_device);
|
||||
return LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
/* setting SPI to 8 bits per word */
|
||||
i = 0;
|
||||
a = ioctl(dev, SPI_IOC_WR_BITS_PER_WORD, &i);
|
||||
b = ioctl(dev, SPI_IOC_RD_BITS_PER_WORD, &i);
|
||||
if ((a < 0) || (b < 0)) {
|
||||
DEBUG_MSG("ERROR: SPI PORT FAIL TO SET 8 BITS-PER-WORD\n");
|
||||
close(dev);
|
||||
return LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
*spi_device = dev;
|
||||
*spi_target_ptr = (void *)spi_device;
|
||||
DEBUG_MSG("Note: SPI port opened and configured ok\n");
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/* SPI release */
|
||||
int lgw_spi_close(void *spi_target) {
|
||||
int spi_device;
|
||||
int a;
|
||||
|
||||
/* check input variables */
|
||||
CHECK_NULL(spi_target);
|
||||
|
||||
/* close file & deallocate file descriptor */
|
||||
spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */
|
||||
a = close(spi_device);
|
||||
free(spi_target);
|
||||
|
||||
/* determine return code */
|
||||
if (a < 0) {
|
||||
DEBUG_MSG("ERROR: SPI PORT FAILED TO CLOSE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
DEBUG_MSG("Note: SPI port closed\n");
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/* Simple write */
|
||||
int lgw_spi_w(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t data) {
|
||||
int spi_device;
|
||||
uint8_t out_buf[4];
|
||||
uint8_t command_size;
|
||||
struct spi_ioc_transfer k;
|
||||
int a;
|
||||
|
||||
/* check input variables */
|
||||
CHECK_NULL(spi_target);
|
||||
|
||||
spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */
|
||||
|
||||
/* prepare frame to be sent */
|
||||
out_buf[0] = spi_mux_target;
|
||||
out_buf[1] = WRITE_ACCESS | ((address >> 8) & 0x7F);
|
||||
out_buf[2] = ((address >> 0) & 0xFF);
|
||||
out_buf[3] = data;
|
||||
command_size = 4;
|
||||
|
||||
/* I/O transaction */
|
||||
memset(&k, 0, sizeof(k)); /* clear k */
|
||||
k.tx_buf = (unsigned long) out_buf;
|
||||
k.len = command_size;
|
||||
k.speed_hz = SPI_SPEED;
|
||||
k.cs_change = 0;
|
||||
k.bits_per_word = 8;
|
||||
a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
|
||||
|
||||
/* determine return code */
|
||||
if (a != (int)k.len) {
|
||||
DEBUG_MSG("ERROR: SPI WRITE FAILURE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
DEBUG_MSG("Note: SPI write success\n");
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/* Simple read */
|
||||
int lgw_spi_r(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t *data) {
|
||||
int spi_device;
|
||||
uint8_t out_buf[5];
|
||||
uint8_t command_size;
|
||||
uint8_t in_buf[ARRAY_SIZE(out_buf)];
|
||||
struct spi_ioc_transfer k;
|
||||
int a;
|
||||
|
||||
/* check input variables */
|
||||
CHECK_NULL(spi_target);
|
||||
CHECK_NULL(data);
|
||||
|
||||
spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */
|
||||
|
||||
/* prepare frame to be sent */
|
||||
out_buf[0] = spi_mux_target;
|
||||
out_buf[1] = READ_ACCESS | ((address >> 8) & 0x7F);
|
||||
out_buf[2] = ((address >> 0) & 0xFF);
|
||||
out_buf[3] = 0x00;
|
||||
out_buf[4] = 0x00;
|
||||
command_size = 5;
|
||||
|
||||
/* I/O transaction */
|
||||
memset(&k, 0, sizeof(k)); /* clear k */
|
||||
k.tx_buf = (unsigned long) out_buf;
|
||||
k.rx_buf = (unsigned long) in_buf;
|
||||
k.len = command_size;
|
||||
k.cs_change = 0;
|
||||
a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
|
||||
|
||||
/* determine return code */
|
||||
if (a != (int)k.len) {
|
||||
DEBUG_MSG("ERROR: SPI READ FAILURE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
DEBUG_MSG("Note: SPI read success\n");
|
||||
*data = in_buf[command_size - 1];
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/* Burst (multiple-byte) write */
|
||||
int lgw_spi_wb(void *spi_target, uint8_t spi_mux_target, uint16_t address, const uint8_t *data, uint16_t size) {
|
||||
int spi_device;
|
||||
uint8_t command[3];
|
||||
uint8_t command_size;
|
||||
struct spi_ioc_transfer k[2];
|
||||
int size_to_do, chunk_size, offset;
|
||||
int byte_transfered = 0;
|
||||
int i;
|
||||
|
||||
/* check input parameters */
|
||||
CHECK_NULL(spi_target);
|
||||
CHECK_NULL(data);
|
||||
if (size == 0) {
|
||||
DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n");
|
||||
return LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */
|
||||
|
||||
/* prepare command byte */
|
||||
command[0] = spi_mux_target;
|
||||
command[1] = WRITE_ACCESS | ((address >> 8) & 0x7F);
|
||||
command[2] = ((address >> 0) & 0xFF);
|
||||
command_size = 3;
|
||||
size_to_do = size;
|
||||
|
||||
/* I/O transaction */
|
||||
memset(&k, 0, sizeof(k)); /* clear k */
|
||||
k[0].tx_buf = (unsigned long) &command[0];
|
||||
k[0].len = command_size;
|
||||
k[0].cs_change = 0;
|
||||
k[1].cs_change = 0;
|
||||
for (i=0; size_to_do > 0; ++i) {
|
||||
chunk_size = (size_to_do < LGW_BURST_CHUNK) ? size_to_do : LGW_BURST_CHUNK;
|
||||
offset = i * LGW_BURST_CHUNK;
|
||||
k[1].tx_buf = (unsigned long)(data + offset);
|
||||
k[1].len = chunk_size;
|
||||
byte_transfered += (ioctl(spi_device, SPI_IOC_MESSAGE(2), &k) - k[0].len );
|
||||
DEBUG_PRINTF("BURST WRITE: to trans %d # chunk %d # transferred %d \n", size_to_do, chunk_size, byte_transfered);
|
||||
size_to_do -= chunk_size; /* subtract the quantity of data already transferred */
|
||||
}
|
||||
|
||||
/* determine return code */
|
||||
if (byte_transfered != size) {
|
||||
DEBUG_MSG("ERROR: SPI BURST WRITE FAILURE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
DEBUG_MSG("Note: SPI burst write success\n");
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
/* Burst (multiple-byte) read */
|
||||
int lgw_spi_rb(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t *data, uint16_t size) {
|
||||
int spi_device;
|
||||
uint8_t command[4];
|
||||
uint8_t command_size;
|
||||
struct spi_ioc_transfer k[2];
|
||||
int size_to_do, chunk_size, offset;
|
||||
int byte_transfered = 0;
|
||||
int i;
|
||||
|
||||
/* check input parameters */
|
||||
CHECK_NULL(spi_target);
|
||||
CHECK_NULL(data);
|
||||
if (size == 0) {
|
||||
DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n");
|
||||
return LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */
|
||||
|
||||
/* prepare command byte */
|
||||
command[0] = spi_mux_target;
|
||||
command[1] = READ_ACCESS | ((address >> 8) & 0x7F);
|
||||
command[2] = ((address >> 0) & 0xFF);
|
||||
command[3] = 0x00;
|
||||
command_size = 4;
|
||||
size_to_do = size;
|
||||
|
||||
/* I/O transaction */
|
||||
memset(&k, 0, sizeof(k)); /* clear k */
|
||||
k[0].tx_buf = (unsigned long) &command[0];
|
||||
k[0].len = command_size;
|
||||
k[0].cs_change = 0;
|
||||
k[1].cs_change = 0;
|
||||
for (i=0; size_to_do > 0; ++i) {
|
||||
chunk_size = (size_to_do < LGW_BURST_CHUNK) ? size_to_do : LGW_BURST_CHUNK;
|
||||
offset = i * LGW_BURST_CHUNK;
|
||||
k[1].rx_buf = (unsigned long)(data + offset);
|
||||
k[1].len = chunk_size;
|
||||
byte_transfered += (ioctl(spi_device, SPI_IOC_MESSAGE(2), &k) - k[0].len );
|
||||
DEBUG_PRINTF("BURST READ: to trans %d # chunk %d # transferred %d \n", size_to_do, chunk_size, byte_transfered);
|
||||
size_to_do -= chunk_size; /* subtract the quantity of data already transferred */
|
||||
}
|
||||
|
||||
/* determine return code */
|
||||
if (byte_transfered != size) {
|
||||
DEBUG_MSG("ERROR: SPI BURST READ FAILURE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
DEBUG_MSG("Note: SPI burst read success\n");
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
213
libloragw/src/loragw_stts751.c
Normal file
213
libloragw/src/loragw_stts751.c
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Basic driver for ST ts751 temperature sensor
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdbool.h> /* bool type */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
|
||||
#include "loragw_i2c.h"
|
||||
#include "loragw_stts751.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#if DEBUG_I2C == 1
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
|
||||
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;}
|
||||
#else
|
||||
#define DEBUG_MSG(str)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define STTS751_REG_TEMP_H 0x00
|
||||
#define STTS751_REG_STATUS 0x01
|
||||
#define STTS751_STATUS_TRIPT BIT(0)
|
||||
#define STTS751_STATUS_TRIPL BIT(5)
|
||||
#define STTS751_STATUS_TRIPH BIT(6)
|
||||
#define STTS751_REG_TEMP_L 0x02
|
||||
#define STTS751_REG_CONF 0x03
|
||||
#define STTS751_CONF_RES_MASK 0x0C
|
||||
#define STTS751_CONF_RES_SHIFT 2
|
||||
#define STTS751_CONF_EVENT_DIS BIT(7)
|
||||
#define STTS751_CONF_STOP BIT(6)
|
||||
#define STTS751_REG_RATE 0x04
|
||||
#define STTS751_REG_HLIM_H 0x05
|
||||
#define STTS751_REG_HLIM_L 0x06
|
||||
#define STTS751_REG_LLIM_H 0x07
|
||||
#define STTS751_REG_LLIM_L 0x08
|
||||
#define STTS751_REG_TLIM 0x20
|
||||
#define STTS751_REG_HYST 0x21
|
||||
#define STTS751_REG_SMBUS_TO 0x22
|
||||
|
||||
#define STTS751_REG_PROD_ID 0xFD
|
||||
#define STTS751_REG_MAN_ID 0xFE
|
||||
#define STTS751_REG_REV_ID 0xFF
|
||||
|
||||
#define STTS751_0_PROD_ID 0x00
|
||||
#define STTS751_1_PROD_ID 0x01
|
||||
#define ST_MAN_ID 0x53
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- INTERNAL SHARED VARIABLES -------------------------------------------- */
|
||||
|
||||
extern int lgw_i2c_target;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
int stts751_configure( int i2c_fd )
|
||||
{
|
||||
int err;
|
||||
uint8_t val;
|
||||
|
||||
/* Check Input Params */
|
||||
if( i2c_fd <= 0 )
|
||||
{
|
||||
printf( "ERROR: invalid I2C file descriptor\n" );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
DEBUG_MSG("INFO: configuring STTS751 temperature sensor...\n");
|
||||
|
||||
/* Get product ID */
|
||||
err = i2c_linuxdev_read( i2c_fd, I2C_PORT_TEMP_SENSOR, STTS751_REG_PROD_ID, &val );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", I2C_PORT_TEMP_SENSOR, err );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
switch( val )
|
||||
{
|
||||
case STTS751_0_PROD_ID:
|
||||
DEBUG_MSG("INFO: Product ID: STTS751-0\n");
|
||||
break;
|
||||
case STTS751_1_PROD_ID:
|
||||
DEBUG_MSG("INFO: Product ID: STTS751-1\n");
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: Product ID: UNKNOWN\n");
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
/* Get Manufacturer ID */
|
||||
err = i2c_linuxdev_read( i2c_fd, I2C_PORT_TEMP_SENSOR, STTS751_REG_MAN_ID, &val );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", I2C_PORT_TEMP_SENSOR, err );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
if ( val != ST_MAN_ID )
|
||||
{
|
||||
printf( "ERROR: Manufacturer ID: UNKNOWN\n" );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINTF("INFO: Manufacturer ID: 0x%02X\n", val);
|
||||
}
|
||||
|
||||
/* Get revision number */
|
||||
err = i2c_linuxdev_read( i2c_fd, I2C_PORT_TEMP_SENSOR, STTS751_REG_REV_ID, &val );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", I2C_PORT_TEMP_SENSOR, err );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
DEBUG_PRINTF("INFO: Revision number: 0x%02X\n", val);
|
||||
|
||||
/* Set conversion resolution to 12 bits */
|
||||
err = i2c_linuxdev_write( i2c_fd, I2C_PORT_TEMP_SENSOR, STTS751_REG_CONF, 0x8C ); /* TODO: do not hardcode the whole byte */
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to write I2C device 0x%02X (err=%i)\n", I2C_PORT_TEMP_SENSOR, err );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
/* Set conversion rate to 1 / second */
|
||||
err = i2c_linuxdev_write( i2c_fd, I2C_PORT_TEMP_SENSOR, STTS751_REG_RATE, 0x04 );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to write I2C device 0x%02X (err=%i)\n", I2C_PORT_TEMP_SENSOR, err );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
return LGW_I2C_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int stts751_get_temperature( int i2c_fd, float * temperature)
|
||||
{
|
||||
int err;
|
||||
uint8_t high_byte, low_byte;
|
||||
int8_t h;
|
||||
|
||||
/* Check Input Params */
|
||||
if( i2c_fd <= 0 )
|
||||
{
|
||||
printf( "ERROR: invalid I2C file descriptor\n" );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
/* Read Temperature LSB */
|
||||
err = i2c_linuxdev_read( i2c_fd, I2C_PORT_TEMP_SENSOR, STTS751_REG_TEMP_L, &low_byte );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", I2C_PORT_TEMP_SENSOR, err );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
/* Read Temperature MSB */
|
||||
err = i2c_linuxdev_read( i2c_fd, I2C_PORT_TEMP_SENSOR, STTS751_REG_TEMP_H, &high_byte );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", I2C_PORT_TEMP_SENSOR, err );
|
||||
return LGW_I2C_ERROR;
|
||||
}
|
||||
|
||||
h = (int8_t)high_byte;
|
||||
*temperature = ((h << 8) | low_byte) / 256.0;
|
||||
|
||||
DEBUG_PRINTF("Temperature: %f C (h:0x%02X l:0x%02X)\n", *temperature, high_byte, low_byte);
|
||||
|
||||
return LGW_I2C_SUCCESS;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
int lgw_stts751_configure(void) {
|
||||
return stts751_configure(lgw_i2c_target);
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_stts751_get_temperature(float * temperature) {
|
||||
return stts751_get_temperature(lgw_i2c_target, temperature);
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
285
libloragw/src/loragw_sx1250.c
Normal file
285
libloragw/src/loragw_sx1250.c
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Functions used to handle LoRa concentrator SX1250 radios.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
#include <stdlib.h> /* malloc free */
|
||||
#include <unistd.h> /* lseek, close */
|
||||
#include <fcntl.h> /* open */
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "loragw_spi.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_sx1250.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#if DEBUG_RAD == 1
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
|
||||
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_SPI_ERROR;}
|
||||
#else
|
||||
#define DEBUG_MSG(str)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#define CHECK_NULL(a) if(a==NULL){return LGW_SPI_ERROR;}
|
||||
#endif
|
||||
|
||||
#define SX1250_FREQ_TO_REG(f) (uint32_t)((uint64_t)f * (1 << 25) / 32000000U)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define WAIT_BUSY_SX1250_MS 1
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- INTERNAL SHARED VARIABLES -------------------------------------------- */
|
||||
|
||||
extern void *lgw_spi_target; /*! generic pointer to the SPI device */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
int sx1250_write_command(uint8_t rf_chain, sx1250_op_code_t op_code, uint8_t *data, uint16_t size) {
|
||||
int spi_device;
|
||||
int cmd_size = 2; /* header + op_code */
|
||||
uint8_t out_buf[cmd_size + size];
|
||||
uint8_t command_size;
|
||||
struct spi_ioc_transfer k;
|
||||
int a, i;
|
||||
|
||||
/* wait BUSY */
|
||||
wait_ms(WAIT_BUSY_SX1250_MS);
|
||||
|
||||
/* check input variables */
|
||||
CHECK_NULL(lgw_spi_target);
|
||||
|
||||
spi_device = *(int *)lgw_spi_target; /* must check that spi_target is not null beforehand */
|
||||
|
||||
/* prepare frame to be sent */
|
||||
out_buf[0] = (rf_chain == 0) ? LGW_SPI_MUX_TARGET_RADIOA : LGW_SPI_MUX_TARGET_RADIOB;
|
||||
out_buf[1] = (uint8_t)op_code;
|
||||
for(i = 0; i < (int)size; i++) {
|
||||
out_buf[cmd_size + i] = data[i];
|
||||
}
|
||||
command_size = cmd_size + size;
|
||||
|
||||
/* I/O transaction */
|
||||
memset(&k, 0, sizeof(k)); /* clear k */
|
||||
k.tx_buf = (unsigned long) out_buf;
|
||||
k.len = command_size;
|
||||
k.speed_hz = SPI_SPEED;
|
||||
k.cs_change = 0;
|
||||
k.bits_per_word = 8;
|
||||
a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
|
||||
|
||||
/* determine return code */
|
||||
if (a != (int)k.len) {
|
||||
DEBUG_MSG("ERROR: SPI WRITE FAILURE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
DEBUG_MSG("Note: SPI write success\n");
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int sx1250_read_command(uint8_t rf_chain, sx1250_op_code_t op_code, uint8_t *data, uint16_t size) {
|
||||
int spi_device;
|
||||
int cmd_size = 2; /* header + op_code + NOP */
|
||||
uint8_t out_buf[cmd_size + size];
|
||||
uint8_t command_size;
|
||||
uint8_t in_buf[ARRAY_SIZE(out_buf)];
|
||||
struct spi_ioc_transfer k;
|
||||
int a, i;
|
||||
|
||||
/* wait BUSY */
|
||||
wait_ms(WAIT_BUSY_SX1250_MS);
|
||||
|
||||
/* check input variables */
|
||||
CHECK_NULL(lgw_spi_target);
|
||||
CHECK_NULL(data);
|
||||
|
||||
spi_device = *(int *)lgw_spi_target; /* must check that spi_target is not null beforehand */
|
||||
|
||||
/* prepare frame to be sent */
|
||||
out_buf[0] = (rf_chain == 0) ? LGW_SPI_MUX_TARGET_RADIOA : LGW_SPI_MUX_TARGET_RADIOB;
|
||||
out_buf[1] = (uint8_t)op_code;
|
||||
for(i = 0; i < (int)size; i++) {
|
||||
out_buf[cmd_size + i] = data[i];
|
||||
}
|
||||
command_size = cmd_size + size;
|
||||
|
||||
/* I/O transaction */
|
||||
memset(&k, 0, sizeof(k)); /* clear k */
|
||||
k.tx_buf = (unsigned long) out_buf;
|
||||
k.rx_buf = (unsigned long) in_buf;
|
||||
k.len = command_size;
|
||||
k.cs_change = 0;
|
||||
a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
|
||||
|
||||
/* determine return code */
|
||||
if (a != (int)k.len) {
|
||||
DEBUG_MSG("ERROR: SPI READ FAILURE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
DEBUG_MSG("Note: SPI read success\n");
|
||||
//*data = in_buf[command_size - 1];
|
||||
memcpy(data, in_buf + cmd_size, size);
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int sx1250_calibrate(uint8_t rf_chain, uint32_t freq_hz) {
|
||||
uint8_t buff[16];
|
||||
|
||||
buff[0] = 0x00;
|
||||
sx1250_read_command(rf_chain, GET_STATUS, buff, 1);
|
||||
|
||||
/* Run calibration */
|
||||
if ((freq_hz > 430E6) && (freq_hz < 440E6)) {
|
||||
buff[0] = 0x6B;
|
||||
buff[1] = 0x6F;
|
||||
} else if ((freq_hz > 470E6) && (freq_hz < 510E6)) {
|
||||
buff[0] = 0x75;
|
||||
buff[1] = 0x81;
|
||||
} else if ((freq_hz > 779E6) && (freq_hz < 787E6)) {
|
||||
buff[0] = 0xC1;
|
||||
buff[1] = 0xC5;
|
||||
} else if ((freq_hz > 863E6) && (freq_hz < 870E6)) {
|
||||
buff[0] = 0xD7;
|
||||
buff[1] = 0xDB;
|
||||
} else if ((freq_hz > 902E6) && (freq_hz < 928E6)) {
|
||||
buff[0] = 0xE1;
|
||||
buff[1] = 0xE9;
|
||||
} else {
|
||||
printf("ERROR: failed to calibrate sx1250 radio, frequency range not supported (%u)\n", freq_hz);
|
||||
return -1;
|
||||
}
|
||||
sx1250_write_command(rf_chain, CALIBRATE_IMAGE, buff, 2);
|
||||
|
||||
/* Wait for calibration to complete */
|
||||
wait_ms(10);
|
||||
|
||||
buff[0] = 0x00;
|
||||
buff[1] = 0x00;
|
||||
buff[2] = 0x00;
|
||||
sx1250_read_command(rf_chain, GET_DEVICE_ERRORS, buff, 3);
|
||||
if (TAKE_N_BITS_FROM(buff[2], 4, 1) != 0) {
|
||||
printf("ERROR: sx1250 Image Calibration Error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int sx1250_setup(uint8_t rf_chain, uint32_t freq_hz) {
|
||||
int32_t freq_reg;
|
||||
uint8_t buff[16];
|
||||
|
||||
/* Set Radio in Standby mode */
|
||||
buff[0] = (uint8_t)STDBY_XOSC;
|
||||
sx1250_write_command(rf_chain, SET_STANDBY, buff, 1);
|
||||
wait_ms(10);
|
||||
|
||||
buff[0] = 0x00;
|
||||
sx1250_read_command(rf_chain, GET_STATUS, buff, 1);
|
||||
|
||||
/* Set Bitrate to maximum (to lower TX to FS switch time) */
|
||||
buff[0] = 0x06;
|
||||
buff[1] = 0xA1;
|
||||
buff[2] = 0x01;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3);
|
||||
buff[0] = 0x06;
|
||||
buff[1] = 0xA2;
|
||||
buff[2] = 0x00;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3);
|
||||
buff[0] = 0x06;
|
||||
buff[1] = 0xA3;
|
||||
buff[2] = 0x00;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3);
|
||||
|
||||
/* Configure DIO for Rx */
|
||||
buff[0] = 0x05;
|
||||
buff[1] = 0x82;
|
||||
buff[2] = 0x00;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3); /* Drive strength to min */
|
||||
buff[0] = 0x05;
|
||||
buff[1] = 0x83;
|
||||
buff[2] = 0x00;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3); /* Input enable, all disabled */
|
||||
buff[0] = 0x05;
|
||||
buff[1] = 0x84;
|
||||
buff[2] = 0x00;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3); /* No pull up */
|
||||
buff[0] = 0x05;
|
||||
buff[1] = 0x85;
|
||||
buff[2] = 0x00;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3); /* No pull down */
|
||||
buff[0] = 0x05;
|
||||
buff[1] = 0x80;
|
||||
buff[2] = 0x00;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3); /* Output enable, all enabled */
|
||||
|
||||
/* Set fix gain (??) */
|
||||
buff[0] = 0x08;
|
||||
buff[1] = 0xB6;
|
||||
buff[2] = 0x2A;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3);
|
||||
|
||||
/* Set frequency */
|
||||
freq_reg = SX1250_FREQ_TO_REG(freq_hz);
|
||||
buff[0] = (uint8_t)(freq_reg >> 24);
|
||||
buff[1] = (uint8_t)(freq_reg >> 16);
|
||||
buff[2] = (uint8_t)(freq_reg >> 8);
|
||||
buff[3] = (uint8_t)(freq_reg >> 0);
|
||||
sx1250_write_command(rf_chain, SET_RF_FREQUENCY, buff, 4);
|
||||
|
||||
/* Set frequency offset to 0 */
|
||||
buff[0] = 0x08;
|
||||
buff[1] = 0x8F;
|
||||
buff[2] = 0x00;
|
||||
buff[3] = 0x00;
|
||||
buff[4] = 0x00;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 5);
|
||||
|
||||
/* Set Radio in Rx mode, necessary to give a clock to SX1302 */
|
||||
buff[0] = 0xFF;
|
||||
buff[1] = 0xFF;
|
||||
buff[2] = 0xFF;
|
||||
sx1250_write_command(rf_chain, SET_RX, buff, 3); /* Rx Continuous */
|
||||
|
||||
buff[0] = 0x05;
|
||||
buff[1] = 0x87;
|
||||
buff[2] = 0x0B;
|
||||
sx1250_write_command(rf_chain, WRITE_REGISTER, buff, 3); /* FPGA_MODE_RX */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
384
libloragw/src/loragw_sx125x.c
Normal file
384
libloragw/src/loragw_sx125x.c
Normal file
|
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Functions used to handle LoRa concentrator SX1255/SX1257 radios.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdbool.h> /* bool type */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
#include <string.h> /* memset */
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "loragw_sx125x.h"
|
||||
#include "loragw_spi.h"
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_hal.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#if DEBUG_RAD == 1
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
|
||||
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;}
|
||||
#else
|
||||
#define DEBUG_MSG(str)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE TYPES -------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define PLL_LOCK_MAX_ATTEMPTS 5
|
||||
|
||||
#define READ_ACCESS 0x00
|
||||
#define WRITE_ACCESS 0x80
|
||||
|
||||
static const struct radio_reg_s sx125x_regs[RADIO_TOTALREGS] = {
|
||||
{0,0,8}, /* MODE */
|
||||
{0,3,1}, /* MODE__PA_DRIVER_EN */
|
||||
{0,2,1}, /* MODE__TX_EN */
|
||||
{0,1,1}, /* MODE__RX_EN */
|
||||
{0,0,1}, /* MODE__STANDBY_EN */
|
||||
{1,0,8}, /* FRF_RX_MSB */
|
||||
{2,0,8}, /* FRF_RX_MID */
|
||||
{3,0,8}, /* FRF_RX_LSB */
|
||||
{4,0,8}, /* FRF_TX_MSB */
|
||||
{5,0,8}, /* FRF_TX_MID */
|
||||
{6,0,8}, /* FRF_TX_LSB */
|
||||
{7,0,8}, /* VERSION */
|
||||
{8,0,8}, /* TX_GAIN */
|
||||
{8,4,3}, /* TX_GAIN__DAC_GAIN */
|
||||
{8,0,4}, /* TX_GAIN__MIX_GAIN */
|
||||
{10,0,8}, /* TX_BW */
|
||||
{10,5,2}, /* TX_BW__PLL_BW */
|
||||
{10,0,5}, /* TX_BW__ANA_BW */
|
||||
{11,0,8}, /* TX_DAC_BW */
|
||||
{12,0,8}, /* RX_ANA_GAIN */
|
||||
{12,5,3}, /* RX_ANA_GAIN__LNA_GAIN */
|
||||
{12,1,4}, /* RX_ANA_GAIN__BB_GAIN */
|
||||
{12,0,1}, /* RX_ANA_GAIN__LNA_ZIN */
|
||||
{13,0,8}, /* RX_BW */
|
||||
{13,5,3}, /* RX_BW__ADC_BW */
|
||||
{13,2,3}, /* RX_BW__ADC_TRIM */
|
||||
{13,0,2}, /* RX_BW__BB_BW */
|
||||
{14,0,8}, /* RX_PLL_BW */
|
||||
{14,1,2}, /* RX_PLL_BW__PLL_BW */
|
||||
{14,0,1}, /* RX_PLL_BW__ADC_TEMP_EN */
|
||||
{15,0,8}, /* DIO_MAPPING */
|
||||
{15,6,2}, /* DIO_MAPPING__DIO_0_MAPPING */
|
||||
{15,4,2}, /* DIO_MAPPING__DIO_1_MAPPING */
|
||||
{15,2,2}, /* DIO_MAPPING__DIO_2_MAPPING */
|
||||
{15,0,2}, /* DIO_MAPPING__DIO_3_MAPPING */
|
||||
{16,0,8}, /* CLK_SELECT */
|
||||
{16,3,1}, /* CLK_SELECT__DIG_LOOPBACK_EN */
|
||||
{16,2,1}, /* CLK_SELECT__RF_LOOPBACK_EN */
|
||||
{16,1,1}, /* CLK_SELECT__CLK_OUT */
|
||||
{16,0,1}, /* CLK_SELECT__DAC_CLK_SELECT */
|
||||
{17,0,8}, /* MODE_STATUS */
|
||||
{17,2,1}, /* MODE_STATUS__LOW_BAT_EN */
|
||||
{17,1,1}, /* MODE_STATUS__RX_PLL_LOCKED */
|
||||
{17,0,1}, /* MODE_STATUS__TX_PLL_LOCKED */
|
||||
{26,0,8}, /* LOW_BAT_THRESH */
|
||||
{38,0,8}, /* SX1257_XOSC_TEST */
|
||||
{38,4,3}, /* SX1257_XOSC_TEST__DISABLE */
|
||||
{38,0,4}, /* SX1257_XOSC_TEST__GM_STARTUP */
|
||||
{40,0,8}, /* SX1255_XOSC_TEST */
|
||||
{40,4,3}, /* SX1255_XOSC_TEST__DISABLE */
|
||||
{40,0,4} /* SX1255_XOSC_TEST__GM_STARTUP */
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
extern void *lgw_spi_target; /*! generic pointer to the SPI device */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
/* Simple read */
|
||||
int sx125x_reg_r(void *spi_target, uint8_t spi_mux_target, uint8_t address, uint8_t *data) {
|
||||
int spi_device;
|
||||
uint8_t out_buf[3];
|
||||
uint8_t command_size;
|
||||
uint8_t in_buf[ARRAY_SIZE(out_buf)];
|
||||
struct spi_ioc_transfer k;
|
||||
int a;
|
||||
|
||||
/* check input variables */
|
||||
CHECK_NULL(spi_target);
|
||||
CHECK_NULL(data);
|
||||
|
||||
spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */
|
||||
|
||||
/* prepare frame to be sent */
|
||||
out_buf[0] = spi_mux_target;
|
||||
out_buf[1] = READ_ACCESS | (address & 0x7F);
|
||||
out_buf[2] = 0x00;
|
||||
command_size = 3;
|
||||
|
||||
/* I/O transaction */
|
||||
memset(&k, 0, sizeof(k)); /* clear k */
|
||||
k.tx_buf = (unsigned long) out_buf;
|
||||
k.rx_buf = (unsigned long) in_buf;
|
||||
k.len = command_size;
|
||||
k.cs_change = 0;
|
||||
a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
|
||||
|
||||
/* determine return code */
|
||||
if (a != (int)k.len) {
|
||||
DEBUG_MSG("ERROR: SPI READ FAILURE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
//DEBUG_MSG("Note: SPI read success\n");
|
||||
*data = in_buf[command_size - 1];
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int sx125x_reg_w(void *spi_target, uint8_t spi_mux_target, uint8_t address, uint8_t data) {
|
||||
int spi_device;
|
||||
uint8_t out_buf[3];
|
||||
uint8_t command_size;
|
||||
struct spi_ioc_transfer k;
|
||||
int a;
|
||||
|
||||
/* check input variables */
|
||||
CHECK_NULL(spi_target);
|
||||
|
||||
spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */
|
||||
|
||||
/* prepare frame to be sent */
|
||||
out_buf[0] = spi_mux_target;
|
||||
out_buf[1] = WRITE_ACCESS | (address & 0x7F);
|
||||
out_buf[2] = data;
|
||||
command_size = 3;
|
||||
|
||||
/* I/O transaction */
|
||||
memset(&k, 0, sizeof(k)); /* clear k */
|
||||
k.tx_buf = (unsigned long) out_buf;
|
||||
k.len = command_size;
|
||||
k.speed_hz = SPI_SPEED;
|
||||
k.cs_change = 0;
|
||||
k.bits_per_word = 8;
|
||||
a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
|
||||
|
||||
/* determine return code */
|
||||
if (a != (int)k.len) {
|
||||
DEBUG_MSG("ERROR: SPI WRITE FAILURE\n");
|
||||
return LGW_SPI_ERROR;
|
||||
} else {
|
||||
//DEBUG_MSG("Note: SPI write success\n");
|
||||
return LGW_SPI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_sx125x_reg_w(radio_reg_t idx, uint8_t data, uint8_t rf_chain) {
|
||||
|
||||
int spi_stat;
|
||||
struct radio_reg_s reg;
|
||||
uint8_t mask;
|
||||
uint8_t r;
|
||||
uint8_t w;
|
||||
uint8_t val_check;
|
||||
|
||||
/* checking input parameters */
|
||||
if (rf_chain >= LGW_RF_CHAIN_NB) {
|
||||
DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
if (idx >= RADIO_TOTALREGS) {
|
||||
DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n");
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
|
||||
reg = sx125x_regs[idx];
|
||||
|
||||
if ((reg.leng == 8) && (reg.offs == 0)){
|
||||
/* direct write */
|
||||
spi_stat = sx125x_reg_w(lgw_spi_target, ((rf_chain == 0) ? LGW_SPI_MUX_TARGET_RADIOA : LGW_SPI_MUX_TARGET_RADIOB), reg.addr, data);
|
||||
} else {
|
||||
/* read-modify-write */
|
||||
spi_stat = sx125x_reg_r(lgw_spi_target, ((rf_chain == 0) ? LGW_SPI_MUX_TARGET_RADIOA : LGW_SPI_MUX_TARGET_RADIOB), reg.addr, &r);
|
||||
mask = ((1 << reg.leng) - 1) << reg.offs;
|
||||
w = (r & ~mask) | ((data << reg.offs) & mask);
|
||||
spi_stat |= sx125x_reg_w(lgw_spi_target, ((rf_chain == 0) ? LGW_SPI_MUX_TARGET_RADIOA : LGW_SPI_MUX_TARGET_RADIOB), reg.addr, w);
|
||||
}
|
||||
|
||||
/* Check that we can read what we have written */
|
||||
lgw_sx125x_reg_r(idx, &val_check, rf_chain);
|
||||
if (val_check != data) {
|
||||
printf("ERROR: sx125x register %d write failed (w:%u r:%u)!!\n", idx, data, val_check);
|
||||
spi_stat = LGW_SPI_ERROR;
|
||||
}
|
||||
|
||||
if (spi_stat != LGW_SPI_SUCCESS) {
|
||||
DEBUG_MSG("ERROR: SPI ERROR DURING RADIO REGISTER WRITE\n");
|
||||
return LGW_REG_ERROR;
|
||||
} else {
|
||||
return LGW_REG_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int lgw_sx125x_reg_r(radio_reg_t idx, uint8_t *data, uint8_t rf_chain) {
|
||||
|
||||
int spi_stat;
|
||||
struct radio_reg_s reg;
|
||||
uint8_t mask;
|
||||
uint8_t r;
|
||||
|
||||
/* checking input parameters */
|
||||
if (rf_chain >= LGW_RF_CHAIN_NB) {
|
||||
DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
if (idx >= RADIO_TOTALREGS) {
|
||||
DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n");
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
|
||||
reg = sx125x_regs[idx];
|
||||
|
||||
spi_stat = sx125x_reg_r(lgw_spi_target, ((rf_chain == 0) ? LGW_SPI_MUX_TARGET_RADIOA : LGW_SPI_MUX_TARGET_RADIOB), reg.addr, &r);
|
||||
mask = ((1 << reg.leng) - 1) << reg.offs;
|
||||
*data = (r & mask) >> reg.offs;
|
||||
|
||||
if (spi_stat != LGW_SPI_SUCCESS) {
|
||||
DEBUG_MSG("ERROR: SPI ERROR DURING RADIO REGISTER READ\n");
|
||||
return LGW_REG_ERROR;
|
||||
} else {
|
||||
return LGW_REG_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
int sx125x_setup(uint8_t rf_chain, uint8_t rf_clkout, bool rf_enable, uint8_t rf_radio_type, uint32_t freq_hz) {
|
||||
uint32_t part_int = 0;
|
||||
uint32_t part_frac = 0;
|
||||
int cpt_attempts = 0;
|
||||
uint8_t val;
|
||||
|
||||
if (rf_chain >= LGW_RF_CHAIN_NB) {
|
||||
DEBUG_MSG("ERROR: INVALID RF_CHAIN\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get version to identify SX1255/57 silicon revision */
|
||||
lgw_sx125x_reg_r(SX125x_REG_VERSION, &val, rf_chain);
|
||||
DEBUG_PRINTF("Note: SX125x #%d version register returned 0x%02x\n", rf_chain, val);
|
||||
|
||||
/* General radio setup */
|
||||
if (rf_clkout == rf_chain) {
|
||||
lgw_sx125x_reg_w(SX125x_REG_CLK_SELECT, SX125x_TX_DAC_CLK_SEL + 2, rf_chain);
|
||||
DEBUG_PRINTF("Note: SX125x #%d clock output enabled\n", rf_chain);
|
||||
} else {
|
||||
lgw_sx125x_reg_w(SX125x_REG_CLK_SELECT, SX125x_TX_DAC_CLK_SEL, rf_chain);
|
||||
DEBUG_PRINTF("Note: SX125x #%d clock output disabled\n", rf_chain);
|
||||
}
|
||||
|
||||
switch (rf_radio_type) {
|
||||
case LGW_RADIO_TYPE_SX1255:
|
||||
lgw_sx125x_reg_w(SX125x_REG_SX1255_XOSC_TEST__GM_STARTUP, SX125x_XOSC_GM_STARTUP, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_SX1255_XOSC_TEST__DISABLE, SX125x_XOSC_DISABLE, rf_chain);
|
||||
break;
|
||||
case LGW_RADIO_TYPE_SX1257:
|
||||
lgw_sx125x_reg_w(SX125x_REG_SX1257_XOSC_TEST__GM_STARTUP, SX125x_XOSC_GM_STARTUP, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_SX1257_XOSC_TEST__DISABLE, SX125x_XOSC_DISABLE, rf_chain);
|
||||
break;
|
||||
default:
|
||||
DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d FOR RADIO TYPE\n", rf_radio_type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rf_enable == true) {
|
||||
/* Tx gain and trim */
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_GAIN__MIX_GAIN, SX125x_TX_MIX_GAIN, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_GAIN__DAC_GAIN, SX125x_TX_DAC_GAIN, rf_chain);
|
||||
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_BW__ANA_BW, SX125x_TX_ANA_BW, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_BW__PLL_BW, SX125x_TX_PLL_BW, rf_chain);
|
||||
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_DAC_BW, SX125x_TX_DAC_BW, rf_chain);
|
||||
|
||||
/* Rx gain and trim */
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_ANA_GAIN__LNA_ZIN, SX125x_LNA_ZIN, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_ANA_GAIN__BB_GAIN, SX125x_RX_BB_GAIN, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_ANA_GAIN__LNA_GAIN, SX125x_RX_LNA_GAIN, rf_chain);
|
||||
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_BW__BB_BW, SX125x_RX_BB_BW, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_BW__ADC_TRIM, SX125x_RX_ADC_TRIM, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_BW__ADC_BW, SX125x_RX_ADC_BW, rf_chain);
|
||||
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_PLL_BW__ADC_TEMP_EN, SX125x_ADC_TEMP, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_PLL_BW__PLL_BW, SX125x_RX_PLL_BW, rf_chain);
|
||||
|
||||
/* set RX PLL frequency */
|
||||
switch (rf_radio_type) {
|
||||
case LGW_RADIO_TYPE_SX1255:
|
||||
part_int = freq_hz / (SX125x_32MHz_FRAC << 7); /* integer part, gives the MSB */
|
||||
part_frac = ((freq_hz % (SX125x_32MHz_FRAC << 7)) << 9) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */
|
||||
break;
|
||||
case LGW_RADIO_TYPE_SX1257:
|
||||
part_int = freq_hz / (SX125x_32MHz_FRAC << 8); /* integer part, gives the MSB */
|
||||
part_frac = ((freq_hz % (SX125x_32MHz_FRAC << 8)) << 8) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */
|
||||
break;
|
||||
default:
|
||||
DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d FOR RADIO TYPE\n", rf_radio_type);
|
||||
break;
|
||||
}
|
||||
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_RX_MSB, 0xFF & part_int, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_RX_MID, 0xFF & (part_frac >> 8), rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_RX_LSB, 0xFF & part_frac, rf_chain);
|
||||
|
||||
/* start and PLL lock */
|
||||
do {
|
||||
if (cpt_attempts >= PLL_LOCK_MAX_ATTEMPTS) {
|
||||
DEBUG_MSG("ERROR: FAIL TO LOCK PLL\n");
|
||||
return -1;
|
||||
}
|
||||
lgw_sx125x_reg_w(SX125x_REG_MODE, 1, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_MODE, 3, rf_chain);
|
||||
++cpt_attempts;
|
||||
DEBUG_PRINTF("Note: SX125x #%d PLL start (attempt %d)\n", rf_chain, cpt_attempts);
|
||||
wait_ms(1);
|
||||
lgw_sx125x_reg_r(SX125x_REG_MODE_STATUS, &val, rf_chain);
|
||||
} while ((val & 0x02) == 0);
|
||||
} else {
|
||||
DEBUG_PRINTF("Note: SX125x #%d kept in standby mode\n", rf_chain);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
2317
libloragw/src/loragw_sx1302.c
Normal file
2317
libloragw/src/loragw_sx1302.c
Normal file
File diff suppressed because it is too large
Load diff
370
libloragw/src/loragw_sx1302_rx.c
Normal file
370
libloragw/src/loragw_sx1302_rx.c
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
SX1302 RX buffer Hardware Abstraction Layer
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
#include <string.h> /* memset */
|
||||
#include <assert.h> /* assert */
|
||||
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_sx1302_rx.h"
|
||||
#include "loragw_sx1302_timestamp.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#if DEBUG_SX1302 == 1
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr, fmt, args)
|
||||
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;}
|
||||
#else
|
||||
#define DEBUG_MSG(str)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;}
|
||||
#endif
|
||||
|
||||
#define SX1302_PKT_PAYLOAD_LENGTH(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 2], 0, 8)
|
||||
#define SX1302_PKT_CHANNEL(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 3], 0, 8)
|
||||
#define SX1302_PKT_CRC_EN(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 4], 0, 1)
|
||||
#define SX1302_PKT_CODING_RATE(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 4], 1, 3)
|
||||
#define SX1302_PKT_DATARATE(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 4], 4, 4)
|
||||
#define SX1302_PKT_MODEM_ID(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 5], 0, 8)
|
||||
#define SX1302_PKT_FREQ_OFFSET_7_0(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 6], 0, 8)
|
||||
#define SX1302_PKT_FREQ_OFFSET_15_8(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 7], 0, 8)
|
||||
#define SX1302_PKT_FREQ_OFFSET_19_16(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 8], 0, 4)
|
||||
#define SX1302_PKT_CRC_ERROR(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 9], 0, 1)
|
||||
#define SX1302_PKT_SYNC_ERROR(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 9], 2, 1)
|
||||
#define SX1302_PKT_HEADER_ERROR(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 9], 3, 1)
|
||||
#define SX1302_PKT_TIMING_SET(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 9], 4, 1)
|
||||
#define SX1302_PKT_SNR_AVG(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 10], 0, 8)
|
||||
#define SX1302_PKT_RSSI_CHAN(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 11], 0, 8)
|
||||
#define SX1302_PKT_RSSI_SIG(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 12], 0, 8)
|
||||
#define SX1302_PKT_RSSI_CHAN_MAX_NEG_DELTA(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 13], 0, 4)
|
||||
#define SX1302_PKT_RSSI_CHAN_MAX_POS_DELTA(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 13], 4, 4)
|
||||
#define SX1302_PKT_RSSI_SIG_MAX_NEG_DELTA(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 14], 0, 4)
|
||||
#define SX1302_PKT_RSSI_SIG_MAX_POS_DELTA(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 14], 4, 4)
|
||||
#define SX1302_PKT_TIMESTAMP_7_0(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 15], 0, 8)
|
||||
#define SX1302_PKT_TIMESTAMP_15_8(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 16], 0, 8)
|
||||
#define SX1302_PKT_TIMESTAMP_23_16(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 17], 0, 8)
|
||||
#define SX1302_PKT_TIMESTAMP_31_24(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 18], 0, 8)
|
||||
#define SX1302_PKT_CRC_PAYLOAD_7_0(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 19], 0, 8)
|
||||
#define SX1302_PKT_CRC_PAYLOAD_15_8(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 20], 0, 8)
|
||||
#define SX1302_PKT_NUM_TS_METRICS(buffer, start_index) TAKE_N_BITS_FROM(buffer[start_index + 21], 0, 8)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE TYPES -------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
/* RX buffer packet structure */
|
||||
#define SX1302_PKT_SYNCWORD_BYTE_0 0xA5
|
||||
#define SX1302_PKT_SYNCWORD_BYTE_1 0xC0
|
||||
#define SX1302_PKT_HEAD_METADATA 9
|
||||
#define SX1302_PKT_TAIL_METADATA 14
|
||||
|
||||
/* modem IDs */
|
||||
#if FPGA_BOARD_16_CH
|
||||
#define SX1302_LORA_MODEM_ID_MAX 15
|
||||
#define SX1302_LORA_STD_MODEM_ID 16
|
||||
#define SX1302_FSK_MODEM_ID 17
|
||||
#else
|
||||
#define SX1302_LORA_MODEM_ID_MAX 11
|
||||
#define SX1302_LORA_STD_MODEM_ID 12
|
||||
#define SX1302_FSK_MODEM_ID 13
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- INTERNAL SHARED VARIABLES -------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
int rx_buffer_new(rx_buffer_t * self) {
|
||||
/* Check input params */
|
||||
CHECK_NULL(self);
|
||||
|
||||
/* Initialize members */
|
||||
memset(self->buffer, 0, sizeof self->buffer);
|
||||
self->buffer_size = 0;
|
||||
self->buffer_index = 0;
|
||||
|
||||
return LGW_REG_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int rx_buffer_del(rx_buffer_t * self) {
|
||||
/* Check input params */
|
||||
CHECK_NULL(self);
|
||||
|
||||
/* Reset index & size */
|
||||
self->buffer_size = 0;
|
||||
self->buffer_index = 0;
|
||||
|
||||
return LGW_REG_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int rx_buffer_fetch(rx_buffer_t * self) {
|
||||
int i, res;
|
||||
uint8_t buff[2];
|
||||
|
||||
/* Check input params */
|
||||
CHECK_NULL(self);
|
||||
|
||||
/* Check if there is data in the FIFO */
|
||||
lgw_reg_rb(SX1302_REG_RX_TOP_RX_BUFFER_NB_BYTES_MSB_RX_BUFFER_NB_BYTES, buff, sizeof buff);
|
||||
self->buffer_size = (uint16_t)((buff[0] << 8) & 0xFF00);
|
||||
self->buffer_size |= (uint16_t)((buff[1] << 0) & 0x00FF);
|
||||
|
||||
/* Fetch bytes from fifo if any */
|
||||
if (self->buffer_size > 0) {
|
||||
DEBUG_MSG ("-----------------\n");
|
||||
DEBUG_PRINTF("%s: nb_bytes to be fetched: %u (%u %u)\n", __FUNCTION__, self->buffer_size, buff[1], buff[0]);
|
||||
|
||||
memset(self->buffer, 0, sizeof self->buffer);
|
||||
res = lgw_mem_rb(0x4000, self->buffer, self->buffer_size, true);
|
||||
if (res != LGW_REG_SUCCESS) {
|
||||
printf("ERROR: Failed to read RX buffer, SPI error\n");
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
|
||||
/* print debug info : TODO to be removed */
|
||||
DEBUG_MSG("RX_BUFFER: ");
|
||||
for (i = 0; i < self->buffer_size; i++) {
|
||||
DEBUG_PRINTF("%02X ", self->buffer[i]);
|
||||
}
|
||||
DEBUG_MSG("\n");
|
||||
|
||||
}
|
||||
|
||||
/* Initialize the current buffer index to iterate on */
|
||||
self->buffer_index = 0;
|
||||
|
||||
return LGW_REG_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int rx_buffer_pop(rx_buffer_t * self, rx_packet_t * pkt) {
|
||||
int i;
|
||||
uint8_t checksum_rcv, checksum_calc = 0;
|
||||
uint16_t checksum_idx;
|
||||
uint16_t pkt_num_bytes;
|
||||
|
||||
/* Check input params */
|
||||
CHECK_NULL(self);
|
||||
CHECK_NULL(pkt);
|
||||
|
||||
/* Is there any data to be parsed ? */
|
||||
if (self->buffer_index >= self->buffer_size) {
|
||||
DEBUG_MSG("INFO: No more data to be parsed\n");
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
|
||||
/* Get pkt sync words */
|
||||
if ((self->buffer[self->buffer_index] != SX1302_PKT_SYNCWORD_BYTE_0) || (self->buffer[self->buffer_index + 1] != SX1302_PKT_SYNCWORD_BYTE_1)) {
|
||||
printf("INFO: searching syncword...\n");
|
||||
self->buffer_index += 1;
|
||||
return LGW_REG_ERROR;
|
||||
/* TODO: while loop until syncword found ?? */
|
||||
}
|
||||
DEBUG_PRINTF("INFO: pkt syncword found at index %u\n", self->buffer_index);
|
||||
|
||||
/* Get payload length */
|
||||
pkt->rxbytenb_modem = SX1302_PKT_PAYLOAD_LENGTH(self->buffer, self->buffer_index);
|
||||
|
||||
/* Get fine timestamp metrics */
|
||||
pkt->num_ts_metrics_stored = SX1302_PKT_NUM_TS_METRICS(self->buffer, self->buffer_index + pkt->rxbytenb_modem);
|
||||
|
||||
/* Calculate the total number of bytes in the packet */
|
||||
pkt_num_bytes = SX1302_PKT_HEAD_METADATA + pkt->rxbytenb_modem + SX1302_PKT_TAIL_METADATA + (2 * pkt->num_ts_metrics_stored);
|
||||
|
||||
/* Check if we have a complete packet in the rx buffer fetched */
|
||||
if((self->buffer_index + pkt_num_bytes) > self->buffer_size) {
|
||||
printf("WARNING: aborting truncated message (size=%u)\n", self->buffer_size);
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
|
||||
/* Get the checksum as received in the RX buffer */
|
||||
checksum_idx = pkt_num_bytes - 1;
|
||||
checksum_rcv = self->buffer[self->buffer_index + pkt_num_bytes - 1];
|
||||
|
||||
/* Calculate the checksum from the actual payload bytes received */
|
||||
for (i = 0; i < (int)checksum_idx; i++) {
|
||||
checksum_calc += self->buffer[self->buffer_index + i];
|
||||
}
|
||||
|
||||
/* Check if the checksum is correct */
|
||||
if (checksum_rcv != checksum_calc) {
|
||||
printf("WARNING: checksum failed (got:0x%02X calc:0x%02X)\n", checksum_rcv, checksum_calc);
|
||||
return LGW_REG_ERROR;
|
||||
} else {
|
||||
DEBUG_PRINTF("Packet checksum OK (0x%02X)\n", checksum_rcv);
|
||||
}
|
||||
|
||||
/* Parse packet metadata */
|
||||
pkt->modem_id = SX1302_PKT_MODEM_ID(self->buffer, self->buffer_index);
|
||||
pkt->rx_channel_in = SX1302_PKT_CHANNEL(self->buffer, self->buffer_index);
|
||||
pkt->crc_en = SX1302_PKT_CRC_EN(self->buffer, self->buffer_index);
|
||||
pkt->payload_crc_error = SX1302_PKT_CRC_ERROR(self->buffer, self->buffer_index + pkt->rxbytenb_modem);
|
||||
pkt->sync_error = SX1302_PKT_SYNC_ERROR(self->buffer, self->buffer_index + pkt->rxbytenb_modem);
|
||||
pkt->header_error = SX1302_PKT_HEADER_ERROR(self->buffer, self->buffer_index + pkt->rxbytenb_modem);
|
||||
pkt->timing_set = SX1302_PKT_TIMING_SET(self->buffer, self->buffer_index + pkt->rxbytenb_modem);
|
||||
pkt->coding_rate = SX1302_PKT_CODING_RATE(self->buffer, self->buffer_index);
|
||||
pkt->rx_rate_sf = SX1302_PKT_DATARATE(self->buffer, self->buffer_index);
|
||||
pkt->rssi_chan_avg = SX1302_PKT_RSSI_CHAN(self->buffer, self->buffer_index + pkt->rxbytenb_modem);
|
||||
pkt->rssi_signal_avg = SX1302_PKT_RSSI_SIG(self->buffer, self->buffer_index + pkt->rxbytenb_modem);
|
||||
pkt->rx_crc16_value = (uint16_t)((SX1302_PKT_CRC_PAYLOAD_7_0(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 0) & 0x00FF);
|
||||
pkt->rx_crc16_value |= (uint16_t)((SX1302_PKT_CRC_PAYLOAD_15_8(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 8) & 0xFF00);
|
||||
pkt->snr_average = (int8_t)SX1302_PKT_SNR_AVG(self->buffer, self->buffer_index + pkt->rxbytenb_modem);
|
||||
|
||||
pkt->frequency_offset_error = (int32_t)((SX1302_PKT_FREQ_OFFSET_19_16(self->buffer, self->buffer_index) << 16) | (SX1302_PKT_FREQ_OFFSET_15_8(self->buffer, self->buffer_index) << 8) | (SX1302_PKT_FREQ_OFFSET_7_0(self->buffer, self->buffer_index) << 0));
|
||||
if (pkt->frequency_offset_error >= (1<<19)) { /* Handle signed value on 20bits */
|
||||
pkt->frequency_offset_error = (pkt->frequency_offset_error - (1<<20));
|
||||
}
|
||||
|
||||
/* Packet timestamp (32MHz ) */
|
||||
pkt->timestamp_cnt = (uint32_t)((SX1302_PKT_TIMESTAMP_7_0(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 0) & 0x000000FF);
|
||||
pkt->timestamp_cnt |= (uint32_t)((SX1302_PKT_TIMESTAMP_15_8(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 8) & 0x0000FF00);
|
||||
pkt->timestamp_cnt |= (uint32_t)((SX1302_PKT_TIMESTAMP_23_16(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 16) & 0x00FF0000);
|
||||
pkt->timestamp_cnt |= (uint32_t)((SX1302_PKT_TIMESTAMP_31_24(self->buffer, self->buffer_index + pkt->rxbytenb_modem) << 24) & 0xFF000000);
|
||||
|
||||
#if 0
|
||||
/* Scale packet timestamp to 1 MHz (microseconds) */
|
||||
pkt->timestamp_cnt /= 32;
|
||||
/* Expand 27-bits counter to 32-bits counter, based on current wrapping status */
|
||||
pkt->timestamp_cnt = timestamp_counter_expand(&counter_us, false, pkt->timestamp_cnt);
|
||||
#endif
|
||||
|
||||
DEBUG_MSG ("-----------------\n");
|
||||
DEBUG_PRINTF(" modem: %u\n", pkt->modem_id);
|
||||
DEBUG_PRINTF(" chan: %u\n", pkt->rx_channel_in);
|
||||
DEBUG_PRINTF(" size: %u\n", pkt->rxbytenb_modem);
|
||||
DEBUG_PRINTF(" crc_en: %u\n", pkt->crc_en);
|
||||
DEBUG_PRINTF(" crc_err: %u\n", pkt->payload_crc_error);
|
||||
DEBUG_PRINTF(" sync_err: %u\n", pkt->sync_error);
|
||||
DEBUG_PRINTF(" hdr_err: %u\n", pkt->header_error);
|
||||
DEBUG_PRINTF(" timing_set: %u\n", pkt->timing_set);
|
||||
DEBUG_PRINTF(" codr: %u\n", pkt->coding_rate);
|
||||
DEBUG_PRINTF(" datr: %u\n", pkt->rx_rate_sf);
|
||||
DEBUG_PRINTF(" num_ts: %u\n", pkt->num_ts_metrics_stored);
|
||||
DEBUG_MSG ("-----------------\n");
|
||||
|
||||
/* Sanity checks: check the range of few metadata */
|
||||
if (pkt->modem_id > SX1302_FSK_MODEM_ID) {
|
||||
printf("ERROR: modem_id is out of range - %u\n", pkt->modem_id);
|
||||
return LGW_REG_ERROR;
|
||||
} else {
|
||||
if (pkt->modem_id <= SX1302_LORA_STD_MODEM_ID) { /* LoRa modems */
|
||||
if (pkt->rx_channel_in > 9) {
|
||||
printf("ERROR: channel is out of range - %u\n", pkt->rx_channel_in);
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
if ((pkt->rx_rate_sf < 5) || (pkt->rx_rate_sf > 12)) {
|
||||
printf("ERROR: SF is out of range - %u\n", pkt->rx_rate_sf);
|
||||
return LGW_REG_ERROR;
|
||||
}
|
||||
} else { /* FSK modem */
|
||||
/* TODO: not checked */
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse & copy payload in packet struct */
|
||||
memcpy((void *)pkt->payload, (void *)(&(self->buffer[self->buffer_index + SX1302_PKT_HEAD_METADATA])), pkt->rxbytenb_modem);
|
||||
|
||||
/* move buffer index toward next message */
|
||||
self->buffer_index += (SX1302_PKT_HEAD_METADATA + pkt->rxbytenb_modem + SX1302_PKT_TAIL_METADATA + (2 * pkt->num_ts_metrics_stored));
|
||||
|
||||
return LGW_REG_SUCCESS;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEBUG FUNCTIONS DEFINITION ------------------------------------------- */
|
||||
|
||||
uint16_t rx_buffer_read_ptr_addr(void) {
|
||||
int32_t val;
|
||||
uint16_t addr;
|
||||
|
||||
lgw_reg_r(SX1302_REG_RX_TOP_RX_BUFFER_LAST_ADDR_READ_MSB_LAST_ADDR_READ, &val); /* mandatory to read MSB first */
|
||||
addr = (uint16_t)(val << 8);
|
||||
lgw_reg_r(SX1302_REG_RX_TOP_RX_BUFFER_LAST_ADDR_READ_LSB_LAST_ADDR_READ, &val);
|
||||
addr |= (uint16_t)val;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
uint16_t rx_buffer_write_ptr_addr(void) {
|
||||
int32_t val;
|
||||
uint16_t addr;
|
||||
|
||||
lgw_reg_r(SX1302_REG_RX_TOP_RX_BUFFER_LAST_ADDR_WRITE_MSB_LAST_ADDR_WRITE, &val); /* mandatory to read MSB first */
|
||||
addr = (uint16_t)(val << 8);
|
||||
lgw_reg_r(SX1302_REG_RX_TOP_RX_BUFFER_LAST_ADDR_WRITE_LSB_LAST_ADDR_WRITE, &val);
|
||||
addr |= (uint16_t)val;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
void rx_buffer_dump(FILE * file, uint16_t start_addr, uint16_t end_addr) {
|
||||
int i;
|
||||
uint8_t rx_buffer_debug[4096];
|
||||
|
||||
printf("Dumping %u bytes, from 0x%X to 0x%X\n", end_addr - start_addr + 1, start_addr, end_addr);
|
||||
|
||||
memset(rx_buffer_debug, 0, sizeof rx_buffer_debug);
|
||||
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_RX_BUFFER_DIRECT_RAM_IF, 1);
|
||||
lgw_mem_rb(0x4000 + start_addr, rx_buffer_debug, end_addr - start_addr + 1, false);
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_RX_BUFFER_DIRECT_RAM_IF, 0);
|
||||
|
||||
for (i = 0; i < (end_addr - start_addr + 1); i++) {
|
||||
if (file == NULL) {
|
||||
printf("%02X ", rx_buffer_debug[i]);
|
||||
} else {
|
||||
fprintf(file, "%02X ", rx_buffer_debug[i]);
|
||||
}
|
||||
}
|
||||
if (file == NULL) {
|
||||
printf("\n");
|
||||
} else {
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
/* Switching to direct-access memory could lead to corruption, so to be done only for debugging */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
295
libloragw/src/loragw_sx1302_timestamp.c
Normal file
295
libloragw/src/loragw_sx1302_timestamp.c
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
SX1302 timestamp counter Hardware Abstraction Layer
|
||||
Handles the conversion of a 32-bits 32MHz counter into a 32-bits 1 MHz counter.
|
||||
This modules MUST be called regularly by the application to maintain counter
|
||||
wrapping handling for conversion in 1MHz counter.
|
||||
Provides function to compute the correction to be applied to the received
|
||||
timestamp for demodulation processing time.
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdio.h> /* printf fprintf */
|
||||
|
||||
#include "loragw_sx1302_timestamp.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_sx1302.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#if DEBUG_SX1302 == 1
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr, fmt, args)
|
||||
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;}
|
||||
#else
|
||||
#define DEBUG_MSG(str)
|
||||
#define DEBUG_PRINTF(fmt, args...)
|
||||
#define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE TYPES -------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- INTERNAL SHARED VARIABLES -------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
|
||||
|
||||
void timestamp_counter_new(timestamp_counter_t * self) {
|
||||
self->counter_us_raw_27bits_inst_prev = 0;
|
||||
self->counter_us_raw_27bits_pps_prev = 0;
|
||||
self->counter_us_raw_27bits_inst_wrap = 0;
|
||||
self->counter_us_raw_27bits_pps_wrap = 0;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
void timestamp_counter_delete(timestamp_counter_t * self) {
|
||||
self->counter_us_raw_27bits_inst_prev = 0;
|
||||
self->counter_us_raw_27bits_pps_prev = 0;
|
||||
self->counter_us_raw_27bits_inst_wrap = 0;
|
||||
self->counter_us_raw_27bits_pps_wrap = 0;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
void timestamp_counter_update(timestamp_counter_t * self, bool pps, uint32_t cnt) {
|
||||
uint32_t counter_us_raw_27bits_prev;
|
||||
uint8_t counter_us_raw_27bits_wrap;
|
||||
|
||||
/* Get the previous counter value and wrap status */
|
||||
if (pps == true) {
|
||||
counter_us_raw_27bits_prev = self->counter_us_raw_27bits_pps_prev;
|
||||
counter_us_raw_27bits_wrap = self->counter_us_raw_27bits_pps_wrap;
|
||||
} else {
|
||||
counter_us_raw_27bits_prev = self->counter_us_raw_27bits_inst_prev;
|
||||
counter_us_raw_27bits_wrap = self->counter_us_raw_27bits_inst_wrap;
|
||||
}
|
||||
|
||||
/* Check if counter has wrapped, and update wrap status if necessary */
|
||||
if (cnt < counter_us_raw_27bits_prev) {
|
||||
counter_us_raw_27bits_wrap += 1;
|
||||
counter_us_raw_27bits_wrap = counter_us_raw_27bits_wrap % 32;
|
||||
}
|
||||
|
||||
/* Store counter value and wrap status for next time */
|
||||
if (pps == true) {
|
||||
self->counter_us_raw_27bits_pps_prev = cnt;
|
||||
self->counter_us_raw_27bits_pps_wrap = counter_us_raw_27bits_wrap;
|
||||
} else {
|
||||
self->counter_us_raw_27bits_inst_prev = cnt;
|
||||
self->counter_us_raw_27bits_inst_wrap = counter_us_raw_27bits_wrap;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
uint32_t timestamp_counter_get(timestamp_counter_t * self, bool pps) {
|
||||
int x;
|
||||
uint8_t buff[4];
|
||||
uint32_t counter_us_raw_27bits_now;
|
||||
|
||||
/* Get the 32MHz timestamp counter - 4 bytes */
|
||||
/* step of 31.25 ns */
|
||||
x = lgw_reg_rb((pps == true) ? SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_MSB2_TIMESTAMP_PPS : SX1302_REG_TIMESTAMP_TIMESTAMP_MSB2_TIMESTAMP, &buff[0], 4);
|
||||
if (x != LGW_REG_SUCCESS) {
|
||||
printf("ERROR: Failed to get timestamp counter value\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
counter_us_raw_27bits_now = (uint32_t)((buff[0] << 24) & 0xFF000000);
|
||||
counter_us_raw_27bits_now |= (uint32_t)((buff[1] << 16) & 0x00FF0000);
|
||||
counter_us_raw_27bits_now |= (uint32_t)((buff[2] << 8) & 0x0000FF00);
|
||||
counter_us_raw_27bits_now |= (uint32_t)((buff[3] << 0) & 0x000000FF);
|
||||
counter_us_raw_27bits_now /= 32; /* scale to 1MHz */
|
||||
|
||||
/* Update counter wrapping status */
|
||||
timestamp_counter_update(self, pps, counter_us_raw_27bits_now);
|
||||
|
||||
/* Convert 27-bits counter to 32-bits counter */
|
||||
return timestamp_counter_expand(self, pps, counter_us_raw_27bits_now);
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
uint32_t timestamp_counter_expand(timestamp_counter_t * self, bool pps, uint32_t cnt_us) {
|
||||
uint32_t counter_us_32bits;
|
||||
|
||||
if (pps == true) {
|
||||
counter_us_32bits = (self->counter_us_raw_27bits_pps_wrap << 27) | cnt_us;
|
||||
} else {
|
||||
counter_us_32bits = (self->counter_us_raw_27bits_inst_wrap << 27) | cnt_us;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* DEBUG: to be enabled when running test_loragw_counter test application
|
||||
This generates a CSV log, and can be plotted with gnuplot:
|
||||
> set datafile separator comma
|
||||
> plot for [col=1:2:1] 'log_count.txt' using col with lines
|
||||
*/
|
||||
printf("%u,%u,%u\n", cnt_us, counter_us_32bits, (pps == true) ? self->counter_us_raw_27bits_pps_wrap : self->counter_us_raw_27bits_inst_wrap);
|
||||
#endif
|
||||
|
||||
return counter_us_32bits;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
int timestamp_counter_mode(bool enable_precision_ts, uint8_t max_ts_metrics, uint8_t nb_symbols) {
|
||||
if (enable_precision_ts == false) {
|
||||
DEBUG_MSG("INFO: using legacy timestamp\n");
|
||||
/* Latch end-of-packet timestamp (sx1301 compatibility) */
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_RX_BUFFER_LEGACY_TIMESTAMP, 0x01);
|
||||
} else {
|
||||
DEBUG_PRINTF("INFO: using precision timestamp (max_ts_metrics:%u nb_symbols:%u)\n", max_ts_metrics, nb_symbols);
|
||||
/* Latch end-of-preamble timestamp */
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_RX_BUFFER_LEGACY_TIMESTAMP, 0x00);
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_RX_BUFFER_TIMESTAMP_CFG_MAX_TS_METRICS, max_ts_metrics);
|
||||
|
||||
/* LoRa multi-SF modems */
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_TIMESTAMP_ENABLE, 0x01);
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_TIMESTAMP_NB_SYMB, nb_symbols);
|
||||
|
||||
/* LoRa service modem */
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TIMESTAMP_ENABLE, 0x01);
|
||||
lgw_reg_w(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TIMESTAMP_NB_SYMB, nb_symbols);
|
||||
}
|
||||
|
||||
return LGW_REG_SUCCESS;
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
uint32_t timestamp_counter_correction(int ifmod, uint8_t bandwidth, uint8_t datarate, uint8_t coderate, uint32_t crc_en, uint16_t payload_length) {
|
||||
int32_t val;
|
||||
uint32_t sf = (uint32_t)datarate, cr = (uint32_t)coderate, bw_pow, ppm;
|
||||
uint32_t clk_period;
|
||||
uint32_t nb_nibble, nb_nibble_in_hdr, nb_nibble_in_last_block;
|
||||
uint32_t dft_peak_en, nb_iter;
|
||||
uint32_t demap_delay, decode_delay, fft_delay_state3, fft_delay, delay_x;
|
||||
uint32_t timestamp_correction;
|
||||
|
||||
/* determine if 'PPM mode' is on */
|
||||
if (SET_PPM_ON(bandwidth, datarate)) {
|
||||
ppm = 1;
|
||||
} else {
|
||||
ppm = 0;
|
||||
}
|
||||
|
||||
/* timestamp correction code, base delay */
|
||||
switch (bandwidth)
|
||||
{
|
||||
case BW_125KHZ:
|
||||
bw_pow = 1;
|
||||
delay_x = 16000000 / bw_pow + 2031250;
|
||||
break;
|
||||
case BW_250KHZ:
|
||||
bw_pow = 2;
|
||||
delay_x = 16000000 / bw_pow + 2031250;
|
||||
break;
|
||||
case BW_500KHZ:
|
||||
bw_pow = 4;
|
||||
delay_x = 16000000 / bw_pow + 2031250;
|
||||
break;
|
||||
default:
|
||||
DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d IN SWITCH STATEMENT\n", bandwidth);
|
||||
delay_x = 0;
|
||||
bw_pow = 0;
|
||||
break;
|
||||
}
|
||||
clk_period = 250000;
|
||||
|
||||
nb_nibble = (payload_length + 2 * crc_en) * 2 + 5;
|
||||
|
||||
if ((sf == 5) || (sf == 6)) {
|
||||
nb_nibble_in_hdr = sf;
|
||||
} else {
|
||||
nb_nibble_in_hdr = sf - 2;
|
||||
}
|
||||
|
||||
nb_nibble_in_last_block = nb_nibble - nb_nibble_in_hdr - (sf - 2 * ppm) * ((nb_nibble - nb_nibble_in_hdr) / (sf - 2 * ppm));
|
||||
if (nb_nibble_in_last_block == 0) {
|
||||
nb_nibble_in_last_block = sf - 2 * ppm;
|
||||
}
|
||||
|
||||
nb_iter = ((sf + 1) >> 1);
|
||||
|
||||
/* timestamp correction code, variable delay */
|
||||
if (ifmod == IF_LORA_STD) {
|
||||
lgw_reg_r(SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG0_DFT_PEAK_EN, &val);
|
||||
} else {
|
||||
lgw_reg_r(SX1302_REG_RX_TOP_RX_CFG0_DFT_PEAK_EN, &val);
|
||||
}
|
||||
if (val != 0) {
|
||||
/* TODO: should we differentiate the mode (FULL/TRACK) ? */
|
||||
dft_peak_en = 1;
|
||||
} else {
|
||||
dft_peak_en = 0;
|
||||
}
|
||||
|
||||
|
||||
if ((sf >= 5) && (sf <= 12) && (bw_pow > 0)) {
|
||||
if ((2 * (payload_length + 2 * crc_en) - (sf - 7)) <= 0) { /* payload fits entirely in first 8 symbols (header) */
|
||||
if (sf > 6) {
|
||||
nb_nibble_in_last_block = sf - 2;
|
||||
} else {
|
||||
nb_nibble_in_last_block = sf; // can't be acheived
|
||||
}
|
||||
dft_peak_en = 0;
|
||||
cr = 4; /* header coding rate is 4 */
|
||||
demap_delay = clk_period + (1 << sf) * clk_period * 3 / 4 + 3 * clk_period + (sf - 2) * clk_period;
|
||||
} else {
|
||||
demap_delay = clk_period + (1 << sf) * clk_period * (1 - ppm / 4) + 3 * clk_period + (sf - 2 * ppm) * clk_period;
|
||||
}
|
||||
|
||||
fft_delay_state3 = clk_period * (((1 << sf) - 6) + 2 * ((1 << sf) * (nb_iter - 1) + 6)) + 4 * clk_period;
|
||||
|
||||
if (dft_peak_en) {
|
||||
fft_delay = (5 - 2 * ppm) * ((1 << sf) * clk_period + 7 * clk_period) + 2 * clk_period;
|
||||
} else {
|
||||
fft_delay = (1 << sf) * 2 * clk_period + 3 * clk_period;
|
||||
}
|
||||
|
||||
decode_delay = 5 * clk_period + (9 * clk_period + clk_period * cr) * nb_nibble_in_last_block + 3 * clk_period;
|
||||
timestamp_correction = (uint32_t)(delay_x + fft_delay_state3 + fft_delay + demap_delay + decode_delay + 0.5e6) / 1e6;
|
||||
//printf("INFO: timestamp_correction = %u us (delay_x %u, fft_delay_state3=%u, fft_delay=%u, demap_delay=%u, decode_delay = %u)\n", timestamp_correction, delay_x, fft_delay_state3, fft_delay, demap_delay, decode_delay);
|
||||
}
|
||||
else
|
||||
{
|
||||
timestamp_correction = 0;
|
||||
DEBUG_MSG("WARNING: invalid packet, no timestamp correction\n");
|
||||
}
|
||||
|
||||
return timestamp_correction;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
698
libloragw/tst/test_loragw_cal.c
Normal file
698
libloragw/tst/test_loragw_cal.c
Normal file
|
|
@ -0,0 +1,698 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for HAL calibration
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <getopt.h> /* getopt_long */
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_sx1302.h"
|
||||
#include "loragw_sx125x.h"
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_cal.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define RAND_RANGE(min, max) (rand() % (max + 1 - min) + min)
|
||||
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
#define DEFAULT_CLK_SRC 0
|
||||
#define DEFAULT_FREQ_HZ 868500000U
|
||||
|
||||
#define DEFAULT_DAC_GAIN 3
|
||||
#define DEFAULT_MIX_GAIN 15
|
||||
|
||||
#define CAL_TX_TONE_FREQ_HZ 250000
|
||||
#define CAL_DEC_GAIN 8
|
||||
#define CAL_SIG_ANA_DURATION 0 /* correlation duration: 0:1, 1:2, 2:4, 3:8 ms) */
|
||||
|
||||
#define TEST_FREQ_SCAN 0
|
||||
#define TEST_OFFSET_IQ 1
|
||||
#define TEST_AMP_PHI 2
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE TYPES -------------------------------------------------------- */
|
||||
struct cal_tx_log {
|
||||
int32_t mean;
|
||||
int32_t i_offset;
|
||||
int32_t q_offset;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
FILE * fp;
|
||||
|
||||
static uint32_t rf_rx_freq[LGW_RF_CHAIN_NB] = {865500000, 865500000};
|
||||
static lgw_radio_type_t rf_radio_type[LGW_RF_CHAIN_NB] = {LGW_RADIO_TYPE_SX1257, LGW_RADIO_TYPE_SX1257};
|
||||
static struct lgw_tx_gain_lut_s txlut; /* TX gain table */
|
||||
|
||||
/* Signal handling variables */
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
#include "../src/cal_fw.var" /* text_cal_sx1257_16_Nov_1 */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
/* describe command line options */
|
||||
void usage(void) {
|
||||
//printf("Library version information: %s\n", lgw_version_info());
|
||||
printf("Available options:\n");
|
||||
printf(" -h print this help\n");
|
||||
printf(" -d <path> use Linux SPI device driver\n");
|
||||
printf(" => default path: " LINUXDEV_PATH_DEFAULT "\n");
|
||||
printf(" -k <uint> Concentrator clock source (Radio A or Radio B) [0..1]\n");
|
||||
printf(" -c <uint> RF chain to be used for TX (Radio A or Radio B) [0..1]\n");
|
||||
printf(" -r <uint> Radio type (1255, 1257, 1250)\n");
|
||||
printf(" -f <float> Radio TX frequency in MHz\n");
|
||||
printf( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
|
||||
printf(" --pa <uint> PA gain [0..3]\n");
|
||||
printf(" --dig <uint> sx1302 digital gain [0..3]\n");
|
||||
printf(" --dac <uint> sx1257 DAC gain [0..3]\n");
|
||||
printf(" --mix <uint> sx1257 MIX gain [0..15]\n");
|
||||
}
|
||||
|
||||
/* handle signals */
|
||||
static void sig_handler(int sigio)
|
||||
{
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;
|
||||
}
|
||||
else if((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int setup_tx_dc_offset(uint8_t rf_chain, uint32_t freq_hz, uint8_t dac_gain, uint8_t mix_gain, uint8_t radio_type) {
|
||||
uint32_t rx_freq_hz, tx_freq_hz;
|
||||
uint32_t rx_freq_int, rx_freq_frac;
|
||||
uint32_t tx_freq_int, tx_freq_frac;
|
||||
uint8_t rx_pll_locked, tx_pll_locked;
|
||||
|
||||
/* Set PLL frequencies */
|
||||
rx_freq_hz = freq_hz - CAL_TX_TONE_FREQ_HZ;
|
||||
tx_freq_hz = freq_hz;
|
||||
switch (radio_type) {
|
||||
case LGW_RADIO_TYPE_SX1255:
|
||||
rx_freq_int = rx_freq_hz / (SX125x_32MHz_FRAC << 7); /* integer part, gives the MSB */
|
||||
rx_freq_frac = ((rx_freq_hz % (SX125x_32MHz_FRAC << 7)) << 9) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */
|
||||
tx_freq_int = tx_freq_hz / (SX125x_32MHz_FRAC << 7); /* integer part, gives the MSB */
|
||||
tx_freq_frac = ((tx_freq_hz % (SX125x_32MHz_FRAC << 7)) << 9) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */
|
||||
break;
|
||||
case LGW_RADIO_TYPE_SX1257:
|
||||
rx_freq_int = rx_freq_hz / (SX125x_32MHz_FRAC << 8); /* integer part, gives the MSB */
|
||||
rx_freq_frac = ((rx_freq_hz % (SX125x_32MHz_FRAC << 8)) << 8) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */
|
||||
tx_freq_int = tx_freq_hz / (SX125x_32MHz_FRAC << 8); /* integer part, gives the MSB */
|
||||
tx_freq_frac = ((tx_freq_hz % (SX125x_32MHz_FRAC << 8)) << 8) / SX125x_32MHz_FRAC; /* fractional part, gives middle part and LSB */
|
||||
break;
|
||||
default:
|
||||
DEBUG_PRINTF("ERROR: UNEXPECTED VALUE %d FOR RADIO TYPE\n", radio_type);
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_RX_MSB, 0xFF & rx_freq_int, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_RX_MID, 0xFF & (rx_freq_frac >> 8), rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_RX_LSB, 0xFF & rx_freq_frac, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_TX_MSB, 0xFF & tx_freq_int, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_TX_MID, 0xFF & (tx_freq_frac >> 8), rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_FRF_TX_LSB, 0xFF & tx_freq_frac, rf_chain);
|
||||
|
||||
/* Radio settings for calibration */
|
||||
//lgw_sx125x_reg_w(SX125x_RX_ANA_GAIN__LNA_ZIN, 1, rf_chain); /* Default: 1 */
|
||||
//lgw_sx125x_reg_w(SX125x_RX_ANA_GAIN__BB_GAIN, 15, rf_chain); /* Default: 15 */
|
||||
//lgw_sx125x_reg_w(SX125x_RX_ANA_GAIN__LNA_GAIN, 1, rf_chain); /* Default: 1 */
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_BW__BB_BW, 0, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_BW__ADC_TRIM, 6, rf_chain);
|
||||
//lgw_sx125x_reg_w(SX125x_RX_BW__ADC_BW, 7, rf_chain); /* Default: 7 */
|
||||
lgw_sx125x_reg_w(SX125x_REG_RX_PLL_BW__PLL_BW, 0, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_BW__PLL_BW, 0, rf_chain);
|
||||
//lgw_sx125x_reg_w(SX125x_TX_BW__ANA_BW, 0, rf_chain); /* Default: 0 */
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_DAC_BW, 5, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_CLK_SELECT__DAC_CLK_SELECT, 1, rf_chain); /* Use external clock from SX1302 */
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_GAIN__DAC_GAIN, dac_gain, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_TX_GAIN__MIX_GAIN, mix_gain, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_CLK_SELECT__RF_LOOPBACK_EN, 1, rf_chain);
|
||||
lgw_sx125x_reg_w(SX125x_REG_MODE, 15, rf_chain);
|
||||
wait_ms(1);
|
||||
lgw_sx125x_reg_r(SX125x_REG_MODE_STATUS__RX_PLL_LOCKED, &rx_pll_locked, rf_chain);
|
||||
lgw_sx125x_reg_r(SX125x_REG_MODE_STATUS__TX_PLL_LOCKED, &tx_pll_locked, rf_chain);
|
||||
if ((rx_pll_locked == 0) || (tx_pll_locked == 0)) {
|
||||
DEBUG_MSG("ERROR: PLL failed to lock\n");
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cal_tx_dc_offset(uint8_t test_id, uint8_t rf_chain, uint32_t freq_hz, uint8_t dac_gain, uint8_t mix_gain, uint8_t radio_type, int32_t f_offset, int32_t i_offset, int32_t q_offset, bool full_log, bool use_agc, uint8_t amp, uint8_t phi) {
|
||||
int i;
|
||||
uint16_t reg;
|
||||
int32_t val_min, val_max;
|
||||
int32_t acc;
|
||||
int32_t val_mean;
|
||||
float val_std;
|
||||
float acc2 = 0 ;
|
||||
int loop_len = 3;
|
||||
float res_sig[loop_len];
|
||||
struct timeval start, stop;
|
||||
|
||||
//DEBUG_MSG("\n");
|
||||
//DEBUG_PRINTF("rf_chain:%u, freq_hz:%u, dac_gain:%u, mix_gain:%u, radio_type:%d\n", rf_chain, freq_hz, dac_gain, mix_gain, radio_type);
|
||||
|
||||
if (setup_tx_dc_offset(rf_chain, freq_hz, dac_gain, mix_gain, radio_type) != LGW_HAL_SUCCESS) {
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Trig calibration */
|
||||
|
||||
/* Select radio to be connected to the Signal Analyzer (warning: RadioA:1, RadioB:0) */
|
||||
lgw_reg_w(SX1302_REG_RADIO_FE_SIG_ANA_CFG_RADIO_SEL, (rf_chain == 0) ? 1 : 0);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_MODE,
|
||||
SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_MODE);
|
||||
lgw_reg_w(reg, 0);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_TX_TOP_A_TX_TRIG_TX_TRIG_IMMEDIATE,
|
||||
SX1302_REG_TX_TOP_B_TX_TRIG_TX_TRIG_IMMEDIATE);
|
||||
lgw_reg_w(reg, 1);
|
||||
lgw_reg_w(reg, 0);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_RADIO_FE_CTRL0_RADIO_A_DC_NOTCH_EN,
|
||||
SX1302_REG_RADIO_FE_CTRL0_RADIO_B_DC_NOTCH_EN);
|
||||
lgw_reg_w(reg, 1);
|
||||
|
||||
/* Measuring */
|
||||
if (use_agc == true) {
|
||||
uint8_t val_sig, val_sig2;
|
||||
|
||||
/* Set calibration parameters */
|
||||
sx1302_agc_mailbox_write(2, rf_chain + 4); /* Sig ana test radio A/B */
|
||||
sx1302_agc_mailbox_write(1, f_offset/*(CAL_TX_TONE_FREQ_HZ + f_offset) * 64e-6*/); /* Set frequency */
|
||||
sx1302_agc_mailbox_write(0, CAL_SIG_ANA_DURATION);
|
||||
|
||||
/* */
|
||||
sx1302_agc_mailbox_write(3, 0x00);
|
||||
sx1302_agc_mailbox_write(3, 0x01);
|
||||
sx1302_agc_wait_status(0x01);
|
||||
|
||||
sx1302_agc_mailbox_write(2, amp); /* amp */
|
||||
sx1302_agc_mailbox_write(1, phi); /* phi */
|
||||
|
||||
sx1302_agc_mailbox_write(3, 0x02);
|
||||
sx1302_agc_wait_status(0x02);
|
||||
|
||||
sx1302_agc_mailbox_write(2, i_offset); /* i offset init */
|
||||
sx1302_agc_mailbox_write(1, q_offset); /* q offset init */
|
||||
|
||||
sx1302_agc_mailbox_write(3, 0x03);
|
||||
sx1302_agc_wait_status(0x03);
|
||||
|
||||
sx1302_agc_mailbox_write(2, CAL_DEC_GAIN); /* dec_gain */
|
||||
sx1302_agc_mailbox_write(2, 0); /* threshold (not used) */
|
||||
|
||||
sx1302_agc_mailbox_write(3, 0x04);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_TX_TOP_A_TX_TRIG_TX_TRIG_IMMEDIATE,
|
||||
SX1302_REG_TX_TOP_B_TX_TRIG_TX_TRIG_IMMEDIATE);
|
||||
lgw_reg_w(reg, 0);
|
||||
|
||||
gettimeofday (&start, NULL);
|
||||
for (i = 0; i < loop_len; i++) {
|
||||
sx1302_agc_wait_status(0x06);
|
||||
sx1302_agc_mailbox_write(3, 0x06);
|
||||
|
||||
sx1302_agc_wait_status(0x07);
|
||||
sx1302_agc_mailbox_read(0, &val_sig);
|
||||
sx1302_agc_mailbox_read(1, &val_sig2);
|
||||
res_sig[i] = val_sig2 * 256 + val_sig;
|
||||
|
||||
if (i == (loop_len - 1)) {
|
||||
sx1302_agc_mailbox_write(3, 0x07); /* unlock */
|
||||
} else {
|
||||
sx1302_agc_mailbox_write(3, 0x00); /* unlock */
|
||||
}
|
||||
}
|
||||
gettimeofday (&stop, NULL);
|
||||
//printf("processing time: %ld us\n", ((stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec) - start.tv_usec);
|
||||
} else {
|
||||
int32_t val;
|
||||
int32_t abs_lsb, abs_msb;
|
||||
float abs_iq;
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_TX_TOP_A_TX_RFFE_IF_Q_OFFSET_Q_OFFSET,
|
||||
SX1302_REG_TX_TOP_B_TX_RFFE_IF_Q_OFFSET_Q_OFFSET);
|
||||
lgw_reg_w(reg, (int8_t)q_offset);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_TX_TOP_A_TX_RFFE_IF_I_OFFSET_I_OFFSET,
|
||||
SX1302_REG_TX_TOP_B_TX_RFFE_IF_I_OFFSET_I_OFFSET);
|
||||
lgw_reg_w(reg, (int8_t)i_offset);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_RADIO_FE_CTRL0_RADIO_A_DC_NOTCH_EN,
|
||||
SX1302_REG_RADIO_FE_CTRL0_RADIO_B_DC_NOTCH_EN);
|
||||
lgw_reg_w(reg, 1);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_RADIO_FE_CTRL0_RADIO_A_FORCE_HOST_FILTER_GAIN,
|
||||
SX1302_REG_RADIO_FE_CTRL0_RADIO_B_FORCE_HOST_FILTER_GAIN);
|
||||
lgw_reg_w(reg, 0x01);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_RADIO_FE_CTRL0_RADIO_A_HOST_FILTER_GAIN,
|
||||
SX1302_REG_RADIO_FE_CTRL0_RADIO_B_HOST_FILTER_GAIN);
|
||||
lgw_reg_w(reg, CAL_DEC_GAIN);
|
||||
|
||||
lgw_reg_w(SX1302_REG_RADIO_FE_SIG_ANA_CFG_FORCE_HAL_CTRL, 1);
|
||||
|
||||
lgw_reg_w(SX1302_REG_RADIO_FE_SIG_ANA_FREQ_FREQ, f_offset);
|
||||
|
||||
lgw_reg_w(SX1302_REG_RADIO_FE_SIG_ANA_CFG_DURATION, CAL_SIG_ANA_DURATION);
|
||||
lgw_reg_w(SX1302_REG_RADIO_FE_SIG_ANA_CFG_EN, 1);
|
||||
|
||||
gettimeofday (&start, NULL);
|
||||
for (i = 0; i < loop_len; i++) {
|
||||
lgw_reg_w(SX1302_REG_RADIO_FE_SIG_ANA_CFG_START, 0);
|
||||
lgw_reg_w(SX1302_REG_RADIO_FE_SIG_ANA_CFG_START, 1);
|
||||
|
||||
do {
|
||||
lgw_reg_r(SX1302_REG_RADIO_FE_SIG_ANA_CFG_VALID, &val);
|
||||
wait_ms(1);
|
||||
} while (val == 0);
|
||||
|
||||
lgw_reg_r(SX1302_REG_RADIO_FE_SIG_ANA_ABS_LSB_CORR_ABS_OUT, &abs_lsb);
|
||||
lgw_reg_r(SX1302_REG_RADIO_FE_SIG_ANA_ABS_MSB_CORR_ABS_OUT, &abs_msb);
|
||||
abs_iq = (abs_msb << 8) | abs_lsb;
|
||||
|
||||
res_sig[i] = abs_iq;
|
||||
}
|
||||
gettimeofday (&stop, NULL);
|
||||
//printf("processing time: %ld us\n", ((stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec) - start.tv_usec);
|
||||
|
||||
lgw_reg_w(SX1302_REG_RADIO_FE_SIG_ANA_CFG_FORCE_HAL_CTRL, 0);
|
||||
}
|
||||
|
||||
if (full_log == true) {
|
||||
printf("i_offset:%d q_offset:%d f_offset:%d dac_gain:%d mix_gain:%d dec_gain:%d amp:%u phi:%u => ", i_offset, q_offset, f_offset, dac_gain, mix_gain, CAL_DEC_GAIN, amp, phi);
|
||||
} else {
|
||||
switch (test_id) {
|
||||
case TEST_FREQ_SCAN:
|
||||
fprintf(fp, "%u ", f_offset);
|
||||
break;
|
||||
case TEST_OFFSET_IQ:
|
||||
fprintf(fp, "%d %d ", i_offset, q_offset);
|
||||
break;
|
||||
case TEST_AMP_PHI:
|
||||
fprintf(fp, "%d %d ", amp, phi);
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: wrong test ID (%u)\n", test_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Analyze result */
|
||||
val_min = res_sig[0];
|
||||
val_max = res_sig[0];
|
||||
acc = 0;
|
||||
for (i = 0; i < loop_len; i++) {
|
||||
if (res_sig[i] > val_max) {
|
||||
val_max = res_sig[i];
|
||||
}
|
||||
if (res_sig[i] < val_min) {
|
||||
val_min = res_sig[i];
|
||||
}
|
||||
acc += res_sig[i];
|
||||
}
|
||||
val_mean = acc / loop_len;
|
||||
|
||||
for (i = 0; i < loop_len; i++) {
|
||||
acc2 += pow((res_sig[i]-val_mean),2);
|
||||
}
|
||||
val_std = sqrt(acc2/loop_len);
|
||||
|
||||
if (full_log == true) {
|
||||
printf(" min:%u max:%u mean:%u std:%f\n", val_min, val_max, val_mean, val_std);
|
||||
} else {
|
||||
switch (test_id) {
|
||||
case TEST_OFFSET_IQ:
|
||||
case TEST_AMP_PHI:
|
||||
fprintf(fp, "%u %u %u %f\n", val_min, val_max, val_mean, val_std);
|
||||
break;
|
||||
case TEST_FREQ_SCAN:
|
||||
fprintf(fp, "%u\n", val_mean);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return LGW_HAL_SUCCESS;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int test_freq_scan(uint8_t rf_chain, bool full_log, bool use_agc) {
|
||||
int f;
|
||||
|
||||
printf("-------------------------------------\n");
|
||||
for (f = 0; f < 256; f++)
|
||||
{
|
||||
cal_tx_dc_offset(TEST_FREQ_SCAN, rf_chain, rf_rx_freq[rf_chain], txlut.lut[0].dac_gain, txlut.lut[0].mix_gain, rf_radio_type[rf_chain], f, 0, 0, full_log, use_agc, 0, 0);
|
||||
|
||||
if ((quit_sig == 1) || (exit_sig == 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_iq_offset(uint8_t rf_chain, uint8_t f_offset, bool full_log, bool use_agc) {
|
||||
int i, q;
|
||||
|
||||
printf("-------------------------------------\n");
|
||||
for (i = -128; i < 127; i+=8)
|
||||
{
|
||||
for (q = -128; q < 127; q+=8)
|
||||
{
|
||||
cal_tx_dc_offset(TEST_OFFSET_IQ, rf_chain, rf_rx_freq[rf_chain], txlut.lut[0].dac_gain, txlut.lut[0].mix_gain, rf_radio_type[rf_chain], f_offset, i, q, full_log, use_agc, 0, 0);
|
||||
if ((quit_sig == 1) || (exit_sig == 1)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_amp_phi(uint8_t rf_chain, uint8_t f_offset, bool full_log, bool use_agc) {
|
||||
int amp, phi;
|
||||
|
||||
printf("-------------------------------------\n");
|
||||
for (amp = 0; amp < 64; amp++)
|
||||
{
|
||||
for (phi = 0; phi < 64; phi++)
|
||||
{
|
||||
cal_tx_dc_offset(TEST_AMP_PHI, rf_chain, rf_rx_freq[rf_chain], txlut.lut[0].dac_gain, txlut.lut[0].mix_gain, rf_radio_type[rf_chain], f_offset, 0, 0, full_log, use_agc, amp, phi);
|
||||
if ((quit_sig == 1) || (exit_sig == 1)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_capture_ram(uint8_t rf_chain) {
|
||||
uint16_t reg;
|
||||
|
||||
setup_tx_dc_offset(rf_chain, rf_rx_freq[rf_chain], txlut.lut[0].dac_gain, txlut.lut[0].mix_gain, rf_radio_type[rf_chain]);
|
||||
|
||||
reg = REG_SELECT(rf_chain, SX1302_REG_RADIO_FE_CTRL0_RADIO_A_DC_NOTCH_EN,
|
||||
SX1302_REG_RADIO_FE_CTRL0_RADIO_B_DC_NOTCH_EN);
|
||||
lgw_reg_w(reg, 1);
|
||||
|
||||
printf("Waiting...\n");
|
||||
while ((quit_sig != 1) && (exit_sig != 1)) {
|
||||
wait_ms(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, x;
|
||||
uint32_t ft = DEFAULT_FREQ_HZ;
|
||||
double arg_d = 0.0;
|
||||
unsigned int arg_u;
|
||||
uint8_t clocksource = 0;
|
||||
uint8_t rf_chain = 0;
|
||||
lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE;
|
||||
|
||||
struct lgw_conf_board_s boardconf;
|
||||
struct lgw_conf_rxrf_s rfconf;
|
||||
|
||||
static struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
|
||||
/* Initialize TX gain LUT */
|
||||
txlut.size = 1;
|
||||
memset(txlut.lut, 0, sizeof txlut.lut);
|
||||
txlut.lut[0].dac_gain = DEFAULT_DAC_GAIN;
|
||||
txlut.lut[0].mix_gain = DEFAULT_MIX_GAIN;
|
||||
|
||||
/* Parameter parsing */
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{"dac", 1, 0, 0},
|
||||
{"mix", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* parse command line options */
|
||||
while ((i = getopt_long (argc, argv, "hf:k:r:c:d:", long_options, &option_index)) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (optarg != NULL) {
|
||||
spidev_path = optarg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r': /* <uint> Radio type */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || ((arg_u != 1255) && (arg_u != 1257) && (arg_u != 1250))) {
|
||||
printf("ERROR: argument parsing of -r argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
switch (arg_u) {
|
||||
case 1255:
|
||||
radio_type = LGW_RADIO_TYPE_SX1255;
|
||||
break;
|
||||
case 1257:
|
||||
radio_type = LGW_RADIO_TYPE_SX1257;
|
||||
break;
|
||||
default: /* 1250 */
|
||||
radio_type = LGW_RADIO_TYPE_SX1250;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'k': /* <uint> Clock Source */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 1)) {
|
||||
printf("ERROR: argument parsing of -k argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
clocksource = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c': /* <uint> RF chain */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 1)) {
|
||||
printf("ERROR: argument parsing of -c argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
rf_chain = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f': /* <float> Radio TX frequency in MHz */
|
||||
i = sscanf(optarg, "%lf", &arg_d);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of -f argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
ft = (uint32_t)((arg_d*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (strcmp(long_options[option_index].name, "dac") == 0) {
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 3)) {
|
||||
printf("ERROR: argument parsing of --dac argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
txlut.size = 1;
|
||||
txlut.lut[0].dac_gain = (uint8_t)arg_u;
|
||||
}
|
||||
} else if (strcmp(long_options[option_index].name, "mix") == 0) {
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 15)) {
|
||||
printf("ERROR: argument parsing of --mix argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
txlut.size = 1;
|
||||
txlut.lut[0].mix_gain = (uint8_t)arg_u;
|
||||
}
|
||||
} else {
|
||||
printf("ERROR: argument parsing options. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: argument parsing\n");
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure signal handling */
|
||||
sigemptyset( &sigact.sa_mask );
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction( SIGQUIT, &sigact, NULL );
|
||||
sigaction( SIGINT, &sigact, NULL );
|
||||
sigaction( SIGTERM, &sigact, NULL );
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Configure the gateway */
|
||||
memset(&boardconf, 0, sizeof boardconf);
|
||||
boardconf.lorawan_public = true;
|
||||
boardconf.clksrc = clocksource;
|
||||
boardconf.full_duplex = false;
|
||||
strncpy(boardconf.spidev_path, spidev_path, sizeof boardconf.spidev_path);
|
||||
if (lgw_board_setconf(&boardconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure board\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset(&rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = ((rf_chain == 0) ? true : false);
|
||||
rfconf.freq_hz = ft;
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = true;
|
||||
if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 0\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset(&rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = ((rf_chain == 1) ? true : false);
|
||||
rfconf.freq_hz = ft;
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = true;
|
||||
if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 1\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (txlut.size > 0) {
|
||||
if (lgw_txgain_setconf(rf_chain, &txlut) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure txgain lut\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* open log file for writing */
|
||||
fp = fopen("log.txt", "w+");
|
||||
|
||||
/* connect the gateway */
|
||||
x = lgw_connect(spidev_path);
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to connect the gateway\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
sx1302_radio_reset(rf_chain, LGW_RADIO_TYPE_SX1257);
|
||||
sx1302_radio_clock_select(clocksource);
|
||||
sx1302_radio_set_mode(rf_chain, LGW_RADIO_TYPE_SX1257);
|
||||
|
||||
printf("Loading CAL fw for sx125x\n");
|
||||
if (sx1302_agc_load_firmware(cal_firmware_sx125x) != LGW_HAL_SUCCESS) {
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
|
||||
printf("waiting for capture ram\n");
|
||||
wait_ms(1000);
|
||||
|
||||
/* testing */
|
||||
printf("testing: rf_chain:%u, dac_gain: %u, mix_gain:%u, dec_gain:%u, sig_ana_duration:%u\n", rf_chain, txlut.lut[0].dac_gain, txlut.lut[0].mix_gain, CAL_DEC_GAIN, CAL_SIG_ANA_DURATION);
|
||||
|
||||
test_freq_scan(rf_chain, false, false); /* rf_chain, full_log, use_agc */
|
||||
/* gnuplot> plot 'log.txt' with lines */
|
||||
|
||||
//test_iq_offset(rf_chain, 16, false, false); /* rf_chain, f_offset, full_log, use_agc */
|
||||
|
||||
//test_amp_phi(rf_chain, 240, true, true); /* rf_chain, f_offset, full_log, use_agc */
|
||||
|
||||
//test_capture_ram(rf_chain);
|
||||
|
||||
sx1302_radio_reset(0, LGW_RADIO_TYPE_SX1257);
|
||||
sx1302_radio_reset(1, LGW_RADIO_TYPE_SX1257);
|
||||
|
||||
/* disconnect the gateway */
|
||||
x = lgw_disconnect();
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to disconnect the gateway\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Close log file */
|
||||
fclose(fp);
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("=========== Test End ===========\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
369
libloragw/tst/test_loragw_capture_ram.c
Normal file
369
libloragw/tst/test_loragw_capture_ram.c
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program to test the capture RAM block
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
|
||||
// #include <stdint.h>
|
||||
#include <stdio.h> /* printf */
|
||||
#include <stdlib.h>
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <getopt.h> /* getopt_long */
|
||||
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_sx1250.h"
|
||||
#include "loragw_sx125x.h"
|
||||
#include "loragw_sx1302.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define DEBUG_MSG(str) fprintf(stderr, str)
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
#define FULL_INIT 0
|
||||
#define CAPTURE_RAM_SIZE 0x4000
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
/* Signal handling variables */
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
uint32_t sampling_frequency[] = {4e6, 4e6, 4e6, 4e6, 4e6, 4e6, 4e6, 0, 0, 1e6, 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 125e3, 8e6, 125e3, 125e3, 125e3, 0, 32e6, 32e6, 0, 32e6, 32e6, 0, 32e6, 32e6, 32e6};
|
||||
|
||||
#if FULL_INIT
|
||||
#include "src/text_agc_sx1250_27_Nov_1.var"
|
||||
#include "src/text_agc_sx1257_19_Nov_1.var"
|
||||
#include "src/text_arb_sx1302_13_Nov_3.var"
|
||||
|
||||
#define FW_VERSION_CAL 0 /* Expected version of calibration firmware */ /* TODO */
|
||||
#define FW_VERSION_AGC 1 /* Expected version of AGC firmware */
|
||||
#define FW_VERSION_ARB 1 /* Expected version of arbiter firmware */
|
||||
|
||||
static bool rf_enable[LGW_RF_CHAIN_NB];
|
||||
static uint32_t rf_rx_freq[LGW_RF_CHAIN_NB]; /* absolute, in Hz */
|
||||
static lgw_radio_type_t rf_radio_type[LGW_RF_CHAIN_NB];
|
||||
static uint8_t rf_clkout = 0;
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
/* describe command line options */
|
||||
void usage(void)
|
||||
{
|
||||
printf("Available options:\n");
|
||||
printf(" -h print this help\n");
|
||||
printf(" -d <path> use Linux SPI device driver\n");
|
||||
printf(" => default path: " LINUXDEV_PATH_DEFAULT "\n");
|
||||
printf(" -s <uint> Capture source [0..31]\n");
|
||||
}
|
||||
|
||||
/* handle signals */
|
||||
static void sig_handler(int sigio)
|
||||
{
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;
|
||||
}
|
||||
else if((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Main program */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int32_t val = 0;
|
||||
int reg_stat;
|
||||
unsigned int arg_u;
|
||||
uint8_t capture_source = 0;
|
||||
uint16_t period_value = 0;
|
||||
int16_t real = 0, imag = 0;
|
||||
#if FULL_INIT
|
||||
uint32_t val1, val2;
|
||||
#endif
|
||||
uint8_t capture_ram_buffer[CAPTURE_RAM_SIZE];
|
||||
|
||||
static struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
|
||||
/* Parameter parsing */
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* parse command line options */
|
||||
while ((i = getopt_long (argc, argv, "h:s:d:", long_options, &option_index)) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (optarg != NULL) {
|
||||
spidev_path = optarg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's': /* <uint> Capture Source */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 31)) {
|
||||
printf("ERROR: argument parsing of -s argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
capture_source = arg_u;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: argument parsing\n");
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure signal handling */
|
||||
sigemptyset( &sigact.sa_mask );
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction( SIGQUIT, &sigact, NULL );
|
||||
sigaction( SIGINT, &sigact, NULL );
|
||||
sigaction( SIGTERM, &sigact, NULL );
|
||||
|
||||
#if FULL_INIT
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize memory for capture */
|
||||
for (i = 0; i < CAPTURE_RAM_SIZE; i++) {
|
||||
capture_ram_buffer[i] = i%256;
|
||||
}
|
||||
|
||||
reg_stat = lgw_connect(spidev_path);
|
||||
if (reg_stat == LGW_REG_ERROR) {
|
||||
DEBUG_MSG("ERROR: FAIL TO CONNECT BOARD\n");
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Manual init */
|
||||
#if FULL_INIT
|
||||
rf_radio_type[0] = LGW_RADIO_TYPE_SX1250;
|
||||
rf_radio_type[1] = LGW_RADIO_TYPE_SX1257;
|
||||
rf_enable[0] = false;
|
||||
rf_enable[1] = true;
|
||||
rf_clkout = 1;
|
||||
rf_rx_freq[1] = 863700000;
|
||||
|
||||
/* setup radios */
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
if (rf_enable[i] == true) {
|
||||
sx1302_radio_reset(i, rf_radio_type[i]);
|
||||
switch (radio_type) {
|
||||
case LGW_RADIO_TYPE_SX1250:
|
||||
sx1250_setup(i, rf_rx_freq[i]);
|
||||
break;
|
||||
case LGW_RADIO_TYPE_SX1255:
|
||||
case LGW_RADIO_TYPE_SX1257:
|
||||
sx125x_setup(i, rf_clkout, true, rf_radio_type[i], rf_rx_freq[i]);
|
||||
break;
|
||||
default:
|
||||
DEBUG_MSG("ERROR: RADIO TYPE NOT SUPPORTED\n");
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
sx1302_radio_set_mode(i, radio_type);
|
||||
}
|
||||
}
|
||||
|
||||
/* Select the radio which provides the clock to the sx1302 */
|
||||
sx1302_radio_clock_select(rf_clkout);
|
||||
|
||||
/* Check that the SX1302 timestamp counter is running */
|
||||
lgw_get_instcnt(&val1);
|
||||
lgw_get_instcnt(&val2);
|
||||
if (val1 == val2) {
|
||||
printf("ERROR: SX1302 timestamp counter is not running (val:%u)\n", (uint32_t)val1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Configure Radio FE */
|
||||
sx1302_radio_fe_configure();
|
||||
|
||||
/* give radio control to AGC MCU */
|
||||
lgw_reg_w(SX1302_REG_COMMON_CTRL0_HOST_RADIO_CTRL, 0x00);
|
||||
|
||||
/* Load firmware */
|
||||
switch (rf_radio_type[rf_clkout]) {
|
||||
case LGW_RADIO_TYPE_SX1250:
|
||||
printf("Loading AGC fw for sx1250\n");
|
||||
if (sx1302_agc_load_firmware(agc_firmware_sx1250) != LGW_HAL_SUCCESS) {
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
if (sx1302_agc_start(FW_VERSION_AGC, SX1302_RADIO_TYPE_SX1250, SX1302_AGC_RADIO_GAIN_AUTO, SX1302_AGC_RADIO_GAIN_AUTO, 0) != LGW_HAL_SUCCESS) {
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
break;
|
||||
case LGW_RADIO_TYPE_SX1257:
|
||||
printf("Loading AGC fw for sx125x\n");
|
||||
if (sx1302_agc_load_firmware(agc_firmware_sx125x) != LGW_HAL_SUCCESS) {
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
if (sx1302_agc_start(FW_VERSION_AGC, SX1302_RADIO_TYPE_SX125X, SX1302_AGC_RADIO_GAIN_AUTO, SX1302_AGC_RADIO_GAIN_AUTO, 0) != LGW_HAL_SUCCESS) {
|
||||
// if (sx1302_agc_start(FW_VERSION_AGC, SX1302_RADIO_TYPE_SX125X, 1, 7, 0) != LGW_HAL_SUCCESS) {
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("Loading ARB fw\n");
|
||||
if (sx1302_arb_load_firmware(arb_firmware) != LGW_HAL_SUCCESS) {
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
if (sx1302_arb_start(FW_VERSION_ARB) != LGW_HAL_SUCCESS) {
|
||||
return LGW_HAL_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
// lgw_reg_w(SX1302_REG_CAPTURE_RAM_CLOCK_GATE_OVERRIDE_CLK_OVERRIDE, 3);
|
||||
|
||||
/* Configure the Capture Ram block */
|
||||
lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_ENABLE, 1); /* Enable Capture RAM */
|
||||
lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_CAPTUREWRAP, 0); /* Capture once, and stop when memory is full */
|
||||
lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_RAMCONFIG, 0); /* RAM configuration, 0: 4kx32, 1: 2kx64 */
|
||||
fprintf(stdout, "Capture source: %d\n", capture_source);
|
||||
lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_SOURCE_A_SOURCEMUX, capture_source);
|
||||
|
||||
printf("Sampling frequency: %d\n", sampling_frequency[capture_source]);
|
||||
if (sampling_frequency[capture_source] != 0)
|
||||
{
|
||||
period_value = (32e6/sampling_frequency[capture_source]) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr ,"ERROR: Sampling frequency is null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// fprintf(stdout, "period_value=%04X\n", period_value);
|
||||
lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_PERIOD_0_CAPTUREPERIOD, period_value & 0xFF); // LSB
|
||||
lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_PERIOD_1_CAPTUREPERIOD, (period_value>>8) & 0xFF); // MSB
|
||||
|
||||
/* Read back registers */
|
||||
// lgw_reg_r(SX1302_REG_CAPTURE_RAM_CAPTURE_PERIOD_0_CAPTUREPERIOD, &val);
|
||||
// fprintf(stdout, "SX1302_REG_CAPTURE_RAM_CAPTURE_PERIOD_0_CAPTUREPERIOD value: %d\n", val);
|
||||
// lgw_reg_r(SX1302_REG_CAPTURE_RAM_CAPTURE_PERIOD_1_CAPTUREPERIOD, &val);
|
||||
// fprintf(stdout, "SX1302_REG_CAPTURE_RAM_CAPTURE_PERIOD_1_CAPTUREPERIOD value: %d\n", val);
|
||||
|
||||
/* Launch capture */
|
||||
lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_CAPTURESTART, 1);
|
||||
// lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_CAPTUREFORCETRIGGER, 1);
|
||||
|
||||
/* Poll Status.CapComplete */
|
||||
do{
|
||||
lgw_reg_r(SX1302_REG_CAPTURE_RAM_STATUS_CAPCOMPLETE, &val);
|
||||
|
||||
wait_ms(10);
|
||||
if ((quit_sig == 1) || (exit_sig == 1)) {
|
||||
break;
|
||||
}
|
||||
} while (val != 1);
|
||||
lgw_reg_w(SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_CAPTURESTART, 0);
|
||||
|
||||
|
||||
// lgw_reg_r(SX1302_REG_CAPTURE_RAM_LAST_RAM_ADDR_0_LASTRAMADDR, &val);
|
||||
// fprintf(stdout, "SX1302_REG_CAPTURE_RAM_LAST_RAM_ADDR_0_LASTRAMADDR value: %02x\n", val);
|
||||
// lgw_reg_r(SX1302_REG_CAPTURE_RAM_LAST_RAM_ADDR_1_LASTRAMADDR, &val);
|
||||
// fprintf(stdout, "SX1302_REG_CAPTURE_RAM_LAST_RAM_ADDR_1_LASTRAMADDR value: %02x\n", val);
|
||||
|
||||
lgw_reg_w(SX1302_REG_COMMON_PAGE_PAGE, 1);
|
||||
lgw_mem_rb(0, capture_ram_buffer, CAPTURE_RAM_SIZE, false);
|
||||
lgw_reg_w(SX1302_REG_COMMON_PAGE_PAGE, 0);
|
||||
|
||||
printf("Data:\n");
|
||||
for (i = 0; i < CAPTURE_RAM_SIZE; i += 4)
|
||||
{
|
||||
if (((capture_source >= 2) && (capture_source <= 3)) || (capture_source == 9))
|
||||
{
|
||||
real = (int16_t)((((uint16_t)(capture_ram_buffer[i+3]) << 8) & 0xFF00) + ((uint16_t)capture_ram_buffer[i+2] & 0x00FF));
|
||||
imag = (int16_t)((((uint16_t)(capture_ram_buffer[i+1]) << 8) & 0xFF00) + ((uint16_t)capture_ram_buffer[i+0] & 0x00FF));
|
||||
real >>= 4; // 12 bits I
|
||||
imag >>= 4; // 12 bits Q
|
||||
}
|
||||
else if ((capture_source >= 4) && (capture_source <= 6))
|
||||
{
|
||||
real = (int16_t)((((uint16_t)(capture_ram_buffer[i+3]) << 8) & 0xFF00) + ((uint16_t)capture_ram_buffer[i+2] & 0x00FF)); // 16 bits I
|
||||
imag = (int16_t)((((uint16_t)(capture_ram_buffer[i+1]) << 8) & 0xFF00) + ((uint16_t)capture_ram_buffer[i+0] & 0x00FF)); // 16 bits Q
|
||||
}
|
||||
else if ((capture_source >= 10) && (capture_source <= 17))
|
||||
{
|
||||
real = (int8_t)(capture_ram_buffer[i+3]); // 8 bits I
|
||||
imag = (int8_t)(capture_ram_buffer[i+1]); // 8 bits Q
|
||||
}
|
||||
else
|
||||
{
|
||||
real = 0;
|
||||
imag = 0;
|
||||
}
|
||||
|
||||
if (((capture_source >= 2) && (capture_source <= 6)) || ((capture_source >= 9) && (capture_source <= 17)))
|
||||
{
|
||||
fprintf(stdout, "%d", real);
|
||||
if (imag >= 0)
|
||||
{
|
||||
fprintf(stdout, "+");
|
||||
}
|
||||
fprintf(stdout, "%di\n", imag);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%02X ", capture_ram_buffer[i]);
|
||||
}
|
||||
}
|
||||
printf("End of Data\n");
|
||||
|
||||
#if FULL_INIT
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
257
libloragw/tst/test_loragw_counter.c
Normal file
257
libloragw/tst/test_loragw_counter.c
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for HAL timestamp counter handling
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_aux.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define RAND_RANGE(min, max) (rand() % (max + 1 - min) + min)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define DEFAULT_FREQ_HZ 868500000U
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio) {
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;;
|
||||
} else if ((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void usage(void) {
|
||||
//printf("Library version information: %s\n", lgw_version_info());
|
||||
printf( "Available options:\n");
|
||||
printf( " -h print this help\n");
|
||||
printf( " -k <uint> Concentrator clock source (Radio A or Radio B) [0..1]\n");
|
||||
printf( " -r <uint> Radio type (1255, 1257, 1250)\n");
|
||||
printf( " -p Test PPS trig counter when set\n" );
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
|
||||
struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
|
||||
int i, x;
|
||||
uint32_t fa = DEFAULT_FREQ_HZ;
|
||||
uint32_t fb = DEFAULT_FREQ_HZ;
|
||||
unsigned int arg_u;
|
||||
uint8_t clocksource = 0;
|
||||
lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE;
|
||||
|
||||
struct lgw_conf_board_s boardconf;
|
||||
struct lgw_conf_rxrf_s rfconf;
|
||||
struct lgw_conf_rxif_s ifconf;
|
||||
|
||||
uint32_t counter;
|
||||
bool trig_cnt = false;
|
||||
|
||||
const int32_t channel_if[9] = {
|
||||
-400000,
|
||||
-200000,
|
||||
0,
|
||||
-400000,
|
||||
-200000,
|
||||
0,
|
||||
200000,
|
||||
400000,
|
||||
-200000 /* lora service */
|
||||
};
|
||||
|
||||
const uint8_t channel_rfchain[9] = { 1, 1, 1, 0, 0, 0, 0, 0, 1 };
|
||||
|
||||
/* parse command line options */
|
||||
while ((i = getopt (argc, argv, "hk:r:p")) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return -1;
|
||||
break;
|
||||
case 'r': /* <uint> Radio type */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || ((arg_u != 1255) && (arg_u != 1257) && (arg_u != 1250))) {
|
||||
printf("ERROR: argument parsing of -r argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
switch (arg_u) {
|
||||
case 1255:
|
||||
radio_type = LGW_RADIO_TYPE_SX1255;
|
||||
break;
|
||||
case 1257:
|
||||
radio_type = LGW_RADIO_TYPE_SX1257;
|
||||
break;
|
||||
default: /* 1250 */
|
||||
radio_type = LGW_RADIO_TYPE_SX1250;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'k': /* <uint> Clock Source */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 1)) {
|
||||
printf("ERROR: argument parsing of -k argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
clocksource = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
trig_cnt = true;
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: argument parsing\n");
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* configure signal handling */
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction(SIGQUIT, &sigact, NULL);
|
||||
sigaction(SIGINT, &sigact, NULL);
|
||||
sigaction(SIGTERM, &sigact, NULL);
|
||||
|
||||
printf("===== sx1302 counter test =====\n");
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Configure the gateway */
|
||||
memset( &boardconf, 0, sizeof boardconf);
|
||||
boardconf.lorawan_public = true;
|
||||
boardconf.clksrc = clocksource;
|
||||
boardconf.full_duplex = false;
|
||||
strncpy(boardconf.spidev_path, spidev_path, sizeof boardconf.spidev_path);
|
||||
if (lgw_board_setconf(&boardconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure board\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* set configuration for RF chains */
|
||||
memset( &rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = true;
|
||||
rfconf.freq_hz = fa;
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = false;
|
||||
if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 0\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset( &rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = true;
|
||||
rfconf.freq_hz = fb;
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = false;
|
||||
if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 1\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* set configuration for LoRa multi-SF channels (bandwidth cannot be set) */
|
||||
memset(&ifconf, 0, sizeof(ifconf));
|
||||
for (i = 0; i < 9; i++) {
|
||||
ifconf.enable = true;
|
||||
ifconf.rf_chain = channel_rfchain[i];
|
||||
ifconf.freq_hz = channel_if[i];
|
||||
ifconf.datarate = DR_LORA_SF7;
|
||||
if (lgw_rxif_setconf(i, &ifconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxif %d\n", i);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* connect, configure and start the LoRa concentrator */
|
||||
x = lgw_start();
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to start the gateway\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Loop until user quits */
|
||||
while( (quit_sig != 1) && (exit_sig != 1) ) {
|
||||
if (trig_cnt == false) {
|
||||
lgw_get_instcnt(&counter);
|
||||
} else {
|
||||
lgw_get_trigcnt(&counter);
|
||||
}
|
||||
wait_ms(10);
|
||||
}
|
||||
|
||||
/* Stop the gateway */
|
||||
x = lgw_stop();
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to stop the gateway\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("=========== Test End ===========\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
415
libloragw/tst/test_loragw_gps.c
Normal file
415
libloragw/tst/test_loragw_gps.c
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for the loragw_gps module
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h> /* C99 types */
|
||||
#include <stdbool.h> /* bool type */
|
||||
#include <stdio.h> /* printf */
|
||||
#include <string.h> /* memset */
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <stdlib.h> /* exit */
|
||||
#include <unistd.h> /* read */
|
||||
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_gps.h"
|
||||
#include "loragw_aux.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define MATCH(a,b) ( ((int32_t)(a-b)<=1) && ((int32_t)(a-b)>=-1) ) /* tolerate 1µs */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
struct tref ppm_ref;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DECLARATION ---------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio);
|
||||
static void gps_process_sync(void);
|
||||
static void gps_process_coords(void);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS DEFINITION ----------------------------------------- */
|
||||
|
||||
void usage(void) {
|
||||
//printf("Library version information: %s\n", lgw_version_info());
|
||||
printf( "Available options:\n");
|
||||
printf( " -h print this help\n");
|
||||
printf( " -k <uint> Concentrator clock source (Radio A or Radio B) [0..1]\n");
|
||||
printf( " -r <uint> Radio type (1255, 1257, 1250)\n");
|
||||
}
|
||||
|
||||
static void sig_handler(int sigio) {
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;;
|
||||
} else if ((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void gps_process_sync(void) {
|
||||
/* variables for PPM pulse GPS synchronization */
|
||||
uint32_t ppm_tstamp;
|
||||
struct timespec ppm_gps;
|
||||
struct timespec ppm_utc;
|
||||
|
||||
/* variables for timestamp <-> GPS time conversions */
|
||||
uint32_t x, z;
|
||||
struct timespec y;
|
||||
|
||||
/* get GPS time for synchronization */
|
||||
int i = lgw_gps_get(&ppm_utc, &ppm_gps, NULL, NULL);
|
||||
if (i != LGW_GPS_SUCCESS) {
|
||||
printf(" No valid reference GPS time available, synchronization impossible.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* get timestamp for synchronization */
|
||||
i = lgw_get_trigcnt(&ppm_tstamp);
|
||||
if (i != LGW_HAL_SUCCESS) {
|
||||
printf(" Failed to read timestamp, synchronization impossible.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to update synchronize time reference with the new GPS & timestamp */
|
||||
i = lgw_gps_sync(&ppm_ref, ppm_tstamp, ppm_utc, ppm_gps);
|
||||
if (i != LGW_GPS_SUCCESS) {
|
||||
printf(" Synchronization error.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* display result */
|
||||
printf(" * Synchronization successful *\n");
|
||||
printf(" UTC reference time: %lld.%09ld\n", (long long)ppm_ref.utc.tv_sec, ppm_ref.utc.tv_nsec);
|
||||
printf(" GPS reference time: %lld.%09ld\n", (long long)ppm_ref.gps.tv_sec, ppm_ref.gps.tv_nsec);
|
||||
printf(" Internal counter reference value: %u\n", ppm_ref.count_us);
|
||||
printf(" Clock error: %.9f\n", ppm_ref.xtal_err);
|
||||
|
||||
x = ppm_tstamp + 500000;
|
||||
|
||||
/* CNT -> GPS -> CNT */
|
||||
printf("\n");
|
||||
printf(" * Test of timestamp counter <-> GPS value conversion *\n");
|
||||
printf(" Test value: %u\n", x);
|
||||
lgw_cnt2gps(ppm_ref, x, &y);
|
||||
printf(" Conversion to GPS: %lld.%09ld\n", (long long)y.tv_sec, y.tv_nsec);
|
||||
lgw_gps2cnt(ppm_ref, y, &z);
|
||||
printf(" Converted back: %u ==> %dµs\n", z, (int32_t)(z-x));
|
||||
/* Display test result */
|
||||
if (MATCH(x,z)) {
|
||||
printf(" ** PASS **: (SX1302 -> GPS -> SX1302) conversion MATCH\n");
|
||||
} else {
|
||||
printf(" ** FAILED **: (SX1302 -> GPS -> SX1302) conversion MISMATCH\n");
|
||||
}
|
||||
|
||||
/* CNT -> UTC -> CNT */
|
||||
printf("\n");
|
||||
printf(" * Test of timestamp counter <-> UTC value conversion *\n");
|
||||
printf(" Test value: %u\n", x);
|
||||
lgw_cnt2utc(ppm_ref, x, &y);
|
||||
printf(" Conversion to UTC: %lld.%09ld\n", (long long)y.tv_sec, y.tv_nsec);
|
||||
lgw_utc2cnt(ppm_ref, y, &z);
|
||||
printf(" Converted back: %u ==> %dµs\n", z, (int32_t)(z-x));
|
||||
/* Display test result */
|
||||
if (MATCH(x,z)) {
|
||||
printf(" ** PASS **: (SX1302 -> UTC -> SX1302) conversion MATCH\n");
|
||||
} else {
|
||||
printf(" ** FAILED **: (SX1302 -> UTC -> SX1302) conversion MISMATCH\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void gps_process_coords(void) {
|
||||
/* position variable */
|
||||
struct coord_s coord;
|
||||
struct coord_s gpserr;
|
||||
int i = lgw_gps_get(NULL, NULL, &coord, &gpserr);
|
||||
|
||||
/* update gateway coordinates */
|
||||
if (i == LGW_GPS_SUCCESS) {
|
||||
printf("\n");
|
||||
printf("# GPS coordinates: latitude %.5f, longitude %.5f, altitude %i m\n", coord.lat, coord.lon, coord.alt);
|
||||
printf("# GPS err: latitude %.5f, longitude %.5f, altitude %i m\n", gpserr.lat, gpserr.lon, gpserr.alt);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
|
||||
struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
|
||||
int i;
|
||||
unsigned int arg_u;
|
||||
|
||||
/* concentrator variables */
|
||||
uint8_t clocksource = 0;
|
||||
lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE;
|
||||
struct lgw_conf_board_s boardconf;
|
||||
struct lgw_conf_rxrf_s rfconf;
|
||||
|
||||
/* serial variables */
|
||||
char serial_buff[128]; /* buffer to receive GPS data */
|
||||
size_t wr_idx = 0; /* pointer to end of chars in buffer */
|
||||
int gps_tty_dev; /* file descriptor to the serial port of the GNSS module */
|
||||
|
||||
/* NMEA/UBX variables */
|
||||
enum gps_msg latest_msg; /* keep track of latest NMEA/UBX message parsed */
|
||||
|
||||
/* parse command line options */
|
||||
while ((i = getopt (argc, argv, "hk:r:")) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return -1;
|
||||
break;
|
||||
case 'r': /* <uint> Radio type */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || ((arg_u != 1255) && (arg_u != 1257) && (arg_u != 1250))) {
|
||||
printf("ERROR: argument parsing of -r argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
switch (arg_u) {
|
||||
case 1255:
|
||||
radio_type = LGW_RADIO_TYPE_SX1255;
|
||||
break;
|
||||
case 1257:
|
||||
radio_type = LGW_RADIO_TYPE_SX1257;
|
||||
break;
|
||||
default: /* 1250 */
|
||||
radio_type = LGW_RADIO_TYPE_SX1250;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'k': /* <uint> Clock Source */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 1)) {
|
||||
printf("ERROR: argument parsing of -k argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
clocksource = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: argument parsing\n");
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check arguments */
|
||||
if (radio_type == LGW_RADIO_TYPE_NONE) {
|
||||
printf("ERROR: radio type must be specified\n");
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* configure signal handling */
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction(SIGQUIT, &sigact, NULL);
|
||||
sigaction(SIGINT, &sigact, NULL);
|
||||
sigaction(SIGTERM, &sigact, NULL);
|
||||
|
||||
/* Intro message and library information */
|
||||
printf("Beginning of test for loragw_gps.c\n");
|
||||
printf("*** Library version information ***\n%s\n***\n", lgw_version_info());
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Open and configure GPS */
|
||||
i = lgw_gps_enable("/dev/ttyS0", "ubx7", 0, &gps_tty_dev);
|
||||
if (i != LGW_GPS_SUCCESS) {
|
||||
printf("ERROR: Failed to enable GPS\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* start concentrator (default conf for IoT SK) */
|
||||
/* board config */
|
||||
memset(&boardconf, 0, sizeof(boardconf));
|
||||
boardconf.lorawan_public = true;
|
||||
boardconf.clksrc = clocksource;
|
||||
boardconf.full_duplex = false;
|
||||
strncpy(boardconf.spidev_path, spidev_path, sizeof boardconf.spidev_path);
|
||||
if (lgw_board_setconf(&boardconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure board\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* set configuration for RF chains */
|
||||
memset( &rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = true;
|
||||
rfconf.freq_hz = 868000000;
|
||||
rfconf.rssi_offset = 0.0;
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = false;
|
||||
if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 0\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset( &rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = true;
|
||||
rfconf.freq_hz = 868000000;
|
||||
rfconf.rssi_offset = 0.0;
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = false;
|
||||
if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 1\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* start */
|
||||
if (lgw_start() != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: IMPOSSIBLE TO START THE GATEWAY\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* initialize some variables before loop */
|
||||
memset(serial_buff, 0, sizeof serial_buff);
|
||||
memset(&ppm_ref, 0, sizeof ppm_ref);
|
||||
|
||||
/* loop until user action */
|
||||
while ((quit_sig != 1) && (exit_sig != 1)) {
|
||||
size_t rd_idx = 0;
|
||||
size_t frame_end_idx = 0;
|
||||
|
||||
/* blocking non-canonical read on serial port */
|
||||
ssize_t nb_char = read(gps_tty_dev, serial_buff + wr_idx, LGW_GPS_MIN_MSG_SIZE);
|
||||
if (nb_char <= 0) {
|
||||
printf("WARNING: [gps] read() returned value %d\n", nb_char);
|
||||
continue;
|
||||
}
|
||||
wr_idx += (size_t)nb_char;
|
||||
|
||||
/*******************************************
|
||||
* Scan buffer for UBX/NMEA sync chars and *
|
||||
* attempt to decode frame if one is found *
|
||||
*******************************************/
|
||||
while (rd_idx < wr_idx) {
|
||||
size_t frame_size = 0;
|
||||
|
||||
/* Scan buffer for UBX sync char */
|
||||
if (serial_buff[rd_idx] == LGW_GPS_UBX_SYNC_CHAR) {
|
||||
|
||||
/***********************
|
||||
* Found UBX sync char *
|
||||
***********************/
|
||||
latest_msg = lgw_parse_ubx(&serial_buff[rd_idx], (wr_idx - rd_idx), &frame_size);
|
||||
|
||||
if (frame_size > 0) {
|
||||
if (latest_msg == INCOMPLETE) {
|
||||
/* UBX header found but frame appears to be missing bytes */
|
||||
frame_size = 0;
|
||||
} else if (latest_msg == INVALID) {
|
||||
/* message header received but message appears to be corrupted */
|
||||
printf("WARNING: [gps] could not get a valid message from GPS (no time)\n");
|
||||
frame_size = 0;
|
||||
} else if (latest_msg == UBX_NAV_TIMEGPS) {
|
||||
printf("\n~~ UBX NAV-TIMEGPS sentence, triggering synchronization attempt ~~\n");
|
||||
gps_process_sync();
|
||||
}
|
||||
}
|
||||
} else if(serial_buff[rd_idx] == LGW_GPS_NMEA_SYNC_CHAR) {
|
||||
/************************
|
||||
* Found NMEA sync char *
|
||||
************************/
|
||||
/* scan for NMEA end marker (LF = 0x0a) */
|
||||
char* nmea_end_ptr = memchr(&serial_buff[rd_idx],(int)0x0a, (wr_idx - rd_idx));
|
||||
|
||||
if (nmea_end_ptr) {
|
||||
/* found end marker */
|
||||
frame_size = nmea_end_ptr - &serial_buff[rd_idx] + 1;
|
||||
latest_msg = lgw_parse_nmea(&serial_buff[rd_idx], frame_size);
|
||||
|
||||
if(latest_msg == INVALID || latest_msg == UNKNOWN) {
|
||||
/* checksum failed */
|
||||
frame_size = 0;
|
||||
} else if (latest_msg == NMEA_RMC) { /* Get location from RMC frames */
|
||||
gps_process_coords();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (frame_size > 0) {
|
||||
/* At this point message is a checksum verified frame
|
||||
we're processed or ignored. Remove frame from buffer */
|
||||
rd_idx += frame_size;
|
||||
frame_end_idx = rd_idx;
|
||||
} else {
|
||||
rd_idx++;
|
||||
}
|
||||
} /* ...for(rd_idx = 0... */
|
||||
|
||||
if (frame_end_idx) {
|
||||
/* Frames have been processed. Remove bytes to end of last processed frame */
|
||||
memcpy(serial_buff,&serial_buff[frame_end_idx],wr_idx - frame_end_idx);
|
||||
wr_idx -= frame_end_idx;
|
||||
} /* ...for(rd_idx = 0... */
|
||||
|
||||
/* Prevent buffer overflow */
|
||||
if ((sizeof(serial_buff) - wr_idx) < LGW_GPS_MIN_MSG_SIZE) {
|
||||
memcpy(serial_buff,&serial_buff[LGW_GPS_MIN_MSG_SIZE],wr_idx - LGW_GPS_MIN_MSG_SIZE);
|
||||
wr_idx -= LGW_GPS_MIN_MSG_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
/* clean up before leaving */
|
||||
if (exit_sig == 1) {
|
||||
lgw_gps_disable(gps_tty_dev);
|
||||
lgw_stop();
|
||||
}
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("\nEnd of test for loragw_gps.c\n");
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
320
libloragw/tst/test_loragw_hal_rx.c
Normal file
320
libloragw/tst/test_loragw_hal_rx.c
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for HAL RX capability
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_aux.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define RAND_RANGE(min, max) (rand() % (max + 1 - min) + min)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define DEFAULT_FREQ_HZ 868500000U
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio) {
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;
|
||||
} else if ((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void usage(void) {
|
||||
//printf("Library version information: %s\n", lgw_version_info());
|
||||
printf( "Available options:\n");
|
||||
printf( " -h print this help\n");
|
||||
printf( " -k <uint> Concentrator clock source (Radio A or Radio B) [0..1]\n");
|
||||
printf( " -r <uint> Radio type (1255, 1257, 1250)\n");
|
||||
printf( " -a <float> Radio A RX frequency in MHz\n");
|
||||
printf( " -b <float> Radio B RX frequency in MHz\n");
|
||||
printf( " -n <uint> number of packet received with CRC OK for each HAL start/stop loop\n");
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
|
||||
struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
|
||||
int i, j, x;
|
||||
uint32_t fa = DEFAULT_FREQ_HZ;
|
||||
uint32_t fb = DEFAULT_FREQ_HZ;
|
||||
double arg_d = 0.0;
|
||||
unsigned int arg_u;
|
||||
uint8_t clocksource = 0;
|
||||
lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE;
|
||||
|
||||
struct lgw_conf_board_s boardconf;
|
||||
struct lgw_conf_rxrf_s rfconf;
|
||||
struct lgw_conf_rxif_s ifconf;
|
||||
struct lgw_pkt_rx_s rxpkt[16];
|
||||
|
||||
unsigned long nb_pkt_crc_ok = 0, nb_loop = 1, cnt_loop;
|
||||
int nb_pkt;
|
||||
|
||||
const int32_t channel_if[9] = {
|
||||
-400000,
|
||||
-200000,
|
||||
0,
|
||||
-400000,
|
||||
-200000,
|
||||
0,
|
||||
200000,
|
||||
400000,
|
||||
-200000 /* lora service */
|
||||
};
|
||||
|
||||
const uint8_t channel_rfchain[9] = { 1, 1, 1, 0, 0, 0, 0, 0, 1 };
|
||||
|
||||
/* parse command line options */
|
||||
while ((i = getopt (argc, argv, "ha:b:k:r:n:")) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return -1;
|
||||
break;
|
||||
case 'r': /* <uint> Radio type */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || ((arg_u != 1255) && (arg_u != 1257) && (arg_u != 1250))) {
|
||||
printf("ERROR: argument parsing of -r argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
switch (arg_u) {
|
||||
case 1255:
|
||||
radio_type = LGW_RADIO_TYPE_SX1255;
|
||||
break;
|
||||
case 1257:
|
||||
radio_type = LGW_RADIO_TYPE_SX1257;
|
||||
break;
|
||||
default: /* 1250 */
|
||||
radio_type = LGW_RADIO_TYPE_SX1250;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'k': /* <uint> Clock Source */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 1)) {
|
||||
printf("ERROR: argument parsing of -k argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
clocksource = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'a': /* <float> Radio A RX frequency in MHz */
|
||||
i = sscanf(optarg, "%lf", &arg_d);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of -f argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
fa = (uint32_t)((arg_d*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
|
||||
}
|
||||
break;
|
||||
case 'b': /* <float> Radio B RX frequency in MHz */
|
||||
i = sscanf(optarg, "%lf", &arg_d);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of -f argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
fb = (uint32_t)((arg_d*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
|
||||
}
|
||||
break;
|
||||
case 'n': /* <uint> NUmber of packets to be received before exiting */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of -n argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
nb_loop = arg_u;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: argument parsing\n");
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* configure signal handling */
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction(SIGQUIT, &sigact, NULL);
|
||||
sigaction(SIGINT, &sigact, NULL);
|
||||
sigaction(SIGTERM, &sigact, NULL);
|
||||
|
||||
printf("===== sx1302 HAL RX test =====\n");
|
||||
|
||||
/* Configure the gateway */
|
||||
memset( &boardconf, 0, sizeof boardconf);
|
||||
boardconf.lorawan_public = true;
|
||||
boardconf.clksrc = clocksource;
|
||||
boardconf.full_duplex = false;
|
||||
strncpy(boardconf.spidev_path, spidev_path, sizeof boardconf.spidev_path);
|
||||
if (lgw_board_setconf(&boardconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure board\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* set configuration for RF chains */
|
||||
memset( &rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = true;
|
||||
rfconf.freq_hz = fa;
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = false;
|
||||
if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 0\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset( &rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = true;
|
||||
rfconf.freq_hz = fb;
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = false;
|
||||
if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 1\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* set configuration for LoRa multi-SF channels (bandwidth cannot be set) */
|
||||
memset(&ifconf, 0, sizeof(ifconf));
|
||||
for (i = 0; i < 9; i++) {
|
||||
ifconf.enable = true;
|
||||
ifconf.rf_chain = channel_rfchain[i];
|
||||
ifconf.freq_hz = channel_if[i];
|
||||
ifconf.datarate = DR_LORA_SF7;
|
||||
if (lgw_rxif_setconf(i, &ifconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxif %d\n", i);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop until user quits */
|
||||
cnt_loop = 0;
|
||||
while( (quit_sig != 1) && (exit_sig != 1) )
|
||||
{
|
||||
cnt_loop += 1;
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* connect, configure and start the LoRa concentrator */
|
||||
x = lgw_start();
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to start the gateway\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Loop until we have enough packets with CRC OK */
|
||||
printf("Waiting for packets...\n");
|
||||
nb_pkt_crc_ok = 0;
|
||||
while ((nb_pkt_crc_ok < nb_loop) && (quit_sig != 1) && (exit_sig != 1)) {
|
||||
/* fetch N packets */
|
||||
nb_pkt = lgw_receive(ARRAY_SIZE(rxpkt), rxpkt);
|
||||
|
||||
if (nb_pkt == 0) {
|
||||
wait_ms(10);
|
||||
} else {
|
||||
printf("Received %d packets\n", nb_pkt);
|
||||
for (i = 0; i < nb_pkt; i++) {
|
||||
if (rxpkt[i].status == STAT_CRC_OK) {
|
||||
nb_pkt_crc_ok += 1;
|
||||
}
|
||||
printf("\n----- %s packet -----\n", (rxpkt[i].modulation == MOD_LORA) ? "LoRa" : "FSK");
|
||||
printf(" count_us: %u\n", rxpkt[i].count_us);
|
||||
printf(" size: %u\n", rxpkt[i].size);
|
||||
printf(" chan: %u\n", rxpkt[i].if_chain);
|
||||
printf(" status: 0x%02X\n", rxpkt[i].status);
|
||||
printf(" datr: %u\n", rxpkt[i].datarate);
|
||||
printf(" codr: %u\n", rxpkt[i].coderate);
|
||||
printf(" rf_chain %u\n", rxpkt[i].rf_chain);
|
||||
printf(" freq_hz %u\n", rxpkt[i].freq_hz);
|
||||
printf(" snr_avg: %.1f\n", rxpkt[i].snr);
|
||||
printf(" rssi_chan:%.1f\n", rxpkt[i].rssic);
|
||||
printf(" rssi_sig :%.1f\n", rxpkt[i].rssis);
|
||||
printf(" crc: 0x%04X\n", rxpkt[i].crc);
|
||||
for (j = 0; j < rxpkt[i].size; j++) {
|
||||
printf("%02X ", rxpkt[i].payload[j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf( "\nNb valid packets received: %lu CRC OK (%lu)\n", nb_pkt_crc_ok, cnt_loop );
|
||||
|
||||
/* Stop the gateway */
|
||||
x = lgw_stop();
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to stop the gateway\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
printf("=========== Test End ===========\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
583
libloragw/tst/test_loragw_hal_tx.c
Normal file
583
libloragw/tst/test_loragw_hal_tx.c
Normal file
|
|
@ -0,0 +1,583 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for HAL TX capability
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <getopt.h> /* getopt_long */
|
||||
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_aux.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define RAND_RANGE(min, max) (rand() % (max + 1 - min) + min)
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
#define DEFAULT_CLK_SRC 0
|
||||
#define DEFAULT_FREQ_HZ 868500000U
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE VARIABLES ---------------------------------------------------- */
|
||||
|
||||
/* Signal handling variables */
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
/* describe command line options */
|
||||
void usage(void) {
|
||||
//printf("Library version information: %s\n", lgw_version_info());
|
||||
printf("Available options:\n");
|
||||
printf(" -h print this help\n");
|
||||
printf(" -k <uint> Concentrator clock source (Radio A or Radio B) [0..1]\n");
|
||||
printf(" -c <uint> RF chain to be used for TX (Radio A or Radio B) [0..1]\n");
|
||||
printf(" -r <uint> Radio type (1255, 1257, 1250)\n");
|
||||
printf(" -f <float> Radio TX frequency in MHz\n");
|
||||
printf(" -m <str> modulation type ['CW', 'LORA', 'FSK']\n");
|
||||
printf(" -o <int> CW frequency offset from Radio TX frequency in kHz [-65..65]\n");
|
||||
printf(" -s <uint> LoRa datarate 0:random, [5..12]\n");
|
||||
printf(" -b <uint> LoRa bandwidth in khz 0:random, [125, 250, 500]\n");
|
||||
printf(" -l <uint> FSK/LoRa preamble length, [6..65535]\n");
|
||||
printf(" -d <uint> FSK frequency deviation in kHz [1:250]\n");
|
||||
printf(" -q <float> FSK bitrate in kbps [0.5:250]\n");
|
||||
printf(" -n <uint> Number of packets to be sent\n");
|
||||
printf(" -z <uint> size of packets to be sent 0:random, [9..255]\n");
|
||||
printf(" -t <uint> TX mode timestamped with delay in ms. If delay is 0, TX mode GPS trigger\n");
|
||||
printf(" -p <int> RF power in dBm\n");
|
||||
printf(" -i Send LoRa packet using inverted modulation polarity\n");
|
||||
printf( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
|
||||
printf(" --pa <uint> PA gain SX125x:[0..3], SX1250:[0,1]\n");
|
||||
printf(" --dig <uint> sx1302 digital gain for sx125x [0..3]\n");
|
||||
printf(" --dac <uint> sx125x DAC gain [0..3]\n");
|
||||
printf(" --mix <uint> sx125x MIX gain [5..15]\n");
|
||||
printf(" --pwid <uint> sx1250 power index [0..22]\n");
|
||||
printf( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
|
||||
printf(" --nhdr Send LoRa packet with implicit header\n");
|
||||
printf( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
|
||||
printf(" --loop Number of loops for HAL start/stop (HAL unitary test)\n");
|
||||
}
|
||||
|
||||
/* handle signals */
|
||||
static void sig_handler(int sigio)
|
||||
{
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;
|
||||
}
|
||||
else if((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, x;
|
||||
uint32_t ft = DEFAULT_FREQ_HZ;
|
||||
int8_t rf_power = 0;
|
||||
uint8_t sf = 0;
|
||||
uint16_t bw_khz = 0;
|
||||
uint32_t nb_pkt = 1;
|
||||
unsigned int nb_loop = 1, cnt_loop;
|
||||
uint8_t size = 0;
|
||||
char mod[64] = "LORA";
|
||||
float br_kbps = 50;
|
||||
uint8_t fdev_khz = 25;
|
||||
int8_t freq_offset = 0;
|
||||
double arg_d = 0.0;
|
||||
unsigned int arg_u;
|
||||
int arg_i;
|
||||
char arg_s[64];
|
||||
float xf = 0.0;
|
||||
uint8_t clocksource = 0;
|
||||
uint8_t rf_chain = 0;
|
||||
lgw_radio_type_t radio_type = LGW_RADIO_TYPE_NONE;
|
||||
uint16_t preamble = 8;
|
||||
bool invert_pol = false;
|
||||
bool no_header = false;
|
||||
|
||||
struct lgw_conf_board_s boardconf;
|
||||
struct lgw_conf_rxrf_s rfconf;
|
||||
struct lgw_pkt_tx_s pkt;
|
||||
struct lgw_tx_gain_lut_s txlut; /* TX gain table */
|
||||
uint8_t tx_status;
|
||||
uint32_t count_us;
|
||||
uint32_t trig_delay_us = 1000000;
|
||||
bool trig_delay = false;
|
||||
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
|
||||
static struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
|
||||
/* Initialize TX gain LUT */
|
||||
txlut.size = 0;
|
||||
memset(txlut.lut, 0, sizeof txlut.lut);
|
||||
|
||||
/* Parameter parsing */
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{"pa", required_argument, 0, 0},
|
||||
{"dac", required_argument, 0, 0},
|
||||
{"dig", required_argument, 0, 0},
|
||||
{"mix", required_argument, 0, 0},
|
||||
{"pwid", required_argument, 0, 0},
|
||||
{"loop", required_argument, 0, 0},
|
||||
{"nhdr", no_argument, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* parse command line options */
|
||||
while ((i = getopt_long (argc, argv, "hif:s:b:n:z:p:k:r:c:l:t:m:o:q:d:", long_options, &option_index)) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return -1;
|
||||
break;
|
||||
case 'i': /* Send packet using inverted modulation polarity */
|
||||
invert_pol = true;
|
||||
break;
|
||||
case 'r': /* <uint> Radio type */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || ((arg_u != 1255) && (arg_u != 1257) && (arg_u != 1250))) {
|
||||
printf("ERROR: argument parsing of -r argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
switch (arg_u) {
|
||||
case 1255:
|
||||
radio_type = LGW_RADIO_TYPE_SX1255;
|
||||
break;
|
||||
case 1257:
|
||||
radio_type = LGW_RADIO_TYPE_SX1257;
|
||||
break;
|
||||
default: /* 1250 */
|
||||
radio_type = LGW_RADIO_TYPE_SX1250;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'l': /* <uint> LoRa/FSK preamble length */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 65535)) {
|
||||
printf("ERROR: argument parsing of -l argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
preamble = (uint16_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'm': /* <str> Modulation type */
|
||||
i = sscanf(optarg, "%s", arg_s);
|
||||
if ((i != 1) || ((strcmp(arg_s, "CW") != 0) && (strcmp(arg_s, "LORA") != 0) && (strcmp(arg_s, "FSK")))) {
|
||||
printf("ERROR: invalid modulation type\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
sprintf(mod, "%s", arg_s);
|
||||
}
|
||||
break;
|
||||
case 'o': /* <int> CW frequency offset from Radio TX frequency */
|
||||
i = sscanf(optarg, "%d", &arg_i);
|
||||
if ((arg_i < -65) || (arg_i > 65)) {
|
||||
printf("ERROR: invalid frequency offset\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
freq_offset = (int32_t)arg_i;
|
||||
}
|
||||
break;
|
||||
case 'd': /* <uint> FSK frequency deviation */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u < 1) || (arg_u > 250)) {
|
||||
printf("ERROR: invalid FSK frequency deviation\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
fdev_khz = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'q': /* <float> FSK bitrate */
|
||||
i = sscanf(optarg, "%f", &xf);
|
||||
if ((i != 1) || (xf < 0.5) || (xf > 250)) {
|
||||
printf("ERROR: invalid FSK bitrate\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
br_kbps = xf;
|
||||
}
|
||||
break;
|
||||
case 't': /* <uint> Trigger delay in ms */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of -t argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
trig_delay = true;
|
||||
trig_delay_us = (uint32_t)(arg_u * 1E3);
|
||||
}
|
||||
break;
|
||||
case 'k': /* <uint> Clock Source */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 1)) {
|
||||
printf("ERROR: argument parsing of -k argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
clocksource = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'c': /* <uint> RF chain */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 1)) {
|
||||
printf("ERROR: argument parsing of -c argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
rf_chain = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'f': /* <float> Radio TX frequency in MHz */
|
||||
i = sscanf(optarg, "%lf", &arg_d);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of -f argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
ft = (uint32_t)((arg_d*1e6) + 0.5); /* .5 Hz offset to get rounding instead of truncating */
|
||||
}
|
||||
break;
|
||||
case 's': /* <uint> LoRa datarate */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u < 5) || (arg_u > 12)) {
|
||||
printf("ERROR: argument parsing of -s argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
sf = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'b': /* <uint> LoRa bandwidth in khz */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || ((arg_u != 125) && (arg_u != 250) && (arg_u != 500))) {
|
||||
printf("ERROR: argument parsing of -b argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
bw_khz = (uint16_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'n': /* <uint> Number of packets to be sent */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of -n argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
nb_pkt = (uint32_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 'p': /* <int> RF power */
|
||||
i = sscanf(optarg, "%d", &arg_i);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of -p argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
rf_power = (int8_t)arg_i;
|
||||
txlut.size = 1;
|
||||
txlut.lut[0].rf_power = rf_power;
|
||||
}
|
||||
break;
|
||||
case 'z': /* <uint> packet size */
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u < 9) || (arg_u > 255)) {
|
||||
printf("ERROR: argument parsing of -z argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
size = (uint8_t)arg_u;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
if (strcmp(long_options[option_index].name, "pa") == 0) {
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 3)) {
|
||||
printf("ERROR: argument parsing of --pa argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
txlut.size = 1;
|
||||
txlut.lut[0].pa_gain = (uint8_t)arg_u;
|
||||
}
|
||||
} else if (strcmp(long_options[option_index].name, "dac") == 0) {
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 3)) {
|
||||
printf("ERROR: argument parsing of --dac argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
txlut.size = 1;
|
||||
txlut.lut[0].dac_gain = (uint8_t)arg_u;
|
||||
}
|
||||
} else if (strcmp(long_options[option_index].name, "mix") == 0) {
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 15)) {
|
||||
printf("ERROR: argument parsing of --mix argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
txlut.size = 1;
|
||||
txlut.lut[0].mix_gain = (uint8_t)arg_u;
|
||||
}
|
||||
} else if (strcmp(long_options[option_index].name, "dig") == 0) {
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 3)) {
|
||||
printf("ERROR: argument parsing of --dig argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
txlut.size = 1;
|
||||
txlut.lut[0].dig_gain = (uint8_t)arg_u;
|
||||
}
|
||||
} else if (strcmp(long_options[option_index].name, "pwid") == 0) {
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if ((i != 1) || (arg_u > 22)) {
|
||||
printf("ERROR: argument parsing of --pwid argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
txlut.size = 1;
|
||||
txlut.lut[0].mix_gain = 5; /* TODO: rework this, should not be needed for sx1250 */
|
||||
txlut.lut[0].pwr_idx = (uint8_t)arg_u;
|
||||
}
|
||||
} else if (strcmp(long_options[option_index].name, "loop") == 0) {
|
||||
printf("%p\n", optarg);
|
||||
i = sscanf(optarg, "%u", &arg_u);
|
||||
if (i != 1) {
|
||||
printf("ERROR: argument parsing of --loop argument. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
nb_loop = arg_u;
|
||||
}
|
||||
} else if (strcmp(long_options[option_index].name, "nhdr") == 0) {
|
||||
no_header = true;
|
||||
} else {
|
||||
printf("ERROR: argument parsing options. Use -h to print help\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: argument parsing\n");
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Summary of packet parameters */
|
||||
if (strcmp(mod, "CW") == 0) {
|
||||
printf("Sending %i CW on %u Hz (Freq. offset %d kHz) at %i dBm\n", nb_pkt, ft, freq_offset, rf_power);
|
||||
}
|
||||
else if (strcmp(mod, "FSK") == 0) {
|
||||
printf("Sending %i FSK packets on %u Hz (FDev %u kHz, Bitrate %.2f, %i bytes payload, %i symbols preamble) at %i dBm\n", nb_pkt, ft, fdev_khz, br_kbps, size, preamble, rf_power);
|
||||
} else {
|
||||
printf("Sending %i LoRa packets on %u Hz (BW %i kHz, SF %i, CR %i, %i bytes payload, %i symbols preamble, %s header, %s polarity) at %i dBm\n", nb_pkt, ft, bw_khz, sf, 1, size, preamble, (no_header == false) ? "explicit" : "implicit", (invert_pol == false) ? "non-inverted" : "inverted", rf_power);
|
||||
}
|
||||
|
||||
/* Configure signal handling */
|
||||
sigemptyset( &sigact.sa_mask );
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction( SIGQUIT, &sigact, NULL );
|
||||
sigaction( SIGINT, &sigact, NULL );
|
||||
sigaction( SIGTERM, &sigact, NULL );
|
||||
|
||||
/* Configure the gateway */
|
||||
memset( &boardconf, 0, sizeof boardconf);
|
||||
boardconf.lorawan_public = true;
|
||||
boardconf.clksrc = clocksource;
|
||||
boardconf.full_duplex = false;
|
||||
strncpy(boardconf.spidev_path, spidev_path, sizeof boardconf.spidev_path);
|
||||
if (lgw_board_setconf(&boardconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure board\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset( &rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = true; /* rf chain 0 needs to be enabled for calibration to work on sx1257 */
|
||||
rfconf.freq_hz = 868500000; /* dummy */
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = true;
|
||||
if (lgw_rxrf_setconf(0, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 0\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset( &rfconf, 0, sizeof rfconf);
|
||||
rfconf.enable = (((rf_chain == 1) || (clocksource == 1)) ? true : false);
|
||||
rfconf.freq_hz = 868500000; /* dummy */
|
||||
rfconf.type = radio_type;
|
||||
rfconf.tx_enable = false;
|
||||
if (lgw_rxrf_setconf(1, &rfconf) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure rxrf 1\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (txlut.size > 0) {
|
||||
if (lgw_txgain_setconf(rf_chain, &txlut) != LGW_HAL_SUCCESS) {
|
||||
printf("ERROR: failed to configure txgain lut\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
for (cnt_loop = 0; cnt_loop < nb_loop; cnt_loop++) {
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* connect, configure and start the LoRa concentrator */
|
||||
x = lgw_start();
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to start the gateway\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Send packets */
|
||||
memset(&pkt, 0, sizeof pkt);
|
||||
pkt.rf_chain = rf_chain;
|
||||
pkt.freq_hz = ft;
|
||||
pkt.rf_power = rf_power;
|
||||
if (trig_delay == false) {
|
||||
pkt.tx_mode = IMMEDIATE;
|
||||
} else {
|
||||
if (trig_delay_us == 0) {
|
||||
pkt.tx_mode = ON_GPS;
|
||||
} else {
|
||||
pkt.tx_mode = TIMESTAMPED;
|
||||
}
|
||||
}
|
||||
if ( strcmp( mod, "CW" ) == 0 ) {
|
||||
pkt.modulation = MOD_CW;
|
||||
pkt.freq_offset = freq_offset;
|
||||
pkt.f_dev = fdev_khz;
|
||||
}
|
||||
else if( strcmp( mod, "FSK" ) == 0 ) {
|
||||
pkt.modulation = MOD_FSK;
|
||||
pkt.no_crc = false;
|
||||
pkt.datarate = br_kbps * 1e3;
|
||||
pkt.f_dev = fdev_khz;
|
||||
} else {
|
||||
pkt.modulation = MOD_LORA;
|
||||
pkt.coderate = CR_LORA_4_5;
|
||||
pkt.no_crc = true;
|
||||
}
|
||||
pkt.invert_pol = invert_pol;
|
||||
pkt.preamble = preamble;
|
||||
pkt.no_header = no_header;
|
||||
pkt.payload[0] = 0x40; /* Confirmed Data Up */
|
||||
pkt.payload[1] = 0xAB;
|
||||
pkt.payload[2] = 0xAB;
|
||||
pkt.payload[3] = 0xAB;
|
||||
pkt.payload[4] = 0xAB;
|
||||
pkt.payload[5] = 0x00; /* FCTrl */
|
||||
pkt.payload[6] = 0; /* FCnt */
|
||||
pkt.payload[7] = 0; /* FCnt */
|
||||
pkt.payload[8] = 0x02; /* FPort */
|
||||
for (i = 9; i < 255; i++) {
|
||||
pkt.payload[i] = i;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)nb_pkt; i++) {
|
||||
if (trig_delay == true) {
|
||||
if (trig_delay_us > 0) {
|
||||
lgw_get_instcnt(&count_us);
|
||||
printf("count_us:%u\n", count_us);
|
||||
pkt.count_us = count_us + trig_delay_us;
|
||||
printf("programming TX for %u\n", pkt.count_us);
|
||||
} else {
|
||||
printf("programming TX for next PPS (GPS)\n");
|
||||
}
|
||||
}
|
||||
|
||||
if( strcmp( mod, "LORA" ) == 0 ) {
|
||||
pkt.datarate = (sf == 0) ? (uint8_t)RAND_RANGE(5, 12) : sf;
|
||||
}
|
||||
|
||||
switch (bw_khz) {
|
||||
case 125:
|
||||
pkt.bandwidth = BW_125KHZ;
|
||||
break;
|
||||
case 250:
|
||||
pkt.bandwidth = BW_250KHZ;
|
||||
break;
|
||||
case 500:
|
||||
pkt.bandwidth = BW_500KHZ;
|
||||
break;
|
||||
default:
|
||||
pkt.bandwidth = (uint8_t)RAND_RANGE(BW_125KHZ, BW_500KHZ);
|
||||
break;
|
||||
}
|
||||
|
||||
pkt.size = (size == 0) ? (uint8_t)RAND_RANGE(9, 255) : size;
|
||||
|
||||
pkt.payload[6] = (uint8_t)(i >> 0); /* FCnt */
|
||||
pkt.payload[7] = (uint8_t)(i >> 8); /* FCnt */
|
||||
x = lgw_send(&pkt);
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to send packet\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
/* wait for packet to finish sending */
|
||||
do {
|
||||
wait_ms(5);
|
||||
lgw_status(pkt.rf_chain, TX_STATUS, &tx_status); /* get TX status */
|
||||
} while ((tx_status != TX_FREE) && (quit_sig != 1) && (exit_sig != 1));
|
||||
|
||||
if ((quit_sig == 1) || (exit_sig == 1)) {
|
||||
break;
|
||||
}
|
||||
printf("TX done\n");
|
||||
}
|
||||
|
||||
printf( "\nNb packets sent: %u (%u)\n", i, cnt_loop + 1 );
|
||||
|
||||
/* Stop the gateway */
|
||||
x = lgw_stop();
|
||||
if (x != 0) {
|
||||
printf("ERROR: failed to stop the gateway\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
printf("=========== Test End ===========\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
245
libloragw/tst/test_loragw_i2c.c
Normal file
245
libloragw/tst/test_loragw_i2c.c
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for the loragw_i2c module
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* Fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <unistd.h> /* getopt, access */
|
||||
#include <time.h>
|
||||
|
||||
#include "loragw_i2c.h"
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_hal.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define I2C_PORT_STTS751 0x39
|
||||
|
||||
#define STTS751_REG_TEMP_H 0x00
|
||||
#define STTS751_REG_TEMP_L 0x02
|
||||
#define STTS751_REG_CONF 0x03
|
||||
#define STTS751_REG_RATE 0x04
|
||||
#define STTS751_REG_PROD_ID 0xFD
|
||||
#define STTS751_REG_MAN_ID 0xFE
|
||||
#define STTS751_REG_REV_ID 0xFF
|
||||
|
||||
#define STTS751_0_PROD_ID 0x00
|
||||
#define STTS751_1_PROD_ID 0x01
|
||||
#define ST_MAN_ID 0x53
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- GLOBAL VARIABLES ----------------------------------------------------- */
|
||||
|
||||
/* Signal handling variables */
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
static int i2c_dev = -1;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- SUBFUNCTIONS DECLARATION --------------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio);
|
||||
static void usage(void);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
int i, err;
|
||||
static struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
uint8_t val;
|
||||
uint8_t high_byte, low_byte;
|
||||
int8_t h;
|
||||
float temperature;
|
||||
|
||||
/* Parse command line options */
|
||||
while ((i = getopt(argc, argv, "hd:")) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return EXIT_SUCCESS;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (optarg != NULL) {
|
||||
/* TODO */
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: argument parsing options, use -h option for help\n");
|
||||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure signal handling */
|
||||
sigemptyset( &sigact.sa_mask );
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction( SIGQUIT, &sigact, NULL );
|
||||
sigaction( SIGINT, &sigact, NULL );
|
||||
sigaction( SIGTERM, &sigact, NULL );
|
||||
|
||||
printf( "+++ Start of I2C test program +++\n" );
|
||||
|
||||
/* Open I2C port expander */
|
||||
err = i2c_linuxdev_open( I2C_DEVICE, I2C_PORT_STTS751, &i2c_dev );
|
||||
if ( (err != 0) || (i2c_dev <= 0) )
|
||||
{
|
||||
printf( "ERROR: failed to open I2C device %s (err=%i)\n", I2C_DEVICE, err );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Get temperature sensor product ID */
|
||||
err = i2c_linuxdev_read( i2c_dev, I2C_PORT_STTS751, STTS751_REG_PROD_ID, &val );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device %s (err=%i)\n", I2C_DEVICE, err );
|
||||
return EXIT_FAILURE;;
|
||||
}
|
||||
switch( val )
|
||||
{
|
||||
case STTS751_0_PROD_ID:
|
||||
printf("INFO: Product ID: STTS751-0\n");
|
||||
break;
|
||||
case STTS751_1_PROD_ID:
|
||||
printf("INFO: Product ID: STTS751-1\n");
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: Product ID: UNKNOWN\n");
|
||||
return EXIT_FAILURE;;
|
||||
}
|
||||
|
||||
/* Get temperature sensor Manufacturer ID */
|
||||
err = i2c_linuxdev_read( i2c_dev, I2C_PORT_STTS751, STTS751_REG_MAN_ID, &val );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device %s (err=%i)\n", I2C_DEVICE, err );
|
||||
return EXIT_FAILURE;;
|
||||
}
|
||||
if ( val != ST_MAN_ID )
|
||||
{
|
||||
printf( "ERROR: Manufacturer ID: UNKNOWN\n" );
|
||||
return EXIT_FAILURE;;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("INFO: Manufacturer ID: 0x%02X\n", val);
|
||||
}
|
||||
|
||||
/* Get temperature sensor revision number */
|
||||
err = i2c_linuxdev_read( i2c_dev, I2C_PORT_STTS751, STTS751_REG_REV_ID, &val );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device %s (err=%i)\n", I2C_DEVICE, err );
|
||||
return EXIT_FAILURE;;
|
||||
}
|
||||
printf("INFO: Revision number: 0x%02X\n", val);
|
||||
|
||||
/* Set conversion resolution to 12 bits */
|
||||
err = i2c_linuxdev_write( i2c_dev, I2C_PORT_STTS751, STTS751_REG_CONF, 0x8C ); /* TODO: do not hardcode the whole byte */
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to write I2C device 0x%02X (err=%i)\n", I2C_PORT_STTS751, err );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Set conversion rate to 1 / second */
|
||||
err = i2c_linuxdev_write( i2c_dev, I2C_PORT_STTS751, STTS751_REG_RATE, 0x04 );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to write I2C device 0x%02X (err=%i)\n", I2C_PORT_STTS751, err );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while ((quit_sig != 1) && (exit_sig != 1)) {
|
||||
/* Read Temperature LSB */
|
||||
err = i2c_linuxdev_read( i2c_dev, I2C_PORT_STTS751, STTS751_REG_TEMP_L, &low_byte );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", I2C_PORT_STTS751, err );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Read Temperature MSB */
|
||||
err = i2c_linuxdev_read( i2c_dev, I2C_PORT_STTS751, STTS751_REG_TEMP_H, &high_byte );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to read I2C device 0x%02X (err=%i)\n", I2C_PORT_STTS751, err );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
h = (int8_t)high_byte;
|
||||
temperature = ((h << 8) | low_byte) / 256.0;
|
||||
|
||||
printf( "Temperature: %f C (h:0x%02X l:0x%02X)\n", temperature, high_byte, low_byte );
|
||||
wait_ms( 100 );
|
||||
}
|
||||
|
||||
/* Terminate */
|
||||
printf( "+++ End of I2C test program +++\n" );
|
||||
|
||||
err = i2c_linuxdev_close( i2c_dev );
|
||||
if ( err != 0 )
|
||||
{
|
||||
printf( "ERROR: failed to close I2C device (err=%i)\n", err );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- SUBFUNCTIONS DEFINITION ---------------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio) {
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;
|
||||
} else if((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
static void usage(void) {
|
||||
printf("~~~ Library version string~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||
printf(" %s\n", lgw_version_info());
|
||||
printf("~~~ Available options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||
printf(" -h print this help\n");
|
||||
printf(" -d <path> use Linux I2C device driver\n");
|
||||
printf(" => default path: " I2C_DEVICE "\n");
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
204
libloragw/tst/test_loragw_reg.c
Normal file
204
libloragw/tst/test_loragw_reg.c
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for the loragw_reg module
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* Fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* getopt, access */
|
||||
#include <math.h>
|
||||
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_hal.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
extern const struct lgw_reg_s loregs[LGW_TOTALREGS+1];
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- SUBFUNCTIONS DECLARATION --------------------------------------------- */
|
||||
|
||||
static void usage(void);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
int x, i;
|
||||
int32_t val;
|
||||
bool error_found = false;
|
||||
uint8_t rand_values[LGW_TOTALREGS];
|
||||
bool reg_ignored[LGW_TOTALREGS]; /* store register to be ignored */
|
||||
uint8_t reg_val;
|
||||
uint8_t reg_max;
|
||||
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
|
||||
/* Parse command line options */
|
||||
while ((i = getopt(argc, argv, "hd:")) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return EXIT_SUCCESS;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (optarg != NULL) {
|
||||
spidev_path = optarg;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: argument parsing options, use -h option for help\n");
|
||||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
x = lgw_connect(spidev_path);
|
||||
if (x != LGW_REG_SUCCESS) {
|
||||
printf("ERROR: failed to connect\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The following registers cannot be tested this way */
|
||||
memset(reg_ignored, 0, sizeof reg_ignored);
|
||||
reg_ignored[SX1302_REG_COMMON_CTRL0_CLK32_RIF_CTRL] = true; /* all test fails if we set this one to 1 */
|
||||
|
||||
/* Test 1: read all registers and check default value for non-read-only registers */
|
||||
printf("## TEST#1: read all registers and check default value for non-read-only registers\n");
|
||||
error_found = false;
|
||||
for (i = 0; i < LGW_TOTALREGS; i++) {
|
||||
if (loregs[i].rdon == 0) {
|
||||
x = lgw_reg_r(i, &val);
|
||||
if (x != LGW_REG_SUCCESS) {
|
||||
printf("ERROR: failed to read register at index %d\n", i);
|
||||
return -1;
|
||||
}
|
||||
if (val != loregs[i].dflt) {
|
||||
printf("ERROR: default value for register at index %d is %d, should be %d\n", i, val, loregs[i].dflt);
|
||||
error_found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("------------------\n");
|
||||
printf(" TEST#1 %s\n", (error_found == false) ? "PASSED" : "FAILED");
|
||||
printf("------------------\n\n");
|
||||
|
||||
/* Test 2: read/write test on all non-read-only, non-pulse, non-w0clr, non-w1clr registers */
|
||||
printf("## TEST#2: read/write test on all non-read-only, non-pulse, non-w0clr, non-w1clr registers\n");
|
||||
/* Write all registers with a random value */
|
||||
error_found = false;
|
||||
for (i = 0; i < LGW_TOTALREGS; i++) {
|
||||
if ((loregs[i].rdon == 0) && (reg_ignored[i] == false)) {
|
||||
/* Peek a random value different form the default reg value */
|
||||
reg_max = pow(2, loregs[i].leng) - 1;
|
||||
if (loregs[i].leng == 1) {
|
||||
reg_val = !loregs[i].dflt;
|
||||
} else {
|
||||
/* ensure random value is not the default one */
|
||||
do {
|
||||
if (loregs[i].sign == 1) {
|
||||
reg_val = rand() % (reg_max / 2);
|
||||
} else {
|
||||
reg_val = rand() % reg_max;
|
||||
}
|
||||
} while (reg_val == loregs[i].dflt);
|
||||
}
|
||||
/* Write selected value */
|
||||
x = lgw_reg_w(i, reg_val);
|
||||
if (x != LGW_REG_SUCCESS) {
|
||||
printf("ERROR: failed to read register at index %d\n", i);
|
||||
return -1;
|
||||
}
|
||||
/* store value for later check */
|
||||
rand_values[i] = reg_val;
|
||||
}
|
||||
}
|
||||
/* Read all registers and check if we got proper random value back */
|
||||
for (i = 0; i < LGW_TOTALREGS; i++) {
|
||||
if ((loregs[i].rdon == 0) && (loregs[i].chck == 1) && (reg_ignored[i] == false)) {
|
||||
x = lgw_reg_r(i, &val);
|
||||
if (x != LGW_REG_SUCCESS) {
|
||||
printf("ERROR: failed to read register at index %d\n", i);
|
||||
return -1;
|
||||
}
|
||||
/* check value */
|
||||
if (val != rand_values[i]) {
|
||||
printf("ERROR: value read from register at index %d differs from the written value (w:%u r:%d)\n", i, rand_values[i], val);
|
||||
error_found = true;
|
||||
} else {
|
||||
//printf("INFO: MATCH reg %d (%u, %u)\n", i, rand_values[i], (uint8_t)val);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("------------------\n");
|
||||
printf(" TEST#2 %s\n", (error_found == false) ? "PASSED" : "FAILED");
|
||||
printf("------------------\n\n");
|
||||
|
||||
x = lgw_disconnect();
|
||||
if (x != LGW_REG_SUCCESS) {
|
||||
printf("ERROR: failed to disconnect\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- SUBFUNCTIONS DEFINITION ---------------------------------------------- */
|
||||
|
||||
static void usage(void) {
|
||||
printf("~~~ Library version string~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||
printf(" %s\n", lgw_version_info());
|
||||
printf("~~~ Available options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||
printf(" -h print this help\n");
|
||||
printf(" -d <path> use Linux SPI device driver\n");
|
||||
printf(" => default path: " LINUXDEV_PATH_DEFAULT "\n");
|
||||
}
|
||||
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
208
libloragw/tst/test_loragw_spi.c
Normal file
208
libloragw/tst/test_loragw_spi.c
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for the loragw_spi module
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* Fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <unistd.h> /* getopt, access */
|
||||
#include <time.h>
|
||||
|
||||
#include "loragw_spi.h"
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_hal.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define BUFF_SIZE 1024
|
||||
|
||||
#define SX1302_AGC_MCU_MEM 0x0000
|
||||
#define SX1302_REG_COMMON 0x5600
|
||||
#define SX1302_REG_AGC_MCU 0x5780
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- GLOBAL VARIABLES ----------------------------------------------------- */
|
||||
|
||||
/* Signal handling variables */
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- SUBFUNCTIONS DECLARATION --------------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio);
|
||||
static void usage(void);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
static struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
|
||||
uint8_t data = 0;
|
||||
uint8_t test_buff[BUFF_SIZE];
|
||||
uint8_t read_buff[BUFF_SIZE];
|
||||
int cycle_number = 0;
|
||||
int i;
|
||||
uint16_t size;
|
||||
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
void *spi_target = NULL;
|
||||
|
||||
/* Parse command line options */
|
||||
while ((i = getopt(argc, argv, "hd:")) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return EXIT_SUCCESS;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (optarg != NULL) {
|
||||
spidev_path = optarg;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: argument parsing options, use -h option for help\n");
|
||||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure signal handling */
|
||||
sigemptyset( &sigact.sa_mask );
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction( SIGQUIT, &sigact, NULL );
|
||||
sigaction( SIGINT, &sigact, NULL );
|
||||
sigaction( SIGTERM, &sigact, NULL );
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Beginning of test for loragw_spi.c\n");
|
||||
i = lgw_spi_open(spidev_path, &spi_target);
|
||||
if (i != 0) {
|
||||
printf("ERROR: failed to open SPI device %s\n", spidev_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* normal R/W test */
|
||||
/* TODO */
|
||||
|
||||
/* burst R/W test, small bursts << LGW_BURST_CHUNK */
|
||||
/* TODO */
|
||||
|
||||
/* burst R/W test, large bursts >> LGW_BURST_CHUNK */
|
||||
/* TODO */
|
||||
|
||||
lgw_spi_r(spi_target, LGW_SPI_MUX_TARGET_SX1302, SX1302_REG_COMMON + 6, &data);
|
||||
printf("SX1302 version: 0x%02X\n", data);
|
||||
|
||||
lgw_spi_r(spi_target, LGW_SPI_MUX_TARGET_SX1302, SX1302_REG_AGC_MCU + 0, &data);
|
||||
lgw_spi_w(spi_target, LGW_SPI_MUX_TARGET_SX1302, SX1302_REG_AGC_MCU + 0, 0x06); /* mcu_clear, host_prog */
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
/* databuffer R/W stress test */
|
||||
while ((quit_sig != 1) && (exit_sig != 1)) {
|
||||
size = rand() % BUFF_SIZE;
|
||||
for (i = 0; i < size; ++i) {
|
||||
test_buff[i] = rand() & 0xFF;
|
||||
}
|
||||
printf("Cycle %i > ", cycle_number);
|
||||
lgw_spi_wb(spi_target, LGW_SPI_MUX_TARGET_SX1302, SX1302_AGC_MCU_MEM, test_buff, size);
|
||||
lgw_spi_rb(spi_target, LGW_SPI_MUX_TARGET_SX1302, SX1302_AGC_MCU_MEM, read_buff, size);
|
||||
for (i=0; ((i<size) && (test_buff[i] == read_buff[i])); ++i);
|
||||
if (i != size) {
|
||||
printf("error during the buffer comparison\n");
|
||||
printf("Written values:\n");
|
||||
for (i=0; i<size; ++i) {
|
||||
printf(" %02X ", test_buff[i]);
|
||||
if (i%16 == 15) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
printf("Read values:\n");
|
||||
for (i=0; i<size; ++i) {
|
||||
printf(" %02X ", read_buff[i]);
|
||||
if (i%16 == 15) printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
printf("did a %i-byte R/W on a data buffer with no error\n", size);
|
||||
++cycle_number;
|
||||
}
|
||||
}
|
||||
|
||||
lgw_spi_close(spi_target);
|
||||
printf("End of test for loragw_spi.c\n");
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- SUBFUNCTIONS DEFINITION ---------------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio) {
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;
|
||||
} else if((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
static void usage(void) {
|
||||
printf("~~~ Library version string~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||
printf(" %s\n", lgw_version_info());
|
||||
printf("~~~ Available options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||
printf(" -h print this help\n");
|
||||
printf(" -d <path> use Linux SPI device driver\n");
|
||||
printf(" => default path: " LINUXDEV_PATH_DEFAULT "\n");
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
216
libloragw/tst/test_loragw_spi_sx1250.c
Normal file
216
libloragw/tst/test_loragw_spi_sx1250.c
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
_____) ) ____| | | || |_| ____( (___| | | |
|
||||
(______/|_____)_|_|_| \__)_____)\____)_| |_|
|
||||
(C)2019 Semtech
|
||||
|
||||
Description:
|
||||
Minimum test program for the sx1250 module
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
*/
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- DEPENDANCIES --------------------------------------------------------- */
|
||||
|
||||
/* Fix an issue between POSIX and C99 */
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#define _XOPEN_SOURCE 600
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h> /* sigaction */
|
||||
#include <unistd.h> /* getopt, access */
|
||||
|
||||
#include "loragw_spi.h"
|
||||
#include "loragw_aux.h"
|
||||
#include "loragw_reg.h"
|
||||
#include "loragw_hal.h"
|
||||
#include "loragw_sx1250.h"
|
||||
#include "loragw_sx1302.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE MACROS ------------------------------------------------------- */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
|
||||
|
||||
#define BUFF_SIZE 16
|
||||
|
||||
#define LINUXDEV_PATH_DEFAULT "/dev/spidev0.0"
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- GLOBAL VARIABLES ----------------------------------------------------- */
|
||||
|
||||
/* Signal handling variables */
|
||||
static int exit_sig = 0; /* 1 -> application terminates cleanly (shut down hardware, close open files, etc) */
|
||||
static int quit_sig = 0; /* 1 -> application terminates without shutting down the hardware */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- SUBFUNCTIONS DECLARATION --------------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio);
|
||||
static void usage(void);
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- MAIN FUNCTION -------------------------------------------------------- */
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
static struct sigaction sigact; /* SIGQUIT&SIGINT&SIGTERM signal handling */
|
||||
|
||||
uint8_t test_buff[BUFF_SIZE];
|
||||
uint8_t read_buff[BUFF_SIZE];
|
||||
uint32_t test_val, read_val;
|
||||
int cycle_number = 0;
|
||||
int i, x;
|
||||
|
||||
/* SPI interfaces */
|
||||
const char spidev_path_default[] = LINUXDEV_PATH_DEFAULT;
|
||||
const char * spidev_path = spidev_path_default;
|
||||
|
||||
/* Parse command line options */
|
||||
while ((i = getopt(argc, argv, "hd:")) != -1) {
|
||||
switch (i) {
|
||||
case 'h':
|
||||
usage();
|
||||
return EXIT_SUCCESS;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (optarg != NULL) {
|
||||
spidev_path = optarg;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: argument parsing options, use -h option for help\n");
|
||||
usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure signal handling */
|
||||
sigemptyset( &sigact.sa_mask );
|
||||
sigact.sa_flags = 0;
|
||||
sigact.sa_handler = sig_handler;
|
||||
sigaction( SIGQUIT, &sigact, NULL );
|
||||
sigaction( SIGINT, &sigact, NULL );
|
||||
sigaction( SIGTERM, &sigact, NULL );
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh start") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
x = lgw_connect(spidev_path);
|
||||
if (x != LGW_REG_SUCCESS) {
|
||||
printf("ERROR: Failed to connect to the concentrator using SPI %s\n", spidev_path);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Reset radios */
|
||||
for (i = 0; i < LGW_RF_CHAIN_NB; i++) {
|
||||
sx1302_radio_reset(i, LGW_RADIO_TYPE_SX1250);
|
||||
sx1302_radio_set_mode(i, LGW_RADIO_TYPE_SX1250);
|
||||
}
|
||||
|
||||
/* Select the radio which provides the clock to the sx1302 */
|
||||
sx1302_radio_clock_select(0);
|
||||
|
||||
/* Ensure we can control the radio */
|
||||
lgw_reg_w(SX1302_REG_COMMON_CTRL0_HOST_RADIO_CTRL, 0x01);
|
||||
|
||||
/* Ensure PA/LNA are disabled */
|
||||
lgw_reg_w(SX1302_REG_AGC_MCU_CTRL_FORCE_HOST_FE_CTRL, 1);
|
||||
lgw_reg_w(SX1302_REG_AGC_MCU_RF_EN_A_PA_EN, 0);
|
||||
lgw_reg_w(SX1302_REG_AGC_MCU_RF_EN_A_LNA_EN, 0);
|
||||
|
||||
/* Set Radio in Standby mode */
|
||||
test_buff[0] = (uint8_t)STDBY_XOSC;
|
||||
sx1250_write_command(0, SET_STANDBY, test_buff, 1);
|
||||
sx1250_write_command(1, SET_STANDBY, test_buff, 1);
|
||||
wait_ms(10);
|
||||
|
||||
test_buff[0] = 0x00;
|
||||
sx1250_read_command(0, GET_STATUS, test_buff, 1);
|
||||
printf("Radio0: get_status: 0x%02X\n", test_buff[0]);
|
||||
sx1250_read_command(1, GET_STATUS, test_buff, 1);
|
||||
printf("Radio1: get_status: 0x%02X\n", test_buff[0]);
|
||||
|
||||
/* databuffer R/W stress test */
|
||||
while ((quit_sig != 1) && (exit_sig != 1)) {
|
||||
test_buff[0] = rand() & 0x7F;
|
||||
test_buff[1] = rand() & 0xFF;
|
||||
test_buff[2] = rand() & 0xFF;
|
||||
test_buff[3] = rand() & 0xFF;
|
||||
test_val = (test_buff[0] << 24) | (test_buff[1] << 16) | (test_buff[2] << 8) | (test_buff[3] << 0);
|
||||
sx1250_write_command(0, SET_RF_FREQUENCY, test_buff, 4);
|
||||
|
||||
read_buff[0] = 0x08;
|
||||
read_buff[1] = 0x8B;
|
||||
read_buff[2] = 0x00;
|
||||
read_buff[3] = 0x00;
|
||||
read_buff[4] = 0x00;
|
||||
read_buff[5] = 0x00;
|
||||
read_buff[6] = 0x00;
|
||||
sx1250_read_command(0, READ_REGISTER, read_buff, 7);
|
||||
read_val = (read_buff[3] << 24) | (read_buff[4] << 16) | (read_buff[5] << 8) | (read_buff[6] << 0);
|
||||
|
||||
printf("Cycle %i > ", cycle_number);
|
||||
if (read_val != test_val) {
|
||||
printf("error during the buffer comparison\n");
|
||||
printf("Written value: %08X\n", test_val);
|
||||
printf("Read value: %08X\n", read_val);
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
printf("did a %i-byte R/W on a register with no error\n", 4);
|
||||
++cycle_number;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lgw_disconnect();
|
||||
printf("End of test for loragw_spi_sx1250.c\n");
|
||||
|
||||
/* Board reset */
|
||||
if (system("./reset_lgw.sh stop") != 0) {
|
||||
printf("ERROR: failed to reset SX1302, check your reset_lgw.sh script\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* --- SUBFUNCTIONS DEFINITION ---------------------------------------------- */
|
||||
|
||||
static void sig_handler(int sigio) {
|
||||
if (sigio == SIGQUIT) {
|
||||
quit_sig = 1;
|
||||
} else if((sigio == SIGINT) || (sigio == SIGTERM)) {
|
||||
exit_sig = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
static void usage(void) {
|
||||
printf("~~~ Library version string~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||
printf(" %s\n", lgw_version_info());
|
||||
printf("~~~ Available options ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
|
||||
printf(" -h print this help\n");
|
||||
printf(" -d <path> use Linux SPI device driver\n");
|
||||
printf(" => default path: " LINUXDEV_PATH_DEFAULT "\n");
|
||||
}
|
||||
|
||||
/* --- EOF ------------------------------------------------------------------ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue