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