Page 4 of 18

Re: About the CAN controller.

Posted: Fri Jan 20, 2017 2:25 am
by WiFive
I 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 SN65HVD230

Re: About the CAN controller.

Posted: Fri Jan 20, 2017 3:39 am
by Sprite
Ah. In that case, I don't know. It looks like you can mash the two together, but my knowledge of CAN is too limited to say for sure.

Re: About the CAN controller.

Posted: Sun Jan 22, 2017 3:12 am
by jaegertuning
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_Init

Code: 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;
}
Configuration

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,
};
You wouldn't happen to have an example do you? I am using an MCP2551 transceiver but it should all work the same.

Re: About the CAN controller.

Posted: Tue Jan 31, 2017 6:36 pm
by ThomasB
I also use the MCP2551.
An example is planned but currently im drowning in work...

Re: About the CAN controller.

Posted: Fri Feb 03, 2017 2:35 pm
by jaegertuning
I also use the MCP2551.
An example is planned but currently im drowning in work...
No problem! I was able to get this working :D The code provided was perfect - I just needed to wire up my MCP2551 correctly.

Re: About the CAN controller.

Posted: Sat Feb 04, 2017 6:34 pm
by ThomasB
great!

I will try my best to upload an example next week

Re: About the CAN controller.

Posted: Mon Feb 06, 2017 11:20 am
by ThomasB
An example project now can be found on:
http://www.barth-dev.de/can-driver-esp32/

Re: About the CAN controller.

Posted: Wed Feb 15, 2017 11:24 am
by Beck-Sisyphus
Sorry, I meant SN65HVD230DR from Texas Instrument.

http://www.ti.com/lit/ds/symlink/sn65hvd232.pdf

Re: About the CAN controller.

Posted: Mon Mar 06, 2017 10:34 pm
by ThomasB
Those transceivers work all the same way, by translating the bus level to logical level.
Basically you only need to check if the transceiver supports your baud-rate.

(of course there are other parameters of the chip [like the package to pick something obvious] but that is nothing you have to deal with [at least I think so ;) ])

Re: About the CAN controller.

Posted: Wed Mar 08, 2017 4:35 pm
by rockyo
Hi group, hi Thomas,
I'm struggling now days since you give demo of your code..
I try first with change of baud rate to 250k to used with my another project. Through transceiver I getting nice signal of frames on RX pin but from ESP32 non of response. Then I try sending frame but again noting on TX pin. I pass through your cod few times and I don't see some problems. Today I tried baud 500k how "Pawel Szabaciuk" said that it's work in his case, but again in my case not :(.
Do you have some tip?
Thanks,
Dejan