Contiki-NG
Toggle main menu visibility
Loading...
Searching...
No Matches
msp430.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2026, RISE Research Institutes of Sweden AB
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
30
/**
31
* \file
32
* MSP430FR5969 CPU initialization
33
*
34
* Configures the Clock System (CS) for 8MHz DCO operation.
35
*/
36
37
#include "contiki.h"
38
#include <msp430.h>
39
40
#if defined(__MSP430__) && defined(__GNUC__)
41
#define asmv(arg) __asm__ __volatile__(arg)
42
#endif
43
44
/* Flag for timers/serial to indicate DCO must be kept on in LPM */
45
int
msp430_dco_required;
46
47
/*---------------------------------------------------------------------------*/
48
/**
49
* Initialize the Clock System (CS) module.
50
*
51
* Configure:
52
* - DCO at 8 MHz
53
* - MCLK = SMCLK = DCO
54
* - ACLK = LFXT (32.768 kHz on-board crystal), with VLOCLK fallback
55
* if the crystal fails to stabilize.
56
*
57
* Also configures FRAM wait states for 8MHz operation.
58
*/
59
static
void
60
msp430_init_dco
(
void
)
61
{
62
/* Route PJ.4/PJ.5 to the LFXT crystal before unlocking the LPM5
63
* port latch so the pins come up in peripheral function. */
64
PJSEL0 |= BIT4 | BIT5;
65
PJSEL1 &= ~(BIT4 | BIT5);
66
67
/* Disable the GPIO power-on default high-impedance mode to activate
68
* previously configured port settings */
69
PM5CTL0 &= ~LOCKLPM5;
70
71
/* Configure FRAM wait state (required for >8MHz operation)
72
* FWPW = FRAM write password
73
* NACCESS_0 = 0 wait states for up to 8MHz operation
74
*/
75
FRCTL0 = FWPW | NACCESS_0;
76
77
/* Unlock CS registers (CSKEY >> 8 to get high byte) */
78
CSCTL0_H = (CSKEY >> 8);
79
80
/* Configure DCO to 8MHz */
81
CSCTL1 = DCOFSEL_6;
/* DCO = 8 MHz */
82
83
/* Start LFXT with default drive strength. Source ACLK from VLO
84
* initially so the system can run even before the crystal
85
* stabilizes; we switch to LFXT below once OFIFG stays cleared. */
86
CSCTL4 = (CSCTL4 & ~(LFXTOFF | LFXTBYPASS)) | LFXTDRIVE_3;
87
CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
88
89
/* Set clock dividers (all divide by 1) */
90
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;
91
92
/* Wait up to ~500 ms for the LFXT to stabilize. Each iteration
93
* clears LFXTOFFG and the system oscillator fault flag, then
94
* delays ~10 ms at 8 MHz; 50 iterations gives a 500 ms cap. If
95
* the crystal never stabilizes (e.g. unpopulated or broken), we
96
* leave ACLK on VLOCLK so etimer/rtimer still tick. */
97
for
(
int
retries = 0; retries < 50; retries++) {
98
CSCTL5 &= ~LFXTOFFG;
99
SFRIFG1 &= ~OFIFG;
100
__delay_cycles(80000);
101
if
((CSCTL5 & LFXTOFFG) == 0 && (SFRIFG1 & OFIFG) == 0) {
102
break
;
103
}
104
}
105
if
((SFRIFG1 & OFIFG) == 0) {
106
CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
107
}
108
109
/* Lock CS registers */
110
CSCTL0_H = 0;
111
112
msp430_dco_required = 0;
113
}
114
/*---------------------------------------------------------------------------*/
115
/**
116
* Initialize all ports to output low to reduce power consumption.
117
*
118
* PJ is intentionally left at its reset default (all inputs):
119
* - PJ.0..PJ.3 carry the JTAG signals used by the eZ-FET probe.
120
* - PJ.4/PJ.5 are the LFXT crystal pins; driving them as outputs
121
* would jam the 32.768 kHz oscillator that sources ACLK.
122
*/
123
static
void
124
init_ports
(
void
)
125
{
126
/* Configure all GPIO to output low */
127
P1OUT = 0;
128
P1DIR = 0xFF;
129
P2OUT = 0;
130
P2DIR = 0xFF;
131
P3OUT = 0;
132
P3DIR = 0xFF;
133
P4OUT = 0;
134
P4DIR = 0xFF;
135
}
136
/*---------------------------------------------------------------------------*/
137
void
138
msp430_cpu_init(
void
)
139
{
140
/* Stop watchdog timer */
141
WDTCTL = WDTPW | WDTHOLD;
142
143
/* Initialize ports first (reduces power) */
144
init_ports
();
145
146
/* Initialize DCO and clock system */
147
msp430_init_dco
();
148
149
/* Enable global interrupts */
150
eint();
151
}
152
/*---------------------------------------------------------------------------*/
153
/**
154
* Synchronize DCO (no-op for FR5969, DCO is automatically calibrated).
155
*/
156
void
157
msp430_sync_dco
(
void
)
158
{
159
/* FR5969 DCO is factory calibrated, no sync needed */
160
}
161
/*---------------------------------------------------------------------------*/
162
/**
163
* Mask all interrupts that can be masked.
164
*/
165
int
166
splhigh_
(
void
)
167
{
168
int
sr;
169
/* Clear the GIE (General Interrupt Enable) flag. */
170
#ifdef __IAR_SYSTEMS_ICC__
171
sr = __get_SR_register();
172
__bic_SR_register(GIE);
173
#else
174
asmv(
"mov r2, %0"
:
"=r"
(sr));
175
asmv(
"bic %0, r2"
: :
"i"
(GIE));
176
/* GCC 9 warns about risk of incorrect execution without nop after
177
interrupt state changes. */
178
asmv(
"nop"
);
179
#endif
180
return
sr & GIE;
/* Ignore other sr bits. */
181
}
182
/*---------------------------------------------------------------------------*/
183
#ifdef __IAR_SYSTEMS_ICC__
184
int
__low_level_init(
void
)
185
{
186
/* turn off watchdog so that C-init will run */
187
WDTCTL = WDTPW + WDTHOLD;
188
return
1;
189
}
190
#endif
191
/*---------------------------------------------------------------------------*/
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
msp430_sync_dco
void msp430_sync_dco(void)
Synchronize DCO (no-op for FR5969, DCO is automatically calibrated).
Definition
msp430.c:157
arch
platform
msp-exp430fr5969
dev
msp430.c
Generated on
for Contiki-NG by
1.17.0