123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- //! Simple CAN example.
- //! Requires a transceiver connected to PA11, PA12 (CAN1) or PB5 PB6 (CAN2).
- #![no_main]
- #![no_std]
- use panic_halt as _;
- use bxcan::filter::Mask32;
- use cortex_m_rt::entry;
- use nb::block;
- use stm32f1xx_hal::{can::Can, pac, prelude::*};
- #[entry]
- fn main() -> ! {
- let dp = pac::Peripherals::take().unwrap();
- let mut flash = dp.FLASH.constrain();
- let mut rcc = dp.RCC.constrain();
- // To meet CAN clock accuracy requirements an external crystal or ceramic
- // resonator must be used. The blue pill has a 8MHz external crystal.
- // Other boards might have a crystal with another frequency or none at all.
- rcc.cfgr.use_hse(8.mhz()).freeze(&mut flash.acr);
- let mut afio = dp.AFIO.constrain(&mut rcc.apb2);
- let mut can1 = {
- #[cfg(not(feature = "connectivity"))]
- let can = Can::new(dp.CAN1, &mut rcc.apb1, dp.USB);
- #[cfg(feature = "connectivity")]
- let can = Can::new(dp.CAN1, &mut rcc.apb1);
- let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
- let rx = gpioa.pa11.into_floating_input(&mut gpioa.crh);
- let tx = gpioa.pa12.into_alternate_push_pull(&mut gpioa.crh);
- can.assign_pins((tx, rx), &mut afio.mapr);
- bxcan::Can::new(can)
- };
- // APB1 (PCLK1): 8MHz, Bit rate: 125kBit/s, Sample Point 87.5%
- // Value was calculated with http://www.bittiming.can-wiki.info/
- can1.modify_config().set_bit_timing(0x001c_0003);
- // Configure filters so that can frames can be received.
- let mut filters = can1.modify_filters();
- filters.enable_bank(0, Mask32::accept_all());
- #[cfg(feature = "connectivity")]
- let _can2 = {
- let can = Can::new(dp.CAN2, &mut rcc.apb1);
- let mut gpiob = dp.GPIOB.split(&mut rcc.apb2);
- let rx = gpiob.pb5.into_floating_input(&mut gpiob.crl);
- let tx = gpiob.pb6.into_alternate_push_pull(&mut gpiob.crl);
- can.assign_pins((tx, rx), &mut afio.mapr);
- let mut can2 = bxcan::Can::new(can);
- // APB1 (PCLK1): 8MHz, Bit rate: 125kBit/s, Sample Point 87.5%
- // Value was calculated with http://www.bittiming.can-wiki.info/
- can2.modify_config().set_bit_timing(0x001c_0003);
- // A total of 28 filters are shared between the two CAN instances.
- // Split them equally between CAN1 and CAN2.
- let mut slave_filters = filters.set_split(14).slave_filters();
- slave_filters.enable_bank(14, Mask32::accept_all());
- can2
- };
- // Drop filters to leave filter configuraiton mode.
- drop(filters);
- // Select the interface.
- let mut can = can1;
- //let mut can = _can2;
- // Split the peripheral into transmitter and receiver parts.
- block!(can.enable()).unwrap();
- // Echo back received packages in sequence.
- // See the `can-rtfm` example for an echo implementation that adheres to
- // correct frame ordering based on the transfer id.
- loop {
- if let Ok(frame) = block!(can.receive()) {
- block!(can.transmit(&frame)).unwrap();
- }
- }
- }
|