1#![no_std]
2
3use core::num::Wrapping;
4
5use arbitrary_int::{Number, u2, u3, u4, u5, u10, u14, u24};
6use bitbybit::{bitenum, bitfield};
7use embedded_hal::{blocking::delay::DelayUs, digital::v2::OutputPin};
8
9pub trait Interface {
11 type Error;
12 fn configure_mode(&mut self, mode: Mode) -> Result<(), Self::Error>;
13 fn write(&mut self, addr: Address, data: &[u8]) -> Result<(), Self::Error>;
14 fn read(
15 &mut self,
16 addr: Address,
17 data: &mut [u8],
18 ) -> Result<(), Self::Error>;
19}
20
21#[derive(PartialEq)]
24#[bitenum(u2, exhaustive = true)]
25pub enum Mode {
26 SingleBitTwoWire = 0b00,
27 SingleBitThreeWire = 0b01,
28 TwoBitSerial = 0b10,
29 FourBitSerial = 0b11,
30}
31
32pub type Channel = u4;
33
34#[bitfield(u8, default = 0xf0)]
35#[derive(Debug, PartialEq)]
36pub struct Csr {
37 #[bit(0, rw)]
38 lsb_first: bool,
39 #[bits(1..=2, rw)]
40 mode: Mode,
41 #[bits(4..=7, rw)]
42 channel: u4,
43}
44
45#[bitfield(u24, default = 0)]
46#[derive(Debug, PartialEq)]
47pub struct Fr1 {
48 #[bit(0, rw)]
49 sw_sync: bool,
50 #[bit(1, rw)]
51 hw_sync: bool,
52 #[bit(4, rw)]
53 dac_ref_pd: bool,
54 #[bit(5, rw)]
55 sync_clk_pd: bool,
56 #[bit(6, rw)]
57 ext_pd: bool,
58 #[bit(7, rw)]
59 ext_clk_pd: bool,
60 #[bits(8..=9, rw)]
61 modulation: u2,
62 #[bits(10..=11, rw)]
63 ramp_up_down: u2,
64 #[bits(12..=14, rw)]
65 profile_pin: u3,
66 #[bits(16..=17, rw)]
67 charge_pump: u2,
68 #[bits(18..=22, rw)]
69 pll_divier: u5,
70 #[bit(23, rw)]
71 vco_high: bool,
72}
73
74#[bitfield(u24, default = 0)]
75#[derive(Debug, PartialEq)]
76pub struct Acr {
77 #[bits(0..=9, rw)]
78 asf: u10,
79 #[bit(10, rw)]
80 load_arr: bool,
81 #[bit(11, rw)]
82 ramp: bool,
83 #[bit(12, rw)]
84 multiplier: bool,
85 #[bits(14..=15, rw)]
86 step: u2,
87 #[bits(16..=23, rw)]
88 arr: u8,
89}
90
91#[allow(clippy::upper_case_acronyms)]
92#[bitenum(u7)]
93pub enum Address {
94 CSR = 0x00,
95 FR1 = 0x01,
96 FR2 = 0x02,
97 CFR = 0x03,
98 CFTW0 = 0x04,
99 CPOW0 = 0x05,
100 ACR = 0x06,
101 LSRR = 0x07,
102 RDW = 0x08,
103 FDW = 0x09,
104 CW1 = 0x0a,
105 CW2 = 0x0b,
106 CW3 = 0x0c,
107 CW4 = 0x0d,
108 CW5 = 0x0e,
109 CW6 = 0x0f,
110 CW7 = 0x10,
111 CW8 = 0x11,
112 CW9 = 0x12,
113 CW10 = 0x13,
114 CW11 = 0x14,
115 CW12 = 0x15,
116 CW13 = 0x16,
117 CW14 = 0x17,
118 CW15 = 0x18,
119}
120
121#[derive(Debug)]
123pub enum Error {
124 Interface,
125 Check,
126 Bounds,
127 Pin,
128 Frequency,
129}
130
131pub struct Ad9959<I> {
142 interface: I,
143 ftw_per_hz: f32,
144 mode: Mode,
145}
146
147impl<I: Interface> Ad9959<I> {
148 pub fn new(
160 interface: I,
161 reset: &mut impl OutputPin,
162 io_update: &mut impl OutputPin,
163 delay: &mut impl DelayUs<u8>,
164 mode: Mode,
165 reference_clock_frequency: f32,
166 multiplier: u5,
167 ) -> Result<Self, Error> {
168 let mut ad9959 = Ad9959 {
169 interface,
170 ftw_per_hz: 0.0,
171 mode,
172 };
173 io_update.set_low().or(Err(Error::Pin))?;
174
175 reset.set_high().or(Err(Error::Pin))?;
179 delay.delay_us(5);
183 reset.set_low().or(Err(Error::Pin))?;
184
185 ad9959
186 .interface
187 .configure_mode(Mode::SingleBitTwoWire)
188 .or(Err(Error::Interface))?;
189
190 let csr = Csr::default().with_channel(u4::new(0b1111)).with_mode(mode);
191 ad9959.write(Address::CSR, &csr.raw_value().to_be_bytes())?;
192
193 io_update.set_high().or(Err(Error::Pin))?;
194 delay.delay_us(5);
195 io_update.set_low().or(Err(Error::Pin))?;
196
197 ad9959
198 .interface
199 .configure_mode(mode)
200 .or(Err(Error::Interface))?;
201
202 delay.delay_us(5);
206
207 let mut updated_csr = 0u8.to_be_bytes();
209 ad9959.read(Address::CSR, &mut updated_csr)?;
210 if updated_csr != csr.raw_value().to_be_bytes() {
211 return Err(Error::Check);
212 }
213
214 ad9959.set_system_clock(reference_clock_frequency, multiplier)?;
216 io_update.set_high().or(Err(Error::Pin))?;
217 delay.delay_us(5);
218 io_update.set_low().or(Err(Error::Pin))?;
219
220 Ok(ad9959)
221 }
222
223 fn read(&mut self, reg: Address, data: &mut [u8]) -> Result<(), Error> {
224 self.interface.read(reg, data).or(Err(Error::Interface))
225 }
226
227 fn write(&mut self, reg: Address, data: &[u8]) -> Result<(), Error> {
228 self.interface.write(reg, data).or(Err(Error::Interface))
229 }
230
231 fn set_system_clock(
240 &mut self,
241 reference_clock_frequency: f32,
242 multiplier: u5,
243 ) -> Result<f32, Error> {
244 let sysclk = multiplier.value() as f32 * reference_clock_frequency;
245 if match multiplier.value() {
246 1 => !(1e6..=500e6).contains(&reference_clock_frequency),
247 4..=20 => {
248 !(10e6..=125e6).contains(&reference_clock_frequency)
249 || !(100e6..=500e6).contains(&sysclk)
250 }
251 _ => true,
252 } {
253 return Err(Error::Bounds);
254 }
255 let mut fr1 = u24::new(0).to_be_bytes();
256 self.read(Address::FR1, &mut fr1)?;
257 let fr1 = Fr1::new_with_raw_value(u24::from_be_bytes(fr1))
258 .with_pll_divier(multiplier)
259 .with_vco_high(sysclk >= 200e6);
260 self.write(Address::FR1, &fr1.raw_value().to_be_bytes())?;
261 self.ftw_per_hz = (1u64 << 32) as f32 / sysclk;
262 Ok(sysclk)
263 }
264
265 pub fn csr(&mut self) -> Result<Csr, Error> {
267 let mut data = u8::new(0).to_be_bytes();
268 self.read(Address::CSR, &mut data)?;
269 Ok(Csr::new_with_raw_value(u8::from_be_bytes(data)))
270 }
271
272 pub fn fr1(&mut self) -> Result<Fr1, Error> {
274 let mut data = u24::new(0).to_be_bytes();
275 self.read(Address::FR1, &mut data)?;
276 Ok(Fr1::new_with_raw_value(u24::from_be_bytes(data)))
277 }
278
279 pub fn self_test(&mut self) -> Result<bool, Error> {
287 let mut data = [0];
288
289 self.read(Address::CSR, &mut data)?;
291 let old_csr = data;
292
293 let mut csr = Csr::new_with_raw_value(data[0]);
294
295 csr.set_channel(u4::new(0b1111));
297 self.write(Address::CSR, &[csr.raw_value()])?;
298 self.read(Address::CSR, &mut data)?;
299 if Csr::new_with_raw_value(data[0]).channel() != csr.channel() {
300 return Ok(false);
301 }
302
303 csr.set_channel(u4::new(0b0000));
305 self.write(Address::CSR, &[csr.raw_value()])?;
306 self.read(Address::CSR, &mut data)?;
307 if Csr::new_with_raw_value(data[0]).channel() != csr.channel() {
308 return Ok(false);
309 }
310
311 self.write(Address::CSR, &old_csr)?;
313
314 Ok(true)
315 }
316
317 fn system_clock_frequency(&self) -> f32 {
319 (1u64 << 32) as f32 / self.ftw_per_hz
320 }
321
322 fn write_channel(
329 &mut self,
330 channel: Channel,
331 register: Address,
332 data: &[u8],
333 ) -> Result<(), Error> {
334 let csr = Csr::default().with_channel(channel).with_mode(self.mode);
337 self.write(Address::CSR, &csr.raw_value().to_be_bytes())?;
338 self.write(register, data)?;
339 Ok(())
340 }
341
342 fn read_channel(
349 &mut self,
350 channel: Channel,
351 register: Address,
352 data: &mut [u8],
353 ) -> Result<(), Error> {
354 let csr = Csr::default().with_channel(channel).with_mode(self.mode);
355 self.write(Address::CSR, &csr.raw_value().to_be_bytes())?;
356 self.read(register, data)?;
357 Ok(())
358 }
359
360 pub fn set_phase(
369 &mut self,
370 channel: Channel,
371 phase: f32,
372 ) -> Result<f32, Error> {
373 let pow = u14::new((phase * (1 << 14) as f32) as u16 & 0x3FFF);
374 self.write_channel(
375 channel,
376 Address::CPOW0,
377 &pow.value().to_be_bytes(),
378 )?;
379 Ok(pow.value() as f32 / (1 << 14) as f32)
380 }
381
382 pub fn get_phase(&mut self, channel: Channel) -> Result<f32, Error> {
390 let mut pow = 0u16.to_be_bytes();
391 self.read_channel(channel, Address::CPOW0, &mut pow)?;
392 let pow = u16::from_be_bytes(pow) & 0x3FFF;
393 Ok(pow as f32 / (1 << 14) as f32)
394 }
395
396 pub fn set_amplitude(
405 &mut self,
406 channel: Channel,
407 amplitude: f32,
408 ) -> Result<f32, Error> {
409 if !(0.0..=1.0).contains(&litude) {
410 return Err(Error::Bounds);
411 }
412 let asf = (amplitude * (1 << 10) as f32) as u16;
413 let acr = match u10::try_new(asf) {
414 Ok(asf) => Acr::default().with_multiplier(true).with_asf(asf),
415 Err(_) => Acr::default().with_multiplier(false),
416 };
417 self.write_channel(
418 channel,
419 Address::ACR,
420 &acr.raw_value().to_be_bytes(),
421 )?;
422 Ok(asf as f32 / (1 << 10) as f32)
423 }
424
425 pub fn get_amplitude(&mut self, channel: Channel) -> Result<f32, Error> {
433 let mut acr = u24::new(0).to_be_bytes();
434 self.read_channel(channel, Address::ACR, &mut acr)?;
435 let acr = Acr::new_with_raw_value(u24::from_be_bytes(acr));
436 Ok(if acr.multiplier() {
437 1.0
438 } else {
439 acr.asf().value() as f32 / (1 << 10) as f32
440 })
441 }
442
443 pub fn set_frequency(
452 &mut self,
453 channel: Channel,
454 frequency: f32,
455 ) -> Result<f32, Error> {
456 if frequency < 0.0 || frequency > self.system_clock_frequency() {
457 return Err(Error::Bounds);
458 }
459 let ftw = (frequency * self.ftw_per_hz) as u32;
460 self.write_channel(channel, Address::CFTW0, &ftw.to_be_bytes())?;
461 Ok(ftw as f32 / self.ftw_per_hz)
462 }
463
464 pub fn get_frequency(&mut self, channel: Channel) -> Result<f32, Error> {
472 let mut ftw = 0u32.to_be_bytes();
473 self.read_channel(channel, Address::CFTW0, &mut ftw)?;
474 let ftw = u32::from_be_bytes(ftw);
475 Ok(ftw as f32 / self.ftw_per_hz)
476 }
477
478 pub fn freeze(self) -> (I, Mode) {
486 (self.interface, self.mode)
487 }
488}
489
490pub struct ProfileSerializer {
492 mode: Mode,
493 index: usize,
497 data: [u8; 32],
498}
499
500impl ProfileSerializer {
501 pub fn new(mode: Mode) -> Self {
506 Self {
507 mode,
508 index: 0,
509 data: [0; 32],
510 }
511 }
512
513 #[inline]
523 pub fn push(
524 &mut self,
525 channels: Channel,
526 ftw: Option<Wrapping<i32>>,
527 pow: Option<Wrapping<u14>>, acr: Option<Acr>,
529 ) {
530 self.push_write(
531 Address::CSR,
532 &Csr::default()
533 .with_mode(self.mode)
534 .with_channel(channels)
535 .raw_value()
536 .to_be_bytes(),
537 );
538 if let Some(ftw) = ftw {
539 self.push_write(Address::CFTW0, &ftw.0.to_be_bytes());
540 }
541 if let Some(pow) = pow {
542 self.push_write(Address::CPOW0, &pow.0.value().to_be_bytes());
543 }
544 if let Some(acr) = acr {
545 self.push_write(Address::ACR, &acr.raw_value().to_be_bytes());
546 }
547 }
548
549 #[inline]
551 fn push_write(&mut self, register: Address, value: &[u8]) {
552 let data = &mut self.data[self.index..];
553 data[0] = register as u8;
554 data[1..1 + value.len()].copy_from_slice(value);
555 self.index += 1 + value.len();
556 }
557
558 #[inline]
567 pub fn finalize(&mut self) -> &[u32] {
568 if self.index & 1 != 0 {
572 self.push_write(Address::LSRR, &0u16.to_be_bytes());
574 }
575 if self.index & 2 != 0 {
576 self.push_write(
578 Address::CSR,
579 &Csr::default()
580 .with_mode(self.mode)
581 .raw_value()
582 .to_be_bytes(),
583 );
584 }
585 bytemuck::cast_slice(&self.data[..self.index])
586 }
587}