aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms/SPC563/hal_lld.c
blob: 3339306f9f6dcb66952c4fc310a47a7ff0a24c79 (plain)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
    ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.

    This file is part of ChibiOS/RT.

    ChibiOS/RT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    ChibiOS/RT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * @file    SPC563/hal_lld.c
 * @brief   SPC563 HAL subsystem low level driver source.
 *
 * @addtogroup SPC563_HAL
 * @{
 */

#include "ch.h"
#include "hal.h"

/*===========================================================================*/
/* Driver exported variables.                                                */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local variables.                                                   */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local functions.                                                   */
/*===========================================================================*/

/*===========================================================================*/
/* Driver interrupt handlers.                                                */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported functions.                                                */
/*===========================================================================*/

/**
 * @brief   Low level HAL driver initialization.
 */
void hal_lld_init(void) {
  extern void _vectors(void);
  uint32_t n;

  /* Enables the branch prediction, clears and enables the BTB into the
     BUCSR special register (1013).*/
  asm volatile ("li      %%r3, 0x0201          \t\n"
                "mtspr   1013, %%r3": : : "r3");

  /* FLASH wait states and prefetching setup.*/
  CFLASH0.BIUCR.R  = SPC563_FLASH_BIUCR | SPC563_FLASH_WS;
  CFLASH0.BIUCR2.R = 0;
  CFLASH0.PFCR3.R  = 0;

  /* Optimal crossbar settings. The DMA priority is placed above the CPU
     priority in order to not starve I/O activities while the CPU is
     excuting tight loops (FLASH and SRAM slave ports only).
     The SRAM is parked on the load/store port, for some unknown reason it
     is defaulted on the instructions port and this kills performance.*/
  XBAR.SGPCR3.B.PARK = 4;               /* RAM slave on load/store port.*/
  XBAR.MPR0.R = 0x00030201;             /* Flash slave port priorities:
                                            eDMA (1):              0 (highest)
                                            Core Instructions (0): 1
                                            Undocumented (2):      2
                                            Core Data (4):         3        */
  XBAR.MPR3.R = 0x00030201;             /* SRAM slave port priorities:
                                            eDMA (1):              0 (highest)
                                            Core Instructions (0): 1
                                            Undocumented (2):      2
                                            Core Data (4):         3        */

  /* Downcounter timer initialized for system tick use, TB enabled for debug
     and measurements.*/
  n = SPC563_SYSCLK / CH_FREQUENCY;
  asm volatile ("li      %%r3, 0            \t\n"
                "mtspr   284, %%r3          \t\n"   /* Clear TBL register.  */
                "mtspr   285, %%r3          \t\n"   /* Clear TBU register.  */
                "mtspr   22, %[n]           \t\n"   /* Init. DEC register.  */
                "mtspr   54, %[n]           \t\n"   /* Init. DECAR register.*/
                "li      %%r3, 0x4000       \t\n"   /* TBEN bit.            */
                "mtspr   1008, %%r3         \t\n"   /* HID0 register.       */
                "lis     %%r3, 0x0440       \t\n"   /* DIE ARE bits.        */
                "mtspr   340, %%r3"                 /* TCR register.        */
                : : [n] "r" (n) : "r3");

  /* INTC initialization, software vector mode, 4 bytes vectors, starting
     at priority 0.*/
  INTC.MCR.R   = 0;
  INTC.CPR.R   = 0;
  INTC.IACKR.R = (uint32_t)_vectors;
}

/**
 * @brief   SPC563 clocks and PLL initialization.
 * @note    All the involved constants come from the file @p board.h and
 *          @p hal_lld.h
 */
void spc563_clock_init(void) {

  /* PLL activation.*/
  FMPLL.ESYNCR1.B.EMODE     = 1;
  FMPLL.ESYNCR1.B.CLKCFG   &= 1;                    /* Bypass mode, PLL off.*/
  FMPLL.ESYNCR1.B.CLKCFG   |= 2;                    /* PLL on.              */
  FMPLL.ESYNCR1.B.EPREDIV   = SPC563_CLK_PREDIV;
  FMPLL.ESYNCR1.B.EMFD      = SPC563_CLK_MFD;
  FMPLL.ESYNCR2.B.ERFD      = SPC563_CLK_RFD;
  while (!FMPLL.SYNSR.B.LOCK)
    ;
  FMPLL.ESYNCR1.B.CLKCFG   |= 4;                    /* Clock from the PLL.  */
}

/** @} */