diff options
| author | eZio Pan <[email protected]> | 2024-03-22 17:29:10 +0800 |
|---|---|---|
| committer | eZio Pan <[email protected]> | 2024-03-23 09:15:25 +0800 |
| commit | 0abcccee966af0b12e62fc7fae8499fa03194823 (patch) | |
| tree | b0cf28261ee18b1bd111de61d93ef5cbddc5f29e /examples/stm32h5/src | |
| parent | 83069e7b49bd181236e6a68005ad6119d39b39c3 (diff) | |
stm32 CORDIC: re-design API
Diffstat (limited to 'examples/stm32h5/src')
| -rw-r--r-- | examples/stm32h5/src/bin/cordic.rs | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/examples/stm32h5/src/bin/cordic.rs b/examples/stm32h5/src/bin/cordic.rs index d49f75b8f..73e873574 100644 --- a/examples/stm32h5/src/bin/cordic.rs +++ b/examples/stm32h5/src/bin/cordic.rs | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | use defmt::*; | 4 | use defmt::*; |
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_stm32::cordic; | 6 | use embassy_stm32::cordic::{self, utils}; |
| 7 | use {defmt_rtt as _, panic_probe as _}; | 7 | use {defmt_rtt as _, panic_probe as _}; |
| 8 | 8 | ||
| 9 | #[embassy_executor::main] | 9 | #[embassy_executor::main] |
| @@ -16,20 +16,63 @@ async fn main(_spawner: Spawner) { | |||
| 16 | cordic::Function::Sin, | 16 | cordic::Function::Sin, |
| 17 | Default::default(), | 17 | Default::default(), |
| 18 | Default::default(), | 18 | Default::default(), |
| 19 | false, | ||
| 20 | )), | 19 | )), |
| 21 | ); | 20 | ); |
| 22 | 21 | ||
| 23 | let mut output = [0f64; 16]; | 22 | // for output buf, the length is not that strict, larger than minimal required is ok. |
| 23 | let mut output_f64 = [0f64; 19]; | ||
| 24 | let mut output_u32 = [0u32; 21]; | ||
| 24 | 25 | ||
| 25 | let arg1 = [1.0, 0.0, -1.0]; // for trigonometric function, the ARG1 value [-pi, pi] should be map to [-1, 1] | 26 | // tips: |
| 26 | let arg2 = [0.5, 1.0]; | 27 | // CORDIC peripheral has some strict on input value, you can also use ".check_argX_fXX()" methods |
| 28 | // to make sure your input values are compatible with current CORDIC setup. | ||
| 29 | let arg1 = [-1.0, -0.5, 0.0, 0.5, 1.0]; // for trigonometric function, the ARG1 value [-pi, pi] should be map to [-1, 1] | ||
| 30 | let arg2 = [0.5]; // and for Sin function, ARG2 should be in [0, 1] | ||
| 27 | 31 | ||
| 28 | let cnt = unwrap!( | 32 | let mut input_buf = [0u32; 9]; |
| 33 | |||
| 34 | // convert input from floating point to fixed point | ||
| 35 | input_buf[0] = unwrap!(utils::f64_to_q1_31(arg1[0])); | ||
| 36 | input_buf[1] = unwrap!(utils::f64_to_q1_31(arg2[0])); | ||
| 37 | |||
| 38 | // If input length is small, blocking mode can be used to minimize overhead. | ||
| 39 | let cnt0 = unwrap!(cordic.blocking_calc_32bit( | ||
| 40 | &input_buf[..2], // input length is strict, since driver use its length to detect calculation count | ||
| 41 | &mut output_u32, | ||
| 42 | false, | ||
| 43 | false | ||
| 44 | )); | ||
| 45 | |||
| 46 | // convert result from fixed point into floating point | ||
| 47 | for (&u32_val, f64_val) in output_u32[..cnt0].iter().zip(output_f64.iter_mut()) { | ||
| 48 | *f64_val = utils::q1_31_to_f64(u32_val); | ||
| 49 | } | ||
| 50 | |||
| 51 | // convert input from floating point to fixed point | ||
| 52 | // | ||
| 53 | // first value from arg1 is used, so truncate to arg1[1..] | ||
| 54 | for (&f64_val, u32_val) in arg1[1..].iter().zip(input_buf.iter_mut()) { | ||
| 55 | *u32_val = unwrap!(utils::f64_to_q1_31(f64_val)); | ||
| 56 | } | ||
| 57 | |||
| 58 | // If calculation is a little longer, async mode can make use of DMA, and let core do some other stuff. | ||
| 59 | let cnt1 = unwrap!( | ||
| 29 | cordic | 60 | cordic |
| 30 | .async_calc_32bit(&mut dp.GPDMA1_CH0, &mut dp.GPDMA1_CH1, &arg1, Some(&arg2), &mut output,) | 61 | .async_calc_32bit( |
| 62 | &mut dp.GPDMA1_CH0, | ||
| 63 | &mut dp.GPDMA1_CH1, | ||
| 64 | &input_buf[..arg1.len() - 1], // limit input buf to its actual length | ||
| 65 | &mut output_u32, | ||
| 66 | true, | ||
| 67 | false | ||
| 68 | ) | ||
| 31 | .await | 69 | .await |
| 32 | ); | 70 | ); |
| 33 | 71 | ||
| 34 | println!("async calc 32bit: {}", output[..cnt]); | 72 | // convert result from fixed point into floating point |
| 73 | for (&u32_val, f64_val) in output_u32[..cnt1].iter().zip(output_f64[cnt0..cnt0 + cnt1].iter_mut()) { | ||
| 74 | *f64_val = utils::q1_31_to_f64(u32_val); | ||
| 75 | } | ||
| 76 | |||
| 77 | println!("result: {}", output_f64[..cnt0 + cnt1]); | ||
| 35 | } | 78 | } |
