2023-08-15 05:18:25 +00:00
|
|
|
|
package com.bg7yoz.ft8cn.rigs;
|
|
|
|
|
|
|
|
|
|
import static com.bg7yoz.ft8cn.GeneralVariables.QUERY_FREQ_TIMEOUT;
|
|
|
|
|
import static com.bg7yoz.ft8cn.GeneralVariables.START_QUERY_FREQ_DELAY;
|
|
|
|
|
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
2023-09-12 05:45:53 +00:00
|
|
|
|
import com.bg7yoz.ft8cn.Ft8Message;
|
2023-08-15 05:18:25 +00:00
|
|
|
|
import com.bg7yoz.ft8cn.GeneralVariables;
|
|
|
|
|
import com.bg7yoz.ft8cn.R;
|
2023-09-12 05:45:53 +00:00
|
|
|
|
import com.bg7yoz.ft8cn.connector.ConnectMode;
|
2023-08-15 05:18:25 +00:00
|
|
|
|
import com.bg7yoz.ft8cn.database.ControlMode;
|
2023-09-12 05:45:53 +00:00
|
|
|
|
import com.bg7yoz.ft8cn.ft8transmit.GenerateFT8;
|
2023-08-15 05:18:25 +00:00
|
|
|
|
import com.bg7yoz.ft8cn.ui.ToastMessage;
|
|
|
|
|
|
|
|
|
|
import java.util.Timer;
|
|
|
|
|
import java.util.TimerTask;
|
|
|
|
|
|
|
|
|
|
public class XieGu6100Rig extends BaseRig {
|
2023-09-12 05:45:53 +00:00
|
|
|
|
private static final String TAG = "x6100Rig";
|
2023-08-15 05:18:25 +00:00
|
|
|
|
|
|
|
|
|
private final int ctrAddress = 0xE0;//接收地址,默认0xE0;电台回复命令有时也可以是0x00
|
|
|
|
|
private byte[] dataBuffer = new byte[0];//数据缓冲区
|
|
|
|
|
private int swr = 0;
|
|
|
|
|
private boolean swrAlert = false;
|
|
|
|
|
private Timer readFreqTimer = new Timer();
|
|
|
|
|
|
|
|
|
|
private TimerTask readTask() {
|
|
|
|
|
return new TimerTask() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
try {
|
|
|
|
|
if (!isConnected()) {
|
|
|
|
|
readFreqTimer.cancel();
|
|
|
|
|
readFreqTimer.purge();
|
|
|
|
|
readFreqTimer = null;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (isPttOn()){
|
|
|
|
|
readSWRMeter();
|
|
|
|
|
}else {
|
|
|
|
|
readFreqFromRig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
Log.e(TAG, "readFreq or meter error:" + e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void setPTT(boolean on) {
|
|
|
|
|
super.setPTT(on);
|
|
|
|
|
|
|
|
|
|
if (getConnector() != null) {
|
2023-09-12 05:45:53 +00:00
|
|
|
|
|
|
|
|
|
if (GeneralVariables.connectMode == ConnectMode.NETWORK) {
|
|
|
|
|
getConnector().setPttOn(on);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-15 05:18:25 +00:00
|
|
|
|
switch (getControlMode()) {
|
|
|
|
|
case ControlMode.CAT://以CIV指令
|
|
|
|
|
getConnector().setPttOn(IcomRigConstant.setPTTState(ctrAddress, getCivAddress()
|
|
|
|
|
, on ? IcomRigConstant.PTT_ON : IcomRigConstant.PTT_OFF));
|
|
|
|
|
break;
|
|
|
|
|
case ControlMode.RTS:
|
|
|
|
|
case ControlMode.DTR:
|
|
|
|
|
getConnector().setPttOn(on);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isConnected() {
|
|
|
|
|
if (getConnector() == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return getConnector().isConnected();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void setUsbModeToRig() {
|
|
|
|
|
if (getConnector() != null) {
|
|
|
|
|
// getConnector().sendData(IcomRigConstant.setOperationMode(ctrAddress
|
|
|
|
|
// , getCivAddress(), 1));//usb=1
|
|
|
|
|
getConnector().sendData(IcomRigConstant.setOperationDataMode(ctrAddress
|
|
|
|
|
, getCivAddress(), IcomRigConstant.USB));//usb-d
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void setFreqToRig() {
|
|
|
|
|
if (getConnector() != null) {
|
|
|
|
|
getConnector().sendData(IcomRigConstant.setOperationFrequency(ctrAddress
|
|
|
|
|
, getCivAddress(), getFreq()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查找指令的结尾的位置,如果没找到,值是-1。
|
|
|
|
|
*
|
|
|
|
|
* @param data 数据
|
|
|
|
|
* @return 位置
|
|
|
|
|
*/
|
|
|
|
|
private int getCommandEnd(byte[] data) {
|
|
|
|
|
for (int i = 0; i < data.length; i++) {
|
|
|
|
|
if (data[i] == (byte) 0xFD) {
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 查找指令头,没找到返回-1,找到返回FE FE的第一个位置
|
|
|
|
|
*
|
|
|
|
|
* @param data 数据
|
|
|
|
|
* @return 位置
|
|
|
|
|
*/
|
|
|
|
|
private int getCommandHead(byte[] data) {
|
|
|
|
|
if (data.length < 2) return -1;
|
|
|
|
|
for (int i = 0; i < data.length - 1; i++) {
|
|
|
|
|
if (data[i] == (byte) 0xFE && data[i + 1] == (byte) 0xFE) {
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void analysisCommand(byte[] data) {
|
|
|
|
|
int headIndex = getCommandHead(data);
|
|
|
|
|
if (headIndex == -1) {//说明没有指令头
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-09-12 05:45:53 +00:00
|
|
|
|
XieGu6100Command xieGu6100Command;
|
2023-08-15 05:18:25 +00:00
|
|
|
|
if (headIndex == 0) {
|
2023-09-12 05:45:53 +00:00
|
|
|
|
xieGu6100Command = XieGu6100Command.getCommand(ctrAddress, getCivAddress(), data);
|
2023-08-15 05:18:25 +00:00
|
|
|
|
} else {
|
|
|
|
|
byte[] temp = new byte[data.length - headIndex];
|
|
|
|
|
System.arraycopy(data, headIndex, temp, 0, temp.length);
|
2023-09-12 05:45:53 +00:00
|
|
|
|
xieGu6100Command = XieGu6100Command.getCommand(ctrAddress, getCivAddress(), temp);
|
2023-08-15 05:18:25 +00:00
|
|
|
|
}
|
2023-09-12 05:45:53 +00:00
|
|
|
|
if (xieGu6100Command == null) {
|
2023-08-15 05:18:25 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//目前只对频率和模式消息作反应
|
2023-09-12 05:45:53 +00:00
|
|
|
|
switch (xieGu6100Command.getCommandID()) {
|
2023-08-15 05:18:25 +00:00
|
|
|
|
case IcomRigConstant.CMD_SEND_FREQUENCY_DATA://获取到的是频率数据
|
|
|
|
|
case IcomRigConstant.CMD_READ_OPERATING_FREQUENCY:
|
|
|
|
|
//获取频率
|
2023-09-12 05:45:53 +00:00
|
|
|
|
long freqTemp = xieGu6100Command.getFrequency(false);
|
2023-08-15 05:18:25 +00:00
|
|
|
|
if (freqTemp >= 500000 && freqTemp <= 250000000) {//协谷的频率范围
|
|
|
|
|
setFreq(freqTemp);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case IcomRigConstant.CMD_SEND_MODE_DATA://获取到的是模式数据
|
|
|
|
|
case IcomRigConstant.CMD_READ_OPERATING_MODE:
|
|
|
|
|
break;
|
|
|
|
|
case IcomRigConstant.CMD_READ_METER://读meter//此处的指令,只在网络模式实现,以后可能会在串口方面实现
|
2023-09-12 05:45:53 +00:00
|
|
|
|
if (xieGu6100Command.getSubCommand() == IcomRigConstant.CMD_READ_METER_SWR) {
|
2023-08-15 05:18:25 +00:00
|
|
|
|
//协谷的小端模式
|
2023-09-12 05:45:53 +00:00
|
|
|
|
int temp=IcomRigConstant.twoByteBcdToIntBigEnd(xieGu6100Command.getData(true));
|
2023-08-15 05:18:25 +00:00
|
|
|
|
if (temp!=255) {
|
|
|
|
|
swr = temp;//
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
showAlert();//检查meter值是否在告警范围
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void showAlert() {
|
|
|
|
|
if (swr >= IcomRigConstant.swr_alert_max) {
|
|
|
|
|
if (!swrAlert) {
|
|
|
|
|
swrAlert = true;
|
|
|
|
|
ToastMessage.show(GeneralVariables.getStringFromResource(R.string.swr_high_alert));
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
swrAlert = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onReceiveData(byte[] data) {
|
|
|
|
|
int commandEnd = getCommandEnd(data);
|
|
|
|
|
if (commandEnd <= -1) {//这是没有指令结尾
|
|
|
|
|
byte[] temp = new byte[dataBuffer.length + data.length];
|
|
|
|
|
System.arraycopy(dataBuffer, 0, temp, 0, dataBuffer.length);
|
|
|
|
|
System.arraycopy(data, 0, temp, dataBuffer.length, data.length);
|
|
|
|
|
dataBuffer = temp;
|
|
|
|
|
} else {
|
|
|
|
|
byte[] temp = new byte[dataBuffer.length + commandEnd + 1];
|
|
|
|
|
System.arraycopy(dataBuffer, 0, temp, 0, dataBuffer.length);
|
|
|
|
|
dataBuffer = temp;
|
|
|
|
|
System.arraycopy(data, 0, dataBuffer, dataBuffer.length - commandEnd - 1, commandEnd + 1);
|
|
|
|
|
}
|
|
|
|
|
if (commandEnd != -1) {
|
|
|
|
|
analysisCommand(dataBuffer);
|
|
|
|
|
}
|
|
|
|
|
dataBuffer = new byte[0];//清空缓冲区
|
|
|
|
|
if (commandEnd <= -1 || commandEnd < data.length) {
|
|
|
|
|
byte[] temp = new byte[data.length - commandEnd + 1];
|
|
|
|
|
for (int i = 0; i < data.length - commandEnd - 1; i++) {
|
|
|
|
|
temp[i] = data[commandEnd + i + 1];
|
|
|
|
|
}
|
|
|
|
|
dataBuffer = temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-12 05:45:53 +00:00
|
|
|
|
@Override
|
|
|
|
|
public void sendWaveData(Ft8Message message) {//发送音频数据到电台,用于网络方式
|
|
|
|
|
if (getConnector() != null) {//把生成的具体音频数据传递到Connector,
|
|
|
|
|
float[] data = GenerateFT8.generateFt8(message, GeneralVariables.getBaseFrequency()
|
|
|
|
|
,12000);//此处icom电台发射音频的采样率是12000
|
|
|
|
|
if (data==null){
|
|
|
|
|
setPTT(false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
getConnector().sendWaveData(data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-15 05:18:25 +00:00
|
|
|
|
@Override
|
|
|
|
|
public void readFreqFromRig() {
|
|
|
|
|
if (getConnector() != null) {
|
|
|
|
|
getConnector().sendData(IcomRigConstant.setReadFreq(ctrAddress, getCivAddress()));
|
2023-09-12 05:45:53 +00:00
|
|
|
|
//getConnector().sendData(IcomRigConstant.setReadFreq(getCivAddress(), getCivAddress()));
|
2023-08-15 05:18:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void readSWRMeter() {
|
|
|
|
|
if (getConnector() != null) {
|
|
|
|
|
getConnector().sendData(IcomRigConstant.getSWRState(ctrAddress, getCivAddress()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getName() {
|
|
|
|
|
return "XIEGU X6100 series";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String getFrequencyStr() {
|
|
|
|
|
return BaseRigOperation.getFrequencyStr(getFreq());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public XieGu6100Rig(int civAddress) {
|
|
|
|
|
Log.d(TAG, "XieGuRig: Create.");
|
|
|
|
|
setCivAddress(civAddress);
|
|
|
|
|
|
|
|
|
|
readFreqTimer.schedule(readTask(), START_QUERY_FREQ_DELAY, QUERY_FREQ_TIMEOUT);
|
|
|
|
|
}
|
|
|
|
|
}
|