1#![doc = crate::before_snippet!()]
19use core::{
57 mem::ManuallyDrop,
58 ops::{Deref, DerefMut},
59};
60
61use crate::{
62 Blocking,
63 clock::Clocks,
64 dma::{ChannelRx, DmaError, DmaPeripheral, DmaRxBuffer, PeripheralRxChannel, RxChannelFor},
65 gpio::{
66 InputConfig,
67 InputSignal,
68 OutputConfig,
69 OutputSignal,
70 interconnect::{PeripheralInput, PeripheralOutput},
71 },
72 lcd_cam::{BitOrder, ByteOrder, ClockError, calculate_clkm},
73 pac,
74 peripherals::LCD_CAM,
75 system::{self, GenericPeripheralGuard},
76 time::Rate,
77};
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81#[cfg_attr(feature = "defmt", derive(defmt::Format))]
82pub enum EofMode {
83 ByteLen,
85 VsyncSignal,
87}
88
89#[derive(Debug, Clone, Copy, PartialEq, Eq)]
91#[cfg_attr(feature = "defmt", derive(defmt::Format))]
92pub enum VsyncFilterThreshold {
93 One,
95 Two,
97 Three,
99 Four,
101 Five,
103 Six,
105 Seven,
107 Eight,
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113#[cfg_attr(feature = "defmt", derive(defmt::Format))]
114pub enum VhdeMode {
115 VsyncHsync,
119
120 De,
125}
126
127#[derive(Debug, Clone, Copy, PartialEq)]
129#[cfg_attr(feature = "defmt", derive(defmt::Format))]
130pub enum ConfigError {
131 Clock(ClockError),
133}
134
135pub struct Cam<'d> {
137 pub(crate) lcd_cam: LCD_CAM<'d>,
139 pub(super) _guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>,
140}
141
142pub struct Camera<'d> {
144 lcd_cam: LCD_CAM<'d>,
145 rx_channel: ChannelRx<Blocking, PeripheralRxChannel<LCD_CAM<'d>>>,
146 _guard: GenericPeripheralGuard<{ system::Peripheral::LcdCam as u8 }>,
147}
148
149impl<'d> Camera<'d> {
150 pub fn new(
152 cam: Cam<'d>,
153 channel: impl RxChannelFor<LCD_CAM<'d>>,
154 config: Config,
155 ) -> Result<Self, ConfigError> {
156 let rx_channel = ChannelRx::new(channel.degrade());
157
158 let mut this = Self {
159 lcd_cam: cam.lcd_cam,
160 rx_channel,
161 _guard: cam._guard,
162 };
163
164 this.apply_config(&config)?;
165
166 Ok(this)
167 }
168
169 fn regs(&self) -> &pac::lcd_cam::RegisterBlock {
170 self.lcd_cam.register_block()
171 }
172
173 pub fn apply_config(&mut self, config: &Config) -> Result<(), ConfigError> {
180 let clocks = Clocks::get();
181 let (i, divider) = calculate_clkm(
182 config.frequency.as_hz() as _,
183 &[
184 clocks.xtal_clock.as_hz() as _,
185 clocks.cpu_clock.as_hz() as _,
186 clocks.crypto_pwm_clock.as_hz() as _,
187 ],
188 )
189 .map_err(ConfigError::Clock)?;
190
191 self.regs().cam_ctrl().write(|w| {
192 unsafe {
194 w.cam_clk_sel().bits((i + 1) as _);
195 w.cam_clkm_div_num().bits(divider.div_num as _);
196 w.cam_clkm_div_b().bits(divider.div_b as _);
197 w.cam_clkm_div_a().bits(divider.div_a as _);
198 if let Some(threshold) = config.vsync_filter_threshold {
199 w.cam_vsync_filter_thres().bits(threshold as _);
200 }
201 w.cam_byte_order()
202 .bit(config.byte_order != ByteOrder::default());
203 w.cam_bit_order()
204 .bit(config.bit_order != BitOrder::default());
205 w.cam_vs_eof_en().set_bit();
206 w.cam_line_int_en().clear_bit();
207 w.cam_stop_en().clear_bit()
208 }
209 });
210 self.regs().cam_ctrl1().write(|w| unsafe {
211 w.cam_2byte_en().bit(config.enable_2byte_mode);
212 w.cam_vh_de_mode_en()
213 .bit(matches!(config.vh_de_mode, VhdeMode::VsyncHsync));
214 w.cam_rec_data_bytelen().bits(0);
215 w.cam_line_int_num().bits(0);
216 w.cam_vsync_filter_en()
217 .bit(config.vsync_filter_threshold.is_some());
218 w.cam_clk_inv().clear_bit();
219 w.cam_de_inv().clear_bit();
220 w.cam_hsync_inv().clear_bit();
221 w.cam_vsync_inv().clear_bit()
222 });
223
224 self.regs()
225 .cam_rgb_yuv()
226 .write(|w| w.cam_conv_bypass().clear_bit());
227
228 self.regs()
229 .cam_ctrl()
230 .modify(|_, w| w.cam_update().set_bit());
231
232 Ok(())
233 }
234}
235
236impl<'d> Camera<'d> {
237 pub fn with_master_clock(self, mclk: impl PeripheralOutput<'d>) -> Self {
239 let mclk = mclk.into();
240
241 mclk.apply_output_config(&OutputConfig::default());
242 mclk.set_output_enable(true);
243
244 OutputSignal::CAM_CLK.connect_to(&mclk);
245
246 self
247 }
248
249 pub fn with_pixel_clock(self, pclk: impl PeripheralInput<'d>) -> Self {
251 let pclk = pclk.into();
252
253 pclk.apply_input_config(&InputConfig::default());
254 pclk.set_input_enable(true);
255 InputSignal::CAM_PCLK.connect_to(&pclk);
256
257 self
258 }
259
260 pub fn with_vsync(self, pin: impl PeripheralInput<'d>) -> Self {
262 let pin = pin.into();
263
264 pin.apply_input_config(&InputConfig::default());
265 pin.set_input_enable(true);
266 InputSignal::CAM_V_SYNC.connect_to(&pin);
267
268 self
269 }
270
271 pub fn with_hsync(self, pin: impl PeripheralInput<'d>) -> Self {
273 let pin = pin.into();
274
275 pin.apply_input_config(&InputConfig::default());
276 pin.set_input_enable(true);
277 InputSignal::CAM_H_SYNC.connect_to(&pin);
278
279 self
280 }
281
282 pub fn with_h_enable(self, pin: impl PeripheralInput<'d>) -> Self {
286 let pin = pin.into();
287
288 pin.apply_input_config(&InputConfig::default());
289 pin.set_input_enable(true);
290 InputSignal::CAM_H_ENABLE.connect_to(&pin);
291
292 self
293 }
294
295 fn with_data_pin(self, signal: InputSignal, pin: impl PeripheralInput<'d>) -> Self {
296 let pin = pin.into();
297
298 pin.apply_input_config(&InputConfig::default());
299 pin.set_input_enable(true);
300 signal.connect_to(&pin);
301
302 self
303 }
304
305 pub fn with_data0(self, pin: impl PeripheralInput<'d>) -> Self {
307 self.with_data_pin(InputSignal::CAM_DATA_0, pin)
308 }
309
310 pub fn with_data1(self, pin: impl PeripheralInput<'d>) -> Self {
312 self.with_data_pin(InputSignal::CAM_DATA_1, pin)
313 }
314
315 pub fn with_data2(self, pin: impl PeripheralInput<'d>) -> Self {
317 self.with_data_pin(InputSignal::CAM_DATA_2, pin)
318 }
319
320 pub fn with_data3(self, pin: impl PeripheralInput<'d>) -> Self {
322 self.with_data_pin(InputSignal::CAM_DATA_3, pin)
323 }
324
325 pub fn with_data4(self, pin: impl PeripheralInput<'d>) -> Self {
327 self.with_data_pin(InputSignal::CAM_DATA_4, pin)
328 }
329
330 pub fn with_data5(self, pin: impl PeripheralInput<'d>) -> Self {
332 self.with_data_pin(InputSignal::CAM_DATA_5, pin)
333 }
334
335 pub fn with_data6(self, pin: impl PeripheralInput<'d>) -> Self {
337 self.with_data_pin(InputSignal::CAM_DATA_6, pin)
338 }
339
340 pub fn with_data7(self, pin: impl PeripheralInput<'d>) -> Self {
342 self.with_data_pin(InputSignal::CAM_DATA_7, pin)
343 }
344
345 pub fn with_data8(self, pin: impl PeripheralInput<'d>) -> Self {
347 self.with_data_pin(InputSignal::CAM_DATA_8, pin)
348 }
349
350 pub fn with_data9(self, pin: impl PeripheralInput<'d>) -> Self {
352 self.with_data_pin(InputSignal::CAM_DATA_9, pin)
353 }
354
355 pub fn with_data10(self, pin: impl PeripheralInput<'d>) -> Self {
357 self.with_data_pin(InputSignal::CAM_DATA_10, pin)
358 }
359
360 pub fn with_data11(self, pin: impl PeripheralInput<'d>) -> Self {
362 self.with_data_pin(InputSignal::CAM_DATA_11, pin)
363 }
364
365 pub fn with_data12(self, pin: impl PeripheralInput<'d>) -> Self {
367 self.with_data_pin(InputSignal::CAM_DATA_12, pin)
368 }
369
370 pub fn with_data13(self, pin: impl PeripheralInput<'d>) -> Self {
372 self.with_data_pin(InputSignal::CAM_DATA_13, pin)
373 }
374
375 pub fn with_data14(self, pin: impl PeripheralInput<'d>) -> Self {
377 self.with_data_pin(InputSignal::CAM_DATA_14, pin)
378 }
379
380 pub fn with_data15(self, pin: impl PeripheralInput<'d>) -> Self {
382 self.with_data_pin(InputSignal::CAM_DATA_15, pin)
383 }
384
385 pub fn receive<BUF: DmaRxBuffer>(
387 mut self,
388 mut buf: BUF,
389 ) -> Result<CameraTransfer<'d, BUF>, (DmaError, Self, BUF)> {
390 self.regs()
392 .cam_ctrl1()
393 .modify(|_, w| w.cam_reset().set_bit());
394 self.regs()
395 .cam_ctrl1()
396 .modify(|_, w| w.cam_reset().clear_bit());
397 self.regs()
398 .cam_ctrl1()
399 .modify(|_, w| w.cam_afifo_reset().set_bit());
400 self.regs()
401 .cam_ctrl1()
402 .modify(|_, w| w.cam_afifo_reset().clear_bit());
403
404 let result = unsafe {
406 self.rx_channel
407 .prepare_transfer(DmaPeripheral::LcdCam, &mut buf)
408 .and_then(|_| self.rx_channel.start_transfer())
409 };
410
411 if let Err(e) = result {
412 return Err((e, self, buf));
413 }
414
415 self.regs().cam_ctrl().modify(|_, w| {
417 w.cam_stop_en().set_bit();
419
420 w.cam_update().set_bit()
421 });
422 self.regs()
423 .cam_ctrl1()
424 .modify(|_, w| w.cam_start().set_bit());
425
426 Ok(CameraTransfer {
427 camera: ManuallyDrop::new(self),
428 buffer_view: ManuallyDrop::new(buf.into_view()),
429 })
430 }
431}
432
433pub struct CameraTransfer<'d, BUF: DmaRxBuffer> {
436 camera: ManuallyDrop<Camera<'d>>,
437 buffer_view: ManuallyDrop<BUF::View>,
438}
439
440impl<'d, BUF: DmaRxBuffer> CameraTransfer<'d, BUF> {
441 pub fn is_done(&self) -> bool {
443 self.camera
460 .regs()
461 .cam_ctrl1()
462 .read()
463 .cam_start()
464 .bit_is_clear()
465 }
466
467 pub fn stop(mut self) -> (Camera<'d>, BUF) {
469 self.stop_peripherals();
470 let (camera, view) = self.release();
471 (camera, BUF::from_view(view))
472 }
473
474 pub fn wait(mut self) -> (Result<(), DmaError>, Camera<'d>, BUF) {
480 while !self.is_done() {}
481
482 self.camera.rx_channel.stop_transfer();
484
485 let (camera, view) = self.release();
488
489 let result = if camera.rx_channel.has_error() {
490 Err(DmaError::DescriptorError)
491 } else {
492 Ok(())
493 };
494
495 (result, camera, BUF::from_view(view))
496 }
497
498 fn release(mut self) -> (Camera<'d>, BUF::View) {
499 let result = unsafe {
502 let camera = ManuallyDrop::take(&mut self.camera);
503 let view = ManuallyDrop::take(&mut self.buffer_view);
504 (camera, view)
505 };
506 core::mem::forget(self);
507 result
508 }
509
510 fn stop_peripherals(&mut self) {
511 self.camera
513 .regs()
514 .cam_ctrl1()
515 .modify(|_, w| w.cam_start().clear_bit());
516
517 self.camera.rx_channel.stop_transfer();
519 }
520}
521
522impl<BUF: DmaRxBuffer> Deref for CameraTransfer<'_, BUF> {
523 type Target = BUF::View;
524
525 fn deref(&self) -> &Self::Target {
526 &self.buffer_view
527 }
528}
529
530impl<BUF: DmaRxBuffer> DerefMut for CameraTransfer<'_, BUF> {
531 fn deref_mut(&mut self) -> &mut Self::Target {
532 &mut self.buffer_view
533 }
534}
535
536impl<BUF: DmaRxBuffer> Drop for CameraTransfer<'_, BUF> {
537 fn drop(&mut self) {
538 self.stop_peripherals();
539
540 unsafe {
543 ManuallyDrop::drop(&mut self.camera);
544 ManuallyDrop::drop(&mut self.buffer_view);
545 }
546 }
547}
548
549#[derive(Debug, Clone, Copy, PartialEq, procmacros::BuilderLite)]
550#[cfg_attr(feature = "defmt", derive(defmt::Format))]
551pub struct Config {
553 frequency: Rate,
555
556 enable_2byte_mode: bool,
558
559 byte_order: ByteOrder,
561
562 bit_order: BitOrder,
564
565 vh_de_mode: VhdeMode,
567
568 vsync_filter_threshold: Option<VsyncFilterThreshold>,
570}
571
572impl Default for Config {
573 fn default() -> Self {
574 Self {
575 frequency: Rate::from_mhz(20),
576 enable_2byte_mode: false,
577 byte_order: Default::default(),
578 bit_order: Default::default(),
579 vh_de_mode: VhdeMode::De,
580 vsync_filter_threshold: None,
581 }
582 }
583}