1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
19558: boards: support for Olimex MSP430-H1611 board r=maribu a=maribu

### Contribution description

- implement a clock driver so that boards declare their clock configuration, rather than initializing the CPU clock in `board_init()` by hand
    - Note: A board can still overwrite the weak symbol `clock_init()` in case some really crazy things should happen
- add support for the Olimex-H1611 board


19598: dist/tools/insufficient_memory: fix collection of app folders r=maribu a=maribu

### Contribution description

There is actually a make target to list the applications in the repo. Let's just use that.


Co-authored-by: Marian Buschsieweke <marian.buschsieweke@ovgu.de>
This commit is contained in:
bors[bot] 2023-05-16 13:20:47 +00:00 committed by GitHub
commit 070025f119
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
96 changed files with 1075 additions and 344 deletions

View File

@ -26,10 +26,6 @@
#include "msp430.h"
#include "debug.h"
static volatile uint32_t __msp430_cpu_speed = MSP430_INITIAL_CPU_SPEED;
void msp430_init_dco(void);
static void msb_ports_init(void)
{
/* Port 1: Free port, for energy saving all outputs are set to zero. */
@ -99,101 +95,7 @@ static void msb_ports_init(void)
/* 1 - P6.7 [OUT] - unused */
}
void msp430_set_cpu_speed(uint32_t speed)
{
irq_disable();
__msp430_cpu_speed = speed;
msp430_init_dco();
irq_enable();
}
/*---------------------------------------------------------------------------*/
void msp430_init_dco(void)
{
#if MSP430_HAS_EXTERNAL_CRYSTAL
/*------------------ use external oszillator -----------------------*/
uint16_t i;
/* Stop watchdog */
WDTCTL = WDTPW + WDTHOLD;
/* Init crystal for mclk */
/* XT2 = HF XTAL */
BCSCTL1 = RSEL2;
/* Wait for xtal to stabilize */
do {
IFG1 &= ~OFIFG; /* Clear oscillator fault flag */
for (i = 0xFF; i > 0; i--); /* Time for flag to set */
}
while ((IFG1 & OFIFG) != 0); /* Oscillator fault flag still set? */
BCSCTL2 = SELM_2 + SELS; /* MCLK und SMCLK = XT2 (safe) */
#else
unsigned int delta = __msp430_cpu_speed >> 12;
unsigned int oldcapture = 0;
unsigned int i;
BCSCTL1 = 0xa4; /* ACLK is divided by 4. RSEL=6 no division for MCLK
and SSMCLK. XT2 is off. */
/* Init FLL to desired frequency using the 32762Hz crystal */
#if MSP430_HAS_DCOR
BCSCTL2 = 0x01;
#else
BCSCTL2 = 0x00;
#endif
WDTCTL = WDTPW + WDTHOLD; /* Stop WDT */
BCSCTL1 |= DIVA1 + DIVA0; /* ACLK = LFXT1CLK/8 */
for (i = 0xffff; i > 0; i--); /* Delay for XTAL to settle */
CCTL2 = CCIS0 + CM0 + CAP; /* Define CCR2, CAP, ACLK */
TACTL = TASSEL1 + TACLR + MC1; /* SMCLK, continuous mode */
while (1) {
unsigned int compare;
while ((CCTL2 & CCIFG) != CCIFG); /* Wait until capture occurred! */
CCTL2 &= ~CCIFG; /* Capture occurred, 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 */
#endif
}
void board_init(void)
{
msb_ports_init();
msp430_set_cpu_speed(CLOCK_CORECLOCK);
}

View File

@ -45,18 +45,6 @@ extern "C" {
#define __MSP430F1612__
#endif
/**
* @name CPU core configuration
* @{
*/
/** @todo Move this to the periph_conf.h */
#define MSP430_INITIAL_CPU_SPEED 2457600uL
#define F_CPU MSP430_INITIAL_CPU_SPEED
#define F_RC_OSCILLATOR 32768
#define MSP430_HAS_DCOR 1
#define MSP430_HAS_EXTERNAL_CRYSTAL 0
/** @} */
/**
* @name Configure on-board SHT11 device
* @{

View File

@ -21,19 +21,28 @@
#ifndef PERIPH_CONF_H
#define PERIPH_CONF_H
#include "periph_cpu.h"
#include "macros/units.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Clock configuration
* @{
*/
/** @todo Move all clock configuration code here from the board.h */
#define CLOCK_CORECLOCK (7372800U)
#define CLOCK_CORECLOCK msp430_fxyz_dco_freq
#define CLOCK_CMCLK CLOCK_CORECLOCK /* no divider programmed */
/** @} */
/**
* @brief Clock configuration
*/
static const msp430_fxyz_clock_params_t clock_params = {
.target_dco_frequency = 7372800U,
.lfxt1_frequency = 32768,
.main_clock_source = MAIN_CLOCK_SOURCE_DCOCLK,
.submain_clock_source = SUBMAIN_CLOCK_SOURCE_DCOCLK,
.main_clock_divier = MAIN_CLOCK_DIVIDE_BY_1,
.submain_clock_divier = SUBMAIN_CLOCK_DIVIDE_BY_1,
.auxiliary_clock_divier = AUXILIARY_CLOCK_DIVIDE_BY_1,
.has_r_osc = true,
};
/**
* @name Timer configuration

View File

@ -33,18 +33,6 @@ extern "C" {
#define __MSP430F1612__
#endif
/**
* @name CPU core configuration
* @{
*/
/** @todo Move this to the periph_conf.h */
#define MSP430_INITIAL_CPU_SPEED 7372800uL
#define F_CPU MSP430_INITIAL_CPU_SPEED
#define F_RC_OSCILLATOR 32768
#define MSP430_HAS_DCOR 1
#define MSP430_HAS_EXTERNAL_CRYSTAL 1
/** @} */
/**
* @name Configure on-board SHT11 device
* @{

View File

@ -27,15 +27,21 @@
extern "C" {
#endif
/**
* @name Clock configuration
* @{
*/
/** @todo Move all clock configuration code here from the board.h */
#define CLOCK_CORECLOCK (7372800U)
#define CLOCK_CMCLK CLOCK_CORECLOCK /* no divider programmed */
/** @} */
/**
* @brief Clock configuration
*/
static const msp430_fxyz_clock_params_t clock_params = {
.xt2_frequency = CLOCK_CORECLOCK,
.lfxt1_frequency = 32768,
.main_clock_source = MAIN_CLOCK_SOURCE_XT2CLK,
.submain_clock_source = SUBMAIN_CLOCK_SOURCE_XT2CLK,
.main_clock_divier = MAIN_CLOCK_DIVIDE_BY_1,
.submain_clock_divier = SUBMAIN_CLOCK_DIVIDE_BY_1,
.auxiliary_clock_divier = AUXILIARY_CLOCK_DIVIDE_BY_1,
.has_r_osc = true,
};
/**
* @name Timer configuration

View File

@ -0,0 +1,18 @@
# Copyright (c) 2020 HAW Hamburg
#
# 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.
config BOARD
default "olimex-msp430-h1611" if BOARD_OLIMEX_MSP430_H1611
config BOARD_OLIMEX_MSP430_H1611
bool
default y
select CPU_MODEL_MSP430F1611
select HAS_PERIPH_GPIO
select HAS_PERIPH_GPIO_IRQ
select HAS_PERIPH_SPI
select HAS_PERIPH_TIMER
select HAS_PERIPH_UART

View File

@ -0,0 +1,3 @@
MODULE = board
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,10 @@
CPU = msp430fxyz
CPU_MODEL = msp430f1611
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_spi
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart
# Various other features (if any)

View File

@ -0,0 +1,26 @@
# set default port depending on operating system
PORT_LINUX ?= /dev/ttyUSB0
PORT_DARWIN ?= $(firstword $(sort $(wildcard /dev/tty.usbserial-MXV*)))
# flash tool configuration
PROGRAMMER ?= mspdebug
MSPDEBUG_PROGRAMMER ?= olimex
PROGRAMMERS_SUPPORTED += mspdebug
# When freshly plugged in the Olimex MSP430-JTAG-Tiny debugger provides a
# ttyACM interface, which is only available until the first flashing. A
# `make term` or even a `make flash term` may pick the JTAG debugger instead
# of the correct USB TTL adapter when the JTAG programmer is plugged in after
# the TTL adapter and `MOST_RECENT_PORT=1` is used.
#
# To fix that, we filter first by the most common USB TTL adapter drivers and
# fall back to all TTY when no such TTL adapter is found.
TTY_BOARD_FILTER := --driver 'cp210x|ch341|ftdi_sio'
TTY_SELECT_CMD := $(RIOTTOOLS)/usb-serial/ttys.py \
--most-recent \
--format path serial \
$(TTY_BOARD_FILTER) || \
$(RIOTTOOLS)/usb-serial/ttys.py \
--most-recent \
--format path serial

View File

@ -0,0 +1,97 @@
/**
@defgroup boards_olimex_msp430_h1611 Olimex MSP430-H1611
@ingroup boards
@brief Support for the Olimex MSP430-H1611 board
<img src="https://github.com/maribu/images/raw/master/Olimex%20MSP430-H1611.jpeg" alt="Photo of Olimex MSP430-H1611 Board" style="width: 512px; max-width: 100%;">
## MCU
| MCU | TI MSP430F1611 |
|:----------------- |:------------------------------------------------------------- |
| Family | MSP430 |
| Vendor | Texas Instruments |
| Package | 64 QFN |
| RAM | 10 KiB |
| Flash | 48 KiB |
| Frequency | 8 MHz |
| FPU | no |
| Timers | 2 (2x 16bit) |
| ADCs | 1x 8 channel 12-bit |
| UARTs | 2 |
| SPIs | 2 |
| I2Cs | 1 |
| Vcc | 2.0V - 3.6V |
| Datasheet MCU | [Datasheet](https://www.ti.com/product/MSP430F1611) |
| User Guide MCU | [User Guide](https://www.ti.com/lit/ug/slau049f/slau049f.pdf) |
| Datasheet Board | [MSP430-H1611 Datasheet](https://www.olimex.com/Products/MSP430/Header/_resources/MSP430-Hxxx-e.pdf) |
| Website | [MSP430-H1611 Website](https://www.olimex.com/Products/MSP430/Header/MSP430-H1611/) |
## Schematics
<img src="https://www.olimex.com/Products/MSP430/Header/_resources/MSP430-Hxxx-sch.gif" alt="Schematics of the Olimex MSP430-H1611 Board" style="max-width: 100%;">
## Pinout
The 64 pins on the edges of the PCB are connected to the corresponding MCU pins.
Hence, the following pinout of the naked MSP430-F1611 MCU chip matches the
pinout of the header board:
<img src="https://github.com/maribu/images/raw/master/MSP430F1611%20Pinout.svg" alt="Pinout of the naked MSP430-F1611 MCU" style="width: 512px; max-width: 100%;">
## Flashing RIOT
<img src="https://github.com/maribu/images/raw/master/Olimex%20MSP430-H1611%20with%20Debugger.jpeg" alt="Photo of Olimex MSP430-H1611 Board connected to a JTAG Debugger" style="width: 512px; max-width: 100%;">
Connect the board to a JTAG debugger supported by
[mspdebug](https://dlbeer.co.nz/mspdebug/); by default the
Olimex MSP430-JTAG-Tiny (as shown in the picture above) is assumed, which is
among the less expensive options.
@note If you are not using the Olimex MSP430-JTAG-Tiny (or a compatible
programmer), set `MSPDEBUG_PROGRAMMER` to the correct value via
an environment variable or as parameter to make. E.g. use
`make BOARD=olimex-msp430-h1611 MSPDEBUG_PROGRAMMER=bus-pirate` to
flash using the bus pirate.
@warning You can power the board via the JTAG programmer by placing a
jumper at `P_IN`. However, the JTAG programmer will only be able
to provide a limited current. You may want to disconnect the
header board from devices consuming a lot of power prior to
flashing.
@warning If the board is powered externally, make sure to place the jumper
in `P_OUT` position, not in `P_IN` position.
@warning A jumper in `P_OUT` is mutually exclusive to a jumper in `P_IN`.
Never connect both at the same time.
@note While the JTAG connector has no markings, you can easily spot pin 1
on to bottom of the board by the square pad; all other JTAG pins
have a circular pad.
Once the jumper is correctly placed in either `P_IN` or in `P_OUT` and the
JTAG cable is connected just run
```
make BOARD=olimex-msp430-h1611 flash
```
## Using the shell
stdio is available via the UART interface with `TXD = P3.6`
(pin 35 on the header) and `RXD = P3.7` (pin 34 on the header) at 115,200 Baud.
The easiest way is to connect an USB TTL adapter (such as the cheap `cp210x`
or `ch341` based adapters) as follows:
```
TTL adapter Olimex MSP430-H1611
----------- -------------------
GND --- 63 (DV_SS)
TXD --- 35 (P3.7)
RXD --- 34 (P3.6)
```
*/

View File

@ -0,0 +1,22 @@
/*
* Copyright (C) 2014 INRIA
*
* 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.
*/
#ifndef BOARD_CONF_H
#define BOARD_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
#define INFOMEM (0x1000)
#ifdef __cplusplus
}
#endif
#endif /* BOARD_CONF_H */

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2013, 2014 INRIA
* 2015 Freie Universität Berlin
*
* 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.
*/
/**
* @ingroup boards_olimex_msp430_h1611
*
* @{
*
* @file
* @brief Basic definitions for the Olimex MSP430-H1611 board
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef BOARD_H
#define BOARD_H
#include "cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Define the CPU model for the <msp430.h>
*/
#ifndef __MSP430F1611__
#define __MSP430F1611__
#endif
/**
* @name Xtimer configuration
* @{
*/
#define XTIMER_WIDTH (16)
#define XTIMER_BACKOFF (40)
/** @} */
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* BOARD_H */

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2014 INRIA
* 2015 Freie Universität Berlin
*
* 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.
*/
/**
* @ingroup boards_olimex_msp430_h1611
* @{
*
* @file
* @brief Olimex-MSP430-H1611 peripheral configuration
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef PERIPH_CONF_H
#define PERIPH_CONF_H
#include "periph_cpu.h"
#include "macros/units.h"
#ifdef __cplusplus
extern "C" {
#endif
#define CLOCK_CORECLOCK msp430_fxyz_dco_freq
/**
* @brief Clock configuration
*/
static const msp430_fxyz_clock_params_t clock_params = {
.target_dco_frequency = MHZ(8),
.lfxt1_frequency = 32768,
.main_clock_source = MAIN_CLOCK_SOURCE_DCOCLK,
.submain_clock_source = SUBMAIN_CLOCK_SOURCE_DCOCLK,
.main_clock_divier = MAIN_CLOCK_DIVIDE_BY_1,
.submain_clock_divier = SUBMAIN_CLOCK_DIVIDE_BY_1,
.auxiliary_clock_divier = AUXILIARY_CLOCK_DIVIDE_BY_1,
};
/**
* @name Timer configuration
* @{
*/
#define TIMER_NUMOF (1U)
#define TIMER_BASE (TIMER_A)
#define TIMER_CHAN (3)
#define TIMER_ISR_CC0 (TIMERA0_VECTOR)
#define TIMER_ISR_CCX (TIMERA1_VECTOR)
/** @} */
/**
* @name UART configuration
* @{
*/
#define UART_NUMOF (1U)
#define UART_BASE (USART_1)
#define UART_IE (SFR->IE2)
#define UART_IF (SFR->IFG2)
#define UART_IE_RX_BIT (1 << 4)
#define UART_IE_TX_BIT (1 << 5)
#define UART_ME (SFR->ME2)
#define UART_ME_BITS (0x30)
#define UART_PORT (PORT_3)
#define UART_RX_PIN (1 << 6)
#define UART_TX_PIN (1 << 7)
#define UART_RX_ISR (USART1RX_VECTOR)
#define UART_TX_ISR (USART1TX_VECTOR)
/** @} */
/**
* @name SPI configuration
* @{
*/
#define SPI_NUMOF (1U)
/* SPI configuration */
#define SPI_BASE (USART_0)
#define SPI_IE (SFR->IE1)
#define SPI_IF (SFR->IFG1)
#define SPI_IE_RX_BIT (1 << 6)
#define SPI_IE_TX_BIT (1 << 7)
#define SPI_ME (SFR->ME1)
#define SPI_ME_BIT (1 << 6)
#define SPI_PIN_MISO GPIO_PIN(P3, 2)
#define SPI_PIN_MOSI GPIO_PIN(P3, 1)
#define SPI_PIN_CLK GPIO_PIN(P3, 3)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* PERIPH_CONF_H */
/** @} */

View File

@ -11,8 +11,6 @@
#include "cpu.h"
#include "periph_conf.h"
void uart_init(void);
static void telosb_ports_init(void)
{
/* Port 1: GDO, Flash, BSL TX */
@ -46,79 +44,7 @@ static void telosb_ports_init(void)
}
/*---------------------------------------------------------------------------*/
/* 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, continuous mode */
while (1) {
unsigned int compare;
while ((CCTL2 & CCIFG) != CCIFG); /* Wait until capture occurred!*/
CCTL2 &= ~CCIFG; /* Capture occurred, 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)
{
/* disable watchdog timer */
WDTCTL = WDTPW + WDTHOLD;
telosb_ports_init();
msp430_init_dco();
/* enable interrupts */
__bis_SR_register(GIE);
}

View File

@ -21,23 +21,27 @@
#ifndef PERIPH_CONF_H
#define PERIPH_CONF_H
#include "macros/units.h"
#include "periph_cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Clock configuration
* @{
*/
#define CLOCK_CORECLOCK (2457600U)
#define MSP430_INITIAL_CPU_SPEED 2457600uL
#define F_CPU MSP430_INITIAL_CPU_SPEED
#define F_RC_OSCILLATOR 32768
#define MSP430_HAS_DCOR 0
#define MSP430_HAS_EXTERNAL_CRYSTAL 1
#define CLOCK_CORECLOCK msp430_fxyz_dco_freq
#define CLOCK_CMCLK CLOCK_CORECLOCK /* no divider programmed */
/** @} */
/**
* @brief Clock configuration
*/
static const msp430_fxyz_clock_params_t clock_params = {
.target_dco_frequency = 2457600U,
.lfxt1_frequency = 32768,
.main_clock_source = MAIN_CLOCK_SOURCE_DCOCLK,
.submain_clock_source = SUBMAIN_CLOCK_SOURCE_DCOCLK,
.main_clock_divier = MAIN_CLOCK_DIVIDE_BY_1,
.submain_clock_divier = SUBMAIN_CLOCK_DIVIDE_BY_1,
.auxiliary_clock_divier = AUXILIARY_CLOCK_DIVIDE_BY_1,
};
/**
* @name Timer configuration

View File

@ -116,99 +116,10 @@ static void z1_ports_init(void)
}
/*---------------------------------------------------------------------------*/
/* taken from Contiki code */
void msp430_init_dco(void)
{
#ifdef CALIBRATE_MSP430_DCO
#define DELTA (F_CPU / (F_RC_OSCILLATOR / 8))
/* This code taken from the FU Berlin sources and reformatted. */
unsigned int oldcapture = 0;
unsigned int i;
/* 10100100 = XT2 is off, ACLK divided by 4, RSELx=4 */
BCSCTL1 = XT2OFF | DIVA_3 | 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 */
__nop();
}
CCTL2 = CCIS0 + CM0 + CAP; /* Define CCR2, CAP, ACLK */
TACTL = TASSEL1 + TACLR + MC1; /* SMCLK, continuous mode */
while (1) {
unsigned int compare;
while ((CCTL2 & CCIFG) != CCIFG); /* Wait until capture occurred!*/
CCTL2 &= ~CCIFG; /* Capture occurred, 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 divisor from ACLK again */
/*
* On a MSP430F2617 (as on a Z1), for a 8 MHz target frequency,
* we normally obtain these values:
* DCOCTL == 0x9a (i.e.: DCOx == 4 && MODx == 26)
* [the MODx field is the most prone to variation]
* BCSCTL1 == 0x0d (i.e.: RSELx == 13)
*/
#else
/* default values for quick start-up */
DCOCTL = 0x00; /* avoid possible temporary overclocking... */
BCSCTL1 = 0x8d; /* as seen in Contiki code */
DCOCTL = 0x88; /* as seen in Contiki code */
#endif
/* Other clock configuration */
BCSCTL1 |= XT2OFF; /* XT2 not connected on Z1 */
BCSCTL2 = 0; /* get MCLK and SMCLK from DCO, without divisor */
BCSCTL3 = XCAP_1; /* default value for LFXT1 capacitor and frequency */
}
/* "public" specific initialization function for the Zolertia Z1 hardware */
void board_init(void)
{
/* disable watchdog timer */
WDTCTL = WDTPW + WDTHOLD;
/* init MCU pins as adequate for Z1 hardware */
z1_ports_init();
/* initializes DCO */
msp430_init_dco();
/* enable interrupts */
__bis_SR_register(GIE);
}

View File

@ -58,20 +58,6 @@ extern "C" {
#define CONFIG_ZTIMER_USEC_ADJUST_SLEEP (100)
/** @} */
/**
* @name CPU core configuration
* @{
*/
/** @todo Move this to the periph_conf.h */
#define MSP430_INITIAL_CPU_SPEED 8000000uL
#ifndef F_CPU
#define F_CPU MSP430_INITIAL_CPU_SPEED
#endif
#define F_RC_OSCILLATOR 32768
#define MSP430_HAS_DCOR 0
#define MSP430_HAS_EXTERNAL_CRYSTAL 1
/** @} */
/**
* @name LED pin definitions and handlers
* @{

View File

@ -21,19 +21,27 @@
#ifndef PERIPH_CONF_H
#define PERIPH_CONF_H
#include "macros/units.h"
#include "periph_cpu.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Clock configuration
* @{
*/
/** @todo Move all clock configuration code here from the board.h */
#define CLOCK_CORECLOCK (8000000U)
#define CLOCK_CORECLOCK MHZ(8)
#define CLOCK_CMCLK CLOCK_CORECLOCK /* no divider programmed */
/** @} */
/**
* @brief Clock configuration
*/
static const msp430_fxyz_clock_params_t clock_params = {
.xt2_frequency = CLOCK_CORECLOCK,
.lfxt1_frequency = 32768,
.main_clock_source = MAIN_CLOCK_SOURCE_XT2CLK,
.submain_clock_source = SUBMAIN_CLOCK_SOURCE_XT2CLK,
.main_clock_divier = MAIN_CLOCK_DIVIDE_BY_1,
.submain_clock_divier = SUBMAIN_CLOCK_DIVIDE_BY_1,
.auxiliary_clock_divier = AUXILIARY_CLOCK_DIVIDE_BY_1,
};
/**
* @name Timer configuration

View File

@ -45,6 +45,7 @@
#include "cpu.h"
#include "irq.h"
#include "periph/init.h"
#include "periph_cpu.h"
/*---------------------------------------------------------------------------*/
static void
@ -108,6 +109,7 @@ void msp430_cpu_init(void)
{
irq_disable();
init_ports();
clock_init();
irq_enable();
}
/*---------------------------------------------------------------------------*/

360
cpu/msp430fxyz/clock.c Normal file
View File

@ -0,0 +1,360 @@
/*
* Copyright (C) 2014 INRIA
* 2023 Otto-von-Guericke-Universität Magdeburg
*
* 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.
*/
/**
* @ingroup cpu_msp430fxyz
* @{
* @file
* @brief MSP430Fxzy clock initialization
*
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
*
* @}
*/
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "debug.h"
#include "macros/math.h"
#include "macros/units.h"
#include "periph_conf.h"
#include "periph_cpu.h"
#define RSEL_MASK (RSEL0 | RSEL1 | RSEL2)
uint32_t msp430_fxyz_dco_freq;
static inline bool is_dco_in_use(const msp430_fxyz_clock_params_t *params)
{
return ((params->main_clock_source == MAIN_CLOCK_SOURCE_DCOCLK) ||
(params->submain_clock_source == SUBMAIN_CLOCK_SOURCE_DCOCLK));
}
/* As low speed crystal only a standard 32.768 kHz watch crystal is allowed */
static inline bool is_valid_low_freq(uint32_t freq) {
return (freq == 32768);
}
/* As high speed crystal anything between 450 kHz and 8 MHz is allowed */
static inline bool is_valid_high_freq(uint32_t freq) {
return ((freq >= KHZ(450)) && (freq <= MHZ(8)));
}
/* C doesn't have constexpr() or an equivalent feature to perform complex
* compile time tests. To still do so, we rely on constant folding and dead
* code elimination:
* If a test doesn't pass, we call an undefined function with a meaningful
* name as "error message". If that call is optimized out (because the
* configuration test passes), the linking step passes. If the config is
* invalid, the function call will not be optimized out and the linker will not
* be able to resolve all symbols, resulting in invalid configs being caught
* at compile time. */
static void check_config(void)
{
/* LFXT1 can either be a low frequency 32.768 kHz watch crystal or a
* high frequency crustal between 450 kHz and 8 MHz. We cannot function
* without this crystal */
if (!is_valid_low_freq(clock_params.lfxt1_frequency)
&& !is_valid_high_freq(clock_params.lfxt1_frequency)) {
extern void lfxt1_frequency_invalid(void);
lfxt1_frequency_invalid();
}
/* XT2 is not required and may be configured as 0 Hz to indicate its
* absence. If it is present, we require 450 kHz <= XT <= 8 MHz */
if ((clock_params.xt2_frequency != 0) &&
!is_valid_high_freq(clock_params.xt2_frequency)) {
extern void xt2_frequency_invalid(void);
xt2_frequency_invalid();
}
/* XT2 can only source the main system clock if it is present */
if ((clock_params.main_clock_source == MAIN_CLOCK_SOURCE_XT2CLK)
&& (clock_params.xt2_frequency == 0)) {
extern void xt2_as_main_clock_source_selected_but_xt2_is_not_present(void);
xt2_as_main_clock_source_selected_but_xt2_is_not_present();
}
/* If the DCO is disabled (0 Hz), we cannot use it as clock source */
if (is_dco_in_use(&clock_params)
&& (clock_params.target_dco_frequency == 0)) {
extern void dco_configured_as_clock_source_but_is_disabled(void);
dco_configured_as_clock_source_but_is_disabled();
}
}
static void busy_wait(uint16_t loops)
{
while (loops) {
/* This empty inline assembly should be enough to convince the
* compiler that the loop cannot be optimized out. Tested with
* GCC 12.2 and clang 16.0.0 successfully. */
__asm__ __volatile__ (
""
: /* no outputs */
: /* no inputs */
: /* no clobbers */
);
loops--;
}
}
static void wait_for_crystals_to_stabilize(void)
{
/* The MSP430x1xx MCU family have an oscillator fault detector that sets
* the OFIFG flag when a fault is detected, which can trigger an IRQ
* and/or be polled in software. We go for polling here.
*
* There are some foot guns to take into account:
*
* 1. The LFXT1 clock is only monitored in high speed mode. So for the
* typical setup of using a 32.768 kHz watch crystal one can only wait
* for some preconfigured static value and hope this was long enough
* to stabilize. (But that seems to work fine in practise.)
* 2. If no high speed crystal is in use (e.g. LFXT1 is used with a
* watch crystal and XT2 is not connected), the fault flag will
* stick and cannot be cleared. Waiting for the flag to clear would
* result in getting stuck during boot.
*
* Because of 1, we go for best effort by just waiting UINT16_MAX busy
* loops for the watch crystal to stabilize. This is common practise and
* seems to work just fine.
* Because of 2 we don't wait for OFIFG if no high speed crystal is in use.
*
* We wait for watch crystal first, as chances are good that by then the
* high speed crystal (if any) is stable or about to become stable as well,
* so that the second wait is fast.
*/
if (is_valid_low_freq(clock_params.lfxt1_frequency)) {
/* wait best effort for watch crystal to stabilize */
busy_wait(UINT16_MAX);
}
if (is_valid_high_freq(clock_params.lfxt1_frequency)
|| is_valid_high_freq(clock_params.xt2_frequency)) {
/* at least one high frequency crystal present, wait for that to
* stabilize */
do {
/* Clear oscillator fault flag */
IFG1 &= ~(OFIFG);
/* Now wait for at least 50 μs so that the oscillator fault flag is
* reliably set again if the oscillators are not stable yet.
* The datasheet indicates that counting down form UINT8_MAX when
* running from DCO with default settings (as during boot) is taking
* at least 50 μs */
busy_wait(UINT8_MAX);
/* Finally, check if the oscillator fault flag was reset by hardware */
} while (IFG1 & OFIFG);
}
}
static void calibrate_dco(void)
{
/* We assume that the LFXT1 frequency is stable. Now we compute what the
* ratio of the (unstable) DCO frequency to the stable LFXT1 frequency
* (available as auxiliary clock with a clock divider of 8) and use a timer
* to capture the actual clock ratio */
const uint16_t clock_ratio = DIV_ROUND(clock_params.target_dco_frequency,
(clock_params.lfxt1_frequency / 8));
/* The CCI2B input on capture/compare unit 2 of timer A has the auxiliary
* clock as internal input. Hence, for every tick of the auxiliary clock
* we will get one capture of the continuously running timer. The diff
* of two subsequent captures matches then the actual clock ratio. */
TACCTL2 = CCIS_1 /* CCI2B as capture input */
| CM_1 /* capture on rising edge */
| CAP; /* capture mode instead of compare mode */
/* configure timer A to run from submain clock, which now is sourced
* by DCO without divider*/
TACTL = TASSEL_2 /* submain clock (DCO) as source */
| TACLR /* clear timer */
| MC_2; /* continuous mode, count up to UINT16_MAX */
/* First, binary search for the correct RSELx settings (which have a
* higher impact on the actual frequency than the DCOCTL settings).
* We're starting with a highest bit. */
uint8_t bcsctl1 = BCSCTL1 & ~(RSEL_MASK);
uint8_t rselx = 0;
for (uint8_t iter = 0x04; iter != 0; iter >>= 1) {
BCSCTL1 = bcsctl1 | rselx | iter;
/* busy wait for timer to capture */
while (!(TACCTL2 & CCIFG)) { }
/* clear capture flag */
TACCTL2 &= ~CCIFG;
uint16_t start = TACCR2;
/* busy wait for timer to capture */
while (!(TACCTL2 & CCIFG)) { }
/* clear capture flag */
TACCTL2 &= ~CCIFG;
uint16_t stop = TACCR2;
uint16_t actual_clock_ratio = stop - start;
if (actual_clock_ratio <= clock_ratio) {
/* DCO too slow, or just fast enough --> keep the bit */
rselx |= iter;
}
}
/* Now do the same dance again, but for DCOCTL */
uint8_t dcoctl = 0;
uint16_t actual_clock_ratio;
for (uint8_t iter = 0x80; iter != 0; iter >>= 1) {
DCOCTL = dcoctl | iter;
/* busy wait for timer to capture */
while (!(TACCTL2 & CCIFG)) { }
/* clear capture flag */
TACCTL2 &= ~CCIFG;
uint16_t start = TACCR2;
/* busy wait for timer to capture */
while (!(TACCTL2 & CCIFG)) { }
/* clear capture flag */
TACCTL2 &= ~CCIFG;
uint16_t stop = TACCR2;
actual_clock_ratio = stop - start;
if (actual_clock_ratio <= clock_ratio) {
/* DCO too slow, or just fast enough --> keep the bit */
dcoctl |= iter;
}
}
/* stopping timer used fore calibration */
TACCTL2 = 0;
TACTL = 0;
/* calculate actual DCO frequency */
msp430_fxyz_dco_freq = (clock_params.lfxt1_frequency * actual_clock_ratio) >> 3;
}
void default_clock_init(void)
{
/* This function contains only dead code and the call should be fully
* optimized out by the compiler. In fact, we rely on this: If it is
* not fully optimized out, we will get linker errors. */
check_config();
#ifdef __MSP430_HAS_WDT__
/* Stopping watchdog timer, clock initialization may take a while. */
WDTCTL = WDTPW | WDTHOLD;
#endif
/* set LFXT1 and XT2 hardware settings, keep RSEL to reset value (only
* RSEL 2 bit set) */
uint8_t bcsctl1 = RSEL2;
if (clock_params.xt2_frequency == 0) {
bcsctl1 |= XT2OFF;
}
if (clock_params.lfxt1_frequency > 32768) {
bcsctl1 |= XTS;
}
/* We want to calibrate DCO against the auxiliary clock domain, which is
* hardwired to use LFXT1 as clock source. Because LFXT1 is always using
* a crystal (and mostly even an accurate watch crystal), we can assume
* that the auxiliary clock to be accurate (enough). The algorithm we
* use for clock calibration assumes that multiple DCO ticks match one
* tick on the auxiliary clock. We use the highest possible clock divider
* for now, to increase the range this works. */
if (clock_params.target_dco_frequency != 0) {
bcsctl1 |= AUXILIARY_CLOCK_DIVIDE_BY_8;
}
BCSCTL1 = bcsctl1;
uint8_t bcsctl2 = 0;
if (clock_params.has_r_osc) {
bcsctl2 = DCOR;
}
BCSCTL2 = bcsctl2;
/* In case we run from a crystal, we need that to stabilize. If we run from
* DCO instead, we also need the crystals to become stable so that we can
* calibrate the DCO against it.
* ==> Wait for crystal to be stable regardless of config */
wait_for_crystals_to_stabilize();
/* If a target DCO frequency was configured, we calibrate the DCO to run at
* that - even if the DCO is not used to source either main or submain
* clock. The application may switch the clock source later on to DCO, e.g.
* to run by default at a low clock to reduce power consumption and go to
* "turbo mode" for event processing */
if (clock_params.target_dco_frequency != 0) {
calibrate_dco();
}
/* Crystals are now stable and the DCO has been calibrated, if the
* board config asked for a calibrated DCO clock. We can now safely
* apply the clock sources and also apply the clock dividers */
/* BCSCTL1 contains now freshly calibrated RSELx parameters in addition
* to the auxiliary clock divider we used for calibration. We read the
* settings back and clear the clock divider to apply the one provided
* by the board settings. */
bcsctl1 = BCSCTL1 & ~(AUXILIARY_CLOCK_DIVIDE_BY_8);
BCSCTL1 = bcsctl1 | clock_params.auxiliary_clock_divier;
/* apply main and submain clock source and clock dividers */
BCSCTL2 = bcsctl2
| clock_params.main_clock_source
| clock_params.submain_clock_source
| clock_params.main_clock_divier
| clock_params.submain_clock_divier;
/* if DCO is not used at all, disable it to preserve power */
if (clock_params.target_dco_frequency == 0) {
/* Setting bit SCG0 in the status register (r2) disables the DCO.
* We do so in assembly, as r2 is not memory mapped. */
__asm__ __volatile__ (
"bis %[scg0], r2" "\n\t"
: /* no outputs */
: /* inputs: */
[scg0] "i"(SCG0) /* bitmask to set SCGO0 as immediate */
: /* no clobbers */
);
}
}
__attribute__((weak, alias("default_clock_init"))) void clock_init(void);
uint32_t msp430_fxyz_submain_clock_freq(void) {
uint16_t shift = (clock_params.submain_clock_divier >> 1) & 0x3;
switch (clock_params.submain_clock_source) {
case SUBMAIN_CLOCK_SOURCE_LFXT1CLK:
/* the submain clock cannot explicitly select LFXT1 or XT2, but really
* is "crystal" or DCO. If the selection is "crystal", it will default
* to XT2 as clock source (if enabled) and falls back to LFXT1. */
if (clock_params.xt2_frequency) {
return clock_params.xt2_frequency >> shift;
}
return clock_params.lfxt1_frequency >> shift;
default:
case SUBMAIN_CLOCK_SOURCE_DCOCLK:
return msp430_fxyz_dco_freq >> shift;
}
}
uint32_t msp430_fxyz_auxiliary_clock_freq(void)
{
uint16_t shift = (clock_params.auxiliary_clock_divier >> 4) & 0x3;
return clock_params.lfxt1_frequency >> shift;
}

View File

@ -22,6 +22,8 @@
#define PERIPH_CPU_H
#include <stdbool.h>
#include "bitarithm.h"
#include "cpu.h"
#include "msp430_regs.h"
@ -132,6 +134,249 @@ void gpio_periph_mode(gpio_t pin, bool enable);
#define PERIPH_SPI_NEEDS_TRANSFER_REGS
/** @} */
/**
* @brief The measured DCO frequency
*
* @warning This will have a value of 0 if the DCO is not enabled in the boards
* `periph_conf.h`
*/
extern uint32_t msp430_fxyz_dco_freq;
/**
* @brief Possible clock sources to generate the main clock from
*/
typedef enum {
/**
* @brief Internal digitally controlled oscillator (DCO) with RC-type
* characteristics.
*/
MAIN_CLOCK_SOURCE_DCOCLK = SELM_0,
/**
* @brief High frequency crystal between 450 kHz and 8 MHz
*
* @note If XT2 is not enabled, this will behave identical to
* @ref MAIN_CLOCK_SOURCE_LFXT1CLK
*/
MAIN_CLOCK_SOURCE_XT2CLK = SELM_2,
/**
* @brief Low frequency 32.768 kHz or high frequency crystal
* between 450 kHz and 8 MHz
*/
MAIN_CLOCK_SOURCE_LFXT1CLK = SELM_3,
} msp430_fxyz_main_clock_source_t;
/**
* @brief Possible clock sources to generate the submain clock from
*/
typedef enum {
/**
* @brief Internal digitally controlled oscillator (DCO) with RC-type
* characteristics.
*/
SUBMAIN_CLOCK_SOURCE_DCOCLK = 0,
/**
* @brief High frequency crystal between 450 kHz and 8 MHz
*
* @note If XT2 is not enabled, this will behave identical to
* @ref SUBMAIN_CLOCK_SOURCE_LFXT1CLK
*/
SUBMAIN_CLOCK_SOURCE_XT2CLK = SELS,
/**
* @brief Low frequency 32.768 kHz or high frequency crystal
* between 450 kHz and 8 MHz
*
* @note If XT2 is enabled, this will behave identical to
* @ref SUBMAIN_CLOCK_SOURCE_XT2CLK
*
* It is recommended to use @ref SUBMAIN_CLOCK_SOURCE_XT2CLK when XT2 is present
* in the config to avoid confusion.
*/
SUBMAIN_CLOCK_SOURCE_LFXT1CLK = SELS,
} msp430_fxyz_submain_clock_source_t;
/**
* @brief Clock dividers for the main clock
*/
typedef enum {
/**
* @brief Divide the main clock by 1
*/
MAIN_CLOCK_DIVIDE_BY_1 = DIVM_0,
/**
* @brief Divide the main clock by 2
*/
MAIN_CLOCK_DIVIDE_BY_2 = DIVM_1,
/**
* @brief Divide the main clock by 4
*/
MAIN_CLOCK_DIVIDE_BY_4 = DIVM_2,
/**
* @brief Divide the main clock by 8
*/
MAIN_CLOCK_DIVIDE_BY_8 = DIVM_3,
} msp430_fxyz_main_clock_divider_t;
/**
* @brief Clock dividers for the submain clock
*/
typedef enum {
/**
* @brief Divide the main clock by 1
*/
SUBMAIN_CLOCK_DIVIDE_BY_1 = DIVS_0,
/**
* @brief Divide the main clock by 2
*/
SUBMAIN_CLOCK_DIVIDE_BY_2 = DIVS_1,
/**
* @brief Divide the main clock by 4
*/
SUBMAIN_CLOCK_DIVIDE_BY_4 = DIVS_2,
/**
* @brief Divide the main clock by 8
*/
SUBMAIN_CLOCK_DIVIDE_BY_8 = DIVS_3,
} msp430_fxyz_submain_clock_divider_t;
/**
* @brief Clock dividers for the auxiliary clock
*/
typedef enum {
/**
* @brief Divide the main clock by 1
*/
AUXILIARY_CLOCK_DIVIDE_BY_1 = DIVA_0,
/**
* @brief Divide the main clock by 2
*/
AUXILIARY_CLOCK_DIVIDE_BY_2 = DIVA_1,
/**
* @brief Divide the main clock by 4
*/
AUXILIARY_CLOCK_DIVIDE_BY_4 = DIVA_2,
/**
* @brief Divide the main clock by 8
*/
AUXILIARY_CLOCK_DIVIDE_BY_8 = DIVA_3,
} msp430_fxyz_auxiliary_clock_divider_t;
/**
* @brief MSP430Fxzy Basic Clock System Parameters
*
* @details This structure is optimized for readability under the assumption
* that its values are readily available compile time constants.
* Hence, accesses to the structure will be fully optimized out be
* a decent optimizing compiler.
*
* MSP430Fxzy boards are expected to declare the parameters to configure the
* Basic Clock System in their `periph_conf.h` as
* `static const msp430_fxzy_clock_params_t clock_params;`.
*/
typedef struct {
/**
* @brief The target frequency to run the DCO at in Hz
*
* A frequency between 160 kHz and 4 MHz is enforced by compile time tests
* to make sure DCO calibration will succeed reliable.
*/
uint32_t target_dco_frequency;
/**
* @brief The frequency of the LFXT1 crystal in Hz
*
* This should be either 32768 Hz watch crystal or a high frequency
* crystal anywhere between 450 kHz and 8 MHz. The clock driver will
* automatically configure high frequency mode of the LFXT1 clock source
* when the frequency is >= 450 kHz.
*/
uint32_t lfxt1_frequency;
/**
* @brief The frequency of the XT2 crystal in Hz
*
* A value of 0 Hz means no XT2 crystal is present. Otherwise the frequency
* must be anywhere between 450 kHz and 8 MHz.
*/
uint32_t xt2_frequency;
/**
* @brief The clock source to select for the main clock
*
* @details This is the clock the CPU will run at
*/
msp430_fxyz_main_clock_source_t main_clock_source;
/**
* @brief The clock source to select for the submain CPU clock
*
* @details This is the clock high speed peripherals will run at
*/
msp430_fxyz_submain_clock_source_t submain_clock_source;
/**
* @brief Divider of the main clock
*/
msp430_fxyz_main_clock_divider_t main_clock_divier;
/**
* @brief Divider of the submain clock
*/
msp430_fxyz_submain_clock_divider_t submain_clock_divier;
/**
* @brief Divider of the auxiliary clock
*/
msp430_fxyz_auxiliary_clock_divider_t auxiliary_clock_divier;
/**
* @brief An external resistor connected to source the current for the DCO
*
* From the datasheet:
*
* > The DCO temperature coefficient can be reduced by using an external
* > resistor R_OSC tied to D_VCC to source the current for the DC generator.
*/
bool has_r_osc;
/**
* @brief A high frequency crystal (e.g. 8 MHz) is connected between
* XT2IN and XT2OUT
*/
bool has_xt2;
} msp430_fxyz_clock_params_t;
/**
* @brief Initialize the basic clock system to provide the main clock,
* the subsystem clock, and the auxiliary clock.
*
* The main clock, the subsystem clock, and the auxiliary clock will be set up
* as specified by `static const msp430_fxyz_clock_params_t clock_params` in
* the `periph_conf.h` of the board.
*
* @note This function takes some time and typically is only called during
* boot.
*
* @post The main clock, the subsystem clock and the auxiliary clock are
* are set up and stable
*/
void default_clock_init(void);
/**
* @brief Call during boot up process to initialize the clock
*
* @note This is a weak alias for @ref default_clock_init so that this can
* be overwritten with a strong symbol from the board in case some
* special handling is required. The boards custom `clock_init()` can
* still call @ref default_clock_init if that is useful; or it could
* do everything from scratch.
*/
void clock_init(void);
/**
* @brief Get the configured submain clock frequency
*
* @note This is only useful when implementing MSP430 peripheral drivers
*/
uint32_t msp430_fxyz_submain_clock_freq(void);
/**
* @brief Get the configured auxiliary clock frequency
*
* @note This is only useful when implementing MSP430 peripheral drivers
*/
uint32_t msp430_fxyz_auxiliary_clock_freq(void);
#ifdef __cplusplus
}
#endif

View File

@ -77,7 +77,7 @@ void spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
mutex_lock(&spi_lock);
/* calculate baudrate */
uint32_t br = CLOCK_CMCLK / clk;
uint32_t br = msp430_fxyz_submain_clock_freq() / clk;
/* make sure the is not smaller then 2 */
if (br < 2) {
br = 2;

View File

@ -72,7 +72,7 @@ static int init_base(uart_t uart, uint32_t baudrate)
dev->TCTL = (USART_TCTL_TXEPT | USART_TCTL_SSEL_SMCLK);
dev->RCTL = 0x00;
/* baudrate configuration */
uint16_t br = (uint16_t)(CLOCK_CMCLK / baudrate);
uint16_t br = (uint16_t)(msp430_fxyz_submain_clock_freq() / baudrate);
dev->BR0 = (uint8_t)br;
dev->BR1 = (uint8_t)(br >> 8);
/* TODO: calculate value for modulation register */
@ -165,7 +165,7 @@ static int init_base(uart_t uart, uint32_t baudrate)
dev->ACTL0 = 0;
dev->ASTAT = 0;
/* configure baudrate */
uint32_t base = ((CLOCK_CMCLK << 7) / baudrate);
uint32_t base = ((msp430_fxyz_submain_clock_freq() << 7) / baudrate);
uint16_t br = (uint16_t)(base >> 7);
uint8_t brs = (((base & 0x3f) * 8) >> 7);
dev->ABR0 = (uint8_t)br;

View File

@ -1415,7 +1415,6 @@ warning: Member CLOCK_APB1 (macro definition) of file cfg_clock_default.h is not
warning: Member CLOCK_APB2 (macro definition) of file cfg_clock_default.h is not documented.
warning: Member CLOCK_BUSCLOCK (macro definition) of file periph_conf_common.h is not documented.
warning: Member CLOCK_BUSCLOCK (macro definition) of file periph_conf.h is not documented.
warning: Member CLOCK_CMCLK (macro definition) of file periph_conf.h is not documented.
warning: Member clock_config (variable) of file periph_conf_common.h is not documented.
warning: Member clock_config (variable) of file periph_conf.h is not documented.
warning: Member CLOCK_CORECLOCK (macro definition) of file board.h is not documented.

View File

@ -47,12 +47,11 @@ export RIOT_CI_BUILD=1
BOARD=$1
RIOTBASE="$(dirname "$0")/../../.."
APPLICATIONS="$APPLICATIONS examples/*/Makefile"
APPLICATIONS="$APPLICATIONS tests/*/Makefile"
TMPFILE="$(mktemp)"
for app in ${APPLICATIONS}; do
application="$(dirname "${app}")"
APPLICATIONS="${APPLICATIONS} $(make -sC "${RIOTBASE}" info-applications)"
for application in ${APPLICATIONS}; do
printf "${CNORMAL}%-40s${CRESET}" "${application}"
# disable warning about globbing and word splitting for ${LOCAL_MAKE_ARGS}
# as this is exactly what we want here

View File

@ -34,6 +34,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -24,6 +24,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -24,6 +24,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -20,6 +20,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -25,6 +25,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -38,6 +38,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -27,6 +27,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -21,6 +21,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -22,6 +22,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -42,6 +42,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -24,6 +24,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -47,6 +47,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l031k6 \
nucleo-l053r8 \
nucleo-l073rz \
olimex-msp430-h1611 \
olimexino-stm32 \
opencm904 \
samd10-xmini \

View File

@ -23,6 +23,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -23,6 +23,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -17,6 +17,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -38,6 +38,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -19,6 +19,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -28,6 +28,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -21,6 +21,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -2,6 +2,7 @@ BOARD_INSUFFICIENT_MEMORY := \
bluepill-stm32f030c8 \
im880b \
nucleo-l011k4 \
olimex-msp430-h1611 \
olimexino-stm32 \
samd10-xmini \
slstk3400a \

View File

@ -2,6 +2,7 @@ BOARD_INSUFFICIENT_MEMORY := \
bluepill-stm32f030c8 \
im880b \
nucleo-l011k4 \
olimex-msp430-h1611 \
olimexino-stm32 \
samd10-xmini \
slstk3400a \

View File

@ -29,6 +29,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -15,6 +15,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -44,6 +44,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l031k6 \
nucleo-l053r8 \
nucleo-l073rz \
olimex-msp430-h1611 \
opencm904 \
samd10-xmini \
saml10-xpro \

View File

@ -34,6 +34,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -30,6 +30,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -26,6 +26,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -48,6 +48,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l031k6 \
nucleo-l053r8 \
nucleo-l073rz \
olimex-msp430-h1611 \
olimexino-stm32 \
opencm904 \
samd10-xmini \

View File

@ -35,6 +35,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -24,6 +24,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -24,6 +24,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -31,6 +31,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -19,6 +19,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -16,6 +16,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -12,6 +12,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -16,6 +16,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -18,6 +18,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -15,6 +15,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -49,6 +49,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l031k6 \
nucleo-l053r8 \
nucleo-l073rz \
olimex-msp430-h1611 \
olimexino-stm32 \
opencm904 \
samd10-xmini \

View File

@ -25,6 +25,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -22,6 +22,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -28,6 +28,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -23,6 +23,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -31,6 +31,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -33,6 +33,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -33,6 +33,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -38,6 +38,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -16,6 +16,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -20,6 +20,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -31,6 +31,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -9,6 +9,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -29,6 +29,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -11,6 +11,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -28,6 +28,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -31,6 +31,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -37,6 +37,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
saml10-xpro \
saml11-xpro \

View File

@ -22,6 +22,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
seeedstudio-gd32 \
slstk3400a \

View File

@ -16,6 +16,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -18,6 +18,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -21,6 +21,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -5,6 +5,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -11,6 +11,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -6,6 +6,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -17,6 +17,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -9,6 +9,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -15,6 +15,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4 \
nucleo-l031k6 \
nucleo-l053r8 \
olimex-msp430-h1611 \
samd10-xmini \
slstk3400a \
stk3200 \

View File

@ -48,6 +48,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l031k6 \
nucleo-l053r8 \
nucleo-l073rz \
olimex-msp430-h1611 \
olimexino-stm32 \
opencm904 \
samd10-xmini \

View File

@ -17,6 +17,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -17,6 +17,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-f042k6 \
nucleo-l011k4 \
nucleo-l031k6 \
olimex-msp430-h1611 \
samd10-xmini \
stk3200 \
stm32f030f4-demo \

View File

@ -10,9 +10,9 @@ BOARD_INSUFFICIENT_MEMORY := \
b-l072z-lrwan1 \
blackpill-stm32f103c8 \
blackpill-stm32f103cb \
bluepill-stm32f030c8 \
bluepill-stm32f103c8 \
bluepill-stm32f103cb \
bluepill-stm32f030c8 \
calliope-mini \
cc1312-launchpad \
cc1350-launchpad \
@ -71,6 +71,7 @@ BOARD_INSUFFICIENT_MEMORY := \
nucleo-l433rc \
nucleo-wl55jc \
nz32-sc151 \
olimex-msp430-h1611 \
olimexino-stm32 \
opencm904 \
openlabs-kw41z-mini-256kib \
@ -85,8 +86,8 @@ BOARD_INSUFFICIENT_MEMORY := \
samr30-xpro \
samr34-xpro \
seeedstudio-gd32 \
sipeed-longan-nano \
sensebox_samd21 \
sipeed-longan-nano \
slstk3400a \
slstk3401a \
sltb001a \