kopia lustrzana https://github.com/N0BOY/FT8CN
265 wiersze
8.7 KiB
Java
265 wiersze
8.7 KiB
Java
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;
|
||
|
||
import com.bg7yoz.ft8cn.Ft8Message;
|
||
import com.bg7yoz.ft8cn.GeneralVariables;
|
||
import com.bg7yoz.ft8cn.R;
|
||
import com.bg7yoz.ft8cn.connector.ConnectMode;
|
||
import com.bg7yoz.ft8cn.database.ControlMode;
|
||
import com.bg7yoz.ft8cn.ft8transmit.GenerateFT8;
|
||
import com.bg7yoz.ft8cn.ui.ToastMessage;
|
||
|
||
import java.util.Timer;
|
||
import java.util.TimerTask;
|
||
|
||
public class XieGu6100Rig extends BaseRig {
|
||
private static final String TAG = "x6100Rig";
|
||
|
||
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) {
|
||
|
||
if (GeneralVariables.connectMode == ConnectMode.NETWORK) {
|
||
getConnector().setPttOn(on);
|
||
return;
|
||
}
|
||
|
||
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;
|
||
}
|
||
XieGu6100Command xieGu6100Command;
|
||
if (headIndex == 0) {
|
||
xieGu6100Command = XieGu6100Command.getCommand(ctrAddress, getCivAddress(), data);
|
||
} else {
|
||
byte[] temp = new byte[data.length - headIndex];
|
||
System.arraycopy(data, headIndex, temp, 0, temp.length);
|
||
xieGu6100Command = XieGu6100Command.getCommand(ctrAddress, getCivAddress(), temp);
|
||
}
|
||
if (xieGu6100Command == null) {
|
||
return;
|
||
}
|
||
|
||
//目前只对频率和模式消息作反应
|
||
switch (xieGu6100Command.getCommandID()) {
|
||
case IcomRigConstant.CMD_SEND_FREQUENCY_DATA://获取到的是频率数据
|
||
case IcomRigConstant.CMD_READ_OPERATING_FREQUENCY:
|
||
//获取频率
|
||
long freqTemp = xieGu6100Command.getFrequency(false);
|
||
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//此处的指令,只在网络模式实现,以后可能会在串口方面实现
|
||
if (xieGu6100Command.getSubCommand() == IcomRigConstant.CMD_READ_METER_SWR) {
|
||
//协谷的小端模式
|
||
int temp=IcomRigConstant.twoByteBcdToIntBigEnd(xieGu6100Command.getData(true));
|
||
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;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
@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);
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void readFreqFromRig() {
|
||
if (getConnector() != null) {
|
||
getConnector().sendData(IcomRigConstant.setReadFreq(ctrAddress, getCivAddress()));
|
||
//getConnector().sendData(IcomRigConstant.setReadFreq(getCivAddress(), getCivAddress()));
|
||
}
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|