void candle_can_init(void) { rx_callback = 0; memset(led_status, 0, sizeof(led_status)); clear_tx_queue(0); clear_tx_queue(1); // enable led outputs rcc_periph_clock_enable(RCC_GPIOD); gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO12 | GPIO13 | GPIO14 | GPIO15); // enable can1 peripheral rcc_periph_clock_enable(RCC_GPIOD); rcc_periph_clock_enable(RCC_CAN1); gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO0 | GPIO1); gpio_set_output_options(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO0 | GPIO1); gpio_set_af(GPIOD, GPIO_AF9, GPIO0 | GPIO1); reset_can(CAN1); init_can(CAN1); // enable can1 transceiver rcc_periph_clock_enable(RCC_GPIOC); gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO6); gpio_clear(GPIOC, GPIO6); // enable can2 peripheral rcc_periph_clock_enable(RCC_GPIOB); rcc_periph_clock_enable(RCC_CAN2); gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO12 | GPIO13); gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100MHZ, GPIO12 | GPIO13); gpio_set_af(GPIOB, GPIO_AF9, GPIO12 | GPIO13); reset_can(CAN2); init_can(CAN2); // enable can2 transceiver rcc_periph_clock_enable(RCC_GPIOD); gpio_mode_setup(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO11); gpio_clear(GPIOD, GPIO11); // init filter banks CAN_FMR(CAN1) |= CAN_FMR_FINIT; // switch filter banks to init mode // configure usage of 14 filter banks for can1 and 14 banks for can2 CAN_FMR(CAN1) &= ~CAN_FMR_CAN2SB_MASK; CAN_FMR(CAN1) |= (14<<CAN_FMR_CAN2SB_SHIFT); can_filter_id_mask_32bit_init(CAN1, 0, 0, 0, 0, 1); // set a catch-all filter for CAN1 fifo 0 can_filter_id_mask_32bit_init(CAN2, 14, 0, 0, 0, 1); // set a catch-all filter for CAN2 fifo 0 CAN_FMR(CAN1) &= ~CAN_FMR_FINIT; // switch filter banks to active mode }
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); }
void can_interface_init(void) { rcc_periph_clock_enable(RCC_CAN); /* STM32F3 CAN on 36MHz configured APB1 peripheral clock 36MHz / 2 -> 18MHz 18MHz / (1tq + 10tq + 7tq) = 1MHz => 1Mbit */ can_init(CAN, // Interface false, // Time triggered communication mode. true, // Automatic bus-off management. false, // Automatic wakeup mode. false, // No automatic retransmission. false, // Receive FIFO locked mode. true, // Transmit FIFO priority. CAN_BTR_SJW_1TQ, // Resynchronization time quanta jump width CAN_BTR_TS1_10TQ,// Time segment 1 time quanta width CAN_BTR_TS2_7TQ, // Time segment 2 time quanta width 2, // Prescaler false, // Loopback false); // Silent // filter to match any standard id // mask bits: 0 = Don't care, 1 = mute match corresponding id bit can_filter_id_mask_32bit_init( CAN, 0, // filter nr 0, // id: only std id, no rtr 6 | (7<<29), // mask: match only std id[10:8] = 0 (bootloader frames) 0, // assign to fifo0 true // enable ); }
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 aseba_can_init(void) { rcc_periph_clock_enable(RCC_CAN1); rcc_periph_clock_enable(RCC_GPIOD); gpio_set_af(GPIOD, GPIO_AF9, GPIO0 | GPIO1); gpio_mode_setup(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO0 | GPIO1); /* CAN cell init. * Setting the bitrate to 1MBit. APB1 = 42MHz, * prescaler = 2 -> 21MHz time quanta frequency. * 1tq sync + 12tq bit segment1 (TS1) + 8tq bit segment2 (TS2) = * 21time quanta per bit period, therefor 21MHz/21 = 1MHz */ if (can_init(CAN1, // Interface false, // Time triggered communication mode. true, // Automatic bus-off management. false, // Automatic wakeup mode. false, // No automatic retransmission. false, // Receive FIFO locked mode. false, // Transmit FIFO priority. CAN_BTR_SJW_1TQ, // Resynchronization time quanta jump width CAN_BTR_TS1_12TQ, // Time segment 1 time quanta width CAN_BTR_TS2_8TQ, // Time segment 2 time quanta width 2, // Prescaler false, // Loopback false)) { // Silent uart_puts("ERROR: CAN init failed\n"); } can_filter_id_mask_32bit_init( CAN1, 0, // nr 0, // id 0, // mask 0, // fifo true // enable ); // match any id }
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); }