Setup channels.

This commit is contained in:
Serge Vakulenko 2018-08-30 13:39:14 -07:00
parent 204d737dcc
commit c82cd5dabf
4 changed files with 344 additions and 117 deletions

194
md380.c
View File

@ -427,49 +427,85 @@ static void setup_channel(int i, int mode, char *name, double rx_mhz, double tx_
int admit, int colorcode, int timeslot, int incall, int grouplist, int contact,
int rxtone, int txtone, int width)
{
//TODO: always set Data Call Confirmed=1 (wait for SMS acknowledge)
//TODO: always set talkaround=0
#if 0
memory_channel_t *ch = i + (memory_channel_t*) &radio_mem[OFFSET_CHANNELS];
channel_t *ch = (channel_t*) &radio_mem[OFFSET_CHANNELS + i*64];
hz_to_freq((int) (rx_mhz * 1000000.0), ch->rxfreq);
// Byte 0
ch->channel_mode = mode;
ch->bandwidth = width;
ch->autoscan = autoscan;
ch->squelch = squelch;
ch->_unused1 = 1;
ch->lone_worker = 0;
double offset_mhz = tx_mhz - rx_mhz;
ch->offset = 0;
ch->txfreq[0] = ch->txfreq[1] = ch->txfreq[2] = 0;
if (offset_mhz == 0) {
ch->duplex = D_SIMPLEX;
} else if (offset_mhz > 0 && offset_mhz < 256 * 0.05) {
ch->duplex = D_POS_OFFSET;
ch->offset = (int) (offset_mhz / 0.05 + 0.5);
} else if (offset_mhz < 0 && offset_mhz > -256 * 0.05) {
ch->duplex = D_NEG_OFFSET;
ch->offset = (int) (-offset_mhz / 0.05 + 0.5);
} else {
ch->duplex = D_CROSS_BAND;
hz_to_freq((int) (tx_mhz * 1000000.0), ch->txfreq);
}
ch->used = (rx_mhz > 0);
ch->tmode = tmode;
// Byte 1
ch->talkaround = 0;
ch->rx_only = rxonly;
ch->repeater_slot = timeslot;
ch->colorcode = colorcode;
// Byte 2
ch->privacy_no = 0;
ch->privacy = PRIV_NONE;
ch->private_call_conf = 0;
ch->data_call_conf = 1; // Always ask for SMS acknowledge
// Byte 3
ch->rx_ref_frequency = REF_LOW;
ch->_unused2 = 0;
ch->emergency_alarm_ack = 0;
ch->_unused3 = 2;
ch->uncompressed_udp = 1;
ch->display_pttid_dis = 1;
// Byte 4
ch->tx_ref_frequency = REF_LOW;
ch->_unused4 = 1;
ch->vox = 0;
ch->power = power;
ch->isnarrow = ! wide;
ch->isam = isam;
ch->step = (rx_mhz >= 400) ? STEP_12_5 : STEP_5;
ch->_u1 = 0;
ch->_u2 = (rx_mhz >= 400);
ch->_u3 = 0;
ch->_u4[0] = 15;
ch->_u4[1] = 0;
ch->_u5[0] = ch->_u5[1] = ch->_u5[2] = 0;
ch->admit_criteria = admit;
// Scan mode.
unsigned char *scan_data = &radio_mem[OFFSET_SCAN + i/4];
int scan_shift = (i & 3) * 2;
*scan_data &= ~(3 << scan_shift);
*scan_data |= scan << scan_shift;
// Byte 5
ch->_unused5 = 0;
ch->in_call_criteria = incall;
ch->_unused6 = 3;
encode_name(i, name);
#endif
// Bytes 6-7
ch->contact_name_index = contact;
// Bytes 8-9
ch->tot = tot;
ch->tot_rekey_delay = 0;
// Bytes 10-11
ch->emergency_system_index = 0;
ch->scan_list_index = scanlist;
// Bytes 12-13
ch->group_list_index = grouplist;
ch->_unused7 = 0;
// Bytes 14-15
ch->_unused8 = 0;
ch->_unused9 = 0xff;
// Bytes 16-23
ch->rx_frequency = mhz_to_bcd(rx_mhz);
ch->tx_frequency = mhz_to_bcd(tx_mhz);
// Bytes 24-27
ch->ctcss_dcs_receive = rxtone;
ch->ctcss_dcs_transmit = txtone;
// Bytes 28-29
ch->rx_signaling_syst = 0;
ch->tx_signaling_syst = 0;
// Bytes 30-31
ch->_unused10 = 0xff;
ch->_unused11 = 0xff;
// Bytes 32-63
utf8_decode(ch->name, name, 16);
}
//
@ -477,7 +513,85 @@ static void setup_channel(int i, int mode, char *name, double rx_mhz, double tx_
//
static void erase_channel(int i)
{
//TODO: erase channel
channel_t *ch = (channel_t*) &radio_mem[OFFSET_CHANNELS + i*64];
// Byte 0
ch->channel_mode = MODE_ANALOG;
ch->bandwidth = BW_25_KHZ;
ch->autoscan = 0;
ch->squelch = SQ_NORMAL;
ch->_unused1 = 1;
ch->lone_worker = 0;
// Byte 1
ch->talkaround = 0;
ch->rx_only = 0;
ch->repeater_slot = 1;
ch->colorcode = 1;
// Byte 2
ch->privacy_no = 0;
ch->privacy = PRIV_NONE;
ch->private_call_conf = 0;
ch->data_call_conf = 0;
// Byte 3
ch->rx_ref_frequency = REF_LOW;
ch->_unused2 = 0;
ch->emergency_alarm_ack = 0;
ch->_unused3 = 2;
ch->uncompressed_udp = 1;
ch->display_pttid_dis = 1;
// Byte 4
ch->tx_ref_frequency = REF_LOW;
ch->_unused4 = 1;
ch->vox = 0;
ch->power = POWER_HIGH;
ch->admit_criteria = ADMIT_ALWAYS;
// Byte 5
ch->_unused5 = 0;
ch->in_call_criteria = INCALL_ALWAYS;
ch->_unused6 = 3;
// Bytes 6-7
ch->contact_name_index = 0;
// Bytes 8-9
ch->tot = 60/15;
ch->tot_rekey_delay = 0;
// Bytes 10-11
ch->emergency_system_index = 0;
ch->scan_list_index = 0;
// Bytes 12-13
ch->group_list_index = 0;
ch->_unused7 = 0;
// Bytes 14-15
ch->_unused8 = 0;
ch->_unused9 = 0xff;
// Bytes 16-23
ch->rx_frequency = 0x40000000;
ch->tx_frequency = 0x40000000;
// Bytes 24-27
ch->ctcss_dcs_receive = 0;
ch->ctcss_dcs_transmit = 0;
// Bytes 28-29
ch->rx_signaling_syst = 0;
ch->tx_signaling_syst = 0;
// Bytes 30-31
ch->_unused10 = 0xff;
ch->_unused11 = 0xff;
// Bytes 32-63
utf8_decode(ch->name, "", 16);
}
static void print_chanlist(FILE *out, uint16_t *unsorted, int nchan)
@ -1278,7 +1392,7 @@ badtx: fprintf(stderr, "Bad transmit frequency.\n");
setup_channel(num-1, MODE_DIGITAL, name_str, rx_mhz, tx_mhz,
power, scanlist, autoscan, squelch, tot, rxonly, admit,
colorcode, timeslot, incall, grouplist, contact, 0, 0, 0);
colorcode, timeslot, incall, grouplist, contact, 0, 0, BW_12_5_KHZ);
radio->channel_count++;
return 1;

49
util.c
View File

@ -114,35 +114,14 @@ void mdelay(unsigned msec)
}
//
// Convert 32-bit value from binary coded decimal
// to integer format (8 digits).
// Round double value to integer.
//
int bcd_to_int(int bcd)
static int iround(double x)
{
return ((bcd >> 28) & 15) * 10000000 +
((bcd >> 24) & 15) * 1000000 +
((bcd >> 20) & 15) * 100000 +
((bcd >> 16) & 15) * 10000 +
((bcd >> 12) & 15) * 1000 +
((bcd >> 8) & 15) * 100 +
((bcd >> 4) & 15) * 10 +
(bcd & 15);
}
if (x >= 0)
return (int)(x + 0.5);
//
// Convert 32-bit value from integer
// binary coded decimal format (8 digits).
//
int int_to_bcd(int val)
{
return ((val / 10000000) % 10) << 28 |
((val / 1000000) % 10) << 24 |
((val / 100000) % 10) << 20 |
((val / 10000) % 10) << 16 |
((val / 1000) % 10) << 12 |
((val / 100) % 10) << 8 |
((val / 10) % 10) << 4 |
(val % 10);
return -(int)(-x + 0.5);
}
//
@ -418,6 +397,24 @@ void print_freq(FILE *out, unsigned data)
}
}
//
// Convert frequency in MHz from floating point to
// a binary coded decimal format (8 digits).
//
unsigned mhz_to_bcd(double mhz)
{
unsigned hz = iround(mhz * 1000000.0);
return ((hz / 100000000) % 10) << 28 |
((hz / 10000000) % 10) << 24 |
((hz / 1000000) % 10) << 20 |
((hz / 100000) % 10) << 16 |
((hz / 10000) % 10) << 12 |
((hz / 1000) % 10) << 8 |
((hz / 100) % 10) << 4 |
((hz / 10) % 10);
}
//
// Convert a 4-byte frequency value from binary coded decimal
// to integer format (in Hertz).

12
util.h
View File

@ -75,16 +75,10 @@ void mdelay(unsigned msec);
int is_file(char *filename);
//
// Convert 32-bit value from binary coded decimal
// to integer format (8 digits).
// Convert frequency in MHz from floating point to
// a binary coded decimal format (8 digits).
//
int bcd_to_int(int bcd);
//
// Convert 32-bit value from integer
// binary coded decimal format (8 digits).
//
int int_to_bcd(int val);
unsigned mhz_to_bcd(double mhz);
//
// Get a binary value of the parameter: On/Off,

202
uv380.c
View File

@ -443,49 +443,89 @@ static void setup_channel(int i, int mode, char *name, double rx_mhz, double tx_
int admit, int colorcode, int timeslot, int incall, int grouplist, int contact,
int rxtone, int txtone, int width)
{
//TODO: always set Data Call Confirmed=1 (wait for SMS acknowledge)
//TODO: always set talkaround=0
#if 0
memory_channel_t *ch = i + (memory_channel_t*) &radio_mem[OFFSET_CHANNELS];
channel_t *ch = (channel_t*) &radio_mem[OFFSET_CHANNELS + i*64];
hz_to_freq((int) (rx_mhz * 1000000.0), ch->rxfreq);
// Byte 0
ch->channel_mode = mode;
ch->bandwidth = width;
ch->autoscan = autoscan;
ch->_unused1 = 3;
ch->lone_worker = 0;
double offset_mhz = tx_mhz - rx_mhz;
ch->offset = 0;
ch->txfreq[0] = ch->txfreq[1] = ch->txfreq[2] = 0;
if (offset_mhz == 0) {
ch->duplex = D_SIMPLEX;
} else if (offset_mhz > 0 && offset_mhz < 256 * 0.05) {
ch->duplex = D_POS_OFFSET;
ch->offset = (int) (offset_mhz / 0.05 + 0.5);
} else if (offset_mhz < 0 && offset_mhz > -256 * 0.05) {
ch->duplex = D_NEG_OFFSET;
ch->offset = (int) (-offset_mhz / 0.05 + 0.5);
} else {
ch->duplex = D_CROSS_BAND;
hz_to_freq((int) (tx_mhz * 1000000.0), ch->txfreq);
}
ch->used = (rx_mhz > 0);
ch->tmode = tmode;
// Byte 1
ch->_unused2 = 0;
ch->rx_only = rxonly;
ch->repeater_slot = timeslot;
ch->colorcode = colorcode;
// Byte 2
ch->privacy_no = 0;
ch->privacy = PRIV_NONE;
ch->private_call_conf = 0;
ch->data_call_conf = 1; // Always ask for SMS acknowledge
// Byte 3
ch->rx_ref_frequency = REF_LOW;
ch->_unused3 = 0;
ch->emergency_alarm_ack = 0;
ch->_unused4 = 6;
ch->display_pttid_dis = 1;
// Byte 4
ch->tx_ref_frequency = REF_LOW;
ch->_unused5 = 1;
ch->vox = 0;
ch->_unused6 = 1;
ch->admit_criteria = admit;
// Byte 5
ch->_unused7 = 0;
ch->in_call_criteria = incall;
ch->turn_off_freq = TURNOFF_NONE;
// Bytes 6-7
ch->contact_name_index = contact;
// Bytes 8-9
ch->tot = tot;
ch->tot_rekey_delay = 0;
// Bytes 10-11
ch->emergency_system_index = 0;
ch->scan_list_index = scanlist;
// Bytes 12-13
ch->group_list_index = grouplist;
ch->_unused8 = 0;
// Bytes 14-15
ch->_unused9 = 0;
ch->squelch = squelch;
// Bytes 16-23
ch->rx_frequency = mhz_to_bcd(rx_mhz);
ch->tx_frequency = mhz_to_bcd(tx_mhz);
// Bytes 24-27
ch->ctcss_dcs_receive = rxtone;
ch->ctcss_dcs_transmit = txtone;
// Bytes 28-29
ch->rx_signaling_syst = 0;
ch->tx_signaling_syst = 0;
// Byte 30
ch->power = power;
ch->isnarrow = ! wide;
ch->isam = isam;
ch->step = (rx_mhz >= 400) ? STEP_12_5 : STEP_5;
ch->_u1 = 0;
ch->_u2 = (rx_mhz >= 400);
ch->_u3 = 0;
ch->_u4[0] = 15;
ch->_u4[1] = 0;
ch->_u5[0] = ch->_u5[1] = ch->_u5[2] = 0;
ch->_unused10 = 0x3f;
// Scan mode.
unsigned char *scan_data = &radio_mem[OFFSET_SCAN + i/4];
int scan_shift = (i & 3) * 2;
*scan_data &= ~(3 << scan_shift);
*scan_data |= scan << scan_shift;
// Byte 31
ch->_unused11 = 7;
ch->dcdm_switch_dis = 1;
ch->leader_ms = DCDM_MS;
ch->_unused12 = 7;
encode_name(i, name);
#endif
// Bytes 32-63
utf8_decode(ch->name, name, 16);
}
//
@ -493,7 +533,89 @@ static void setup_channel(int i, int mode, char *name, double rx_mhz, double tx_
//
static void erase_channel(int i)
{
//TODO: erase channel
channel_t *ch = (channel_t*) &radio_mem[OFFSET_CHANNELS + i*64];
// Byte 0
ch->channel_mode = MODE_ANALOG;
ch->bandwidth = BW_25_KHZ;
ch->autoscan = 0;
ch->_unused1 = 3;
ch->lone_worker = 0;
// Byte 1
ch->_unused2 = 0;
ch->rx_only = 0;
ch->repeater_slot = 1;
ch->colorcode = 1;
// Byte 2
ch->privacy_no = 0;
ch->privacy = PRIV_NONE;
ch->private_call_conf = 0;
ch->data_call_conf = 0;
// Byte 3
ch->rx_ref_frequency = REF_LOW;
ch->_unused3 = 0;
ch->emergency_alarm_ack = 0;
ch->_unused4 = 6;
ch->display_pttid_dis = 1;
// Byte 4
ch->tx_ref_frequency = REF_LOW;
ch->_unused5 = 1;
ch->vox = 0;
ch->_unused6 = 1;
ch->admit_criteria = ADMIT_ALWAYS;
// Byte 5
ch->_unused7 = 0;
ch->in_call_criteria = INCALL_ALWAYS;
ch->turn_off_freq = TURNOFF_NONE;
// Bytes 6-7
ch->contact_name_index = 0;
// Bytes 8-9
ch->tot = 60/15;
ch->tot_rekey_delay = 0;
// Bytes 10-11
ch->emergency_system_index = 0;
ch->scan_list_index = 0;
// Bytes 12-13
ch->group_list_index = 0;
ch->_unused8 = 0;
// Bytes 14-15
ch->_unused9 = 0;
ch->squelch = 3;
// Bytes 16-23
ch->rx_frequency = 0x40000000;
ch->tx_frequency = 0x40000000;
// Bytes 24-27
ch->ctcss_dcs_receive = 0;
ch->ctcss_dcs_transmit = 0;
// Bytes 28-29
ch->rx_signaling_syst = 0;
ch->tx_signaling_syst = 0;
// Byte 30
ch->power = POWER_HIGH;
ch->_unused10 = 0x3f;
// Byte 31
ch->_unused11 = 7;
ch->dcdm_switch_dis = 1;
ch->leader_ms = DCDM_MS;
ch->_unused12 = 7;
// Bytes 32-63
utf8_decode(ch->name, "", 16);
}
static void print_chanlist(FILE *out, uint16_t *unsorted, int nchan)
@ -1325,7 +1447,7 @@ badtx: fprintf(stderr, "Bad transmit frequency.\n");
setup_channel(num-1, MODE_DIGITAL, name_str, rx_mhz, tx_mhz,
power, scanlist, autoscan, squelch, tot, rxonly, admit,
colorcode, timeslot, incall, grouplist, contact, 0, 0, 0);
colorcode, timeslot, incall, grouplist, contact, 0, 0, BW_12_5_KHZ);
radio->channel_count++;
return 1;