can.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //! # Controller Area Network (CAN) Interface
  2. //!
  3. //! ## Alternate function remapping
  4. //!
  5. //! TX: Alternate Push-Pull Output
  6. //! RX: Input Floating Input
  7. //!
  8. //! ### CAN1
  9. //!
  10. //! | Function | NoRemap | Remap |
  11. //! |----------|---------|-------|
  12. //! | TX | PA12 | PB9 |
  13. //! | RX | PA11 | PB8 |
  14. //!
  15. //! ### CAN2
  16. //!
  17. //! | Function | NoRemap | Remap |
  18. //! |----------|---------|-------|
  19. //! | TX | PB6 | PB13 |
  20. //! | RX | PB5 | PB12 |
  21. use crate::afio::MAPR;
  22. #[cfg(feature = "connectivity")]
  23. use crate::gpio::gpiob::{PB12, PB13, PB5, PB6};
  24. use crate::gpio::{
  25. gpioa::{PA11, PA12},
  26. gpiob::{PB8, PB9},
  27. Alternate, Floating, Input, PushPull,
  28. };
  29. use crate::pac::CAN1;
  30. #[cfg(feature = "connectivity")]
  31. use crate::pac::CAN2;
  32. #[cfg(not(feature = "connectivity"))]
  33. use crate::pac::USB;
  34. use crate::rcc::APB1;
  35. mod sealed {
  36. pub trait Sealed {}
  37. }
  38. pub trait Pins: sealed::Sealed {
  39. type Instance;
  40. fn remap(mapr: &mut MAPR);
  41. }
  42. impl sealed::Sealed for (PA12<Alternate<PushPull>>, PA11<Input<Floating>>) {}
  43. impl Pins for (PA12<Alternate<PushPull>>, PA11<Input<Floating>>) {
  44. type Instance = CAN1;
  45. fn remap(mapr: &mut MAPR) {
  46. #[cfg(not(feature = "connectivity"))]
  47. mapr.modify_mapr(|_, w| unsafe { w.can_remap().bits(0) });
  48. #[cfg(feature = "connectivity")]
  49. mapr.modify_mapr(|_, w| unsafe { w.can1_remap().bits(0) });
  50. }
  51. }
  52. impl sealed::Sealed for (PB9<Alternate<PushPull>>, PB8<Input<Floating>>) {}
  53. impl Pins for (PB9<Alternate<PushPull>>, PB8<Input<Floating>>) {
  54. type Instance = CAN1;
  55. fn remap(mapr: &mut MAPR) {
  56. #[cfg(not(feature = "connectivity"))]
  57. mapr.modify_mapr(|_, w| unsafe { w.can_remap().bits(0b10) });
  58. #[cfg(feature = "connectivity")]
  59. mapr.modify_mapr(|_, w| unsafe { w.can1_remap().bits(0b10) });
  60. }
  61. }
  62. #[cfg(feature = "connectivity")]
  63. impl sealed::Sealed for (PB13<Alternate<PushPull>>, PB12<Input<Floating>>) {}
  64. #[cfg(feature = "connectivity")]
  65. impl Pins for (PB13<Alternate<PushPull>>, PB12<Input<Floating>>) {
  66. type Instance = CAN2;
  67. fn remap(mapr: &mut MAPR) {
  68. mapr.modify_mapr(|_, w| w.can2_remap().clear_bit());
  69. }
  70. }
  71. #[cfg(feature = "connectivity")]
  72. impl sealed::Sealed for (PB6<Alternate<PushPull>>, PB5<Input<Floating>>) {}
  73. #[cfg(feature = "connectivity")]
  74. impl Pins for (PB6<Alternate<PushPull>>, PB5<Input<Floating>>) {
  75. type Instance = CAN2;
  76. fn remap(mapr: &mut MAPR) {
  77. mapr.modify_mapr(|_, w| w.can2_remap().set_bit());
  78. }
  79. }
  80. /// Interface to the CAN peripheral.
  81. pub struct Can<Instance> {
  82. _peripheral: Instance,
  83. }
  84. impl<Instance> Can<Instance>
  85. where
  86. Instance: crate::rcc::Enable<Bus = APB1>,
  87. {
  88. /// Creates a CAN interaface.
  89. ///
  90. /// CAN shares SRAM with the USB peripheral. Take ownership of USB to
  91. /// prevent accidental shared usage.
  92. #[cfg(not(feature = "connectivity"))]
  93. pub fn new(can: Instance, apb: &mut APB1, _usb: USB) -> Can<Instance> {
  94. Instance::enable(apb);
  95. Can { _peripheral: can }
  96. }
  97. /// Creates a CAN interaface.
  98. #[cfg(feature = "connectivity")]
  99. pub fn new(can: Instance, apb: &mut APB1) -> Can<Instance> {
  100. Instance::enable(apb);
  101. Can { _peripheral: can }
  102. }
  103. /// Routes CAN TX signals and RX signals to pins.
  104. pub fn assign_pins<P>(&self, _pins: P, mapr: &mut MAPR)
  105. where
  106. P: Pins<Instance = Instance>,
  107. {
  108. P::remap(mapr);
  109. }
  110. }
  111. unsafe impl bxcan::Instance for Can<CAN1> {
  112. const REGISTERS: *mut bxcan::RegisterBlock = CAN1::ptr() as *mut _;
  113. }
  114. #[cfg(feature = "connectivity")]
  115. unsafe impl bxcan::Instance for Can<CAN2> {
  116. const REGISTERS: *mut bxcan::RegisterBlock = CAN2::ptr() as *mut _;
  117. }
  118. unsafe impl bxcan::FilterOwner for Can<CAN1> {
  119. const NUM_FILTER_BANKS: u8 = 28;
  120. }
  121. #[cfg(feature = "connectivity")]
  122. unsafe impl bxcan::MasterInstance for Can<CAN1> {}