Skip to content

Commit 1fa6e09

Browse files
committed
cpu/samd5x: improve can-initialization
1 parent e8be6ee commit 1fa6e09

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

cpu/samd5x/periph/can.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#include <assert.h>
21+
#include <stdint.h>
2122
#include <string.h>
2223

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

188189
static void _setup_clock(can_t *dev)
189190
{
190-
if (dev->conf->can == CAN0) {
191-
GCLK->PCHCTRL[CAN0_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(dev->conf->gclk_src);
191+
int pchid = 0;
192+
if (dev->conf->can == CAN0){
193+
pchid = CAN0_GCLK_ID;
192194
}
193-
else if (dev->conf->can == CAN1) {
194-
GCLK->PCHCTRL[CAN1_GCLK_ID].reg = GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(dev->conf->gclk_src);
195+
else if (dev->conf->can == CAN1){
196+
pchid = CAN1_GCLK_ID;
195197
}
196198
else {
199+
/* only CAN0 and CAN1 supported. When ported to MCUs with more
200+
* CAN controllers, this code needs to be adapted */
197201
DEBUG_PUTS("CAN channel not supported");
202+
assert(0);
203+
return;
198204
}
205+
206+
uint32_t pchctrl = GCLK->PCHCTRL[pchid].reg;
207+
208+
/* disable */
209+
GCLK->PCHCTRL[pchid].reg = pchctrl & (~GCLK_PCHCTRL_CHEN);
210+
do {
211+
pchctrl = GCLK->PCHCTRL[pchid].reg;
212+
} while (pchctrl & GCLK_PCHCTRL_CHEN);
213+
214+
/* setup */
215+
pchctrl = GCLK_PCHCTRL_GEN(dev->conf->gclk_src);
216+
GCLK->PCHCTRL[pchid].reg = pchctrl;
217+
218+
/* enable */
219+
pchctrl |= GCLK_PCHCTRL_CHEN;
220+
GCLK->PCHCTRL[pchid].reg = pchctrl;
221+
do {
222+
pchctrl = GCLK->PCHCTRL[pchid].reg;
223+
} while (!(pchctrl & GCLK_PCHCTRL_CHEN));
199224
}
200225

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

382407
/* Reject all remote frames */
383-
dev->conf->can->GFC.reg |= CAN_GFC_RRFE | CAN_GFC_RRFS;
408+
dev->conf->can->GFC.reg = CAN_GFC_RRFE | CAN_GFC_RRFS;
384409

385410
/* Enable reception interrupts: reception on FIFO0 and FIFO1 */
386-
dev->conf->can->IE.reg |= CAN_IE_RF0NE | CAN_IE_RF1NE;
411+
uint32_t ie_reg = CAN_IE_RF0NE | CAN_IE_RF1NE;
387412
/* Enable transmission events interrupts */
388-
dev->conf->can->IE.reg |= CAN_IE_TEFNE;
413+
ie_reg |= CAN_IE_TEFNE;
389414
/* Enable errors interrupts */
390-
dev->conf->can->IE.reg |= CAN_IE_PEDE | CAN_IE_PEAE | CAN_IE_BOE | CAN_IE_EWE | CAN_IE_EPE;
415+
ie_reg |= CAN_IE_PEDE | CAN_IE_PEAE | CAN_IE_BOE | CAN_IE_EWE | CAN_IE_EPE;
416+
/* write Interrupt enable register */
417+
dev->conf->can->IE.reg = ie_reg;
418+
391419
/* Enable the interrupt lines */
392420
dev->conf->can->ILE.reg = CAN_ILE_EINT0 | CAN_ILE_EINT1;
393421

0 commit comments

Comments
 (0)