FT8CN/ft8cn/app/src/main/java/com/bg7yoz/ft8cn/rigs/XieGu6100Rig.java

273 wiersze
9.1 KiB
Java
Czysty Wina Historia

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.connector.X6100Connector;
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
//判断如果是ft8cns就传输a19数据包
if (GeneralVariables.instructionSet == InstructionSet.XIEGU_6100_FT8CNS){
//Log.e(TAG,"generate A91");
getConnector().sendFt8A91(GenerateFT8.generateA91(message,true)
,GeneralVariables.getBaseFrequency());
}else {//否则正常传输音频数据
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);
}
}