diff --git a/rigs/icom/ic746.c b/rigs/icom/ic746.c index a17a04ced..2023a3160 100644 --- a/rigs/icom/ic746.c +++ b/rigs/icom/ic746.c @@ -42,7 +42,6 @@ * * TODO: * - advanced scanning functions - * - set_channel * - set_ctcss_tone/ctcss_sql * - set keyer? * - test all that stuff.. @@ -115,9 +114,9 @@ typedef struct { - unsigned char freq[5]; /* little endian frequency */ + unsigned char freq[5]; /* little endian frequency */ unsigned char mode; - unsigned char pb; /* passband or filter selection*/ + signed char pb; /* passband or filter selection*/ unsigned char data; /* data port 0=off 1=on */ unsigned char dup; /* duplex, tone, tonesql and DTCS Values in hex are "or"ed together @@ -131,8 +130,7 @@ typedef struct unsigned char tone_sql[3]; /* tone squelch frequency as tone */ struct { - //unsigned char - //pol; /* DTCS polarity by nibbles Tx pol | Rx pol; 0 = normal; 1 = rev */ + unsigned char pol; /* DTCS polarity by nibbles Tx pol | Rx pol; 0 = normal; 1 = rev */ unsigned char code[2]; /* DTCS code bigendian */ } dcs; } channel_str_t; @@ -157,6 +155,7 @@ typedef channel_str_t band_stack_reg_t; static int ic746_set_parm(RIG *rig, setting_t parm, value_t val); static int ic746_get_parm(RIG *rig, setting_t parm, value_t *val); static int ic746pro_get_channel(RIG *rig, channel_t *chan); +static int ic746pro_set_channel(RIG *rig, const channel_t *chan); static int ic746pro_set_ext_parm(RIG *rig, token_t token, value_t val); static int ic746pro_get_ext_parm(RIG *rig, token_t token, value_t *val); @@ -576,6 +575,7 @@ const struct rig_caps ic746pro_caps = .set_ext_parm = ic746pro_set_ext_parm, .get_ext_parm = ic746pro_get_ext_parm, .get_channel = ic746pro_get_channel, + .set_channel = ic746pro_set_channel, }; @@ -905,7 +905,7 @@ int ic746pro_get_channel(RIG *rig, channel_t *chan) { struct icom_priv_data *priv; struct rig_state *rs; - unsigned char chanbuf[50]; + unsigned char chanbuf[MAXFRAMELEN]; mem_buf_t *membuf; int chan_len, freq_len, retval, data_len; @@ -984,7 +984,8 @@ int ic746pro_get_channel(RIG *rig, channel_t *chan) membuf = (mem_buf_t *)(chanbuf + 4); - chan->flags = membuf->chan_flag && 0x01 ? RIG_CHFLAG_SKIP : RIG_CHFLAG_NONE; + chan->split = membuf->chan_flag & 0x10 ? RIG_SPLIT_ON : RIG_SPLIT_OFF; + chan->flags = membuf->chan_flag & 0x01 ? RIG_CHFLAG_SKIP : RIG_CHFLAG_NONE; rig_debug(RIG_DEBUG_TRACE, "%s: chan->flags=0x%02x\n", __func__, chan->flags); /* data mode on */ rig_debug(RIG_DEBUG_TRACE, "%s: membuf->rx.data=0x%02x\n", __func__, membuf->rx.data); @@ -1003,7 +1004,7 @@ int ic746pro_get_channel(RIG *rig, channel_t *chan) rig_debug(RIG_DEBUG_TRACE, "%s: chan->rptr_shift=%d\n", __func__, chan->rptr_shift); /* offset is default for the band & is not stored in channel memory. - The following retrieves the system default for the band */ + The following retrieves the system default for the band */ band = (int) chan->freq / 1000000; /* hf, 2m or 6 m */ if (band < 50) { sc = S_MEM_HF_DUP_OFST; } @@ -1041,3 +1042,153 @@ int ic746pro_get_channel(RIG *rig, channel_t *chan) return RIG_OK; } + +/* + * ic746pro_set_channel + * Assumes rig!=NULL, rig->state.priv!=NULL, chan!=NULL + */ +int ic746pro_set_channel(RIG *rig, const channel_t *chan) +{ + struct icom_priv_data *priv; + struct rig_state *rs; + mem_buf_t membuf = {0}; + unsigned char chanbuf[MAXFRAMELEN], ackbuf[MAXFRAMELEN]; + int chan_len, ack_len, freq_len, retval; + + rs = &rig->state; + priv = (struct icom_priv_data *)rs->priv; + + freq_len = priv->civ_731_mode ? 4 : 5; + + // set memory channel + to_bcd_be(chanbuf, chan->channel_num, 4); + chan_len = 2; + + // if good value, we change the memory otherwise clear + if (chan->freq != 0 || chan->mode != 0) + { + if (chan->split == RIG_SPLIT_ON) + membuf.chan_flag |= 0x10; + else + membuf.chan_flag |= chan->flags & RIG_CHFLAG_SKIP ? 0x01 : 0x00; + + // RX + to_bcd(membuf.rx.freq, chan->freq, freq_len * 2); + + retval = rig2icom_mode(rig, chan->mode, chan->width, + &membuf.rx.mode, &membuf.rx.pb); + + if (retval != RIG_OK) + { + return retval; + } + + if(membuf.rx.pb == -1) + membuf.rx.pb = PD_MEDIUM_3; + + membuf.rx.data = chan->flags & RIG_CHFLAG_DATA ? 1 : 0; + membuf.rx.dup = chan->rptr_shift; + + // not empty otherwise the call fail + if (chan->ctcss_tone == 0) + to_bcd_be(membuf.rx.tone, 885, 6); + else + to_bcd_be(membuf.rx.tone, chan->ctcss_tone, 6); + if (chan->ctcss_sql == 0) + to_bcd_be(membuf.rx.tone_sql, 885, 6); + else + to_bcd_be(membuf.rx.tone_sql, chan->ctcss_sql, 6); + + if (chan->dcs_code == 0) + to_bcd_be(membuf.rx.dcs.code, 23, 4); + else + to_bcd_be(membuf.rx.dcs.code, chan->dcs_code, 4); + + // TX + to_bcd(membuf.tx.freq, chan->tx_freq, freq_len * 2); + + retval = rig2icom_mode(rig, chan->tx_mode, chan->tx_width, + &membuf.tx.mode, &membuf.tx.pb); + + if (retval != RIG_OK) + { + return retval; + } + + if(membuf.tx.pb == -1) + membuf.tx.pb = PD_MEDIUM_3; + + membuf.tx.data = chan->flags | RIG_CHFLAG_DATA ? 1 : 0; + membuf.tx.dup = chan->rptr_shift; + + // not empty otherwise the call fail + if (chan->ctcss_tone == 0) + to_bcd_be(membuf.tx.tone, 885, 6); + else + to_bcd_be(membuf.tx.tone, chan->ctcss_tone, 6); + if (chan->ctcss_sql == 0) + to_bcd_be(membuf.tx.tone_sql, 885, 6); + else + to_bcd_be(membuf.tx.tone_sql, chan->ctcss_sql, 6); + + if (chan->dcs_code == 0) + to_bcd_be(membuf.tx.dcs.code, 23, 4); + else + to_bcd_be(membuf.tx.dcs.code, chan->dcs_code, 4); + + // set description + memcpy(membuf.name, chan->channel_desc, sizeof(membuf.name)); + + memcpy(chanbuf+chan_len, &membuf, sizeof(mem_buf_t)); + chan_len += sizeof(mem_buf_t); + + retval = icom_transaction(rig, C_CTL_MEM, S_MEM_CNTNT, + chanbuf, chan_len, ackbuf, &ack_len); + + if (retval != RIG_OK) + { + return retval; + } + + if (ack_len != 1 || ackbuf[0] != ACK) + { + rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " + "len=%d\n", ackbuf[0], ack_len); + return -RIG_ERJCTED; + } + } + else + { + retval = icom_transaction(rig, C_SET_MEM, -1, + chanbuf, chan_len, ackbuf, &ack_len); + + if (retval != RIG_OK) + { + return retval; + } + + if (ack_len != 1 || ackbuf[0] != ACK) + { + rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " + "len=%d\n", ackbuf[0], ack_len); + return -RIG_ERJCTED; + } + + retval = icom_transaction(rig, C_CLR_MEM, -1, NULL, 0, ackbuf, &ack_len); + + if (retval != RIG_OK) + { + return retval; + } + + if (ack_len != 1 || ackbuf[0] != ACK) + { + rig_debug(RIG_DEBUG_ERR, "icom_set_channel: ack NG (%#.2x), " + "len=%d\n", ackbuf[0], ack_len); + return -RIG_ERJCTED; + } + + } + + return RIG_OK; +} diff --git a/tests/memcsv.c b/tests/memcsv.c index 1383efe71..d0ce5a0dd 100644 --- a/tests/memcsv.c +++ b/tests/memcsv.c @@ -548,11 +548,6 @@ void dump_csv_name(const channel_cap_t *mem_caps, FILE *f) fprintf(f, "flags%c", csv_sep); } - if (mem_caps->channel_desc) - { - fprintf(f, "channel_desc%c", csv_sep); - } - fprintf(f, "\n"); } @@ -708,11 +703,6 @@ int dump_csv_chan(RIG *rig, fprintf(f, "%x%c", chan.flags, csv_sep); } - if (mem_caps->channel_desc) - { - fprintf(f, "%s", chan.channel_desc); - } - fprintf(f, "\n"); /* diff --git a/tests/memsave.c b/tests/memsave.c index 218a805fa..fca02853b 100644 --- a/tests/memsave.c +++ b/tests/memsave.c @@ -285,12 +285,6 @@ int dump_xml_chan(RIG *rig, xmlNewProp(node, (unsigned char *) "flags", (unsigned char *) attrbuf); } - if (mem_caps->channel_desc) - { - sprintf(attrbuf, "%s", chan.channel_desc); - xmlNewProp(node, (unsigned char *) "channel_desc", (unsigned char *) attrbuf); - } - return 0; } #endif