aboutsummaryrefslogtreecommitdiffstats
path: root/demos/ARM7-AT91SAM7X-GCC/board.c
blob: bc0d46189c84b23b8d2adf2c579f3a8dff684458 (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
/*
    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/>.
*/

#include <ch.h>

#include "at91lib/AT91SAM7X256.h"

extern void FiqHandler(void);

__attribute__((interrupt("IRQ")))
static void SpuriousHandler(void) {

  AT91C_BASE_AIC->AIC_EOICR = (AT91_REG)AT91C_BASE_AIC;
}

void hwinit(void) {
  int i;
  AT91PS_PMC pmcp = AT91C_BASE_PMC;
  AT91PS_AIC aicp = AT91C_BASE_AIC;

  /*
   * Flash Memory: 1 wait state, about 50 cycles in a microsecond.
   */
  AT91C_BASE_MC->MC_FMR = (AT91C_MC_FMCN & (50 << 16)) | AT91C_MC_FWS_1FWS;

  /*
   * Watchdog disabled.
   */
  AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;

  /*
   * Enables the main oscillator and waits 56 slow cycles as startup time.
   */
  pmcp->PMC_MOR = (AT91C_CKGR_OSCOUNT & (7 << 8)) | AT91C_CKGR_MOSCEN;
  while (!(pmcp->PMC_SR & AT91C_PMC_MOSCS))
    ;

  /*
   * PLL setup: DIV = 14, MUL = 72, PLLCOUNT = 10
   * PLLfreq = 96109714 Hz (rounded)
   */
  pmcp->PMC_PLLR = (AT91C_CKGR_DIV & 14) |
                   (AT91C_CKGR_PLLCOUNT & (10 << 8)) |
                   (AT91C_CKGR_MUL & (72 << 16));
  while (!(pmcp->PMC_SR & (AT91C_PMC_LOCK)))
    ;

  /*
   * Master clock = PLLfreq / 2 = 48054858 Hz (rounded)
   */
  pmcp->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_2;
  while (!(pmcp->PMC_SR & (AT91C_PMC_MCKRDY)))
    ;

  /*
   * Default AIC setup, the device drivers will modify it as needed.
   */
  aicp->AIC_SVR[0] = (AT91_REG)FiqHandler;
  for (i = 1; i < 31; i++) {
    aicp->AIC_SVR[i] = (AT91_REG)NULL;
    aicp->AIC_EOICR = (AT91_REG)i;
  }
  aicp->AIC_SPU  = (AT91_REG)SpuriousHandler;

  /*
   * I/O setup, enable clocks, initially all pins are inputs with pullups.
   */
  pmcp->PMC_PCER = (1 << AT91C_ID_PIOA) | (1 << AT91C_ID_PIOB);
  AT91C_BASE_PIOA->PIO_PER = 0xFFFFFFFF;
}