Re: About the CAN controller.
Posted: Fri Jan 20, 2017 2:25 am
I think he means SN65HVD230I am not familiar with that chip, and Google yields no datasheets; do you have a link with more info about it?
I think he means SN65HVD230I am not familiar with that chip, and Google yields no datasheets; do you have a link with more info about it?
You wouldn't happen to have an example do you? I am using an MCP2551 transceiver but it should all work the same.Update.
Now the driver calculates the baud rate prescaler based on the APB clock and I added a few more baud rates. (requires math.h)
CAN_InitConfigurationCode: Select all
intCAN_init(){ //Time quantum double __tq = 0; //Bit timing float __bt = 1000/CAN_cfg.speed; //enable module SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN); CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST); //configure TX pin gpio_set_direction(CAN_cfg.tx_pin_id,GPIO_MODE_OUTPUT); gpio_matrix_out(CAN_cfg.tx_pin_id,CAN_TX_IDX,0,0); gpio_pad_select_gpio(CAN_cfg.tx_pin_id); //configure RX pin gpio_set_direction(CAN_cfg.rx_pin_id,GPIO_MODE_INPUT); gpio_matrix_in(CAN_cfg.rx_pin_id,CAN_RX_IDX,0); gpio_pad_select_gpio(CAN_cfg.rx_pin_id); //set to PELICAN mode MODULE_CAN->CDR.B.CAN_M=0x1; //synchronization jump width is the same for all baud rates MODULE_CAN->BTR0.B.SJW =0x1; //TSEG2 is the same for all baud rates MODULE_CAN->BTR1.B.TSEG2 =0x1; //select time quantum and set TSEG1 switch(CAN_cfg.speed){ case CAN_SPEED_1000KBPS: MODULE_CAN->BTR1.B.TSEG1 =0x4; __tq = 0.125; break; case CAN_SPEED_800KBPS: MODULE_CAN->BTR1.B.TSEG1 =0x6; __tq = 0.125; break; default: MODULE_CAN->BTR1.B.TSEG1 =0xc; __tq = __bt / 16; } //set baud rate prescaler MODULE_CAN->BTR0.B.BRP=(uint8_t)round((((APB_CLK_FREQ * __tq) / 2) - 1)/1000000)-1; /* Set sampling * 1 -> triple; the bus is sampled three times; recommended for low/medium speed buses (class A and B) where filtering spikes on the bus line is beneficial * 0 -> single; the bus is sampled once; recommended for high speed buses (SAE class C)*/ MODULE_CAN->BTR1.B.SAM =0x1; //enable all interrupts MODULE_CAN->IER.U = 0xff; //no acceptance filtering, as we want to fetch all messages MODULE_CAN->MBX_CTRL.ACC.CODE[0] = 0; MODULE_CAN->MBX_CTRL.ACC.CODE[1] = 0; MODULE_CAN->MBX_CTRL.ACC.CODE[2] = 0; MODULE_CAN->MBX_CTRL.ACC.CODE[3] = 0; MODULE_CAN->MBX_CTRL.ACC.MASK[0] = 0xff; MODULE_CAN->MBX_CTRL.ACC.MASK[1] = 0xff; MODULE_CAN->MBX_CTRL.ACC.MASK[2] = 0xff; MODULE_CAN->MBX_CTRL.ACC.MASK[3] = 0xff; //set to normal mode MODULE_CAN->OCR.B.OCMODE=__CAN_OC_NOM; //clear error counters MODULE_CAN->TXERR.U = 0; MODULE_CAN->RXERR.U = 0; (void)MODULE_CAN->ECC; //clear interrupt flags (void)MODULE_CAN->IR.U; //install CAN ISR esp_intr_alloc(ETS_CAN_INTR_SOURCE,0,CAN_isr,NULL,NULL); //Showtime. Release Reset Mode. MODULE_CAN->MOD.B.RM = 0; return 0; }Code: Select all
/** \brief CAN Node Bus speed */ typedef enum { CAN_SPEED_100KBPS=100, /**< \brief CAN Node runs at 100kBit/s. */ CAN_SPEED_125KBPS=125, /**< \brief CAN Node runs at 125kBit/s. */ CAN_SPEED_250KBPS=250, /**< \brief CAN Node runs at 250kBit/s. */ CAN_SPEED_500KBPS=500, /**< \brief CAN Node runs at 500kBit/s. */ CAN_SPEED_800KBPS=800, /**< \brief CAN Node runs at 800kBit/s. */ CAN_SPEED_1000KBPS=1000 /**< \brief CAN Node runs at 1000kBit/s. */ }CAN_speed_t; /** \brief CAN configuration structure */ typedef struct { CAN_speed_t speed; /**< \brief CAN speed. */ gpio_num_t tx_pin_id; /**< \brief TX pin. */ gpio_num_t rx_pin_id; /**< \brief RX pin. */ QueueHandle_t rx_queue; /**< \brief Handler to FreeRTOS RX queue. */ }CAN_device_t; extern CAN_device_t CAN_cfg; CAN_device_t CAN_cfg = { .speed=CAN_SPEED_500KBPS, .tx_pin_id = GPIO_NUM_5, .rx_pin_id = GPIO_NUM_4, .rx_queue=NULL, };
No problem! I was able to get this workingI also use the MCP2551.
An example is planned but currently im drowning in work...