aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authoreZio Pan <[email protected]>2024-03-22 17:29:10 +0800
committereZio Pan <[email protected]>2024-03-23 09:15:25 +0800
commit0abcccee966af0b12e62fc7fae8499fa03194823 (patch)
treeb0cf28261ee18b1bd111de61d93ef5cbddc5f29e /examples
parent83069e7b49bd181236e6a68005ad6119d39b39c3 (diff)
stm32 CORDIC: re-design API
Diffstat (limited to 'examples')
-rw-r--r--examples/stm32h5/src/bin/cordic.rs59
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
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::cordic; 6use embassy_stm32::cordic::{self, utils};
7use {defmt_rtt as _, panic_probe as _}; 7use {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}