Skip to content

Commit

Permalink
cpu/samd5x: improve can-initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
kfessel committed Jan 30, 2025
1 parent e8be6ee commit 1fa6e09
Showing 1 changed file with 37 additions and 9 deletions.
46 changes: 37 additions & 9 deletions cpu/samd5x/periph/can.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

#include <assert.h>
#include <stdint.h>
#include <string.h>

#include "periph/can.h"
Expand Down Expand Up @@ -187,15 +188,39 @@ static int _set_mode(Can *can, can_mode_t can_mode)

static void _setup_clock(can_t *dev)
{
if (dev->conf->can == CAN0) {
GCLK->PCHCTRL[CAN0_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(dev->conf->gclk_src);
int pchid = 0;
if (dev->conf->can == CAN0){
pchid = CAN0_GCLK_ID;
}
else if (dev->conf->can == CAN1) {
GCLK->PCHCTRL[CAN1_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(dev->conf->gclk_src);
else if (dev->conf->can == CAN1){
pchid = CAN1_GCLK_ID;
}
else {
/* only CAN0 and CAN1 supported. When ported to MCUs with more
* CAN controllers, this code needs to be adapted */
DEBUG_PUTS("CAN channel not supported");
assert(0);
return;
}

uint32_t pchctrl = GCLK->PCHCTRL[pchid].reg;

/* disable */
GCLK->PCHCTRL[pchid].reg = pchctrl & (~GCLK_PCHCTRL_CHEN);
do {
pchctrl = GCLK->PCHCTRL[pchid].reg;
} while (pchctrl & GCLK_PCHCTRL_CHEN);

/* setup */
pchctrl = GCLK_PCHCTRL_GEN(dev->conf->gclk_src);
GCLK->PCHCTRL[pchid].reg = pchctrl;

/* enable */
pchctrl |= GCLK_PCHCTRL_CHEN;
GCLK->PCHCTRL[pchid].reg = pchctrl;
do {
pchctrl = GCLK->PCHCTRL[pchid].reg;
} while (!(pchctrl & GCLK_PCHCTRL_CHEN));
}

static void _set_bit_timing(can_t *dev)
Expand Down Expand Up @@ -377,17 +402,20 @@ static int _init(candev_t *candev)
}
/* Disable automatic retransmission by default */
/* This can be added as a configuration parameter for the CAN controller */
dev->conf->can->CCCR.reg |= CAN_CCCR_DAR;
dev->conf->can->CCCR.reg = CAN_CCCR_DAR;

/* Reject all remote frames */
dev->conf->can->GFC.reg |= CAN_GFC_RRFE | CAN_GFC_RRFS;
dev->conf->can->GFC.reg = CAN_GFC_RRFE | CAN_GFC_RRFS;

/* Enable reception interrupts: reception on FIFO0 and FIFO1 */
dev->conf->can->IE.reg |= CAN_IE_RF0NE | CAN_IE_RF1NE;
uint32_t ie_reg = CAN_IE_RF0NE | CAN_IE_RF1NE;
/* Enable transmission events interrupts */
dev->conf->can->IE.reg |= CAN_IE_TEFNE;
ie_reg |= CAN_IE_TEFNE;
/* Enable errors interrupts */
dev->conf->can->IE.reg |= CAN_IE_PEDE | CAN_IE_PEAE | CAN_IE_BOE | CAN_IE_EWE | CAN_IE_EPE;
ie_reg |= CAN_IE_PEDE | CAN_IE_PEAE | CAN_IE_BOE | CAN_IE_EWE | CAN_IE_EPE;
/* write Interrupt enable register */
dev->conf->can->IE.reg = ie_reg;

/* Enable the interrupt lines */
dev->conf->can->ILE.reg = CAN_ILE_EINT0 | CAN_ILE_EINT1;

Expand Down

0 comments on commit 1fa6e09

Please sign in to comment.