};
static bool adc_is_read_finished = false;
- static bool adc_is_read_continuous = false;
-
-void adc_read_callback([[maybe_unused]] ADCDriver *driver)
-{
- gptStopTimer(gptd);
- adc_is_read_finished = true;
-}
+static adcsample_t *adc_current_buffer = nullptr;
+static size_t adc_current_buffer_size = 0;
- static adc_operation_t adc_operation_func = nullptr;
++static adc::operation_t adc_operation_func = nullptr;
- void adc_init()
+ namespace adc
{
- palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG);
-
- gptStart(gptd, &gpt_config);
- adcStart(adcd, &adc_config);
- adcSTM32EnableVREF(adcd);
- }
-
- adcsample_t *adc_read(adcsample_t *buffer, size_t count)
- {
- adc_is_read_finished = false;
- adc_is_read_continuous = false;
- adc_group_config.circular = false;
- adcStartConversion(adcd, &adc_group_config, buffer, count);
- gptStartContinuous(gptd, 100); // 10kHz
- while (!adc_is_read_finished);
- return buffer;
- }
-
- void adc_read_start(adc_operation_t operation_func, adcsample_t *buffer, size_t count)
- {
- adc_is_read_continuous = true;
- adc_current_buffer = buffer;
- adc_current_buffer_size = count;
- adc_operation_func = operation_func;
- adc_group_config.circular = true;
- adcStartConversion(adcd, &adc_group_config, buffer, count);
- gptStartContinuous(gptd, 100); // 10kHz
- }
+ void init()
+ {
+ palSetPadMode(GPIOA, 0, PAL_MODE_INPUT_ANALOG);
+
+ gptStart(gptd, &gpt_config);
+ adcStart(adcd, &adc_config);
+ adcSTM32EnableVREF(adcd);
+ }
+
+ adcsample_t *read(adcsample_t *buffer, size_t count)
+ {
+ adc_is_read_finished = false;
++ adc_group_config.circular = false;
+ adcStartConversion(adcd, &adc_group_config, buffer, count);
+ gptStartContinuous(gptd, 100); // 10kHz
+ while (!adc_is_read_finished);
+ return buffer;
+ }
+
- void adc_read_stop()
- {
- adc_is_read_continuous = false;
- gptStopTimer(gptd);
++ void read_start(operation_t operation_func, adcsample_t *buffer, size_t count)
++ {
++ adc_current_buffer = buffer;
++ adc_current_buffer_size = count;
++ adc_operation_func = operation_func;
++ adc_group_config.circular = true;
++ adcStartConversion(adcd, &adc_group_config, buffer, count);
++ gptStartContinuous(gptd, 100); // 10kHz
++ }
++
++ void read_stop()
++ {
++ gptStopTimer(gptd);
++ adc_group_config.circular = false;
++ adc_current_buffer = nullptr;
++ adc_current_buffer_size = 0;
++ adc_operation_func = nullptr;
++ }
+
+ void set_rate(rate r)
+ {
+ uint32_t val = 0;
+
+ switch (r) {
+ case rate::R2P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_2P5);
+ break;
+ case rate::R6P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_6P5);
+ break;
+ case rate::R12P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_12P5);
+ break;
+ case rate::R24P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_24P5);
+ break;
+ case rate::R47P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_47P5);
+ break;
+ case rate::R92P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_92P5);
+ break;
+ case rate::R247P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_247P5);
+ break;
+ case rate::R640P5:
+ val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_640P5);
+ break;
+ }
+
+ adc_group_config.smpr[0] = val;
+ }
}
- if (!adc_is_read_continuous) {
+void adc_read_callback(ADCDriver *driver)
+{
- void adc_set_rate(ADCRate rate)
- {
- uint32_t val = 0;
-
- switch (rate) {
- case ADCRate::R2P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_2P5);
- break;
- case ADCRate::R6P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_6P5);
- break;
- case ADCRate::R12P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_12P5);
- break;
- case ADCRate::R24P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_24P5);
- break;
- case ADCRate::R47P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_47P5);
- break;
- case ADCRate::R92P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_92P5);
- break;
- case ADCRate::R247P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_247P5);
- break;
- case ADCRate::R640P5:
- val = ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_640P5);
- break;
- }
-
- adc_group_config.smpr[0] = val;
- }
-
++ if (!adc_group_config.circular) {
+ gptStopTimer(gptd);
+ adc_is_read_finished = true;
+ } else if (adc_operation_func != nullptr) {
+ auto half_size = adc_current_buffer_size / 2;
+ if (driver->state == ADC_ACTIVE) {
+ // Half full
+ adc_operation_func(adc_current_buffer, half_size);
+ } else if (driver->state == ADC_COMPLETE) {
+ // Second half full
+ adc_operation_func(adc_current_buffer + half_size, half_size);
+ }
+ }
+}
+
static unsigned int dac_sample_count = 2048;
while (true) {
- if (usbserial_is_active()) {
+ if (usbserial::is_active()) {
// Expect to receive a byte command 'packet'.
- if (char cmd[3]; usbserial_read(&cmd, 1) > 0) {
+ if (char cmd[3]; usbserial::read(&cmd, 1) > 0) {
switch (cmd[0]) {
case 'r': // Read in analog signal
- if (usbserial_read(&cmd[1], 2) < 2)
+ if (usbserial::read(&cmd[1], 2) < 2)
break;
if (auto count = std::min(static_cast<unsigned int>(cmd[1] | (cmd[2] << 8)), adc_samples.size()); count > 0) {
- adc_read(&adc_samples[0], count);
- usbserial_write(adc_samples.data(), count * sizeof(adcsample_t));
+ adc::read(&adc_samples[0], count);
+ usbserial::write(adc_samples.data(), count * sizeof(adcsample_t));
}
break;
- adc_read_start(signal_operate, &adc_samples[0], adc_samples.size() * sizeof(adcsample_t));
+ case 'R':
- adc_read_stop();
++ adc::read_start(signal_operate, &adc_samples[0], adc_samples.size() * sizeof(adcsample_t));
+ break;
+ case 'S':
++ adc::read_stop();
+ break;
case 'W':
- if (usbserial_read(&cmd[1], 2) < 2)
+ if (usbserial::read(&cmd[1], 2) < 2)
break;
if (auto count = std::min(static_cast<unsigned int>(cmd[1] | (cmd[2] << 8)), dac_samples.size()); count > 0)
dac_sample_count = count;