Contiki-NG
Loading...
Searching...
No Matches
platform.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 * Platform initialization for MSP-EXP430FR5969 LaunchPad
33 */
34
35#include <stdio.h>
36#include <string.h>
37#include "contiki.h"
38#include "sys/energest.h"
39#include "dev/button-hal.h"
40#include "dev/gpio-hal.h"
41#include "dev/leds.h"
42#include "dev/serial-line.h"
43#include "dev/uart0.h"
44#include "dev/watchdog.h"
45#include "sys/node-id.h"
46
47extern int msp430_dco_required;
48
49/*---------------------------------------------------------------------------*/
50/* Log configuration */
51/*---------------------------------------------------------------------------*/
52#include "sys/log.h"
53#define LOG_MODULE "FR5969"
54#define LOG_LEVEL LOG_LEVEL_MAIN
55
56/*---------------------------------------------------------------------------*/
57/*
58 * The MSP430FR5969 carries a factory-programmed Device Descriptor
59 * Table at 0x1A00. After an 8-byte header it stores a sequence of
60 * TLV entries; tag 0x08 is the per-die Random Number, which gives a
61 * unique seed for the link-layer address. Tag 0xfe marks the end of
62 * the table.
63 */
64#define DEVICE_DESCRIPTOR_BASE ((const uint8_t *)0x1A00)
65#define DEVICE_DESCRIPTOR_MAX_LEN 256
66#define TLV_TAG_RANDOM_NUMBER 0x08
67#define TLV_TAG_END 0xfe
68
69static int
70lladdr_from_device_descriptor(linkaddr_t *addr)
71{
72 const uint8_t *desc = DEVICE_DESCRIPTOR_BASE;
73 uint8_t info_len_words = desc[0];
74 const uint8_t *p;
75 const uint8_t *end;
76
77 /* Sanity-check the header so an unprogrammed/erased descriptor
78 * cannot send us walking off into FRAM. */
79 if(info_len_words == 0 || info_len_words > DEVICE_DESCRIPTOR_MAX_LEN / 4) {
80 return 0;
81 }
82
83 p = desc + 8;
84 end = desc + info_len_words * 4;
85
86 while(p + 1 < end) {
87 uint8_t tag = p[0];
88 uint8_t len = p[1];
89
90 if(tag == TLV_TAG_END || p + 2 + len > end) {
91 break;
92 }
93 if(tag == TLV_TAG_RANDOM_NUMBER && len > 0) {
94 /* Replicate the random bytes if the entry is shorter than
95 * LINKADDR_SIZE so every byte of the address contributes to
96 * uniqueness. */
97 for(size_t i = 0; i < LINKADDR_SIZE; i++) {
98 addr->u8[i] = p[2 + (i % len)];
99 }
100 /* Mark the address as locally administered (EUI-64 convention)
101 * and clear the multicast bit. */
102 addr->u8[0] = (addr->u8[0] & ~0x01) | 0x02;
103 return 1;
104 }
105 p += 2 + len;
106 }
107 return 0;
108}
109/*---------------------------------------------------------------------------*/
110static void
111set_lladdr(void)
112{
113 linkaddr_t addr;
114
115 memset(&addr, 0, sizeof(linkaddr_t));
116 if(!lladdr_from_device_descriptor(&addr)) {
117 /* No usable factory random-number entry: fall back to node_id. */
118 addr.u8[0] = (node_id >> 8) & 0xff;
119 addr.u8[1] = node_id & 0xff;
120 }
122}
123/*---------------------------------------------------------------------------*/
124void
126{
127 /* Initialize hardware */
128 msp430_cpu_init();
129
130 leds_init();
131 leds_on(LEDS_RED);
132}
133/*---------------------------------------------------------------------------*/
134void
136{
137 /* Initialize UART for serial communication. The argument is
138 * ignored; the driver hard-codes 115200 baud at 8 MHz SMCLK. */
139 uart0_init(0);
140
141 /*
142 * Delay to allow the eZ-FET debug probe to fully disconnect and switch
143 * to UART passthrough mode. The debug probe buffers UART data while a
144 * debug session is active. This delay ensures serial output occurs after
145 * the debugger has released the device. Experimentally, 200ms is the
146 * minimum; we use 250ms for margin. The argument to __delay_cycles must
147 * be a compile-time constant, so derive it from F_CPU.
148 */
149 __delay_cycles(F_CPU / 4);
150
151 leds_on(LEDS_GREEN);
152
153 /* Set link-layer address */
154 set_lladdr();
155
156 leds_off(LEDS_RED);
157
158 LOG_INFO("Platform: MSP-EXP430FR5969 LaunchPad\n");
159}
160/*---------------------------------------------------------------------------*/
161void
163{
164 /* Starts the GPIO HAL release-poll process; must run before the button HAL
165 * configures and enables the button interrupts. */
168
169 LOG_INFO("Node ID: %u\n", node_id);
170
171 /* Enable serial line input */
172 uart0_set_input(serial_line_input_byte);
173 serial_line_init();
174
175 leds_off(LEDS_GREEN);
176}
177/*---------------------------------------------------------------------------*/
178void
180{
181 int s = splhigh(); /* Disable interrupts */
182
183 /* Check if we can go to sleep */
184 if(process_nevents() != 0 || uart0_active()) {
185 splx(s); /* Re-enable interrupts */
186 } else {
187 /* Re-enable interrupts and go to sleep atomically */
188 ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
190
191 /* Check if DCO needs to be on - if so, only LPM1 */
192 if(msp430_dco_required) {
193 _BIS_SR(GIE | CPUOFF); /* LPM1 sleep */
194 } else {
195 _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep */
196 }
197
199 ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
200 }
201}
202/*---------------------------------------------------------------------------*/
Header file for the button HAL.
Header file for the energy estimation mechanism.
Header file for the GPIO HAL.
void button_hal_init()
Initialise the button HAL.
Definition button-hal.c:213
void uart0_init(void)
Initializes the UART driver.
Definition uart0-arch.c:83
void watchdog_start(void)
Starts the WDT in watchdog mode if enabled by user configuration, maximum interval.
Definition watchdog.c:72
void platform_init_stage_three()
Final stage of platform driver initialisation.
Definition platform.c:165
void platform_init_stage_one(void)
Basic (Stage 1) platform driver initialisation.
Definition platform.c:113
void platform_idle()
The platform's idle/sleep function.
Definition platform.c:181
void platform_init_stage_two()
Stage 2 of platform driver initialisation.
Definition platform.c:122
void watchdog_stop(void)
Stops the WDT such that it won't timeout and cause MCU reset.
void leds_init(void)
Initialise the LED HAL.
Definition minileds.c:44
void gpio_hal_init()
Initialise the GPIO HAL.
Definition gpio-hal.c:95
static void linkaddr_set_node_addr(linkaddr_t *addr)
Set the address of the current node.
Definition linkaddr.h:151
process_num_events_t process_nevents(void)
Number of events waiting to be processed.
Definition process.c:319
Header file for the LED HAL.
Header file for the logging system.
Node-id (simple 16-bit identifiers) handling.
eUSCI_A0 UART driver header for MSP430FR5969
Generic serial I/O process header filer.
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition uip-nd6.c:107