You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm writing a firmware where the ADC should be runtime configured for sampling the selected set of inputs (configured as regular sequence) with the selected frequency. Data should be transferred via DMA, and the measurement should be triggered via a timer.
I have found that the current API is extremely inconvenient for that.
For with_scan_dma, I need to provide my own implementation of SetChannels (example here).
However that implementation does not allow using runtime-configurable list of inputs.
I have worked it arround implementing code like this:
staticADC_CHANS:Vec<u8,{ sizes::MAX_CHANNELS}> = Vec::new();
...pubstructAdcPins{}implSetChannels<AdcPins>forAdc<ADC1>{fnset_samples(&mutself){for v in&crate::ADC_CHANS{self.set_channel_sample_time(*v, adc::SampleTime::T_28);}}fnset_sequence(&mutself){self.set_regular_sequence(crate::ADC_CHANS.as_slice());// Optionally we can set continuous scan modeself.set_continuous_mode(true);// Also we can use discontinuous conversion (3 channels per conversion)self.set_discontinuous_mode(Some(u8::try_from(crate::ADC_CHANS.len()).unwrap()));}}
The sampling is delegated to the async software task in rtic v2. The ADC and DMA is initialized in init, and passes as Locale to that task.
//Initialization in initletmut dma_ch1 = ctx.device.DMA1.split().1;letmut adc1 = adc::Adc::adc1(ctx.device.ADC1, clocks);
Than the task is running a loop where it receives the CONFIGURE, START, and STOP command.
After START it configures the ADC and DMA, starts the transfer and waits for STOP.
However, the problem is that I can't perform proper configuration due to ownership problems:
// Configure ADC and DMA
adc1.with_scan_dma(AdcPins{}, dma_ch1);
The code above generates:
error[E0308]: mismatched types
--> src/main.rs:233:56
|
233 | adc1.with_scan_dma(AdcPins {}, dma_ch1);
| ------------- ^^^^^^^ expected `C1`, found `&mut C1`
| |
| arguments to this method are incorrect
If i modify it to:
// Configure ADC and DMA
adc1.with_scan_dma(AdcPins{},*dma_ch1);
I get:
error[E0507]: cannot move out of `*adc1` which is behind a mutable reference
--> src/main.rs:233:25
|
233 | adc1.with_scan_dma(AdcPins {}, *dma_ch1);
| ^^^^ ----------------------------------- `*adc1` moved due to this method call
| |
| move occurs because `*adc1` has type `Adc<ADC1>`, which does not implement the `Copy` trait
|
note: `Adc::<ADC1>::with_scan_dma` takes ownership of the receiver `self`, which moves `*adc1`
--> /home/emb/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stm32f1xx-hal-0.10.0/src/adc.rs:814:1
|
814 | / adcdma! {
815 | | pac::ADC1: (
816 | | AdcDma1,
817 | | dma1::C1,
818 | | )
819 | | }
| |_^
= note: this error originates in the macro `adcdma` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0507]: cannot move out of `*dma_ch1` which is behind a mutable reference
--> src/main.rs:233:56
|
233 | adc1.with_scan_dma(AdcPins {}, *dma_ch1);
| ^^^^^^^^ move occurs because `*dma_ch1` has type `stm32f1xx_hal::dma::dma1::C1`, which does not implement the `Copy` trait
I can work it around, by passing the reference to the RegisterBlock for ADC and DMA to the data acquisition task, like done (for STM32F3...) in this example. Certain modifications for porting from STM32F3... to STM32F1... are needed, but generally this approach looks promissing.
At least the below initialization does not lead to errors:
//Initialize ADC and DMA to make sure that proper clocks are enabledletmut dma_ch1 = ctx.device.DMA1.split().1;letmut adc1 = adc::Adc::adc1(ctx.device.ADC1, clocks);//Prepare the register blocks to be passed as `Local` to the data acquiring tasklet r_adc1 = unsafe{&mut*(ADC1::ptr()as*mut_)};let r_dma1 = unsafe{&mut*(DMA1::ptr()as*mut_)};
The text was updated successfully, but these errors were encountered:
I'm writing a firmware where the ADC should be runtime configured for sampling the selected set of inputs (configured as regular sequence) with the selected frequency. Data should be transferred via DMA, and the measurement should be triggered via a timer.
I have found that the current API is extremely inconvenient for that.
For with_scan_dma, I need to provide my own implementation of SetChannels (example here).
However that implementation does not allow using runtime-configurable list of inputs.
I have worked it arround implementing code like this:
The sampling is delegated to the async software task in rtic v2. The ADC and DMA is initialized in
init
, and passes asLocale
to that task.Than the task is running a loop where it receives the CONFIGURE, START, and STOP command.
After START it configures the ADC and DMA, starts the transfer and waits for STOP.
However, the problem is that I can't perform proper configuration due to ownership problems:
The code above generates:
If i modify it to:
I get:
I can work it around, by passing the reference to the RegisterBlock for ADC and DMA to the data acquisition task, like done (for STM32F3...) in this example. Certain modifications for porting from STM32F3... to STM32F1... are needed, but generally this approach looks promissing.
At least the below initialization does not lead to errors:
The text was updated successfully, but these errors were encountered: