rfdsatt: Move to 1-based channel and stage numbers
This matches more with how SCPI controlled attenuators work
This commit is contained in:
parent
dfb3294ac8
commit
3cfd61baa7
|
@ -43,9 +43,40 @@ static void gpio_pulse_clk(void)
|
|||
gpio_pulse(g_att_cfg->gpio_clock.bank, g_att_cfg->gpio_clock.gpio_nr);
|
||||
}
|
||||
|
||||
/* validate if a channel number is within the permitted range */
|
||||
static bool chan_is_valid(uint8_t channel)
|
||||
{
|
||||
if (channel == 0)
|
||||
return false;
|
||||
|
||||
if (channel > g_att_cfg->num_channels)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* validate if a stage number is within the permitted range */
|
||||
static bool stage_is_valid(uint8_t channel, uint8_t stage)
|
||||
{
|
||||
if (!chan_is_valid(channel))
|
||||
return false;
|
||||
|
||||
if (stage == 0)
|
||||
return false;
|
||||
|
||||
if (stage > g_att_cfg->channels[channel-1].num_stages)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* internal low-level helper */
|
||||
static void _attenuator_stage_set(uint8_t channel, uint8_t stage, uint8_t val_qdb)
|
||||
{
|
||||
const struct attenuator_def *ad = &g_att_cfg->channels[channel].stage[stage];
|
||||
/* we assume the [internal] caller has verified those */
|
||||
uint8_t chan_idx = channel-1;
|
||||
uint8_t stage_idx = stage-1;
|
||||
const struct attenuator_def *ad = &g_att_cfg->channels[chan_idx].stage[stage_idx];
|
||||
uint8_t val;
|
||||
int i;
|
||||
|
||||
|
@ -67,13 +98,13 @@ static void _attenuator_stage_set(uint8_t channel, uint8_t stage, uint8_t val_qd
|
|||
gpio_pulse(ad->le.bank, ad->le.gpio_nr);
|
||||
|
||||
/* actual value we have set may not be exactly what was requested */
|
||||
g_att_state[channel][stage].value_qdB.current = val_qdb;
|
||||
g_att_state[chan_idx][stage_idx].value_qdB.current = val_qdb;
|
||||
}
|
||||
|
||||
/* set a given attenuator to a given value
|
||||
* \param channel The RF channel (0..7)
|
||||
* \param stage Attenuator stage (0..1)
|
||||
* \param value in quarter-dB (0..124)
|
||||
/*! set a given attenuator to a given value
|
||||
* \param channel The RF channel (1..8)
|
||||
* \param stage Attenuator stage (1..2)
|
||||
* \param val_qdb in quarter-dB (0..124)
|
||||
*/
|
||||
int attenuator_stage_set(uint8_t channel, uint8_t stage, uint8_t val_qdb)
|
||||
{
|
||||
|
@ -82,10 +113,7 @@ int attenuator_stage_set(uint8_t channel, uint8_t stage, uint8_t val_qdb)
|
|||
if (!g_att_cfg)
|
||||
return -ENODEV;
|
||||
|
||||
if (channel >= g_att_cfg->num_channels)
|
||||
return -ENODEV;
|
||||
|
||||
if (stage >= g_att_cfg->channels[channel].num_stages)
|
||||
if (!stage_is_valid(channel, stage))
|
||||
return -ENODEV;
|
||||
|
||||
if (val > 0x1f)
|
||||
|
@ -98,29 +126,37 @@ int attenuator_stage_set(uint8_t channel, uint8_t stage, uint8_t val_qdb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* get current attenuator value in quarter-dB */
|
||||
/*! get current attenuator value in quarter-dB
|
||||
* \param channel The RF channel (1..8)
|
||||
* \param stage Attenuator stage (1..2)
|
||||
*/
|
||||
int attenuator_stage_get(uint8_t channel, uint8_t stage, enum attenuator_value av)
|
||||
{
|
||||
uint8_t chan_idx;
|
||||
uint8_t stage_idx;
|
||||
|
||||
if (!g_att_cfg)
|
||||
return -ENODEV;
|
||||
|
||||
if (channel >= g_att_cfg->num_channels)
|
||||
if (!stage_is_valid(channel, stage))
|
||||
return -ENODEV;
|
||||
|
||||
if (stage >= g_att_cfg->channels[channel].num_stages)
|
||||
return -ENODEV;
|
||||
chan_idx = channel - 1;
|
||||
stage_idx = stage - 1;
|
||||
|
||||
switch (av) {
|
||||
case ATT_VAL_CURRENT:
|
||||
return g_att_state[channel][stage].value_qdB.current;
|
||||
return g_att_state[chan_idx][stage_idx].value_qdB.current;
|
||||
case ATT_VAL_STARTUP:
|
||||
return g_att_state[channel][stage].value_qdB.startup;
|
||||
return g_att_state[chan_idx][stage_idx].value_qdB.startup;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* set an overall attenuation value for an entire channel */
|
||||
/*! set an overall attenuation value for an entire channel (combination of stages)
|
||||
* \param channel The RF channel (1..8)
|
||||
* \param val_qdb Attenuation in quarter-dB (0..124) */
|
||||
int attenuator_chan_set(uint8_t channel, uint8_t val_qdb, bool split_equal)
|
||||
{
|
||||
uint8_t val_a, val_b;
|
||||
|
@ -128,7 +164,7 @@ int attenuator_chan_set(uint8_t channel, uint8_t val_qdb, bool split_equal)
|
|||
if (!g_att_cfg)
|
||||
return -ENODEV;
|
||||
|
||||
if (channel >= g_att_cfg->num_channels)
|
||||
if (!chan_is_valid(channel))
|
||||
return -ENODEV;
|
||||
|
||||
if (val_qdb/4 > 0x3f)
|
||||
|
@ -148,25 +184,29 @@ int attenuator_chan_set(uint8_t channel, uint8_t val_qdb, bool split_equal)
|
|||
|
||||
printf("Setting CH%u to %02u + %02u = %03u dB\r\n", channel, val_a/4, val_b/4, val_qdb/4);
|
||||
|
||||
_attenuator_stage_set(channel, 0, val_a);
|
||||
_attenuator_stage_set(channel, 1, val_b);
|
||||
_attenuator_stage_set(channel, 1, val_a);
|
||||
_attenuator_stage_set(channel, 2, val_b);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the cumulative attenuation of all stages within one channel */
|
||||
/*! get the cumulative attenuation of all stages within one channel
|
||||
* \param channel The RF channel (1..8) */
|
||||
int attenuator_chan_get(uint8_t channel, enum attenuator_value av)
|
||||
{
|
||||
uint8_t chan_idx;
|
||||
uint8_t stage;
|
||||
int res;
|
||||
int res = 0;
|
||||
|
||||
if (!g_att_cfg)
|
||||
return -ENODEV;
|
||||
|
||||
if (channel >= g_att_cfg->num_channels)
|
||||
if (!chan_is_valid(channel))
|
||||
return -ENODEV;
|
||||
|
||||
for (stage = 0; stage < g_att_cfg->channels[channel].num_stages; stage++) {
|
||||
chan_idx = channel-1;
|
||||
|
||||
for (stage = 1; stage <= g_att_cfg->channels[chan_idx].num_stages; stage++) {
|
||||
int rc = attenuator_stage_get(channel, stage, av);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
@ -176,7 +216,7 @@ int attenuator_chan_get(uint8_t channel, enum attenuator_value av)
|
|||
return res;
|
||||
}
|
||||
|
||||
/* initialize the attenuator driver */
|
||||
/*! initialize the attenuator driver */
|
||||
void attenuator_init(const struct attenuator_cfg *cfg,
|
||||
struct attenuator_state **state)
|
||||
{
|
||||
|
|
|
@ -183,14 +183,14 @@ DEFUN(att_show, att_show_cmd, "show", "Show state of all attenuators")
|
|||
{
|
||||
unsigned int channel;
|
||||
|
||||
for (channel = 0; channel < board_att_cfg.num_channels; channel++) {
|
||||
unsigned int stage;
|
||||
for (channel = 1; channel <= board_att_cfg.num_channels; channel++) {
|
||||
unsigned int stage_idx;
|
||||
int stage_qdb[2];
|
||||
int sum_qdb = 0;
|
||||
|
||||
for (stage = 0; stage < ARRAY_SIZE(stage_qdb); stage++) {
|
||||
stage_qdb[stage] = attenuator_stage_get(channel, stage, ATT_VAL_CURRENT);
|
||||
sum_qdb += stage_qdb[stage];
|
||||
for (stage_idx = 0; stage_idx < ARRAY_SIZE(stage_qdb); stage_idx++) {
|
||||
stage_qdb[stage_idx] = attenuator_stage_get(channel, stage_idx+1, ATT_VAL_CURRENT);
|
||||
sum_qdb += stage_qdb[stage_idx];
|
||||
}
|
||||
printf("Channel %02u: Stage1 %02d dB, Stage2 %02d dB, Sum %02d dB\r\n",
|
||||
channel, stage_qdb[0]/4, stage_qdb[1]/4, sum_qdb/4);
|
||||
|
@ -203,26 +203,36 @@ DEFUN(att_set, att_set_cmd, "set",
|
|||
int channel, stage, dB;
|
||||
int rc;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("You muts specify three arguments (channel, stage, db)\r\n");
|
||||
if (argc < 3 || argc > 4) {
|
||||
printf("You must specify two (channel, dB) or three arguments (channel, stage, db)\r\n");
|
||||
return;
|
||||
}
|
||||
channel = atoi(argv[1]);
|
||||
stage = atoi(argv[2]);
|
||||
dB = atoi(argv[3]);
|
||||
switch (argc) {
|
||||
case 3:
|
||||
channel = atoi(argv[1]);
|
||||
dB = atoi(argv[2]);
|
||||
rc = attenuator_chan_set(channel, dB*4, true);
|
||||
break;
|
||||
case 4:
|
||||
channel = atoi(argv[1]);
|
||||
stage = atoi(argv[2]);
|
||||
dB = atoi(argv[3]);
|
||||
rc = attenuator_stage_set(channel, stage, dB*4);
|
||||
break;
|
||||
default:
|
||||
printf("You must specify two (channel, dB) or three arguments (channel, stage, db)\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Setting attenuator channel %d stage %d to %d dB...\r\n", channel, stage, dB);
|
||||
|
||||
rc = attenuator_stage_set(channel, stage, dB*4);
|
||||
if (rc < 0)
|
||||
printf("Error setting attenuator: %d\r\n", rc);
|
||||
printf("Error setting attenuator %d: %d\r\n", channel, rc);
|
||||
}
|
||||
|
||||
|
||||
DEFUN(interact, interact_cmd, "interact", "Enter interactive single-key mode")
|
||||
{
|
||||
uint8_t g_chan = 0;
|
||||
uint8_t g_stage = 0;
|
||||
uint8_t g_chan = 1;
|
||||
uint8_t g_stage = 1;
|
||||
uint8_t g_val = 0;
|
||||
|
||||
printf("Entering interactive single-key mode. Press 'X' for exit\r\n");
|
||||
|
@ -238,8 +248,8 @@ DEFUN(interact, interact_cmd, "interact", "Enter interactive single-key mode")
|
|||
case 'X': /* exit */
|
||||
return;
|
||||
case '1': case '2': case '3': case '4': /* channel number */
|
||||
g_chan = ch - '1';
|
||||
g_stage = 0;
|
||||
g_chan = ch - '0';
|
||||
g_stage = 1;
|
||||
g_val = attenuator_stage_get(g_chan, g_stage, ATT_VAL_CURRENT);
|
||||
break;
|
||||
case '0': /* set to 0dB */
|
||||
|
@ -256,15 +266,15 @@ DEFUN(interact, interact_cmd, "interact", "Enter interactive single-key mode")
|
|||
if (g_val > 0)
|
||||
g_val--;
|
||||
break;
|
||||
case 'a': /* stage 0 */
|
||||
if (g_stage != 0) {
|
||||
g_stage = 0;
|
||||
case 'a': /* stage 1 */
|
||||
if (g_stage != 1) {
|
||||
g_stage = 1;
|
||||
g_val = attenuator_stage_get(g_chan, g_stage, ATT_VAL_CURRENT);
|
||||
}
|
||||
break;
|
||||
case 'b': /* stage 1 */
|
||||
if (g_stage != 1) {
|
||||
g_stage = 1;
|
||||
case 'b': /* stage 2 */
|
||||
if (g_stage != 2) {
|
||||
g_stage = 2;
|
||||
g_val = attenuator_stage_get(g_chan, g_stage, ATT_VAL_CURRENT);
|
||||
}
|
||||
break;
|
||||
|
@ -277,8 +287,7 @@ DEFUN(interact, interact_cmd, "interact", "Enter interactive single-key mode")
|
|||
|
||||
DEFUN(test, test_cmd, "test", "Enter interactive test-ramp mode")
|
||||
{
|
||||
uint8_t g_chan = 0;
|
||||
uint8_t g_stage = 0;
|
||||
uint8_t g_chan = 1;
|
||||
uint8_t g_val = 0;
|
||||
|
||||
printf("Entering interactive test-ramp mode. Press 'X' for exit\r\n");
|
||||
|
@ -290,7 +299,7 @@ DEFUN(test, test_cmd, "test", "Enter interactive test-ramp mode")
|
|||
case 'X': /* exit */
|
||||
return;
|
||||
case '1': case '2': case '3': case '4': /* channel number */
|
||||
g_chan = ch - '1';
|
||||
g_chan = ch - '0';
|
||||
g_val = 0;
|
||||
break;
|
||||
case '0': /* set to 0dB */
|
||||
|
|
Loading…
Reference in New Issue