|
18 | 18 | */ |
19 | 19 |
|
20 | 20 | #include <assert.h> |
| 21 | +#include <stdint.h> |
21 | 22 | #include <string.h> |
22 | 23 |
|
23 | 24 | #include "periph/can.h" |
@@ -187,15 +188,39 @@ static int _set_mode(Can *can, can_mode_t can_mode) |
187 | 188 |
|
188 | 189 | static void _setup_clock(can_t *dev) |
189 | 190 | { |
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; |
192 | 194 | } |
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; |
195 | 197 | } |
196 | 198 | else { |
| 199 | + /* only CAN0 and CAN1 supported. When ported to MCUs with more |
| 200 | + * CAN controllers, this code needs to be adapted */ |
197 | 201 | DEBUG_PUTS("CAN channel not supported"); |
| 202 | + assert(0); |
| 203 | + return; |
198 | 204 | } |
| 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)); |
199 | 224 | } |
200 | 225 |
|
201 | 226 | static void _set_bit_timing(can_t *dev) |
@@ -377,17 +402,20 @@ static int _init(candev_t *candev) |
377 | 402 | } |
378 | 403 | /* Disable automatic retransmission by default */ |
379 | 404 | /* 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; |
381 | 406 |
|
382 | 407 | /* 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; |
384 | 409 |
|
385 | 410 | /* 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; |
387 | 412 | /* Enable transmission events interrupts */ |
388 | | - dev->conf->can->IE.reg |= CAN_IE_TEFNE; |
| 413 | + ie_reg |= CAN_IE_TEFNE; |
389 | 414 | /* 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 | + |
391 | 419 | /* Enable the interrupt lines */ |
392 | 420 | dev->conf->can->ILE.reg = CAN_ILE_EINT0 | CAN_ILE_EINT1; |
393 | 421 |
|
|
0 commit comments