void can_setup(void) { /* Enable peripheral clocks. */ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPBEN); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CANEN); AFIO_MAPR = AFIO_MAPR_CAN1_REMAP_PORTB; /* Configure CAN pin: RX (input pull-up). */ gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX); gpio_set(GPIOB, GPIO_CAN1_PB_RX); /* Configure CAN pin: TX. */ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX); /* NVIC setup. */ nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1); /* Reset CAN. */ can_reset(CAN1); /* CAN cell init. */ if (can_init(CAN1, false, /* TTCM: Time triggered comm mode? */ true, /* ABOM: Automatic bus-off management? */ false, /* AWUM: Automatic wakeup mode? */ false, /* NART: No automatic retransmission? */ false, /* RFLM: Receive FIFO locked mode? */ false, /* TXFP: Transmit FIFO priority? */ CAN_BTR_SJW_1TQ, CAN_BTR_TS1_3TQ, CAN_BTR_TS2_4TQ, 12)) /* BRP+1: Baud rate prescaler */ { gpio_set(GPIOA, GPIO8); /* LED0 off */ gpio_set(GPIOB, GPIO4); /* LED1 off */ gpio_set(GPIOC, GPIO15); /* LED2 off */ gpio_clear(GPIOC, GPIO2); /* LED3 on */ gpio_set(GPIOC, GPIO5); /* LED4 off */ /* Die because we failed to initialize. */ while (1) __asm__("nop"); } /* CAN filter 0 init. */ can_filter_id_mask_32bit_init(CAN1, 0, /* Filter ID */ 0, /* CAN ID */ 0, /* CAN ID mask */ 0, /* FIFO assignment (here: FIFO0) */ true); /* Enable the filter. */ /* Enable CAN RX interrupt. */ can_enable_irq(CAN1, CAN_IER_FMPIE0); }
static void can_setup(void) { /* Enable peripheral clocks */ rcc_periph_clock_enable(RCC_AFIO); rcc_periph_clock_enable(RCC_CAN1); AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB; /* Configure CAN pin: RX (input pull-up) */ gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX); gpio_set(GPIO_BANK_CAN1_PB_RX, GPIO_CAN1_PB_RX); /* Configure CAN pin: TX */ gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX); /* NVIC setup */ nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1); /* Reset CAN */ can_reset(CAN1); /* CAN cell init. * Setting the bitrate to 250kHz. APB1 = 36MHz, * prescaler = 9 -> 4MHz time quanta frequency. * 1tq sync + 9tq bit segment1 (TS1) + 6tq bit segment2 (TS2) = * 16time quanto per bit period, therefor 4MHz/16 = 250kHz */ if (can_init(CAN1, false, /* TTCM: Time triggered comm mode? */ true, /* ABOM: Automatic bus-off management? */ false, /* AWUM: Automatic wakeup mode? */ false, /* NART: No automatic retransmission? */ false, /* RFLM: Receive FIFO locked mode? */ false, /* TXFP: Transmit FIFO priority? */ CAN_BTR_SJW_1TQ, CAN_BTR_TS1_9TQ, CAN_BTR_TS2_6TQ, 9, false, false)) { gpio_clear(GPIOC, GPIO13); /* LED green on */ /* Die because we failed to initialize. */ while (1) __asm__("nop"); } /* CAN filter 0 init. */ can_filter_id_mask_32bit_init(CAN1, 0, /* Filter ID */ 0, /* CAN ID */ 0, /* CAN ID mask */ 0, /* FIFO assignment (here: FIFO0) */ true); /* Enable the filter. */ /* Enable CAN RX interrupt. */ can_enable_irq(CAN1, CAN_IER_FMPIE0); }
void can_hw_init(void) { /* Enable peripheral clocks. */ rcc_periph_clock_enable(RCC_AFIO); rcc_periph_clock_enable(RCC_GPIOB); rcc_periph_clock_enable(RCC_CAN1); /* Remap the gpio pin if necessary. */ AFIO_MAPR |= AFIO_MAPR_CAN1_REMAP_PORTB; /* Configure CAN pin: RX (input pull-up). */ gpio_set_mode(GPIO_BANK_CAN1_PB_RX, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN1_PB_RX); gpio_set(GPIO_BANK_CAN1_PB_RX, GPIO_CAN1_PB_RX); /* Configure CAN pin: TX (output push-pull). */ gpio_set_mode(GPIO_BANK_CAN1_PB_TX, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN1_PB_TX); /* NVIC setup. */ nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, NVIC_USB_LP_CAN_RX0_IRQ_PRIO); /* Reset CAN. */ can_reset(CAN1); /* CAN cell init. * For time quanta calculation see STM32 reference manual * section 24.7.7 "Bit timing" page 645 * * To talk to CSC using LPC mcu we need a baud rate of 375kHz * The APB1 runs at 36MHz therefor we select a prescaler of 12 * resulting in time quanta frequency of 36MHz / 12 = 3MHz * * As the Bit time is combined of 1tq for SYNC_SEG, TS1tq for bit * segment 1 and TS2tq for bit segment 2: * BITtq = 1tq + TS1tq + TS2tq * * We can choose to use TS1 = 3 and TS2 = 4 getting * 1tq + 3tq + 4tq = 8tq per bit therefor a bit frequency is * 3MHZ / 8 = 375kHz * * Maximum baud rate of CAN is 1MHz so we can choose to use * prescaler of 2 resulting in a quanta frequency of 36MHz / 2 = 18Mhz * * So we need to devide the frequency by 18. This can be accomplished * using TS1 = 10 and TS2 = 7 resulting in: * 1tq + 10tq + 7tq = 18tq * * NOTE: Although it is out of spec I managed to have CAN run at 2MBit * Just decrease the prescaler to 1. It worked for me(tm) (esden) */ if (can_init(CAN1, false, /* TTCM: Time triggered comm mode? */ true, /* ABOM: Automatic bus-off management? */ false, /* AWUM: Automatic wakeup mode? */ false, /* NART: No automatic retransmission? */ false, /* RFLM: Receive FIFO locked mode? */ false, /* TXFP: Transmit FIFO priority? */ CAN_BTR_SJW_1TQ, CAN_BTR_TS1_10TQ, CAN_BTR_TS2_7TQ, 2, /* BRP+1: Baud rate prescaler */ false, /* loopback mode */ false)) /* silent mode */ { /* TODO we need something somewhere where we can leave a note * that CAN was unable to initialize. Just like any other * driver should... */ can_reset(CAN1); return; } /* CAN filter 0 init. */ can_filter_id_mask_32bit_init(CAN1, 0, /* Filter ID */ 0, /* CAN ID */ 0, /* CAN ID mask */ 0, /* FIFO assignment (here: FIFO0) */ true); /* Enable the filter. */ /* Enable CAN RX interrupt. */ can_enable_irq(CAN1, CAN_IER_FMPIE0); /* Remember that we succeeded to initialize. */ can_initialized = true; }
void can_setup(void) { /* Enable peripheral clocks. */ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_AFIOEN); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN); rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_CANEN); /* Configure CAN pin: RX */ gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO_CAN_RX); gpio_set(GPIOA, GPIO_CAN_RX); /* Configure CAN pin: TX */ gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_CAN_TX); /* NVIC configuration */ nvic_enable_irq(NVIC_USB_LP_CAN_RX0_IRQ); nvic_set_priority(NVIC_USB_LP_CAN_RX0_IRQ, 1); /* CAN register init */ can_reset(CAN1); /* CAN cell init */ if (can_init(CAN1, false, /* TTCM: Time triggered comm mode? */ true, /* ABOM: Automatic bus-off management? */ false, /* AWUM: Automatic wakeup mode? */ false, /* NART: No automatic retransmission? */ false, /* RFLM: Receive FIFO locked mode? */ false, /* TXFP: Transmit FIFO priority? */ CAN_BTR_SJW_1TQ, CAN_BTR_TS1_3TQ, CAN_BTR_TS2_4TQ, 12, false, false)) /* BRP+1: Baud rate prescaler */ { ON(LED_RED); OFF(LED_GREEN); OFF(LED_BLUE); OFF(LED_ORANGE); /* Die because we failed to initialize. */ while (1) __asm__("nop"); } /* CAN filter init */ can_filter_id_mask_32bit_init(CAN1, 0, /* Filter ID */ 0, /* CAN ID */ 0, /* CAN ID mask */ 0, /* FIFO assignment (here: FIFO0) */ true); /* Enable the filter. */ /* transmit struct init */ can_tx_msg.id = 0x0; can_tx_msg.rtr = false; #ifdef CAN__USE_EXT_ID can_tx_msg.ide = true; #else can_tx_msg.ide = false; #endif can_tx_msg.dlc = 1; can_enable_irq(CAN1, CAN_IER_FMPIE0); }
void modcan_init(void) { // enable the clocks rcc_periph_clock_enable(RCC_CAN1); rcc_periph_clock_enable(RCC_CAN2); rcc_periph_clock_enable(RCC_GPIOB); rcc_periph_clock_enable(RCC_GPIOA); // init pins gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO5 | GPIO6 ); gpio_set_af(GPIOB, GPIO_AF9, GPIO5 | GPIO6 ); gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO11 | GPIO12 ); gpio_set_af(GPIOA, GPIO_AF9, GPIO11 | GPIO12 ); gpio_set_output_options(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, GPIO6 ); gpio_set_output_options(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, GPIO12 ); can_reset(CAN1); can_reset(CAN2); can_leave_sleep_mode(CAN1); can_leave_sleep_mode(CAN2); struct can_timing ct; can_timing_init(&ct, CAN_FREQ_500K, CAN_SAMPLE_75); //uint32_t canfreq = can_timing_getfreq(&ct); if (can_enter_init_mode_blocking(CAN1)) { can_mode_set_autobusoff(CAN1, true); can_mode_set_timetriggered(CAN1, true); can_timing_set(CAN1, &ct); can_filter_set_slave_start(CAN1, 5); //CAN_MCR(CAN1) &= ~CAN_MCR_DBF; can_filter_init_enter(CAN1); can_filter_set_mask32(CAN1, 0, 0, MOB_ANY, MOB_ANY); can_filter_set_mask32(CAN1, 5, 0, MOB_ANY, MOB_ANY); can_filter_init_leave(CAN1); can_leave_init_mode_blocking(CAN1); } if (can_enter_init_mode_blocking(CAN2)) { can_mode_set_autobusoff(CAN2, true); can_mode_set_timetriggered(CAN2, true); can_timing_set(CAN2, &ct); can_leave_init_mode_blocking(CAN2); } nvic_enable_irq(NVIC_CAN1_RX0_IRQ); nvic_enable_irq(NVIC_CAN1_RX1_IRQ); nvic_enable_irq(NVIC_CAN2_RX0_IRQ); nvic_enable_irq(NVIC_CAN2_RX1_IRQ); nvic_enable_irq(NVIC_CAN1_SCE_IRQ); nvic_enable_irq(NVIC_CAN2_SCE_IRQ); nvic_enable_irq(NVIC_CAN1_TX_IRQ); nvic_enable_irq(NVIC_CAN2_TX_IRQ); nvic_set_priority(NVIC_CAN1_RX0_IRQ, 1); nvic_set_priority(NVIC_CAN1_RX1_IRQ, 1); nvic_set_priority(NVIC_CAN2_RX0_IRQ, 1); nvic_set_priority(NVIC_CAN2_RX1_IRQ, 1); nvic_set_priority(NVIC_CAN1_SCE_IRQ, 1); nvic_set_priority(NVIC_CAN2_SCE_IRQ, 1); nvic_set_priority(NVIC_CAN1_TX_IRQ, 1); nvic_set_priority(NVIC_CAN2_TX_IRQ, 1); /* Enable CAN RX interrupt. */ can_enable_irq(CAN1, CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_TMEIE); can_enable_irq(CAN2, CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_TMEIE); }