Blame view

RIOT/boards/telosb/board.c 4.01 KB
a752c7ab   elopes   add first test an...
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
126
127
128
129
130
  /*
   * board.c - Board initiazilation for the TelosB
   * Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
   *
   * 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.
   */
  
  #include "cpu.h"
  #include "board.h"
  #include "uart_stdio.h"
  
  void uart_init(void);
  
  static void telosb_ports_init(void)
  {
      /* Port 1: GDO, Flash, BSL TX */
      P1SEL = 0x02;    /* Port1 Select: 00000010 = 0x02 */
      P1OUT = 0x00;    /* Port1 Output: 00000000 = 0x00 */
      P1DIR = 0x87;    /* Port1 Direction: 10000111 = 0x87 */
  
      /* Port 2: GPIO, BSL RX, 1wire */
      P2SEL = 0x04;    /* Port2 Select: 00000100 = 0x04 */
      P2OUT = 0x00;    /* Port2 Output: 00000000 = 0x00 */
      P2DIR = 0xFF;    /* Port2 Direction: 11111111 = 0xFF */
  
      /* Port 3: UART and SPI */
      P3SEL = 0x0E;    /* Port3 Select: 11001110 = 0xCE */
      P3OUT = 0x00;    /* Port3 Output: 00000000 = 0x00 */
      P3DIR = 0xFE;    /* Port3 Direction: 01001110 = 0x4E */
  
      /* Port 4: CS */
      P4SEL = 0x02;    /* Port4 Select: 00000010 = 0x02 */
      P4OUT = 0x04;    /* Port4 Output: 00000100 = 0x04 */
      P4DIR = 0x64;    /* Port4 Direction: 01100100 = 0x64 */
  
      /* Port 5: SPI, LED */
      P5SEL = 0x00;    /* Port5 Select: 00000000 = 0x00 */
      P5OUT = 0x70;    /* Port5 Output: 01110000 = 0x70 */
      P5DIR = 0x70;    /* Port5 Direction: 01110000 = 0x70 */
  
  
      P6SEL = 0xFF;    /* Port6 Select: 11111111 = 0xFF */
      P6OUT = 0x00;    /* Port6 Output: 00000000 = 0x00 */
      P6DIR = 0xFF;    /* Port6 Direction: 11111000 = 0xFF */
  
  }
  
  /*---------------------------------------------------------------------------*/
  /* taken from Contiki code */
  void msp430_init_dco(void)
  {
      /* This code taken from the FU Berlin sources and reformatted. */
  #define DELTA    (F_CPU / (F_RC_OSCILLATOR / 8))
  
      unsigned int oldcapture = 0;
      unsigned int i;
  
      /* 10100100 = XT2 is off, ACLK divided by 4, RSELx=4 */
      BCSCTL1 = XT2OFF | DIVA_2 | RSEL2;
  
      /* Init undivided DCO with internal resistor for MCLK and SMCLK
       * DCO = 32762Hz -> FLL = 2,4576 MHz */
      BCSCTL2 = 0x00;
  
      BCSCTL1 |= DIVA1 + DIVA0;             /* ACLK = LFXT1CLK/8 */
  
      for (i = 0xFFFF; i > 0; i--) {        /* Delay for XTAL to settle */
          __asm__("nop");
      }
  
      CCTL2 = CCIS0 + CM0 + CAP;            /* Define CCR2, CAP, ACLK */
      TACTL = TASSEL1 + TACLR + MC1;        /* SMCLK, continous mode */
  
      while (1) {
          unsigned int compare;
  
          while ((CCTL2 & CCIFG) != CCIFG);   /* Wait until capture occured!*/
  
          CCTL2 &= ~CCIFG;                    /* Capture occured, clear flag */
          compare = CCR2;                     /* Get current captured SMCLK */
          compare = compare - oldcapture;     /* SMCLK difference */
          oldcapture = CCR2;                  /* Save current captured SMCLK */
  
          if (DELTA == compare) {
              break;                            /* if equal, leave "while (1)" */
          }
          else if (DELTA < compare) {        /* DCO is too fast, slow it down */
              DCOCTL--;
  
              if (DCOCTL == 0xFF) {             /* Did DCO role under? */
                  BCSCTL1--;
              }
          }
          else {                            /* -> Select next lower RSEL */
              DCOCTL++;
  
              if (DCOCTL == 0x00) {             /* Did DCO role over? */
                  BCSCTL1++;
              }
  
              /* -> Select next higher RSEL  */
          }
      }
  
      CCTL2 = 0;                            /* Stop CCR2 function */
      TACTL = 0;                            /* Stop Timer_A */
  
      BCSCTL1 &= ~(DIVA1 + DIVA0);          /* remove /8 divisor from ACLK again */
  }
  
  
  //=========================== public ==========================================
  
  void board_init(void)
  {
      msp430_cpu_init();
      /* disable watchdog timer */
      WDTCTL     =  WDTPW + WDTHOLD;
  
      telosb_ports_init();
      msp430_init_dco();
  
      /* initialize STDIO over UART */
      uart_stdio_init();
  
      /* enable interrupts */
      __bis_SR_register(GIE);
  }