Skip to content

Commit

Permalink
kingst-la2016: cope with 800MHz base clock for 500MHz models
Browse files Browse the repository at this point in the history
The LA5016 uses an 800MHz base clock to derive the samplerate from. And
communicates divider 1 to configure the 500MHz rate. And does support
the 200MHz rate (divider 4). Which also makes the 10kHz lower boundary
unavailable on some models. Update the capture configuration logic, the
config API routines, and associated comments. Discuss how streaming may
make finer grained rates tables desirable (but stick with 1/2/5 for now).
  • Loading branch information
gsigh committed Feb 22, 2022
1 parent 1c445e0 commit cafcfe6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 16 deletions.
27 changes: 14 additions & 13 deletions src/hardware/kingst-la2016/api.c
Expand Up @@ -87,20 +87,23 @@ static const char *channel_names_pwm[] = {
};

/*
* The hardware uses a 100/200/500MHz base clock (model dependent) and
* a 16bit divider (common across all models). The range from 10kHz to
* 100/200/500MHz should be applicable to all devices. High rates may
* suffer from coarse resolution (e.g. in the "500MHz div 2" case) and
* may not provide the desired 1/2/5 steps. Fortunately this exclusively
* affects the 500MHz model where 250MHz is used instead of 200MHz and
* the 166MHz and 125MHz rates are not presented to users. Deep memory
* of these models and hardware compression reduce the necessity to let
* users pick from a huge list of possible rates.
* The devices have an upper samplerate limit of 100/200/500 MHz each.
* But their hardware uses different base clocks (100/200/800MHz, this
* is _not_ a typo) and a 16bit divider. Which results in per-model ranges
* of supported rates which not only differ in the upper boundary, but
* also at the lower boundary. It's assumed that the 10kHz rate is not
* useful enough to provide by all means. Starting at 20kHz for all models
* simplfies the implementation of the config API routines, and eliminates
* redundancy in these samplerates tables.
*
* Streaming mode is constrained by the channel count and samplerate
* product (the bits per second which need to travel the USB connection
* while the acquisition is executing). Because streaming mode does not
* compress the capture data, a later implementation may desire a finer
* resolution. For now let's just stick with the 1/2/5 steps.
*/

static const uint64_t rates_500mhz[] = {
SR_KHZ(10),
SR_KHZ(20),
SR_KHZ(50),
SR_KHZ(100),
Expand All @@ -113,12 +116,11 @@ static const uint64_t rates_500mhz[] = {
SR_MHZ(20),
SR_MHZ(50),
SR_MHZ(100),
SR_MHZ(250),
SR_MHZ(200),
SR_MHZ(500),
};

static const uint64_t rates_200mhz[] = {
SR_KHZ(10),
SR_KHZ(20),
SR_KHZ(50),
SR_KHZ(100),
Expand All @@ -135,7 +137,6 @@ static const uint64_t rates_200mhz[] = {
};

static const uint64_t rates_100mhz[] = {
SR_KHZ(10),
SR_KHZ(20),
SR_KHZ(50),
SR_KHZ(100),
Expand Down
15 changes: 12 additions & 3 deletions src/hardware/kingst-la2016/protocol.c
Expand Up @@ -48,13 +48,13 @@ static const struct kingst_model models[] = {
{ 3, 1, "LA1016", "la1016a1", SR_MHZ(100), 16, 1, 0, },
{ 3, 0, "LA1016", "la1016", SR_MHZ(100), 16, 1, 0, },
{ 4, 0, "LA1010", "la1010a0", SR_MHZ(100), 16, 0, SR_MHZ(800), },
{ 5, 0, "LA5016", "la5016a1", SR_MHZ(500), 16, 2, 0, },
{ 6, 0, "LA5032", "la5032a0", SR_MHZ(500), 32, 4, 0, },
{ 5, 0, "LA5016", "la5016a1", SR_MHZ(500), 16, 2, SR_MHZ(800), },
{ 6, 0, "LA5032", "la5032a0", SR_MHZ(500), 32, 4, SR_MHZ(800), },
{ 7, 0, "LA1010", "la1010a1", SR_MHZ(100), 16, 0, SR_MHZ(800), },
{ 8, 0, "LA2016", "la2016a1", SR_MHZ(200), 16, 1, 0, },
{ 9, 0, "LA1016", "la1016a1", SR_MHZ(100), 16, 1, 0, },
{ 10, 0, "LA1010", "la1010a2", SR_MHZ(100), 16, 0, SR_MHZ(800), },
{ 65, 0, "LA5016", "la5016a1", SR_MHZ(500), 16, 2, 0, },
{ 65, 0, "LA5016", "la5016a1", SR_MHZ(500), 16, 2, SR_MHZ(800), },
};

/* USB vendor class control requests, executed by the Cypress FX2 MCU. */
Expand Down Expand Up @@ -729,6 +729,13 @@ static int set_sample_config(const struct sr_dev_inst *sdi)

devc = sdi->priv;

/*
* The base clock need not be identical to the maximum samplerate,
* and differs between models. The 500MHz devices even use a base
* clock of 800MHz, and communicate divider 1 to the hardware to
* configure the 500MHz samplerate. This allows them to operate at
* a 200MHz samplerate which uses divider 4.
*/
if (devc->samplerate > devc->model->samplerate) {
sr_err("Too high a sample rate: %" PRIu64 ".",
devc->samplerate);
Expand All @@ -746,6 +753,8 @@ static int set_sample_config(const struct sr_dev_inst *sdi)
}
divider_u16 = baseclock / devc->samplerate;
eff_samplerate = baseclock / divider_u16;
if (eff_samplerate > devc->model->samplerate)
eff_samplerate = devc->model->samplerate;

ret = sr_sw_limits_get_remain(&devc->sw_limits,
&limit_samples, NULL, NULL, NULL);
Expand Down

0 comments on commit cafcfe6

Please sign in to comment.