Contiki-NG
Toggle main menu visibility
Loading...
Searching...
No Matches
msp430.c
1
/*
2
* Copyright (c) 2011, Swedish Institute of Computer Science
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of the Institute nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*
29
* This file is part of the Contiki operating system.
30
*/
31
#include "contiki.h"
32
#include "dev/watchdog.h"
33
34
/* dco_required set to 1 will cause the CPU not to go into
35
sleep modes where the DCO clock stopped */
36
int
msp430_dco_required;
37
38
#if defined(__MSP430__) && defined(__GNUC__)
39
#define asmv(arg) __asm__ __volatile__(arg)
40
#endif
41
/*---------------------------------------------------------------------------*/
42
void
43
msp430_init_dco
(
void
)
44
{
45
#ifdef __IAR_SYSTEMS_ICC__
46
__bis_SR_register(SCG0);
47
#else
48
asmv(
"bis %0, r2"
: :
"i"
(SCG0));
49
#endif
50
51
UCSCTL0 = 0x0000;
52
UCSCTL1 = DCORSEL_4;
53
54
UCSCTL2 = MSP430_CPU_SPEED / 32768;
55
UCSCTL4 = 0x33;
/* instead of 0x44 that is DCO/2 */
56
57
#ifdef __IAR_SYSTEMS_ICC__
58
__bic_SR_register(SCG0);
59
#else
60
asmv(
"bic %0, r2"
: :
"i"
(SCG0));
61
#endif
62
}
63
/*---------------------------------------------------------------------------*/
64
65
static
void
66
init_ports
(
void
)
67
{
68
/* Turn everything off, device drivers enable what is needed. */
69
/* All configured for digital I/O */
70
#ifdef P1SEL
71
P1SEL = 0;
72
#endif
73
#ifdef P2SEL
74
P2SEL = 0;
75
#endif
76
#ifdef P3SEL
77
P3SEL = 0;
78
#endif
79
#ifdef P4SEL
80
P4SEL = 0;
81
#endif
82
#ifdef P5SEL
83
P5SEL = 0;
84
#endif
85
#ifdef P6SEL
86
P6SEL = 0;
87
#endif
88
89
/* All available inputs */
90
#ifdef P1DIR
91
P1DIR = 0;
92
P1OUT = 0;
93
#endif
94
#ifdef P2DIR
95
P2DIR = 0;
96
P2OUT = 0;
97
#endif
98
#ifdef P3DIR
99
P3DIR = 0;
100
P3OUT = 0;
101
#endif
102
#ifdef P4DIR
103
P4DIR = 0;
104
P4OUT = 0;
105
#endif
106
107
#ifdef P5DIR
108
P5DIR = 0;
109
P5OUT = 0;
110
#endif
111
112
#ifdef P6DIR
113
P6DIR = 0;
114
P6OUT = 0;
115
#endif
116
117
#ifdef P7DIR
118
P7DIR = 0;
119
P7OUT = 0;
120
#endif
121
122
#ifdef P8DIR
123
P8DIR = 0;
124
P8OUT = 0;
125
#endif
126
127
P1IE = 0;
128
P2IE = 0;
129
}
130
/*---------------------------------------------------------------------------*/
131
/* msp430-ld may align _end incorrectly. Workaround in cpu_init. */
132
#if defined(__MSP430__) && defined(__GNUC__)
133
extern
int
_end;
/* Not in sys/unistd.h */
134
static
char
*cur_break = (
char
*)&_end;
135
#endif
136
137
/*---------------------------------------------------------------------------*/
138
/* add/remove_lpm_req - for requiring a specific LPM mode. currently Contiki */
139
/* jumps to LPM3 to save power, but DMA will not work if DCO is not clocked */
140
/* so some modules might need to enter their LPM requirements */
141
/* NOTE: currently only works with LPM1 (e.g. DCO) requirements. */
142
/*---------------------------------------------------------------------------*/
143
void
144
msp430_add_lpm_req(
int
req)
145
{
146
if
(req <= MSP430_REQUIRE_LPM1) {
147
msp430_dco_required++;
148
}
149
}
150
151
void
152
msp430_remove_lpm_req(
int
req)
153
{
154
if
(req <= MSP430_REQUIRE_LPM1) {
155
msp430_dco_required--;
156
}
157
}
158
159
void
160
msp430_cpu_init(
void
)
161
{
162
dint();
163
watchdog_init
();
164
init_ports
();
165
msp430_init_dco
();
166
eint();
167
#if defined(__MSP430__) && defined(__GNUC__)
168
if
((uintptr_t)cur_break & 1) {
/* Workaround for msp430-ld bug! */
169
cur_break++;
170
}
171
#endif
172
173
msp430_dco_required = 0;
174
}
175
/*---------------------------------------------------------------------------*/
176
177
#define STACK_EXTRA 32
178
179
/*
180
* Allocate memory from the heap. Check that we don't collide with the
181
* stack right now (some other routine might later). A watchdog might
182
* be used to check if cur_break and the stack pointer meet during
183
* runtime.
184
*/
185
#if defined(__MSP430__) && defined(__GNUC__)
186
void
*
187
sbrk(
int
incr)
188
{
189
char
*stack_pointer;
190
191
asmv(
"mov r1, %0"
:
"=r"
(stack_pointer));
192
stack_pointer -= STACK_EXTRA;
193
if
(incr > (stack_pointer - cur_break))
194
return
(
void
*)-1;
/* ENOMEM */
195
196
void
*old_break = cur_break;
197
cur_break += incr;
198
/*
199
* If the stack was never here then [old_break .. cur_break] should
200
* be filled with zeros.
201
*/
202
return
old_break;
203
}
204
#endif
205
/*---------------------------------------------------------------------------*/
206
/*
207
* Mask all interrupts that can be masked.
208
*/
209
int
210
splhigh_
(
void
)
211
{
212
int
sr;
213
/* Clear the GIE (General Interrupt Enable) flag. */
214
#ifdef __IAR_SYSTEMS_ICC__
215
sr = __get_SR_register();
216
__bic_SR_register(GIE);
217
#else
218
asmv(
"mov r2, %0"
:
"=r"
(sr));
219
asmv(
"bic %0, r2"
: :
"i"
(GIE));
220
/* GCC 9 warns about risk of incorrect execution without nop after
221
interrupt state changes. */
222
asmv(
"nop"
);
223
#endif
224
return
sr & GIE;
/* Ignore other sr bits. */
225
}
226
/*---------------------------------------------------------------------------*/
227
#ifdef __IAR_SYSTEMS_ICC__
228
int
__low_level_init(
void
)
229
{
230
/* turn off watchdog so that C-init will run */
231
WDTCTL = WDTPW + WDTHOLD;
232
/*
233
* Return value:
234
*
235
* 1 - Perform data segment initialization.
236
* 0 - Skip data segment initialization.
237
*/
238
return
1;
239
}
240
#endif
241
/*---------------------------------------------------------------------------*/
watchdog_init
void watchdog_init(void)
Initialisation function for the WDT.
Definition
watchdog.c:63
msp430_init_dco
static void msp430_init_dco(void)
Initialize the Clock System (CS) module.
Definition
msp430.c:60
init_ports
static void init_ports(void)
Initialize all ports to output low to reduce power consumption.
Definition
msp430.c:124
splhigh_
int splhigh_(void)
Mask all interrupts that can be masked.
Definition
msp430.c:166
arch
cpu
msp430
f5xxx
msp430.c
Generated on
for Contiki-NG by
1.17.0