#![no_std] #![no_main] use defmt::*; use embassy_executor::Spawner; use embassy_stm32::cordic::{self, utils}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let mut dp = embassy_stm32::init(Default::default()); let mut cordic = cordic::Cordic::new( &mut dp.CORDIC, unwrap!(cordic::Config::new( cordic::Function::Sin, Default::default(), Default::default(), )), ); // for output buf, the length is not that strict, larger than minimal required is ok. let mut output_f64 = [0f64; 19]; let mut output_u32 = [0u32; 21]; // tips: // CORDIC peripheral has some strict on input value, you can also use ".check_argX_fXX()" methods // to make sure your input values are compatible with current CORDIC setup. 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] let arg2 = [0.5]; // and for Sin function, ARG2 should be in [0, 1] let mut input_buf = [0u32; 9]; // convert input from floating point to fixed point input_buf[0] = unwrap!(utils::f64_to_q1_31(arg1[0])); input_buf[1] = unwrap!(utils::f64_to_q1_31(arg2[0])); // If input length is small, blocking mode can be used to minimize overhead. let cnt0 = unwrap!(cordic.blocking_calc_32bit( &input_buf[..2], // input length is strict, since driver use its length to detect calculation count &mut output_u32, false, false )); // convert result from fixed point into floating point for (&u32_val, f64_val) in output_u32[..cnt0].iter().zip(output_f64.iter_mut()) { *f64_val = utils::q1_31_to_f64(u32_val); } // convert input from floating point to fixed point // // first value from arg1 is used, so truncate to arg1[1..] for (&f64_val, u32_val) in arg1[1..].iter().zip(input_buf.iter_mut()) { *u32_val = unwrap!(utils::f64_to_q1_31(f64_val)); } // If calculation is a little longer, async mode can make use of DMA, and let core do some other stuff. let cnt1 = unwrap!( cordic .async_calc_32bit( &mut dp.GPDMA1_CH0, &mut dp.GPDMA1_CH1, &input_buf[..arg1.len() - 1], // limit input buf to its actual length &mut output_u32, true, false ) .await ); // convert result from fixed point into floating point for (&u32_val, f64_val) in output_u32[..cnt1].iter().zip(output_f64[cnt0..cnt0 + cnt1].iter_mut()) { *f64_val = utils::q1_31_to_f64(u32_val); } println!("result: {}", output_f64[..cnt0 + cnt1]); }