diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-08-25 17:31:38 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-05 15:19:22 +0200 |
| commit | 60b640bd977ac2d056061e0c0b7a497f815417f4 (patch) | |
| tree | e09d531dbf5583f9621352300cc81bd46997ff9f | |
| parent | f6414d8cd22d18eb1adc5dfa2780bc94a150be30 (diff) | |
stm32/sai: update for new metapac, simplify cfgs.
| -rw-r--r-- | embassy-stm32/src/sai/mod.rs | 318 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/sai.rs | 72 | ||||
| -rw-r--r-- | examples/stm32h723/src/bin/spdifrx.rs | 2 |
3 files changed, 56 insertions, 336 deletions
diff --git a/embassy-stm32/src/sai/mod.rs b/embassy-stm32/src/sai/mod.rs index 88cc225dd..ff81dabed 100644 --- a/embassy-stm32/src/sai/mod.rs +++ b/embassy-stm32/src/sai/mod.rs | |||
| @@ -8,6 +8,7 @@ use embassy_hal_internal::PeripheralType; | |||
| 8 | pub use crate::dma::word; | 8 | pub use crate::dma::word; |
| 9 | use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; | 9 | use crate::dma::{ringbuffer, Channel, ReadableRingBuffer, Request, TransferOptions, WritableRingBuffer}; |
| 10 | use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; | 10 | use crate::gpio::{AfType, AnyPin, OutputType, Pull, SealedPin as _, Speed}; |
| 11 | pub use crate::pac::sai::vals::Mckdiv as MasterClockDivider; | ||
| 11 | use crate::pac::sai::{vals, Sai as Regs}; | 12 | use crate::pac::sai::{vals, Sai as Regs}; |
| 12 | use crate::rcc::{self, RccPeripheral}; | 13 | use crate::rcc::{self, RccPeripheral}; |
| 13 | use crate::{peripherals, Peri}; | 14 | use crate::{peripherals, Peri}; |
| @@ -45,7 +46,6 @@ pub enum Mode { | |||
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | impl Mode { | 48 | impl Mode { |
| 48 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 49 | const fn mode(&self, tx_rx: TxRx) -> vals::Mode { | 49 | const fn mode(&self, tx_rx: TxRx) -> vals::Mode { |
| 50 | match tx_rx { | 50 | match tx_rx { |
| 51 | TxRx::Transmitter => match self { | 51 | TxRx::Transmitter => match self { |
| @@ -80,7 +80,6 @@ pub enum SlotSize { | |||
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | impl SlotSize { | 82 | impl SlotSize { |
| 83 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 84 | const fn slotsz(&self) -> vals::Slotsz { | 83 | const fn slotsz(&self) -> vals::Slotsz { |
| 85 | match self { | 84 | match self { |
| 86 | SlotSize::DataSize => vals::Slotsz::DATA_SIZE, | 85 | SlotSize::DataSize => vals::Slotsz::DATA_SIZE, |
| @@ -103,7 +102,6 @@ pub enum DataSize { | |||
| 103 | } | 102 | } |
| 104 | 103 | ||
| 105 | impl DataSize { | 104 | impl DataSize { |
| 106 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 107 | const fn ds(&self) -> vals::Ds { | 105 | const fn ds(&self) -> vals::Ds { |
| 108 | match self { | 106 | match self { |
| 109 | DataSize::Data8 => vals::Ds::BIT8, | 107 | DataSize::Data8 => vals::Ds::BIT8, |
| @@ -128,7 +126,6 @@ pub enum FifoThreshold { | |||
| 128 | } | 126 | } |
| 129 | 127 | ||
| 130 | impl FifoThreshold { | 128 | impl FifoThreshold { |
| 131 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 132 | const fn fth(&self) -> vals::Fth { | 129 | const fn fth(&self) -> vals::Fth { |
| 133 | match self { | 130 | match self { |
| 134 | FifoThreshold::Empty => vals::Fth::EMPTY, | 131 | FifoThreshold::Empty => vals::Fth::EMPTY, |
| @@ -149,7 +146,6 @@ pub enum MuteValue { | |||
| 149 | } | 146 | } |
| 150 | 147 | ||
| 151 | impl MuteValue { | 148 | impl MuteValue { |
| 152 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 153 | const fn muteval(&self) -> vals::Muteval { | 149 | const fn muteval(&self) -> vals::Muteval { |
| 154 | match self { | 150 | match self { |
| 155 | MuteValue::Zero => vals::Muteval::SEND_ZERO, | 151 | MuteValue::Zero => vals::Muteval::SEND_ZERO, |
| @@ -168,7 +164,6 @@ pub enum Protocol { | |||
| 168 | } | 164 | } |
| 169 | 165 | ||
| 170 | impl Protocol { | 166 | impl Protocol { |
| 171 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 172 | const fn prtcfg(&self) -> vals::Prtcfg { | 167 | const fn prtcfg(&self) -> vals::Prtcfg { |
| 173 | match self { | 168 | match self { |
| 174 | Protocol::Free => vals::Prtcfg::FREE, | 169 | Protocol::Free => vals::Prtcfg::FREE, |
| @@ -226,7 +221,6 @@ pub enum StereoMono { | |||
| 226 | } | 221 | } |
| 227 | 222 | ||
| 228 | impl StereoMono { | 223 | impl StereoMono { |
| 229 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 230 | const fn mono(&self) -> vals::Mono { | 224 | const fn mono(&self) -> vals::Mono { |
| 231 | match self { | 225 | match self { |
| 232 | StereoMono::Stereo => vals::Mono::STEREO, | 226 | StereoMono::Stereo => vals::Mono::STEREO, |
| @@ -245,7 +239,6 @@ pub enum BitOrder { | |||
| 245 | } | 239 | } |
| 246 | 240 | ||
| 247 | impl BitOrder { | 241 | impl BitOrder { |
| 248 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 249 | const fn lsbfirst(&self) -> vals::Lsbfirst { | 242 | const fn lsbfirst(&self) -> vals::Lsbfirst { |
| 250 | match self { | 243 | match self { |
| 251 | BitOrder::LsbFirst => vals::Lsbfirst::LSB_FIRST, | 244 | BitOrder::LsbFirst => vals::Lsbfirst::LSB_FIRST, |
| @@ -264,7 +257,6 @@ pub enum FrameSyncOffset { | |||
| 264 | } | 257 | } |
| 265 | 258 | ||
| 266 | impl FrameSyncOffset { | 259 | impl FrameSyncOffset { |
| 267 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 268 | const fn fsoff(&self) -> vals::Fsoff { | 260 | const fn fsoff(&self) -> vals::Fsoff { |
| 269 | match self { | 261 | match self { |
| 270 | FrameSyncOffset::OnFirstBit => vals::Fsoff::ON_FIRST, | 262 | FrameSyncOffset::OnFirstBit => vals::Fsoff::ON_FIRST, |
| @@ -283,7 +275,6 @@ pub enum FrameSyncPolarity { | |||
| 283 | } | 275 | } |
| 284 | 276 | ||
| 285 | impl FrameSyncPolarity { | 277 | impl FrameSyncPolarity { |
| 286 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 287 | const fn fspol(&self) -> vals::Fspol { | 278 | const fn fspol(&self) -> vals::Fspol { |
| 288 | match self { | 279 | match self { |
| 289 | FrameSyncPolarity::ActiveLow => vals::Fspol::FALLING_EDGE, | 280 | FrameSyncPolarity::ActiveLow => vals::Fspol::FALLING_EDGE, |
| @@ -301,7 +292,6 @@ pub enum FrameSyncDefinition { | |||
| 301 | } | 292 | } |
| 302 | 293 | ||
| 303 | impl FrameSyncDefinition { | 294 | impl FrameSyncDefinition { |
| 304 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 305 | const fn fsdef(&self) -> bool { | 295 | const fn fsdef(&self) -> bool { |
| 306 | match self { | 296 | match self { |
| 307 | FrameSyncDefinition::StartOfFrame => false, | 297 | FrameSyncDefinition::StartOfFrame => false, |
| @@ -319,7 +309,6 @@ pub enum ClockStrobe { | |||
| 319 | } | 309 | } |
| 320 | 310 | ||
| 321 | impl ClockStrobe { | 311 | impl ClockStrobe { |
| 322 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 323 | const fn ckstr(&self) -> vals::Ckstr { | 312 | const fn ckstr(&self) -> vals::Ckstr { |
| 324 | match self { | 313 | match self { |
| 325 | ClockStrobe::Falling => vals::Ckstr::FALLING_EDGE, | 314 | ClockStrobe::Falling => vals::Ckstr::FALLING_EDGE, |
| @@ -337,7 +326,6 @@ pub enum ComplementFormat { | |||
| 337 | } | 326 | } |
| 338 | 327 | ||
| 339 | impl ComplementFormat { | 328 | impl ComplementFormat { |
| 340 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 341 | const fn cpl(&self) -> vals::Cpl { | 329 | const fn cpl(&self) -> vals::Cpl { |
| 342 | match self { | 330 | match self { |
| 343 | ComplementFormat::OnesComplement => vals::Cpl::ONES_COMPLEMENT, | 331 | ComplementFormat::OnesComplement => vals::Cpl::ONES_COMPLEMENT, |
| @@ -356,7 +344,6 @@ pub enum Companding { | |||
| 356 | } | 344 | } |
| 357 | 345 | ||
| 358 | impl Companding { | 346 | impl Companding { |
| 359 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 360 | const fn comp(&self) -> vals::Comp { | 347 | const fn comp(&self) -> vals::Comp { |
| 361 | match self { | 348 | match self { |
| 362 | Companding::None => vals::Comp::NO_COMPANDING, | 349 | Companding::None => vals::Comp::NO_COMPANDING, |
| @@ -375,7 +362,6 @@ pub enum OutputDrive { | |||
| 375 | } | 362 | } |
| 376 | 363 | ||
| 377 | impl OutputDrive { | 364 | impl OutputDrive { |
| 378 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 379 | const fn outdriv(&self) -> vals::Outdriv { | 365 | const fn outdriv(&self) -> vals::Outdriv { |
| 380 | match self { | 366 | match self { |
| 381 | OutputDrive::OnStart => vals::Outdriv::ON_START, | 367 | OutputDrive::OnStart => vals::Outdriv::ON_START, |
| @@ -384,196 +370,6 @@ impl OutputDrive { | |||
| 384 | } | 370 | } |
| 385 | } | 371 | } |
| 386 | 372 | ||
| 387 | /// Master clock divider. | ||
| 388 | #[derive(Copy, Clone, PartialEq)] | ||
| 389 | #[allow(missing_docs)] | ||
| 390 | #[cfg(any(sai_v1, sai_v2))] | ||
| 391 | pub enum MasterClockDivider { | ||
| 392 | MasterClockDisabled, | ||
| 393 | Div1, | ||
| 394 | Div2, | ||
| 395 | Div4, | ||
| 396 | Div6, | ||
| 397 | Div8, | ||
| 398 | Div10, | ||
| 399 | Div12, | ||
| 400 | Div14, | ||
| 401 | Div16, | ||
| 402 | Div18, | ||
| 403 | Div20, | ||
| 404 | Div22, | ||
| 405 | Div24, | ||
| 406 | Div26, | ||
| 407 | Div28, | ||
| 408 | Div30, | ||
| 409 | } | ||
| 410 | |||
| 411 | /// Master clock divider. | ||
| 412 | #[derive(Copy, Clone, PartialEq)] | ||
| 413 | #[allow(missing_docs)] | ||
| 414 | #[cfg(any(sai_v1_4pdm, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 415 | pub enum MasterClockDivider { | ||
| 416 | MasterClockDisabled, | ||
| 417 | Div1, | ||
| 418 | Div2, | ||
| 419 | Div3, | ||
| 420 | Div4, | ||
| 421 | Div5, | ||
| 422 | Div6, | ||
| 423 | Div7, | ||
| 424 | Div8, | ||
| 425 | Div9, | ||
| 426 | Div10, | ||
| 427 | Div11, | ||
| 428 | Div12, | ||
| 429 | Div13, | ||
| 430 | Div14, | ||
| 431 | Div15, | ||
| 432 | Div16, | ||
| 433 | Div17, | ||
| 434 | Div18, | ||
| 435 | Div19, | ||
| 436 | Div20, | ||
| 437 | Div21, | ||
| 438 | Div22, | ||
| 439 | Div23, | ||
| 440 | Div24, | ||
| 441 | Div25, | ||
| 442 | Div26, | ||
| 443 | Div27, | ||
| 444 | Div28, | ||
| 445 | Div29, | ||
| 446 | Div30, | ||
| 447 | Div31, | ||
| 448 | Div32, | ||
| 449 | Div33, | ||
| 450 | Div34, | ||
| 451 | Div35, | ||
| 452 | Div36, | ||
| 453 | Div37, | ||
| 454 | Div38, | ||
| 455 | Div39, | ||
| 456 | Div40, | ||
| 457 | Div41, | ||
| 458 | Div42, | ||
| 459 | Div43, | ||
| 460 | Div44, | ||
| 461 | Div45, | ||
| 462 | Div46, | ||
| 463 | Div47, | ||
| 464 | Div48, | ||
| 465 | Div49, | ||
| 466 | Div50, | ||
| 467 | Div51, | ||
| 468 | Div52, | ||
| 469 | Div53, | ||
| 470 | Div54, | ||
| 471 | Div55, | ||
| 472 | Div56, | ||
| 473 | Div57, | ||
| 474 | Div58, | ||
| 475 | Div59, | ||
| 476 | Div60, | ||
| 477 | Div61, | ||
| 478 | Div62, | ||
| 479 | Div63, | ||
| 480 | } | ||
| 481 | |||
| 482 | impl MasterClockDivider { | ||
| 483 | #[cfg(any(sai_v1, sai_v2))] | ||
| 484 | const fn mckdiv(&self) -> u8 { | ||
| 485 | match self { | ||
| 486 | MasterClockDivider::MasterClockDisabled => 0, | ||
| 487 | MasterClockDivider::Div1 => 0, | ||
| 488 | MasterClockDivider::Div2 => 1, | ||
| 489 | MasterClockDivider::Div4 => 2, | ||
| 490 | MasterClockDivider::Div6 => 3, | ||
| 491 | MasterClockDivider::Div8 => 4, | ||
| 492 | MasterClockDivider::Div10 => 5, | ||
| 493 | MasterClockDivider::Div12 => 6, | ||
| 494 | MasterClockDivider::Div14 => 7, | ||
| 495 | MasterClockDivider::Div16 => 8, | ||
| 496 | MasterClockDivider::Div18 => 9, | ||
| 497 | MasterClockDivider::Div20 => 10, | ||
| 498 | MasterClockDivider::Div22 => 11, | ||
| 499 | MasterClockDivider::Div24 => 12, | ||
| 500 | MasterClockDivider::Div26 => 13, | ||
| 501 | MasterClockDivider::Div28 => 14, | ||
| 502 | MasterClockDivider::Div30 => 15, | ||
| 503 | } | ||
| 504 | } | ||
| 505 | |||
| 506 | #[cfg(any(sai_v1_4pdm, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | ||
| 507 | const fn mckdiv(&self) -> u8 { | ||
| 508 | match self { | ||
| 509 | MasterClockDivider::MasterClockDisabled => 0, | ||
| 510 | MasterClockDivider::Div1 => 1, | ||
| 511 | MasterClockDivider::Div2 => 2, | ||
| 512 | MasterClockDivider::Div3 => 3, | ||
| 513 | MasterClockDivider::Div4 => 4, | ||
| 514 | MasterClockDivider::Div5 => 5, | ||
| 515 | MasterClockDivider::Div6 => 6, | ||
| 516 | MasterClockDivider::Div7 => 7, | ||
| 517 | MasterClockDivider::Div8 => 8, | ||
| 518 | MasterClockDivider::Div9 => 9, | ||
| 519 | MasterClockDivider::Div10 => 10, | ||
| 520 | MasterClockDivider::Div11 => 11, | ||
| 521 | MasterClockDivider::Div12 => 12, | ||
| 522 | MasterClockDivider::Div13 => 13, | ||
| 523 | MasterClockDivider::Div14 => 14, | ||
| 524 | MasterClockDivider::Div15 => 15, | ||
| 525 | MasterClockDivider::Div16 => 16, | ||
| 526 | MasterClockDivider::Div17 => 17, | ||
| 527 | MasterClockDivider::Div18 => 18, | ||
| 528 | MasterClockDivider::Div19 => 19, | ||
| 529 | MasterClockDivider::Div20 => 20, | ||
| 530 | MasterClockDivider::Div21 => 21, | ||
| 531 | MasterClockDivider::Div22 => 22, | ||
| 532 | MasterClockDivider::Div23 => 23, | ||
| 533 | MasterClockDivider::Div24 => 24, | ||
| 534 | MasterClockDivider::Div25 => 25, | ||
| 535 | MasterClockDivider::Div26 => 26, | ||
| 536 | MasterClockDivider::Div27 => 27, | ||
| 537 | MasterClockDivider::Div28 => 28, | ||
| 538 | MasterClockDivider::Div29 => 29, | ||
| 539 | MasterClockDivider::Div30 => 30, | ||
| 540 | MasterClockDivider::Div31 => 31, | ||
| 541 | MasterClockDivider::Div32 => 32, | ||
| 542 | MasterClockDivider::Div33 => 33, | ||
| 543 | MasterClockDivider::Div34 => 34, | ||
| 544 | MasterClockDivider::Div35 => 35, | ||
| 545 | MasterClockDivider::Div36 => 36, | ||
| 546 | MasterClockDivider::Div37 => 37, | ||
| 547 | MasterClockDivider::Div38 => 38, | ||
| 548 | MasterClockDivider::Div39 => 39, | ||
| 549 | MasterClockDivider::Div40 => 40, | ||
| 550 | MasterClockDivider::Div41 => 41, | ||
| 551 | MasterClockDivider::Div42 => 42, | ||
| 552 | MasterClockDivider::Div43 => 43, | ||
| 553 | MasterClockDivider::Div44 => 44, | ||
| 554 | MasterClockDivider::Div45 => 45, | ||
| 555 | MasterClockDivider::Div46 => 46, | ||
| 556 | MasterClockDivider::Div47 => 47, | ||
| 557 | MasterClockDivider::Div48 => 48, | ||
| 558 | MasterClockDivider::Div49 => 49, | ||
| 559 | MasterClockDivider::Div50 => 50, | ||
| 560 | MasterClockDivider::Div51 => 51, | ||
| 561 | MasterClockDivider::Div52 => 52, | ||
| 562 | MasterClockDivider::Div53 => 53, | ||
| 563 | MasterClockDivider::Div54 => 54, | ||
| 564 | MasterClockDivider::Div55 => 55, | ||
| 565 | MasterClockDivider::Div56 => 56, | ||
| 566 | MasterClockDivider::Div57 => 57, | ||
| 567 | MasterClockDivider::Div58 => 58, | ||
| 568 | MasterClockDivider::Div59 => 59, | ||
| 569 | MasterClockDivider::Div60 => 60, | ||
| 570 | MasterClockDivider::Div61 => 61, | ||
| 571 | MasterClockDivider::Div62 => 62, | ||
| 572 | MasterClockDivider::Div63 => 63, | ||
| 573 | } | ||
| 574 | } | ||
| 575 | } | ||
| 576 | |||
| 577 | /// [`SAI`] configuration. | 373 | /// [`SAI`] configuration. |
| 578 | #[allow(missing_docs)] | 374 | #[allow(missing_docs)] |
| 579 | #[non_exhaustive] | 375 | #[non_exhaustive] |
| @@ -598,8 +394,7 @@ pub struct Config { | |||
| 598 | pub frame_length: u8, | 394 | pub frame_length: u8, |
| 599 | pub clock_strobe: ClockStrobe, | 395 | pub clock_strobe: ClockStrobe, |
| 600 | pub output_drive: OutputDrive, | 396 | pub output_drive: OutputDrive, |
| 601 | pub master_clock_divider: MasterClockDivider, | 397 | pub master_clock_divider: Option<MasterClockDivider>, |
| 602 | pub nodiv: bool, | ||
| 603 | pub is_high_impedance_on_inactive_slot: bool, | 398 | pub is_high_impedance_on_inactive_slot: bool, |
| 604 | pub fifo_threshold: FifoThreshold, | 399 | pub fifo_threshold: FifoThreshold, |
| 605 | pub companding: Companding, | 400 | pub companding: Companding, |
| @@ -628,8 +423,7 @@ impl Default for Config { | |||
| 628 | frame_sync_active_level_length: word::U7(16), | 423 | frame_sync_active_level_length: word::U7(16), |
| 629 | frame_sync_definition: FrameSyncDefinition::ChannelIdentification, | 424 | frame_sync_definition: FrameSyncDefinition::ChannelIdentification, |
| 630 | frame_length: 32, | 425 | frame_length: 32, |
| 631 | master_clock_divider: MasterClockDivider::MasterClockDisabled, | 426 | master_clock_divider: None, |
| 632 | nodiv: false, | ||
| 633 | clock_strobe: ClockStrobe::Rising, | 427 | clock_strobe: ClockStrobe::Rising, |
| 634 | output_drive: OutputDrive::Immediately, | 428 | output_drive: OutputDrive::Immediately, |
| 635 | is_high_impedance_on_inactive_slot: false, | 429 | is_high_impedance_on_inactive_slot: false, |
| @@ -761,15 +555,11 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { | |||
| 761 | mclk: Peri<'d, impl MclkPin<T, S>>, | 555 | mclk: Peri<'d, impl MclkPin<T, S>>, |
| 762 | dma: Peri<'d, impl Channel + Dma<T, S>>, | 556 | dma: Peri<'d, impl Channel + Dma<T, S>>, |
| 763 | dma_buf: &'d mut [W], | 557 | dma_buf: &'d mut [W], |
| 764 | mut config: Config, | 558 | config: Config, |
| 765 | ) -> Self { | 559 | ) -> Self { |
| 766 | let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); | 560 | let (_sd_af_type, ck_af_type) = get_af_types(config.mode, config.tx_rx); |
| 767 | mclk.set_as_af(mclk.af_num(), ck_af_type); | 561 | mclk.set_as_af(mclk.af_num(), ck_af_type); |
| 768 | 562 | ||
| 769 | if config.master_clock_divider == MasterClockDivider::MasterClockDisabled { | ||
| 770 | config.master_clock_divider = MasterClockDivider::Div1; | ||
| 771 | } | ||
| 772 | |||
| 773 | Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config) | 563 | Self::new_asynchronous(peri, sck, sd, fs, dma, dma_buf, config) |
| 774 | } | 564 | } |
| 775 | 565 | ||
| @@ -851,10 +641,7 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { | |||
| 851 | ) -> Self { | 641 | ) -> Self { |
| 852 | let ch = T::REGS.ch(sub_block as usize); | 642 | let ch = T::REGS.ch(sub_block as usize); |
| 853 | 643 | ||
| 854 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | 644 | ch.cr1().modify(|w| w.set_saien(false)); |
| 855 | { | ||
| 856 | ch.cr1().modify(|w| w.set_saien(false)); | ||
| 857 | } | ||
| 858 | 645 | ||
| 859 | ch.cr2().modify(|w| w.set_fflush(true)); | 646 | ch.cr2().modify(|w| w.set_fflush(true)); |
| 860 | 647 | ||
| @@ -877,55 +664,52 @@ impl<'d, T: Instance, W: word::Word> Sai<'d, T, W> { | |||
| 877 | } | 664 | } |
| 878 | } | 665 | } |
| 879 | 666 | ||
| 880 | #[cfg(any(sai_v1, sai_v1_4pdm, sai_v2, sai_v3_2pdm, sai_v3_4pdm, sai_v4_2pdm, sai_v4_4pdm))] | 667 | ch.cr1().modify(|w| { |
| 881 | { | 668 | w.set_mode(config.mode.mode(if Self::is_transmitter(&ring_buffer) { |
| 882 | ch.cr1().modify(|w| { | 669 | TxRx::Transmitter |
| 883 | w.set_mode(config.mode.mode(if Self::is_transmitter(&ring_buffer) { | 670 | } else { |
| 884 | TxRx::Transmitter | 671 | TxRx::Receiver |
| 885 | } else { | 672 | })); |
| 886 | TxRx::Receiver | 673 | w.set_prtcfg(config.protocol.prtcfg()); |
| 887 | })); | 674 | w.set_ds(config.data_size.ds()); |
| 888 | w.set_prtcfg(config.protocol.prtcfg()); | 675 | w.set_lsbfirst(config.bit_order.lsbfirst()); |
| 889 | w.set_ds(config.data_size.ds()); | 676 | w.set_ckstr(config.clock_strobe.ckstr()); |
| 890 | w.set_lsbfirst(config.bit_order.lsbfirst()); | 677 | w.set_syncen(config.sync_input.syncen()); |
| 891 | w.set_ckstr(config.clock_strobe.ckstr()); | 678 | w.set_mono(config.stereo_mono.mono()); |
| 892 | w.set_syncen(config.sync_input.syncen()); | 679 | w.set_outdriv(config.output_drive.outdriv()); |
| 893 | w.set_mono(config.stereo_mono.mono()); | 680 | w.set_mckdiv(config.master_clock_divider.unwrap_or(MasterClockDivider::DIV1)); |
| 894 | w.set_outdriv(config.output_drive.outdriv()); | 681 | w.set_nodiv(config.master_clock_divider.is_none()); |
| 895 | w.set_mckdiv(config.master_clock_divider.mckdiv().into()); | 682 | w.set_dmaen(true); |
| 896 | w.set_nodiv(config.nodiv); | 683 | }); |
| 897 | w.set_dmaen(true); | 684 | |
| 898 | }); | 685 | ch.cr2().modify(|w| { |
| 899 | 686 | w.set_fth(config.fifo_threshold.fth()); | |
| 900 | ch.cr2().modify(|w| { | 687 | w.set_comp(config.companding.comp()); |
| 901 | w.set_fth(config.fifo_threshold.fth()); | 688 | w.set_cpl(config.complement_format.cpl()); |
| 902 | w.set_comp(config.companding.comp()); | 689 | w.set_muteval(config.mute_value.muteval()); |
| 903 | w.set_cpl(config.complement_format.cpl()); | 690 | w.set_mutecnt(config.mute_detection_counter.0 as u8); |
| 904 | w.set_muteval(config.mute_value.muteval()); | 691 | w.set_tris(config.is_high_impedance_on_inactive_slot); |
| 905 | w.set_mutecnt(config.mute_detection_counter.0 as u8); | 692 | }); |
| 906 | w.set_tris(config.is_high_impedance_on_inactive_slot); | 693 | |
| 907 | }); | 694 | ch.frcr().modify(|w| { |
| 908 | 695 | w.set_fsoff(config.frame_sync_offset.fsoff()); | |
| 909 | ch.frcr().modify(|w| { | 696 | w.set_fspol(config.frame_sync_polarity.fspol()); |
| 910 | w.set_fsoff(config.frame_sync_offset.fsoff()); | 697 | w.set_fsdef(config.frame_sync_definition.fsdef()); |
| 911 | w.set_fspol(config.frame_sync_polarity.fspol()); | 698 | w.set_fsall(config.frame_sync_active_level_length.0 as u8 - 1); |
| 912 | w.set_fsdef(config.frame_sync_definition.fsdef()); | 699 | w.set_frl(config.frame_length - 1); |
| 913 | w.set_fsall(config.frame_sync_active_level_length.0 as u8 - 1); | 700 | }); |
| 914 | w.set_frl(config.frame_length - 1); | 701 | |
| 915 | }); | 702 | ch.slotr().modify(|w| { |
| 916 | 703 | w.set_nbslot(config.slot_count.0 as u8 - 1); | |
| 917 | ch.slotr().modify(|w| { | 704 | w.set_slotsz(config.slot_size.slotsz()); |
| 918 | w.set_nbslot(config.slot_count.0 as u8 - 1); | 705 | w.set_fboff(config.first_bit_offset.0 as u8); |
| 919 | w.set_slotsz(config.slot_size.slotsz()); | 706 | w.set_sloten(vals::Sloten::from_bits(config.slot_enable as u16)); |
| 920 | w.set_fboff(config.first_bit_offset.0 as u8); | 707 | }); |
| 921 | w.set_sloten(vals::Sloten::from_bits(config.slot_enable as u16)); | 708 | |
| 922 | }); | 709 | ch.cr1().modify(|w| w.set_saien(true)); |
| 923 | 710 | ||
| 924 | ch.cr1().modify(|w| w.set_saien(true)); | 711 | if ch.cr1().read().saien() == false { |
| 925 | 712 | panic!("SAI failed to enable. Check that config is valid (frame length, slot count, etc)"); | |
| 926 | if ch.cr1().read().saien() == false { | ||
| 927 | panic!("SAI failed to enable. Check that config is valid (frame length, slot count, etc)"); | ||
| 928 | } | ||
| 929 | } | 713 | } |
| 930 | 714 | ||
| 931 | Self { | 715 | Self { |
diff --git a/examples/stm32h7/src/bin/sai.rs b/examples/stm32h7/src/bin/sai.rs index 01937593a..847b70c85 100644 --- a/examples/stm32h7/src/bin/sai.rs +++ b/examples/stm32h7/src/bin/sai.rs | |||
| @@ -63,7 +63,7 @@ async fn main(_spawner: Spawner) { | |||
| 63 | tx_config.tx_rx = TxRx::Transmitter; | 63 | tx_config.tx_rx = TxRx::Transmitter; |
| 64 | tx_config.sync_output = true; | 64 | tx_config.sync_output = true; |
| 65 | tx_config.clock_strobe = ClockStrobe::Falling; | 65 | tx_config.clock_strobe = ClockStrobe::Falling; |
| 66 | tx_config.master_clock_divider = mclk_div; | 66 | tx_config.master_clock_divider = Some(mclk_div); |
| 67 | tx_config.stereo_mono = StereoMono::Stereo; | 67 | tx_config.stereo_mono = StereoMono::Stereo; |
| 68 | tx_config.data_size = DataSize::Data24; | 68 | tx_config.data_size = DataSize::Data24; |
| 69 | tx_config.bit_order = BitOrder::MsbFirst; | 69 | tx_config.bit_order = BitOrder::MsbFirst; |
| @@ -119,71 +119,7 @@ async fn main(_spawner: Spawner) { | |||
| 119 | } | 119 | } |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | const fn mclk_div_from_u8(v: u8) -> MasterClockDivider { | 122 | fn mclk_div_from_u8(v: u8) -> MasterClockDivider { |
| 123 | match v { | 123 | assert!((1..=63).contains(&v)); |
| 124 | 1 => MasterClockDivider::Div1, | 124 | MasterClockDivider::from_bits(v) |
| 125 | 2 => MasterClockDivider::Div2, | ||
| 126 | 3 => MasterClockDivider::Div3, | ||
| 127 | 4 => MasterClockDivider::Div4, | ||
| 128 | 5 => MasterClockDivider::Div5, | ||
| 129 | 6 => MasterClockDivider::Div6, | ||
| 130 | 7 => MasterClockDivider::Div7, | ||
| 131 | 8 => MasterClockDivider::Div8, | ||
| 132 | 9 => MasterClockDivider::Div9, | ||
| 133 | 10 => MasterClockDivider::Div10, | ||
| 134 | 11 => MasterClockDivider::Div11, | ||
| 135 | 12 => MasterClockDivider::Div12, | ||
| 136 | 13 => MasterClockDivider::Div13, | ||
| 137 | 14 => MasterClockDivider::Div14, | ||
| 138 | 15 => MasterClockDivider::Div15, | ||
| 139 | 16 => MasterClockDivider::Div16, | ||
| 140 | 17 => MasterClockDivider::Div17, | ||
| 141 | 18 => MasterClockDivider::Div18, | ||
| 142 | 19 => MasterClockDivider::Div19, | ||
| 143 | 20 => MasterClockDivider::Div20, | ||
| 144 | 21 => MasterClockDivider::Div21, | ||
| 145 | 22 => MasterClockDivider::Div22, | ||
| 146 | 23 => MasterClockDivider::Div23, | ||
| 147 | 24 => MasterClockDivider::Div24, | ||
| 148 | 25 => MasterClockDivider::Div25, | ||
| 149 | 26 => MasterClockDivider::Div26, | ||
| 150 | 27 => MasterClockDivider::Div27, | ||
| 151 | 28 => MasterClockDivider::Div28, | ||
| 152 | 29 => MasterClockDivider::Div29, | ||
| 153 | 30 => MasterClockDivider::Div30, | ||
| 154 | 31 => MasterClockDivider::Div31, | ||
| 155 | 32 => MasterClockDivider::Div32, | ||
| 156 | 33 => MasterClockDivider::Div33, | ||
| 157 | 34 => MasterClockDivider::Div34, | ||
| 158 | 35 => MasterClockDivider::Div35, | ||
| 159 | 36 => MasterClockDivider::Div36, | ||
| 160 | 37 => MasterClockDivider::Div37, | ||
| 161 | 38 => MasterClockDivider::Div38, | ||
| 162 | 39 => MasterClockDivider::Div39, | ||
| 163 | 40 => MasterClockDivider::Div40, | ||
| 164 | 41 => MasterClockDivider::Div41, | ||
| 165 | 42 => MasterClockDivider::Div42, | ||
| 166 | 43 => MasterClockDivider::Div43, | ||
| 167 | 44 => MasterClockDivider::Div44, | ||
| 168 | 45 => MasterClockDivider::Div45, | ||
| 169 | 46 => MasterClockDivider::Div46, | ||
| 170 | 47 => MasterClockDivider::Div47, | ||
| 171 | 48 => MasterClockDivider::Div48, | ||
| 172 | 49 => MasterClockDivider::Div49, | ||
| 173 | 50 => MasterClockDivider::Div50, | ||
| 174 | 51 => MasterClockDivider::Div51, | ||
| 175 | 52 => MasterClockDivider::Div52, | ||
| 176 | 53 => MasterClockDivider::Div53, | ||
| 177 | 54 => MasterClockDivider::Div54, | ||
| 178 | 55 => MasterClockDivider::Div55, | ||
| 179 | 56 => MasterClockDivider::Div56, | ||
| 180 | 57 => MasterClockDivider::Div57, | ||
| 181 | 58 => MasterClockDivider::Div58, | ||
| 182 | 59 => MasterClockDivider::Div59, | ||
| 183 | 60 => MasterClockDivider::Div60, | ||
| 184 | 61 => MasterClockDivider::Div61, | ||
| 185 | 62 => MasterClockDivider::Div62, | ||
| 186 | 63 => MasterClockDivider::Div63, | ||
| 187 | _ => panic!(), | ||
| 188 | } | ||
| 189 | } | 125 | } |
diff --git a/examples/stm32h723/src/bin/spdifrx.rs b/examples/stm32h723/src/bin/spdifrx.rs index 6d29e8a4d..b75a03ae8 100644 --- a/examples/stm32h723/src/bin/spdifrx.rs +++ b/examples/stm32h723/src/bin/spdifrx.rs | |||
| @@ -168,7 +168,7 @@ fn new_sai_transmitter<'d>( | |||
| 168 | sai_config.slot_enable = 0xFFFF; // All slots | 168 | sai_config.slot_enable = 0xFFFF; // All slots |
| 169 | sai_config.data_size = sai::DataSize::Data32; | 169 | sai_config.data_size = sai::DataSize::Data32; |
| 170 | sai_config.frame_length = (CHANNEL_COUNT * 32) as u8; | 170 | sai_config.frame_length = (CHANNEL_COUNT * 32) as u8; |
| 171 | sai_config.master_clock_divider = hal::sai::MasterClockDivider::MasterClockDisabled; | 171 | sai_config.master_clock_divider = None; |
| 172 | 172 | ||
| 173 | let (sub_block_tx, _) = hal::sai::split_subblocks(sai); | 173 | let (sub_block_tx, _) = hal::sai::split_subblocks(sai); |
| 174 | Sai::new_asynchronous(sub_block_tx, sck, sd, fs, dma, buf, sai_config) | 174 | Sai::new_asynchronous(sub_block_tx, sck, sd, fs, dma, buf, sai_config) |
