diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-03-03 20:33:03 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-03-03 20:33:03 +0000 |
| commit | 0cd293acc2ef9c957c0c3dfb7ee9956cdbfc6610 (patch) | |
| tree | 623afd3119d8efbd11b9bd2fe25b2b911452d84c | |
| parent | 64890498ca6d6193ca0ac30952c24a657b8b88f3 (diff) | |
| parent | b693ab9b34fad5844401bc80b9968940e750680e (diff) | |
Merge pull request #2647 from cschuhen/feature/fdcan-tx-fifo
stm32: can: fd: allow TX buffers in FIFO mode
| -rw-r--r-- | embassy-stm32/src/can/fd/config.rs | 30 | ||||
| -rw-r--r-- | embassy-stm32/src/can/fd/peripheral.rs | 174 | ||||
| -rw-r--r-- | embassy-stm32/src/can/fdcan.rs | 92 |
3 files changed, 167 insertions, 129 deletions
diff --git a/embassy-stm32/src/can/fd/config.rs b/embassy-stm32/src/can/fd/config.rs index f2401d92f..adaffe9cc 100644 --- a/embassy-stm32/src/can/fd/config.rs +++ b/embassy-stm32/src/can/fd/config.rs | |||
| @@ -287,6 +287,33 @@ impl Default for GlobalFilter { | |||
| 287 | } | 287 | } |
| 288 | } | 288 | } |
| 289 | 289 | ||
| 290 | /// TX buffer operation mode | ||
| 291 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| 292 | pub enum TxBufferMode { | ||
| 293 | /// TX FIFO operation - In this mode CAN frames are trasmitted strictly in write order. | ||
| 294 | Fifo, | ||
| 295 | /// TX queue operation - In this mode CAN frames are transmitted according to CAN priority. | ||
| 296 | Queue, | ||
| 297 | } | ||
| 298 | |||
| 299 | impl From<TxBufferMode> for crate::pac::can::vals::Tfqm { | ||
| 300 | fn from(value: TxBufferMode) -> Self { | ||
| 301 | match value { | ||
| 302 | TxBufferMode::Queue => Self::QUEUE, | ||
| 303 | TxBufferMode::Fifo => Self::FIFO, | ||
| 304 | } | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 | impl From<crate::pac::can::vals::Tfqm> for TxBufferMode { | ||
| 309 | fn from(value: crate::pac::can::vals::Tfqm) -> Self { | ||
| 310 | match value { | ||
| 311 | crate::pac::can::vals::Tfqm::QUEUE => Self::Queue, | ||
| 312 | crate::pac::can::vals::Tfqm::FIFO => Self::Fifo, | ||
| 313 | } | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 290 | /// FdCan Config Struct | 317 | /// FdCan Config Struct |
| 291 | #[derive(Clone, Copy, Debug)] | 318 | #[derive(Clone, Copy, Debug)] |
| 292 | pub struct FdCanConfig { | 319 | pub struct FdCanConfig { |
| @@ -327,6 +354,8 @@ pub struct FdCanConfig { | |||
| 327 | pub timestamp_source: TimestampSource, | 354 | pub timestamp_source: TimestampSource, |
| 328 | /// Configures the Global Filter | 355 | /// Configures the Global Filter |
| 329 | pub global_filter: GlobalFilter, | 356 | pub global_filter: GlobalFilter, |
| 357 | /// TX buffer mode (FIFO or queue) | ||
| 358 | pub tx_buffer_mode: TxBufferMode, | ||
| 330 | } | 359 | } |
| 331 | 360 | ||
| 332 | impl FdCanConfig { | 361 | impl FdCanConfig { |
| @@ -433,6 +462,7 @@ impl Default for FdCanConfig { | |||
| 433 | clock_divider: ClockDivider::_1, | 462 | clock_divider: ClockDivider::_1, |
| 434 | timestamp_source: TimestampSource::None, | 463 | timestamp_source: TimestampSource::None, |
| 435 | global_filter: GlobalFilter::default(), | 464 | global_filter: GlobalFilter::default(), |
| 465 | tx_buffer_mode: TxBufferMode::Queue, | ||
| 436 | } | 466 | } |
| 437 | } | 467 | } |
| 438 | } | 468 | } |
diff --git a/embassy-stm32/src/can/fd/peripheral.rs b/embassy-stm32/src/can/fd/peripheral.rs index e87a3c213..8ec09ac12 100644 --- a/embassy-stm32/src/can/fd/peripheral.rs +++ b/embassy-stm32/src/can/fd/peripheral.rs | |||
| @@ -22,6 +22,7 @@ enum LoopbackMode { | |||
| 22 | pub struct Registers { | 22 | pub struct Registers { |
| 23 | pub regs: &'static crate::pac::can::Fdcan, | 23 | pub regs: &'static crate::pac::can::Fdcan, |
| 24 | pub msgram: &'static crate::pac::fdcanram::Fdcanram, | 24 | pub msgram: &'static crate::pac::fdcanram::Fdcanram, |
| 25 | pub msg_ram_offset: usize, | ||
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | impl Registers { | 28 | impl Registers { |
| @@ -114,6 +115,12 @@ impl Registers { | |||
| 114 | self.regs.txfqs().read().tfqf() | 115 | self.regs.txfqs().read().tfqf() |
| 115 | } | 116 | } |
| 116 | 117 | ||
| 118 | /// Returns the current TX buffer operation mode (queue or FIFO) | ||
| 119 | #[inline] | ||
| 120 | pub fn tx_queue_mode(&self) -> TxBufferMode { | ||
| 121 | self.regs.txbc().read().tfqm().into() | ||
| 122 | } | ||
| 123 | |||
| 117 | #[inline] | 124 | #[inline] |
| 118 | pub fn has_pending_frame(&self, idx: usize) -> bool { | 125 | pub fn has_pending_frame(&self, idx: usize) -> bool { |
| 119 | self.regs.txbrp().read().trp(idx) | 126 | self.regs.txbrp().read().trp(idx) |
| @@ -164,7 +171,7 @@ impl Registers { | |||
| 164 | } | 171 | } |
| 165 | 172 | ||
| 166 | #[inline] | 173 | #[inline] |
| 167 | pub fn abort_pending_mailbox_generic<F: embedded_can::Frame>(&self, bufidx: usize) -> Option<F> { | 174 | fn abort_pending_mailbox<F: embedded_can::Frame>(&self, bufidx: usize) -> Option<F> { |
| 168 | if self.abort(bufidx) { | 175 | if self.abort(bufidx) { |
| 169 | let mailbox = self.tx_buffer_element(bufidx); | 176 | let mailbox = self.tx_buffer_element(bufidx); |
| 170 | 177 | ||
| @@ -197,19 +204,20 @@ impl Registers { | |||
| 197 | } | 204 | } |
| 198 | 205 | ||
| 199 | pub fn write<F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> nb::Result<Option<F>, Infallible> { | 206 | pub fn write<F: embedded_can::Frame + CanHeader>(&self, frame: &F) -> nb::Result<Option<F>, Infallible> { |
| 200 | let queue_is_full = self.tx_queue_is_full(); | 207 | let (idx, pending_frame) = if self.tx_queue_is_full() { |
| 201 | 208 | if self.tx_queue_mode() == TxBufferMode::Fifo { | |
| 202 | let id = frame.header().id(); | 209 | // Does not make sense to cancel a pending frame when using FIFO |
| 203 | 210 | return Err(nb::Error::WouldBlock); | |
| 204 | // If the queue is full, | 211 | } |
| 205 | // Discard the first slot with a lower priority message | 212 | // If the queue is full, |
| 206 | let (idx, pending_frame) = if queue_is_full { | 213 | // Discard the first slot with a lower priority message |
| 214 | let id = frame.header().id(); | ||
| 207 | if self.is_available(0, id) { | 215 | if self.is_available(0, id) { |
| 208 | (0, self.abort_pending_mailbox_generic(0)) | 216 | (0, self.abort_pending_mailbox(0)) |
| 209 | } else if self.is_available(1, id) { | 217 | } else if self.is_available(1, id) { |
| 210 | (1, self.abort_pending_mailbox_generic(1)) | 218 | (1, self.abort_pending_mailbox(1)) |
| 211 | } else if self.is_available(2, id) { | 219 | } else if self.is_available(2, id) { |
| 212 | (2, self.abort_pending_mailbox_generic(2)) | 220 | (2, self.abort_pending_mailbox(2)) |
| 213 | } else { | 221 | } else { |
| 214 | // For now we bail when there is no lower priority slot available | 222 | // For now we bail when there is no lower priority slot available |
| 215 | // Can this lead to priority inversion? | 223 | // Can this lead to priority inversion? |
| @@ -287,7 +295,6 @@ impl Registers { | |||
| 287 | pub fn into_config_mode(mut self, _config: FdCanConfig) { | 295 | pub fn into_config_mode(mut self, _config: FdCanConfig) { |
| 288 | self.set_power_down_mode(false); | 296 | self.set_power_down_mode(false); |
| 289 | self.enter_init_mode(); | 297 | self.enter_init_mode(); |
| 290 | |||
| 291 | self.reset_msg_ram(); | 298 | self.reset_msg_ram(); |
| 292 | 299 | ||
| 293 | // check the FDCAN core matches our expections | 300 | // check the FDCAN core matches our expections |
| @@ -300,12 +307,31 @@ impl Registers { | |||
| 300 | "Error reading endianness test value from FDCAN core" | 307 | "Error reading endianness test value from FDCAN core" |
| 301 | ); | 308 | ); |
| 302 | 309 | ||
| 303 | // Framework specific settings are set here | 310 | /* |
| 311 | for fid in 0..crate::can::message_ram::STANDARD_FILTER_MAX { | ||
| 312 | self.set_standard_filter((fid as u8).into(), StandardFilter::disable()); | ||
| 313 | } | ||
| 314 | for fid in 0..Ecrate::can::message_ram::XTENDED_FILTER_MAX { | ||
| 315 | self.set_extended_filter(fid.into(), ExtendedFilter::disable()); | ||
| 316 | } | ||
| 317 | */ | ||
| 318 | } | ||
| 304 | 319 | ||
| 305 | // set TxBuffer to Queue Mode | 320 | /// Disables the CAN interface and returns back the raw peripheral it was created from. |
| 306 | self.regs | 321 | #[inline] |
| 307 | .txbc() | 322 | pub fn free(mut self) { |
| 308 | .write(|w| w.set_tfqm(crate::pac::can::vals::Tfqm::QUEUE)); | 323 | //self.disable_interrupts(Interrupts::all()); |
| 324 | |||
| 325 | //TODO check this! | ||
| 326 | self.enter_init_mode(); | ||
| 327 | self.set_power_down_mode(true); | ||
| 328 | //self.control.instance | ||
| 329 | } | ||
| 330 | |||
| 331 | /// Applies the settings of a new FdCanConfig See [`FdCanConfig`] | ||
| 332 | #[inline] | ||
| 333 | pub fn apply_config(&mut self, config: FdCanConfig) { | ||
| 334 | self.set_tx_buffer_mode(config.tx_buffer_mode); | ||
| 309 | 335 | ||
| 310 | // set standard filters list size to 28 | 336 | // set standard filters list size to 28 |
| 311 | // set extended filters list size to 8 | 337 | // set extended filters list size to 8 |
| @@ -328,30 +354,29 @@ impl Registers { | |||
| 328 | .modify(|w| w.set_lse(crate::can::fd::message_ram::EXTENDED_FILTER_MAX)); | 354 | .modify(|w| w.set_lse(crate::can::fd::message_ram::EXTENDED_FILTER_MAX)); |
| 329 | } | 355 | } |
| 330 | 356 | ||
| 331 | /* | 357 | self.configure_msg_ram(); |
| 332 | for fid in 0..crate::can::message_ram::STANDARD_FILTER_MAX { | ||
| 333 | self.set_standard_filter((fid as u8).into(), StandardFilter::disable()); | ||
| 334 | } | ||
| 335 | for fid in 0..Ecrate::can::message_ram::XTENDED_FILTER_MAX { | ||
| 336 | self.set_extended_filter(fid.into(), ExtendedFilter::disable()); | ||
| 337 | } | ||
| 338 | */ | ||
| 339 | } | ||
| 340 | |||
| 341 | /// Disables the CAN interface and returns back the raw peripheral it was created from. | ||
| 342 | #[inline] | ||
| 343 | pub fn free(mut self) { | ||
| 344 | //self.disable_interrupts(Interrupts::all()); | ||
| 345 | 358 | ||
| 346 | //TODO check this! | 359 | // Enable timestamping |
| 347 | self.enter_init_mode(); | 360 | #[cfg(not(stm32h7))] |
| 348 | self.set_power_down_mode(true); | 361 | self.regs |
| 349 | //self.control.instance | 362 | .tscc() |
| 350 | } | 363 | .write(|w| w.set_tss(stm32_metapac::can::vals::Tss::INCREMENT)); |
| 364 | #[cfg(stm32h7)] | ||
| 365 | self.regs.tscc().write(|w| w.set_tss(0x01)); | ||
| 366 | |||
| 367 | // this isn't really documented in the reference manual | ||
| 368 | // but corresponding txbtie bit has to be set for the TC (TxComplete) interrupt to fire | ||
| 369 | self.regs.txbtie().write(|w| w.0 = 0xffff_ffff); | ||
| 370 | self.regs.ie().modify(|w| { | ||
| 371 | w.set_rfne(0, true); // Rx Fifo 0 New Msg | ||
| 372 | w.set_rfne(1, true); // Rx Fifo 1 New Msg | ||
| 373 | w.set_tce(true); // Tx Complete | ||
| 374 | }); | ||
| 375 | self.regs.ile().modify(|w| { | ||
| 376 | w.set_eint0(true); // Interrupt Line 0 | ||
| 377 | w.set_eint1(true); // Interrupt Line 1 | ||
| 378 | }); | ||
| 351 | 379 | ||
| 352 | /// Applies the settings of a new FdCanConfig See [`FdCanConfig`] | ||
| 353 | #[inline] | ||
| 354 | pub fn apply_config(&mut self, config: FdCanConfig) { | ||
| 355 | self.set_data_bit_timing(config.dbtr); | 380 | self.set_data_bit_timing(config.dbtr); |
| 356 | self.set_nominal_bit_timing(config.nbtr); | 381 | self.set_nominal_bit_timing(config.nbtr); |
| 357 | self.set_automatic_retransmit(config.automatic_retransmit); | 382 | self.set_automatic_retransmit(config.automatic_retransmit); |
| @@ -499,6 +524,12 @@ impl Registers { | |||
| 499 | self.regs.cccr().modify(|w| w.set_efbi(enabled)); | 524 | self.regs.cccr().modify(|w| w.set_efbi(enabled)); |
| 500 | } | 525 | } |
| 501 | 526 | ||
| 527 | /// Configures TX Buffer Mode | ||
| 528 | #[inline] | ||
| 529 | pub fn set_tx_buffer_mode(&mut self, tbm: TxBufferMode) { | ||
| 530 | self.regs.txbc().write(|w| w.set_tfqm(tbm.into())); | ||
| 531 | } | ||
| 532 | |||
| 502 | /// Configures frame transmission mode. See | 533 | /// Configures frame transmission mode. See |
| 503 | /// [`FdCanConfig::set_frame_transmit`] | 534 | /// [`FdCanConfig::set_frame_transmit`] |
| 504 | #[inline] | 535 | #[inline] |
| @@ -593,6 +624,71 @@ impl Registers { | |||
| 593 | w.set_rrfe(filter.reject_remote_extended_frames); | 624 | w.set_rrfe(filter.reject_remote_extended_frames); |
| 594 | }); | 625 | }); |
| 595 | } | 626 | } |
| 627 | |||
| 628 | #[cfg(not(stm32h7))] | ||
| 629 | fn configure_msg_ram(&mut self) {} | ||
| 630 | |||
| 631 | #[cfg(stm32h7)] | ||
| 632 | fn configure_msg_ram(&mut self) { | ||
| 633 | let r = self.regs; | ||
| 634 | |||
| 635 | use crate::can::fd::message_ram::*; | ||
| 636 | //use fdcan::message_ram::*; | ||
| 637 | let mut offset_words = self.msg_ram_offset as u16; | ||
| 638 | |||
| 639 | // 11-bit filter | ||
| 640 | r.sidfc().modify(|w| w.set_flssa(offset_words)); | ||
| 641 | offset_words += STANDARD_FILTER_MAX as u16; | ||
| 642 | |||
| 643 | // 29-bit filter | ||
| 644 | r.xidfc().modify(|w| w.set_flesa(offset_words)); | ||
| 645 | offset_words += 2 * EXTENDED_FILTER_MAX as u16; | ||
| 646 | |||
| 647 | // Rx FIFO 0 and 1 | ||
| 648 | for i in 0..=1 { | ||
| 649 | r.rxfc(i).modify(|w| { | ||
| 650 | w.set_fsa(offset_words); | ||
| 651 | w.set_fs(RX_FIFO_MAX); | ||
| 652 | w.set_fwm(RX_FIFO_MAX); | ||
| 653 | }); | ||
| 654 | offset_words += 18 * RX_FIFO_MAX as u16; | ||
| 655 | } | ||
| 656 | |||
| 657 | // Rx buffer - see below | ||
| 658 | // Tx event FIFO | ||
| 659 | r.txefc().modify(|w| { | ||
| 660 | w.set_efsa(offset_words); | ||
| 661 | w.set_efs(TX_EVENT_MAX); | ||
| 662 | w.set_efwm(TX_EVENT_MAX); | ||
| 663 | }); | ||
| 664 | offset_words += 2 * TX_EVENT_MAX as u16; | ||
| 665 | |||
| 666 | // Tx buffers | ||
| 667 | r.txbc().modify(|w| { | ||
| 668 | w.set_tbsa(offset_words); | ||
| 669 | w.set_tfqs(TX_FIFO_MAX); | ||
| 670 | }); | ||
| 671 | offset_words += 18 * TX_FIFO_MAX as u16; | ||
| 672 | |||
| 673 | // Rx Buffer - not used | ||
| 674 | r.rxbc().modify(|w| { | ||
| 675 | w.set_rbsa(offset_words); | ||
| 676 | }); | ||
| 677 | |||
| 678 | // TX event FIFO? | ||
| 679 | // Trigger memory? | ||
| 680 | |||
| 681 | // Set the element sizes to 16 bytes | ||
| 682 | r.rxesc().modify(|w| { | ||
| 683 | w.set_rbds(0b111); | ||
| 684 | for i in 0..=1 { | ||
| 685 | w.set_fds(i, 0b111); | ||
| 686 | } | ||
| 687 | }); | ||
| 688 | r.txesc().modify(|w| { | ||
| 689 | w.set_tbds(0b111); | ||
| 690 | }) | ||
| 691 | } | ||
| 596 | } | 692 | } |
| 597 | 693 | ||
| 598 | fn make_id(id: u32, extended: bool) -> embedded_can::Id { | 694 | fn make_id(id: u32, extended: bool) -> embedded_can::Id { |
diff --git a/embassy-stm32/src/can/fdcan.rs b/embassy-stm32/src/can/fdcan.rs index 77db774fc..20d00ccb5 100644 --- a/embassy-stm32/src/can/fdcan.rs +++ b/embassy-stm32/src/can/fdcan.rs | |||
| @@ -184,43 +184,20 @@ impl<'d, T: Instance> FdcanConfigurator<'d, T> { | |||
| 184 | T::enable_and_reset(); | 184 | T::enable_and_reset(); |
| 185 | 185 | ||
| 186 | let mut config = crate::can::fd::config::FdCanConfig::default(); | 186 | let mut config = crate::can::fd::config::FdCanConfig::default(); |
| 187 | config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1); | ||
| 187 | T::registers().into_config_mode(config); | 188 | T::registers().into_config_mode(config); |
| 188 | 189 | ||
| 189 | rx.set_as_af(rx.af_num(), AFType::Input); | 190 | rx.set_as_af(rx.af_num(), AFType::Input); |
| 190 | tx.set_as_af(tx.af_num(), AFType::OutputPushPull); | 191 | tx.set_as_af(tx.af_num(), AFType::OutputPushPull); |
| 191 | 192 | ||
| 192 | T::configure_msg_ram(); | ||
| 193 | unsafe { | 193 | unsafe { |
| 194 | // Enable timestamping | ||
| 195 | #[cfg(not(stm32h7))] | ||
| 196 | T::regs() | ||
| 197 | .tscc() | ||
| 198 | .write(|w| w.set_tss(stm32_metapac::can::vals::Tss::INCREMENT)); | ||
| 199 | #[cfg(stm32h7)] | ||
| 200 | T::regs().tscc().write(|w| w.set_tss(0x01)); | ||
| 201 | config.timestamp_source = TimestampSource::Prescaler(TimestampPrescaler::_1); | ||
| 202 | |||
| 203 | T::IT0Interrupt::unpend(); // Not unsafe | 194 | T::IT0Interrupt::unpend(); // Not unsafe |
| 204 | T::IT0Interrupt::enable(); | 195 | T::IT0Interrupt::enable(); |
| 205 | 196 | ||
| 206 | T::IT1Interrupt::unpend(); // Not unsafe | 197 | T::IT1Interrupt::unpend(); // Not unsafe |
| 207 | T::IT1Interrupt::enable(); | 198 | T::IT1Interrupt::enable(); |
| 208 | |||
| 209 | // this isn't really documented in the reference manual | ||
| 210 | // but corresponding txbtie bit has to be set for the TC (TxComplete) interrupt to fire | ||
| 211 | T::regs().txbtie().write(|w| w.0 = 0xffff_ffff); | ||
| 212 | } | 199 | } |
| 213 | 200 | ||
| 214 | T::regs().ie().modify(|w| { | ||
| 215 | w.set_rfne(0, true); // Rx Fifo 0 New Msg | ||
| 216 | w.set_rfne(1, true); // Rx Fifo 1 New Msg | ||
| 217 | w.set_tce(true); // Tx Complete | ||
| 218 | }); | ||
| 219 | T::regs().ile().modify(|w| { | ||
| 220 | w.set_eint0(true); // Interrupt Line 0 | ||
| 221 | w.set_eint1(true); // Interrupt Line 1 | ||
| 222 | }); | ||
| 223 | |||
| 224 | Self { | 201 | Self { |
| 225 | config, | 202 | config, |
| 226 | instance: FdcanInstance(peri), | 203 | instance: FdcanInstance(peri), |
| @@ -869,71 +846,6 @@ pub(crate) mod sealed { | |||
| 869 | fn state() -> &'static State; | 846 | fn state() -> &'static State; |
| 870 | unsafe fn mut_state() -> &'static mut State; | 847 | unsafe fn mut_state() -> &'static mut State; |
| 871 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp; | 848 | fn calc_timestamp(ns_per_timer_tick: u64, ts_val: u16) -> Timestamp; |
| 872 | |||
| 873 | #[cfg(not(stm32h7))] | ||
| 874 | fn configure_msg_ram() {} | ||
| 875 | |||
| 876 | #[cfg(stm32h7)] | ||
| 877 | fn configure_msg_ram() { | ||
| 878 | let r = Self::regs(); | ||
| 879 | |||
| 880 | use crate::can::fd::message_ram::*; | ||
| 881 | //use fdcan::message_ram::*; | ||
| 882 | let mut offset_words = Self::MSG_RAM_OFFSET as u16; | ||
| 883 | |||
| 884 | // 11-bit filter | ||
| 885 | r.sidfc().modify(|w| w.set_flssa(offset_words)); | ||
| 886 | offset_words += STANDARD_FILTER_MAX as u16; | ||
| 887 | |||
| 888 | // 29-bit filter | ||
| 889 | r.xidfc().modify(|w| w.set_flesa(offset_words)); | ||
| 890 | offset_words += 2 * EXTENDED_FILTER_MAX as u16; | ||
| 891 | |||
| 892 | // Rx FIFO 0 and 1 | ||
| 893 | for i in 0..=1 { | ||
| 894 | r.rxfc(i).modify(|w| { | ||
| 895 | w.set_fsa(offset_words); | ||
| 896 | w.set_fs(RX_FIFO_MAX); | ||
| 897 | w.set_fwm(RX_FIFO_MAX); | ||
| 898 | }); | ||
| 899 | offset_words += 18 * RX_FIFO_MAX as u16; | ||
| 900 | } | ||
| 901 | |||
| 902 | // Rx buffer - see below | ||
| 903 | // Tx event FIFO | ||
| 904 | r.txefc().modify(|w| { | ||
| 905 | w.set_efsa(offset_words); | ||
| 906 | w.set_efs(TX_EVENT_MAX); | ||
| 907 | w.set_efwm(TX_EVENT_MAX); | ||
| 908 | }); | ||
| 909 | offset_words += 2 * TX_EVENT_MAX as u16; | ||
| 910 | |||
| 911 | // Tx buffers | ||
| 912 | r.txbc().modify(|w| { | ||
| 913 | w.set_tbsa(offset_words); | ||
| 914 | w.set_tfqs(TX_FIFO_MAX); | ||
| 915 | }); | ||
| 916 | offset_words += 18 * TX_FIFO_MAX as u16; | ||
| 917 | |||
| 918 | // Rx Buffer - not used | ||
| 919 | r.rxbc().modify(|w| { | ||
| 920 | w.set_rbsa(offset_words); | ||
| 921 | }); | ||
| 922 | |||
| 923 | // TX event FIFO? | ||
| 924 | // Trigger memory? | ||
| 925 | |||
| 926 | // Set the element sizes to 16 bytes | ||
| 927 | r.rxesc().modify(|w| { | ||
| 928 | w.set_rbds(0b111); | ||
| 929 | for i in 0..=1 { | ||
| 930 | w.set_fds(i, 0b111); | ||
| 931 | } | ||
| 932 | }); | ||
| 933 | r.txesc().modify(|w| { | ||
| 934 | w.set_tbds(0b111); | ||
| 935 | }) | ||
| 936 | } | ||
| 937 | } | 849 | } |
| 938 | } | 850 | } |
| 939 | 851 | ||
| @@ -957,7 +869,7 @@ macro_rules! impl_fdcan { | |||
| 957 | &crate::pac::$inst | 869 | &crate::pac::$inst |
| 958 | } | 870 | } |
| 959 | fn registers() -> Registers { | 871 | fn registers() -> Registers { |
| 960 | Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst} | 872 | Registers{regs: &crate::pac::$inst, msgram: &crate::pac::$msg_ram_inst, msg_ram_offset: Self::MSG_RAM_OFFSET} |
| 961 | } | 873 | } |
| 962 | fn ram() -> &'static crate::pac::fdcanram::Fdcanram { | 874 | fn ram() -> &'static crate::pac::fdcanram::Fdcanram { |
| 963 | &crate::pac::$msg_ram_inst | 875 | &crate::pac::$msg_ram_inst |
