Blame view

RIOT/cpu/samd21/cpu.c 3.43 KB
fb11e647   vrobic   reseau statique a...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  /*
   * Copyright (C) 2015 Freie Universitรคt Berlin
   *
   * This file is subject to the terms and conditions of the GNU Lesser
   * General Public License v2.1. See the file LICENSE in the top level
   * directory for more details.
   */
  
  /**
   * @ingroup     cpu_samd21
   * @{
   *
   * @file
   * @brief       Implementation of the CPU initialization
   *
   * @author      Thomas Eichinger <thomas.eichinger@fu-berlin.de>
   * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
   * @}
   */
  
  #include "cpu.h"
  #include "periph_conf.h"
  
  /**
   * @brief   Configure clock sources and the cpu frequency
   */
  static void clk_init(void)
  {
      /* enable clocks for the power, sysctrl and gclk modules */
      PM->APBAMASK.reg = (PM_APBAMASK_PM | PM_APBAMASK_SYSCTRL |
                          PM_APBAMASK_GCLK);
  
      /* adjust NVM wait states, see table 42.30 (p. 1070) in the datasheet */
  #if (CLOCK_CORECLOCK > 24000000)
      PM->APBAMASK.reg |= PM_AHBMASK_NVMCTRL;
      NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_RWS(1);
      PM->APBAMASK.reg &= ~PM_AHBMASK_NVMCTRL;
  #endif
  
      /* configure internal 8MHz oscillator to run without prescaler */
      SYSCTRL->OSC8M.bit.PRESC = 0;
      SYSCTRL->OSC8M.bit.ONDEMAND = 0;
      SYSCTRL->OSC8M.bit.RUNSTDBY = 0;
      SYSCTRL->OSC8M.bit.ENABLE = 1;
      while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC8MRDY)) {}
  
  #if CLOCK_USE_PLL
      /* reset the GCLK module so it is in a known state */
      GCLK->CTRL.reg = GCLK_CTRL_SWRST;
      while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
  
      /* setup generic clock 1 to feed DPLL with 1MHz */
      GCLK->GENDIV.reg = (GCLK_GENDIV_DIV(8) |
                          GCLK_GENDIV_ID(1));
      GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
                           GCLK_GENCTRL_SRC_OSC8M |
                           GCLK_GENCTRL_ID(1));
      GCLK->CLKCTRL.reg = (GCLK_CLKCTRL_GEN(1) |
                           GCLK_CLKCTRL_ID(1) |
                           GCLK_CLKCTRL_CLKEN);
      while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
  
      /* enable PLL */
      SYSCTRL->DPLLRATIO.reg = (SYSCTRL_DPLLRATIO_LDR(CLOCK_PLL_MUL));
      SYSCTRL->DPLLCTRLB.reg = (SYSCTRL_DPLLCTRLB_REFCLK_GCLK);
      SYSCTRL->DPLLCTRLA.reg = (SYSCTRL_DPLLCTRLA_ENABLE);
      while(!(SYSCTRL->DPLLSTATUS.reg &
             (SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK))) {}
  
      /* select the PLL as source for clock generator 0 (CPU core clock) */
      GCLK->GENDIV.reg =  (GCLK_GENDIV_DIV(CLOCK_PLL_DIV) |
                          GCLK_GENDIV_ID(0));
      GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
                           GCLK_GENCTRL_SRC_FDPLL |
                           GCLK_GENCTRL_ID(0));
  #else /* do not use PLL, use internal 8MHz oscillator directly */
      GCLK->GENDIV.reg =  (GCLK_GENDIV_DIV(CLOCK_DIV) |
                          GCLK_GENDIV_ID(0));
      GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN |
                           GCLK_GENCTRL_SRC_OSC8M |
                           GCLK_GENCTRL_ID(0));
  #endif
  
      /* make sure we synchronize clock generator 0 before we go on */
      while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
  
      /* redirect all peripherals to a disabled clock generator (7) by default */
      for (int i = 0x3; i <= 0x22; i++) {
          GCLK->CLKCTRL.reg = ( GCLK_CLKCTRL_ID(i) | GCLK_CLKCTRL_GEN_GCLK7 );
          while (GCLK->STATUS.bit.SYNCBUSY) {}
      }
  }
  
  void cpu_init(void)
  {
      /* disable the watchdog timer */
      WDT->CTRL.bit.ENABLE = 0;
      /* initialize the Cortex-M core */
      cortexm_init();
      /* Initialise clock sources and generic clocks */
      clk_init();
  }