mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
19733: cpu/msp430: reorganize code r=maribu a=maribu ### Contribution description RIOT supports two distinct families of the MSP430: The [MSP430 x1xx] MCU family and the [MSP430 F2xx/G2xx] MCU family. For both incompatible MCU families the code was located in the msp430fxyz folder, resulting in case of the UART driver in particularly bizarre code looking roughly like this: ```C #ifndef UART_USE_USCI /* implementation of x1xx peripheral ... */ #else /* implementation of F2xx/G2xx peripheral ... */ #endif /* zero shared code between both variants */ ``` This moves peripheral drivers shared between the two families to msp430_common and splits the SPI and UART driver into two MCU families. In addition, it cleans up the `msp430_regs.h` by dropping most of it and using the macros and symbols provided by the vendor header files. There is little reason for us to maintain constants when TI is already doing that. [MSP430 x1xx]: https://www.ti.com/lit/ug/slau049f/slau049f.pdf [MSP430 F2xx/G2xx]: https://www.ti.com/lit/ug/slau144k/slau144k.pdf 19747: gnrc/ipv6/nib: reset rs_sent counter also for not-6LN interfaces r=maribu a=fabian18 19769: cpu/nrf53: add initial support with nRF5340DK-APP board r=maribu a=dylad ### Contribution description This PR adds support for nRF5340 MCU and its associated Nordic development board, nRF5340DK. This MCU provides a dual Cortex-M33, one application core running at up to 128MHz, and one network core running at up to 64MHz. Peripherals are inherited from others Nordic MCUs families so it shouldn't be hard to add more of them in followup PRs. For now, only the minimal set of peripherals is supported: - GPIO / GPIO_IRQ - UART - TIMER ### Testing procedure Build the usual test application for the supported peripherals and flash the board. nRF5340DK provides two serial ports on its embedded debugger. RIOT's shell should be available on the first one (/dev/ttyACM0) ### Issues/PRs references #18576 #19267 19782: cpu/msp430: fix for ti's msp430-gcc-opensource package ld version r=maribu a=hugueslarrive ### Contribution description My msp430 toolchain (https://www.ti.com/tool/MSP430-GCC-OPENSOURCE) was broken by #19484: ``` hugues@p700:~/github/cpu_msp430_common/RIOT$ BOARD=msb-430 make -j64 -C examples/hello-world make : on entre dans le répertoire « /home/hugues/github/cpu_msp430_common/RIOT/examples/hello-world » Building application "hello-world" for "msb-430" with MCU "msp430fxyz". "make" -C /home/hugues/github/cpu_msp430_common/RIOT/boards/common/init "make" -C /home/hugues/github/cpu_msp430_common/RIOT/boards/msb-430 "make" -C /home/hugues/github/cpu_msp430_common/RIOT/core "make" -C /home/hugues/github/cpu_msp430_common/RIOT/core/lib "make" -C /home/hugues/github/cpu_msp430_common/RIOT/cpu/msp430fxyz "make" -C /home/hugues/github/cpu_msp430_common/RIOT/drivers "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys "make" -C /home/hugues/github/cpu_msp430_common/RIOT/boards/common/msb-430 "make" -C /home/hugues/github/cpu_msp430_common/RIOT/drivers/periph_common "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/auto_init "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/div "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/libc "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/malloc_thread_safe "make" -C /home/hugues/github/cpu_msp430_common/RIOT/cpu/msp430_common "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/newlib_syscalls_default "make" -C /home/hugues/github/cpu_msp430_common/RIOT/cpu/msp430fxyz/periph "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/preprocessor "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/stdio_uart "make" -C /home/hugues/github/cpu_msp430_common/RIOT/cpu/msp430_common/periph /opt/ti/msp430-gcc/bin/../lib/gcc/msp430-elf/9.3.1/../../../../msp430-elf/bin/ld: .rodata not found for insert collect2: error: ld returned 1 exit status make: *** [/home/hugues/github/cpu_msp430_common/RIOT/examples/hello-world/../../Makefile.include:761 : /home/hugues/github/cpu_msp430_common/RIOT/examples/hello-world/bin/msb-430/hello-world.elf] Erreur 1 make : on quitte le répertoire « /home/hugues/github/cpu_msp430_common/RIOT/examples/hello-world » hugues@p700:~/github/cpu_msp430_common/RIOT$ /opt/ti/msp430-gcc/msp430-elf/bin/ld --version GNU ld (Mitto Systems Limited - msp430-gcc 9.3.1.11) 2.34 Copyright (C) 2020 Free Software Foundation, Inc. This program is free software; you may redistribute it under the terms of the GNU General Public License version 3 or (at your option) a later version. This program has absolutely no warranty. hugues@p700:~/github/cpu_msp430_common/RIOT$ /opt/ti/msp430-gcc/msp430-elf/bin/ld --version | grep -Eo '[0-9]\.[0-9]+' 9.3 1.11 2.34 hugues@p700:~/github/cpu_msp430_common/RIOT$ /opt/ti/msp430-gcc/msp430-elf/bin/ld --version | grep -Eo '[0-9]\.[0-9]+$' 2.34 ``` ### Testing procedure ``` hugues@p700:~/github/cpu_msp430_common/RIOT$ BOARD=msb-430 make -j64 -C examples/hello-world make : on entre dans le répertoire « /home/hugues/github/cpu_msp430_common/RIOT/examples/hello-world » Building application "hello-world" for "msb-430" with MCU "msp430fxyz". "make" -C /home/hugues/github/cpu_msp430_common/RIOT/boards/common/init "make" -C /home/hugues/github/cpu_msp430_common/RIOT/boards/msb-430 "make" -C /home/hugues/github/cpu_msp430_common/RIOT/core "make" -C /home/hugues/github/cpu_msp430_common/RIOT/core/lib "make" -C /home/hugues/github/cpu_msp430_common/RIOT/cpu/msp430fxyz "make" -C /home/hugues/github/cpu_msp430_common/RIOT/drivers "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys "make" -C /home/hugues/github/cpu_msp430_common/RIOT/boards/common/msb-430 "make" -C /home/hugues/github/cpu_msp430_common/RIOT/drivers/periph_common "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/auto_init "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/div "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/libc "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/malloc_thread_safe "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/newlib_syscalls_default "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/preprocessor "make" -C /home/hugues/github/cpu_msp430_common/RIOT/cpu/msp430_common "make" -C /home/hugues/github/cpu_msp430_common/RIOT/sys/stdio_uart "make" -C /home/hugues/github/cpu_msp430_common/RIOT/cpu/msp430fxyz/periph "make" -C /home/hugues/github/cpu_msp430_common/RIOT/cpu/msp430_common/periph text data bss dec hex filename 8612 722 866 10200 27d8 /home/hugues/github/cpu_msp430_common/RIOT/examples/hello-world/bin/msb-430/hello-world.elf make : on quitte le répertoire « /home/hugues/github/cpu_msp430_common/RIOT/examples/hello-world » ``` ### Issues/PRs references Introduced by #19484, highlighted in #16727. Co-authored-by: Marian Buschsieweke <marian.buschsieweke@posteo.net> Co-authored-by: Fabian Hüßler <fabian.huessler@ml-pa.com> Co-authored-by: Dylan Laduranty <dylan.laduranty@mesotic.com> Co-authored-by: Hugues Larrive <hlarrive@pm.me>
This commit is contained in:
commit
ddf1fe252d
@ -1,2 +1,2 @@
|
||||
CPU = msp430fxyz
|
||||
CPU = msp430
|
||||
CPU_MODEL = msp430f1612
|
||||
|
@ -28,12 +28,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CLOCK_CORECLOCK msp430_fxyz_dco_freq
|
||||
#define CLOCK_CORECLOCK msp430_dco_freq
|
||||
|
||||
/**
|
||||
* @brief Clock configuration
|
||||
*/
|
||||
static const msp430_fxyz_clock_params_t clock_params = {
|
||||
static const msp430_clock_params_t clock_params = {
|
||||
.target_dco_frequency = 7372800U,
|
||||
.lfxt1_frequency = 32768,
|
||||
.main_clock_source = MAIN_CLOCK_SOURCE_DCOCLK,
|
||||
@ -49,7 +49,7 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_BASE (TIMER_A)
|
||||
#define TIMER_BASE (&TIMER_A)
|
||||
#define TIMER_CHAN (3)
|
||||
#define TIMER_ISR_CC0 (TIMERA0_VECTOR)
|
||||
#define TIMER_ISR_CCX (TIMERA1_VECTOR)
|
||||
@ -61,14 +61,12 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
*/
|
||||
#define UART_NUMOF (1U)
|
||||
|
||||
#define UART_BASE (USART_1)
|
||||
#define UART_IE (SFR->IE2)
|
||||
#define UART_IF (SFR->IFG2)
|
||||
#define UART_BASE (&USART_1)
|
||||
#define UART_SFR (&USART_1_SFR)
|
||||
#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_PORT (&PORT_3)
|
||||
#define UART_RX_PIN (1 << 6)
|
||||
#define UART_TX_PIN (1 << 7)
|
||||
#define UART_RX_ISR (USART1RX_VECTOR)
|
||||
@ -82,12 +80,10 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
#define SPI_NUMOF (1U)
|
||||
|
||||
/* SPI configuration */
|
||||
#define SPI_BASE (USART_0)
|
||||
#define SPI_IE (SFR->IE1)
|
||||
#define SPI_IF (SFR->IFG1)
|
||||
#define SPI_BASE (&USART_0)
|
||||
#define SPI_SFR (&USART_0_SFR)
|
||||
#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(P5, 2)
|
||||
#define SPI_PIN_MOSI GPIO_PIN(P5, 1)
|
||||
|
@ -32,7 +32,7 @@ extern "C" {
|
||||
/**
|
||||
* @brief Clock configuration
|
||||
*/
|
||||
static const msp430_fxyz_clock_params_t clock_params = {
|
||||
static const msp430_clock_params_t clock_params = {
|
||||
.xt2_frequency = CLOCK_CORECLOCK,
|
||||
.lfxt1_frequency = 32768,
|
||||
.main_clock_source = MAIN_CLOCK_SOURCE_XT2CLK,
|
||||
@ -48,7 +48,7 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_BASE (TIMER_A)
|
||||
#define TIMER_BASE (&TIMER_A)
|
||||
#define TIMER_CHAN (3)
|
||||
#define TIMER_ISR_CC0 (TIMERA0_VECTOR)
|
||||
#define TIMER_ISR_CCX (TIMERA1_VECTOR)
|
||||
@ -60,14 +60,12 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
*/
|
||||
#define UART_NUMOF (1U)
|
||||
|
||||
#define UART_BASE (USART_1)
|
||||
#define UART_IE (SFR->IE2)
|
||||
#define UART_IF (SFR->IFG2)
|
||||
#define UART_BASE (&USART_1)
|
||||
#define UART_SFR (&USART_1_SFR)
|
||||
#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_PORT (&PORT_3)
|
||||
#define UART_RX_PIN (1 << 6)
|
||||
#define UART_TX_PIN (1 << 7)
|
||||
#define UART_RX_ISR (USART1RX_VECTOR)
|
||||
@ -81,12 +79,10 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
#define SPI_NUMOF (1U)
|
||||
|
||||
/* SPI configuration */
|
||||
#define SPI_BASE (USART_0)
|
||||
#define SPI_IE (SFR->IE1)
|
||||
#define SPI_IF (SFR->IFG1)
|
||||
#define SPI_BASE (&USART_0)
|
||||
#define SPI_SFR (&USART_0_SFR)
|
||||
#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)
|
||||
|
18
boards/nrf5340dk-app/Kconfig
Normal file
18
boards/nrf5340dk-app/Kconfig
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (c) 2023 Mesotic SAS
|
||||
#
|
||||
# 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 "nrf5340dk-app" if BOARD_NRF5340DK_APP
|
||||
|
||||
config BOARD_NRF5340DK_APP
|
||||
bool
|
||||
default y
|
||||
select CPU_MODEL_NRF5340_APP
|
||||
select HAS_PERIPH_TIMER
|
||||
select HAS_PERIPH_UART
|
||||
select HAS_PERIPH_UART_HW_FC
|
||||
|
||||
# Put other features for this board (in alphabetical order)
|
3
boards/nrf5340dk-app/Makefile
Normal file
3
boards/nrf5340dk-app/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = board
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
7
boards/nrf5340dk-app/Makefile.features
Normal file
7
boards/nrf5340dk-app/Makefile.features
Normal file
@ -0,0 +1,7 @@
|
||||
CPU_MODEL = nrf5340_app
|
||||
CPU = nrf53
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
FEATURES_PROVIDED += periph_timer
|
||||
FEATURES_PROVIDED += periph_uart
|
||||
FEATURES_PROVIDED += periph_uart_hw_fc
|
2
boards/nrf5340dk-app/Makefile.include
Normal file
2
boards/nrf5340dk-app/Makefile.include
Normal file
@ -0,0 +1,2 @@
|
||||
# include this module into the build
|
||||
INCLUDES += -I$(RIOTBOARD)/nrf5340dk-app/include
|
38
boards/nrf5340dk-app/doc.txt
Normal file
38
boards/nrf5340dk-app/doc.txt
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
@defgroup boards_nrf5340dk-app nRF5340DK
|
||||
@ingroup boards
|
||||
@brief Support for the nRF5340DK-app board
|
||||
|
||||
### General information
|
||||
|
||||
The nRF5340DK is a devboard based on nRF5340 MCU which offers a dual core
|
||||
Cortex-M33 with one application core and one network core.
|
||||
The network core is able to handle Bluetooth 5.3, BLE, mesh, NFC, Thread and
|
||||
Zigbee connectivity.
|
||||
Currently only the application core can be used with RIOT-OS.
|
||||
|
||||
The board features four LEDs, four user buttons/switches and a reset button.
|
||||
|
||||
### Links
|
||||
|
||||
- [nRF5340DK web page](https://infocenter.nordicsemi.com/topic/ug_nrf5340_dk/UG/dk/intro.html)
|
||||
- [documentation and hardware description](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fstruct_nrf53%2Fstruct%2Fnrf5340.html)
|
||||
|
||||
### Flash the board
|
||||
|
||||
The board is flashed using JLink or nrfjprog software. Programs needs to
|
||||
be installed.
|
||||
|
||||
The process is automated in the usual `make flash` target.
|
||||
|
||||
### Accessing STDIO via UART
|
||||
|
||||
The STDIO is directly accessible via the USB port. On a Linux host, it's
|
||||
generally mapped to `/dev/ttyACM0`.
|
||||
|
||||
Use the `term` target to connect to the board serial port<br/>
|
||||
```
|
||||
make BOARD=nrf5340dk-app -C examples/hello-world term
|
||||
```
|
||||
|
||||
*/
|
98
boards/nrf5340dk-app/include/board.h
Normal file
98
boards/nrf5340dk-app/include/board.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Mesotic SAS
|
||||
*
|
||||
* 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_nrf5340dk-app
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Board configuration for the nRF5340DK-app board
|
||||
*
|
||||
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H
|
||||
#define BOARD_H
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief System core clock speed, for all NRF53 Application core.
|
||||
*/
|
||||
#define CLOCK_CORECLOCK MHZ(128)
|
||||
|
||||
/**
|
||||
* @name HF Clock configuration
|
||||
*
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* CLOCK_HFCLKSRC_SRC_HFXO to use external 32MHz crystal
|
||||
* CLOCK_HFCLKSRC_SRC_HFINT to use internal crystal */
|
||||
#define CLOCK_HFCLK (CLOCK_HFCLKSRC_SRC_HFXO) /**< HFCLK Source selection */
|
||||
#define CLOCK_LFCLK (3) /**< LFCLK Source selection */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LED pin configuration
|
||||
* @{
|
||||
*/
|
||||
#define LED0_PIN GPIO_PIN(0, 28) /**< LED0 pin definition */
|
||||
#define LED1_PIN GPIO_PIN(0, 29) /**< LED1 pin definition */
|
||||
#define LED2_PIN GPIO_PIN(0, 30) /**< LED2 pin definition */
|
||||
#define LED3_PIN GPIO_PIN(0, 31) /**< LED3 pin definition */
|
||||
|
||||
#define LED0_MASK (1 << 28) /**< LED0 PORT bitmask */
|
||||
#define LED1_MASK (1 << 29) /**< LED1 PORT bitmask */
|
||||
#define LED2_MASK (1 << 30) /**< LED2 PORT bitmask */
|
||||
#define LED3_MASK (1 << 31) /**< LED3 PORT bitmask */
|
||||
|
||||
#define LED_PORT (NRF_P0_S) /**< Default LED PORT */
|
||||
|
||||
#define LED0_ON (LED_PORT->OUTCLR = LED0_MASK) /**< LED0 ON macro */
|
||||
#define LED0_OFF (LED_PORT->OUTSET = LED0_MASK) /**< LED0 OFF macro */
|
||||
#define LED0_TOGGLE (LED_PORT->OUT ^= LED0_MASK) /**< LED0 toggle macro */
|
||||
|
||||
#define LED1_ON (LED_PORT->OUTCLR = LED1_MASK) /**< LED1 ON macro */
|
||||
#define LED1_OFF (LED_PORT->OUTSET = LED1_MASK) /**< LED1 OFF macro */
|
||||
#define LED1_TOGGLE (LED_PORT->OUT ^= LED1_MASK) /**< LED1 toggle macro */
|
||||
|
||||
#define LED2_ON (LED_PORT->OUTCLR = LED2_MASK) /**< LED2 ON macro */
|
||||
#define LED2_OFF (LED_PORT->OUTSET = LED2_MASK) /**< LED2 OFF macro */
|
||||
#define LED2_TOGGLE (LED_PORT->OUT ^= LED2_MASK) /**< LED2 toggle macro */
|
||||
|
||||
#define LED3_ON (LED_PORT->OUTCLR = LED3_MASK) /**< LED3 ON macro */
|
||||
#define LED3_OFF (LED_PORT->OUTSET = LED3_MASK) /**< LED3 OFF macro */
|
||||
#define LED3_TOGGLE (LED_PORT->OUT ^= LED3_MASK) /**< LED3 toggle macro */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Button pin configuration
|
||||
* @{
|
||||
*/
|
||||
#define BTN0_PIN GPIO_PIN(0, 23) /**< BTN0 pin definition */
|
||||
#define BTN0_MODE GPIO_IN_PU /**< BTN0 default mode */
|
||||
#define BTN1_PIN GPIO_PIN(0, 24) /**< BTN1 pin definition */
|
||||
#define BTN1_MODE GPIO_IN_PU /**< BTN1 default mode */
|
||||
#define BTN2_PIN GPIO_PIN(0, 8) /**< BTN2 pin definition */
|
||||
#define BTN2_MODE GPIO_IN_PU /**< BTN2 default mode */
|
||||
#define BTN3_PIN GPIO_PIN(0, 9) /**< BTN3 pin definition */
|
||||
#define BTN3_MODE GPIO_IN_PU /**< BTN3 default mode */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BOARD_H */
|
||||
/** @} */
|
83
boards/nrf5340dk-app/include/periph_conf.h
Normal file
83
boards/nrf5340dk-app/include/periph_conf.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Mesotic SAS
|
||||
*
|
||||
* 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_nrf5340dk-app
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Peripheral configuration for the nRF5340DK-app
|
||||
*
|
||||
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CONF_H
|
||||
#define PERIPH_CONF_H
|
||||
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Timer configuration
|
||||
* @{
|
||||
*/
|
||||
static const timer_conf_t timer_config[] = {
|
||||
{
|
||||
.dev = NRF_TIMER0_S,
|
||||
.channels = 5,
|
||||
.bitmode = TIMER_BITMODE_BITMODE_32Bit,
|
||||
.irqn = TIMER0_IRQn
|
||||
},
|
||||
{
|
||||
.dev = NRF_TIMER1_S,
|
||||
.channels = 5,
|
||||
.bitmode = TIMER_BITMODE_BITMODE_32Bit,
|
||||
.irqn = TIMER1_IRQn
|
||||
},
|
||||
};
|
||||
|
||||
#define TIMER_0_ISR isr_timer0 /**< Timer0 IRQ*/
|
||||
#define TIMER_1_ISR isr_timer1 /**< Timer1 IRQ */
|
||||
|
||||
#define TIMER_NUMOF ARRAY_SIZE(timer_config) /**< Timer configuration NUMOF */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name UART configuration
|
||||
* @{
|
||||
*/
|
||||
static const uart_conf_t uart_config[] = {
|
||||
{
|
||||
.dev = NRF_UARTE0_S,
|
||||
.rx_pin = GPIO_PIN(1, 0),
|
||||
.tx_pin = GPIO_PIN(1, 1),
|
||||
#ifdef MODULE_PERIPH_UART_HW_FC
|
||||
.rts_pin = GPIO_UNDEF,
|
||||
.cts_pin = GPIO_UNDEF,
|
||||
#endif
|
||||
.irqn = SERIAL0_IRQn,
|
||||
},
|
||||
};
|
||||
|
||||
#define UART_0_ISR (isr_serial0) /**< SERIAL0_IRQn */
|
||||
|
||||
#define UART_NUMOF ARRAY_SIZE(uart_config) /**< UART configuration NUMOF */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PERIPH_CONF_H */
|
||||
/** @} */
|
@ -1,4 +1,4 @@
|
||||
CPU = msp430fxyz
|
||||
CPU = msp430
|
||||
CPU_MODEL = msp430f1611
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
|
@ -28,12 +28,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CLOCK_CORECLOCK msp430_fxyz_dco_freq
|
||||
#define CLOCK_CORECLOCK msp430_dco_freq
|
||||
|
||||
/**
|
||||
* @brief Clock configuration
|
||||
*/
|
||||
static const msp430_fxyz_clock_params_t clock_params = {
|
||||
static const msp430_clock_params_t clock_params = {
|
||||
.target_dco_frequency = MHZ(8),
|
||||
.lfxt1_frequency = 32768,
|
||||
.main_clock_source = MAIN_CLOCK_SOURCE_DCOCLK,
|
||||
@ -48,7 +48,7 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_BASE (TIMER_A)
|
||||
#define TIMER_BASE (&TIMER_A)
|
||||
#define TIMER_CHAN (3)
|
||||
#define TIMER_ISR_CC0 (TIMERA0_VECTOR)
|
||||
#define TIMER_ISR_CCX (TIMERA1_VECTOR)
|
||||
@ -60,14 +60,12 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
*/
|
||||
#define UART_NUMOF (1U)
|
||||
|
||||
#define UART_BASE (USART_1)
|
||||
#define UART_IE (SFR->IE2)
|
||||
#define UART_IF (SFR->IFG2)
|
||||
#define UART_BASE (&USART_1)
|
||||
#define UART_SFR (&USART_1_SFR)
|
||||
#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_PORT (&PORT_3)
|
||||
#define UART_RX_PIN (1 << 6)
|
||||
#define UART_TX_PIN (1 << 7)
|
||||
#define UART_RX_ISR (USART1RX_VECTOR)
|
||||
@ -81,12 +79,10 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
#define SPI_NUMOF (1U)
|
||||
|
||||
/* SPI configuration */
|
||||
#define SPI_BASE (USART_0)
|
||||
#define SPI_IE (SFR->IE1)
|
||||
#define SPI_IF (SFR->IFG1)
|
||||
#define SPI_BASE (&USART_0)
|
||||
#define SPI_SFR (&USART_0_SFR)
|
||||
#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)
|
||||
|
@ -1,4 +1,4 @@
|
||||
CPU = msp430fxyz
|
||||
CPU = msp430
|
||||
CPU_MODEL = msp430f2618
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
|
@ -27,12 +27,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CLOCK_CORECLOCK msp430_fxyz_dco_freq
|
||||
#define CLOCK_CORECLOCK msp430_dco_freq
|
||||
|
||||
/**
|
||||
* @brief Clock configuration
|
||||
*/
|
||||
static const msp430_fxyz_clock_params_t clock_params = {
|
||||
static const msp430_clock_params_t clock_params = {
|
||||
.target_dco_frequency = MHZ(16),
|
||||
.lfxt1_frequency = 32768,
|
||||
.main_clock_source = MAIN_CLOCK_SOURCE_DCOCLK,
|
||||
@ -47,7 +47,7 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_BASE (TIMER_A)
|
||||
#define TIMER_BASE (&TIMER_A)
|
||||
#define TIMER_CHAN (3)
|
||||
#define TIMER_ISR_CC0 (TIMERA0_VECTOR)
|
||||
#define TIMER_ISR_CCX (TIMERA1_VECTOR)
|
||||
@ -59,15 +59,14 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
*/
|
||||
#define UART_NUMOF (1U)
|
||||
|
||||
#define UART_USE_USCI
|
||||
#define UART_BASE (USCI_0)
|
||||
#define UART_IE (SFR->IE2)
|
||||
#define UART_IF (SFR->IFG2)
|
||||
#define UART_BASE (&USCI_A0)
|
||||
#define UART_IE (IE2)
|
||||
#define UART_IF (IFG2)
|
||||
#define UART_IE_RX_BIT (1 << 0)
|
||||
#define UART_IE_TX_BIT (1 << 1)
|
||||
#define UART_RX_PORT ((msp_port_t *)PORT_3)
|
||||
#define UART_RX_PORT (&PORT_3)
|
||||
#define UART_RX_PIN (1 << 5)
|
||||
#define UART_TX_PORT ((msp_port_t *)PORT_3)
|
||||
#define UART_TX_PORT (&PORT_3)
|
||||
#define UART_TX_PIN (1 << 4)
|
||||
#define UART_RX_ISR (USCIAB0RX_VECTOR)
|
||||
#define UART_TX_ISR (USCIAB0TX_VECTOR)
|
||||
@ -80,10 +79,9 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
#define SPI_NUMOF (1U)
|
||||
|
||||
/* SPI configuration */
|
||||
#define SPI_USE_USCI
|
||||
#define SPI_BASE (USCI_0_B_SPI)
|
||||
#define SPI_IE (SFR->IE2)
|
||||
#define SPI_IF (SFR->IFG2)
|
||||
#define SPI_BASE (&USCI_B0)
|
||||
#define SPI_IE (IE2)
|
||||
#define SPI_IF (IFG2)
|
||||
#define SPI_IE_RX_BIT (1 << 2)
|
||||
#define SPI_IE_TX_BIT (1 << 3)
|
||||
#define SPI_PIN_MISO GPIO_PIN(P3, 2)
|
||||
|
@ -1,4 +1,4 @@
|
||||
CPU = msp430fxyz
|
||||
CPU = msp430
|
||||
CPU_MODEL = msp430f1611
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
|
@ -28,12 +28,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CLOCK_CORECLOCK msp430_fxyz_dco_freq
|
||||
#define CLOCK_CORECLOCK msp430_dco_freq
|
||||
|
||||
/**
|
||||
* @brief Clock configuration
|
||||
*/
|
||||
static const msp430_fxyz_clock_params_t clock_params = {
|
||||
static const msp430_clock_params_t clock_params = {
|
||||
.target_dco_frequency = 2457600U,
|
||||
.lfxt1_frequency = 32768,
|
||||
.main_clock_source = MAIN_CLOCK_SOURCE_DCOCLK,
|
||||
@ -48,7 +48,7 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_BASE (TIMER_A)
|
||||
#define TIMER_BASE (&TIMER_A)
|
||||
#define TIMER_CHAN (3)
|
||||
#define TIMER_ISR_CC0 (TIMERA0_VECTOR)
|
||||
#define TIMER_ISR_CCX (TIMERA1_VECTOR)
|
||||
@ -60,14 +60,12 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
*/
|
||||
#define UART_NUMOF (1U)
|
||||
|
||||
#define UART_BASE (USART_1)
|
||||
#define UART_IE (SFR->IE2)
|
||||
#define UART_IF (SFR->IFG2)
|
||||
#define UART_BASE (&USART_1)
|
||||
#define UART_SFR (&USART_1_SFR)
|
||||
#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_PORT (&PORT_3)
|
||||
#define UART_RX_PIN (1 << 6)
|
||||
#define UART_TX_PIN (1 << 7)
|
||||
#define UART_RX_ISR (USART1RX_VECTOR)
|
||||
@ -80,13 +78,10 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
*/
|
||||
#define SPI_NUMOF (1U)
|
||||
|
||||
/* SPI configuration */
|
||||
#define SPI_BASE (USART_0)
|
||||
#define SPI_IE (SFR->IE1)
|
||||
#define SPI_IF (SFR->IFG1)
|
||||
#define SPI_BASE (&USART_0)
|
||||
#define SPI_SFR (&USART_0_SFR)
|
||||
#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)
|
||||
|
@ -1,4 +1,4 @@
|
||||
CPU = msp430fxyz
|
||||
CPU = msp430
|
||||
CPU_MODEL = msp430f2617
|
||||
|
||||
# Put defined MCU peripherals here (in alphabetical order)
|
||||
|
@ -28,12 +28,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CLOCK_CORECLOCK msp430_fxyz_dco_freq
|
||||
#define CLOCK_CORECLOCK msp430_dco_freq
|
||||
|
||||
/**
|
||||
* @brief Clock configuration
|
||||
*/
|
||||
static const msp430_fxyz_clock_params_t clock_params = {
|
||||
static const msp430_clock_params_t clock_params = {
|
||||
.target_dco_frequency = MHZ(8),
|
||||
.lfxt1_frequency = 32768,
|
||||
.main_clock_source = MAIN_CLOCK_SOURCE_DCOCLK,
|
||||
@ -48,7 +48,7 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_NUMOF (1U)
|
||||
#define TIMER_BASE (TIMER_A)
|
||||
#define TIMER_BASE (&TIMER_A)
|
||||
#define TIMER_CHAN (3)
|
||||
#define TIMER_ISR_CC0 (TIMERA0_VECTOR)
|
||||
#define TIMER_ISR_CCX (TIMERA1_VECTOR)
|
||||
@ -60,15 +60,14 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
*/
|
||||
#define UART_NUMOF (1U)
|
||||
|
||||
#define UART_USE_USCI
|
||||
#define UART_BASE (USCI_0)
|
||||
#define UART_IE (SFR->IE2)
|
||||
#define UART_IF (SFR->IFG2)
|
||||
#define UART_BASE (&USCI_A0)
|
||||
#define UART_IE (IE2)
|
||||
#define UART_IF (IFG2)
|
||||
#define UART_IE_RX_BIT (1 << 0)
|
||||
#define UART_IE_TX_BIT (1 << 1)
|
||||
#define UART_RX_PORT ((msp_port_t *)PORT_3)
|
||||
#define UART_RX_PORT (&PORT_3)
|
||||
#define UART_RX_PIN (1 << 5)
|
||||
#define UART_TX_PORT ((msp_port_t *)PORT_3)
|
||||
#define UART_TX_PORT (&PORT_3)
|
||||
#define UART_TX_PIN (1 << 4)
|
||||
#define UART_RX_ISR (USCIAB0RX_VECTOR)
|
||||
#define UART_TX_ISR (USCIAB0TX_VECTOR)
|
||||
@ -81,10 +80,9 @@ static const msp430_fxyz_clock_params_t clock_params = {
|
||||
#define SPI_NUMOF (1U)
|
||||
|
||||
/* SPI configuration */
|
||||
#define SPI_USE_USCI
|
||||
#define SPI_BASE (USCI_0_B_SPI)
|
||||
#define SPI_IE (SFR->IE2)
|
||||
#define SPI_IF (SFR->IFG2)
|
||||
#define SPI_BASE (&USCI_B0)
|
||||
#define SPI_IE (IE2)
|
||||
#define SPI_IF (IFG2)
|
||||
#define SPI_IE_RX_BIT (1 << 2)
|
||||
#define SPI_IE_TX_BIT (1 << 3)
|
||||
#define SPI_PIN_MISO GPIO_PIN(P3, 2)
|
||||
|
@ -6,48 +6,42 @@
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
config MODULE_MSP430_COMMON
|
||||
config CPU_ARCH_MSP430
|
||||
bool
|
||||
default y if CPU_CORE_MSP430
|
||||
depends on TEST_KCONFIG
|
||||
imply MODULE_NEWLIB_NANO
|
||||
select MODULE_MALLOC_THREAD_SAFE
|
||||
help
|
||||
Common code for MSP430 cores.
|
||||
select HAS_ARCH_16BIT
|
||||
select HAS_ARCH_MSP430
|
||||
select HAS_CPU_MSP430
|
||||
select HAS_DBGPIN
|
||||
select HAS_NEWLIB
|
||||
select HAS_PERIPH_FLASHPAGE
|
||||
select HAS_PERIPH_FLASHPAGE_IN_ADDRESS_SPACE
|
||||
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||
select HAS_PERIPH_PM
|
||||
select MODULE_MALLOC_THREAD_SAFE if TEST_KCONFIG
|
||||
|
||||
config MODULE_MSP430_COMMON_PERIPH
|
||||
config HAS_CPU_MSP430
|
||||
bool
|
||||
default y if CPU_CORE_MSP430
|
||||
depends on TEST_KCONFIG
|
||||
select MODULE_PERIPH
|
||||
help
|
||||
Common peripheral code for MSP430 cores.
|
||||
Indicates that an 'MSP430' CPU is being used.
|
||||
|
||||
config CPU_MSP430
|
||||
bool
|
||||
select CPU_ARCH_MSP430
|
||||
|
||||
choice LIBC_IMPLEMENTATION
|
||||
default MODULE_NEWLIB
|
||||
endchoice
|
||||
|
||||
config CPU_ARCH_MSP430
|
||||
bool
|
||||
select HAS_ARCH_16BIT
|
||||
select HAS_ARCH_MSP430
|
||||
select HAS_DBGPIN
|
||||
select HAS_PERIPH_FLASHPAGE
|
||||
select HAS_PERIPH_FLASHPAGE_IN_ADDRESS_SPACE
|
||||
select HAS_PERIPH_FLASHPAGE_PAGEWISE
|
||||
select HAS_NEWLIB
|
||||
select HAS_PERIPH_PM
|
||||
|
||||
config CPU_CORE_MSP430
|
||||
bool
|
||||
select CPU_ARCH_MSP430
|
||||
|
||||
## Common CPU symbols
|
||||
config CPU_ARCH
|
||||
default "msp430" if CPU_ARCH_MSP430
|
||||
default "msp430" if CPU_MSP430
|
||||
|
||||
config CPU
|
||||
default "msp430" if CPU_MSP430
|
||||
|
||||
config CPU_CORE
|
||||
default "msp430" if CPU_CORE_MSP430
|
||||
default "msp430" if CPU_MSP430
|
||||
|
||||
## Definition of specific features
|
||||
config HAS_ARCH_MSP430
|
||||
@ -59,3 +53,7 @@ config HAS_ARCH_MSP430
|
||||
config GNRC_PKTBUF_SIZE
|
||||
default 2560
|
||||
depends on KCONFIG_USEMODULE_GNRC_PKTBUF_STATIC
|
||||
|
||||
source "$(RIOTCPU)/msp430/periph/Kconfig"
|
||||
source "$(RIOTCPU)/msp430/kconfigs/x1xx/Kconfig"
|
||||
source "$(RIOTCPU)/msp430/kconfigs/f2xx_g2xx/Kconfig"
|
5
cpu/msp430/Makefile
Normal file
5
cpu/msp430/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
MODULE = cpu
|
||||
|
||||
DIRS := periph
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -1,5 +1,4 @@
|
||||
USEMODULE += msp430_common
|
||||
USEMODULE += msp430_common_periph
|
||||
USEMODULE += newlib
|
||||
USEMODULE += periph
|
||||
|
||||
ifneq (,$(filter newlib,$(USEMODULE)))
|
@ -1,8 +1,17 @@
|
||||
CPU_ARCH = msp430
|
||||
CPU_CORE = msp430
|
||||
|
||||
ifneq (,$(filter msp430f2% msp430g2%,$(CPU_MODEL)))
|
||||
CPU_FAM := msp430_f2xx_g2xx
|
||||
endif
|
||||
|
||||
ifneq (,$(filter msp430f1%,$(CPU_MODEL)))
|
||||
CPU_FAM := msp430_x1xx
|
||||
endif
|
||||
|
||||
FEATURES_PROVIDED += arch_16bit
|
||||
FEATURES_PROVIDED += arch_msp430
|
||||
FEATURES_PROVIDED += cpu_$(CPU_FAM)
|
||||
FEATURES_PROVIDED += dbgpin
|
||||
FEATURES_PROVIDED += newlib
|
||||
FEATURES_PROVIDED += periph_flashpage
|
@ -1,4 +1,5 @@
|
||||
INCLUDES += -I$(RIOTCPU)/msp430_common/include/
|
||||
INCLUDES += -I$(RIOTCPU)/msp430/include/
|
||||
INCLUDES += -I$(RIOTCPU)/msp430/include/$(subst msp430_,,$(CPU_FAM))
|
||||
|
||||
CFLAGS += -DCPU_MODEL_$(call uppercase_and_underscore,$(CPU_MODEL))
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430fxyz
|
||||
* @ingroup cpu_msp430
|
||||
* @{
|
||||
* @file
|
||||
* @brief MSP430Fxzy clock initialization
|
||||
@ -38,9 +38,9 @@
|
||||
#define HAS_RSEL3 0
|
||||
#endif
|
||||
|
||||
uint32_t msp430_fxyz_dco_freq;
|
||||
uint32_t msp430_dco_freq;
|
||||
|
||||
static inline bool is_dco_in_use(const msp430_fxyz_clock_params_t *params)
|
||||
static inline bool is_dco_in_use(const msp430_clock_params_t *params)
|
||||
{
|
||||
return ((params->main_clock_source == MAIN_CLOCK_SOURCE_DCOCLK) ||
|
||||
(params->submain_clock_source == SUBMAIN_CLOCK_SOURCE_DCOCLK));
|
||||
@ -253,7 +253,7 @@ static void calibrate_dco(void)
|
||||
TACTL = 0;
|
||||
|
||||
/* calculate actual DCO frequency */
|
||||
msp430_fxyz_dco_freq = (clock_params.lfxt1_frequency * actual_clock_ratio) >> 3;
|
||||
msp430_dco_freq = (clock_params.lfxt1_frequency * actual_clock_ratio) >> 3;
|
||||
}
|
||||
|
||||
void default_clock_init(void)
|
||||
@ -348,7 +348,7 @@ void default_clock_init(void)
|
||||
|
||||
__attribute__((weak, alias("default_clock_init"))) void clock_init(void);
|
||||
|
||||
uint32_t msp430_fxyz_submain_clock_freq(void) {
|
||||
uint32_t msp430_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:
|
||||
@ -361,11 +361,11 @@ uint32_t msp430_fxyz_submain_clock_freq(void) {
|
||||
return clock_params.lfxt1_frequency >> shift;
|
||||
default:
|
||||
case SUBMAIN_CLOCK_SOURCE_DCOCLK:
|
||||
return msp430_fxyz_dco_freq >> shift;
|
||||
return msp430_dco_freq >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t msp430_fxyz_auxiliary_clock_freq(void)
|
||||
uint32_t msp430_auxiliary_clock_freq(void)
|
||||
{
|
||||
uint16_t shift = (clock_params.auxiliary_clock_divier >> 4) & 0x3;
|
||||
return clock_params.lfxt1_frequency >> shift;
|
36
cpu/msp430/doc.txt
Normal file
36
cpu/msp430/doc.txt
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
@defgroup cpu_msp430 TI MSP430
|
||||
@ingroup cpu
|
||||
@brief Texas Instruments MSP430 specific code
|
||||
|
||||
Support for [TI MSP430] CPU architecture. Check the [MSP430 Dev Guide Book]
|
||||
for an overview and a starting point for the CPU architecture. See
|
||||
[MSP430 Programming With JTAG] on how to interface with the MCUs.
|
||||
|
||||
[TI MSP430]: https://www.ti.com/microcontrollers-mcus-processors/msp430-microcontrollers/overview.html
|
||||
[MSP430 Dev Guide Book]: https://www.ti.com/lit/ug/slau840a/slau840a.pdf
|
||||
[MSP430 Programming With JTAG]: https://www.ti.com/lit/ug/slau320aj/slau320aj.pdf
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
@defgroup cpu_msp430_f2xx_g2xx MSP430 F2xx/G2xx MCU family
|
||||
@ingroup cpu_msp430
|
||||
@brief Common code for the MSP430 F2xx/G2xx MCU family
|
||||
|
||||
This module contains code common to all of the [MSP430 F2xx/G2xx] MCU family.
|
||||
|
||||
[MSP430 F2xx/G2xx]: https://www.ti.com/lit/ug/slau144k/slau144k.pdf
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
@defgroup cpu_msp430_x1xx MSP430 x1xx MCU family
|
||||
@ingroup cpu_msp430
|
||||
@brief Common code for the MSP430 x1xx MCU family
|
||||
|
||||
This module contains code common to all of the [MSP430 x1xx] MCU family.
|
||||
|
||||
[MSP430 x1xx]: https://www.ti.com/lit/ug/slau049f/slau049f.pdf
|
||||
|
||||
*/
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430_common
|
||||
* @ingroup cpu_msp430
|
||||
* @{
|
||||
*
|
||||
* @file
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430_common
|
||||
* @ingroup cpu_msp430
|
||||
*
|
||||
* @{
|
||||
*
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cpu_msp430_common TI MSP430
|
||||
* @ingroup cpu
|
||||
* @ingroup cpu_msp430
|
||||
* @brief Texas Instruments MSP430 specific code
|
||||
*
|
||||
* @{
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430_common
|
||||
* @ingroup cpu_msp430
|
||||
* @{
|
||||
*
|
||||
* @file
|
155
cpu/msp430/include/f2xx_g2xx/msp430_regs.h
Normal file
155
cpu/msp430/include/f2xx_g2xx/msp430_regs.h
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430_f2xx_g2xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Cortex CMSIS style definition of MSP430 registers
|
||||
*
|
||||
* @todo This file is incomplete, not all registers are listed. Further
|
||||
* There are probably some inconsistencies throughout the MSP430
|
||||
* family which need to be addressed.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef F2XX_G2XX_MSP430_REGS_H
|
||||
#define F2XX_G2XX_MSP430_REGS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "msp430_regs_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Universal Serial Control Interface Type A (USCI_A) Registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 ABCTL; /**< auto baud rate control */
|
||||
REG8 IRTCTL; /**< IrDA transmit control */
|
||||
REG8 IRRCTL; /**< IrDA receive control */
|
||||
REG8 CTL0; /**< control 0 */
|
||||
REG8 CTL1; /**< control 1 */
|
||||
REG8 BR0; /**< baud rate control 0 */
|
||||
REG8 BR1; /**< baud rate control 1 */
|
||||
REG8 MCTL; /**< modulation control */
|
||||
REG8 STAT; /**< status register */
|
||||
REG8 RXBUF; /**< receive buffer */
|
||||
REG8 TXBUF; /**< transmit buffer */
|
||||
} msp_usci_a_t;
|
||||
|
||||
/**
|
||||
* @brief Universal Serial Control Interface Type B (USCI_B) Registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 CTL0; /**< control 0 */
|
||||
REG8 CTL1; /**< control 1 */
|
||||
REG8 BR0; /**< baud rate control 0 */
|
||||
REG8 BR1; /**< baud rate control 1 */
|
||||
REG8 MCTL; /**< modulation control */
|
||||
REG8 STAT; /**< status register */
|
||||
REG8 RXBUF; /**< receive buffer */
|
||||
REG8 TXBUF; /**< transmit buffer */
|
||||
} msp_usci_b_t;
|
||||
|
||||
/**
|
||||
* @name USCI clock selection
|
||||
*
|
||||
* The vendor header files expose clock configurations with hard to read
|
||||
* names. So we provide alias with better names
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define UCSSEL_UCLKI UCSSEL_0 /**< Clock USCI using CLKI (n/a in SPI mode) */
|
||||
#define UCSSEL_ACLK UCSSEL_1 /**< Clock USCI using auxiliary clock */
|
||||
#define UCSSEL_SMCLK UCSSEL_2 /**< Clock USCI using sub-system master clock */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name USCI Modulation Control fields
|
||||
*
|
||||
* The vendor header files provides bitmasks for each of the possible values
|
||||
* from 0..7. But rather than creating a look up table, we can just shift the
|
||||
* number in place, if there only would be a UCRBS_SHIFT macro.
|
||||
* @{
|
||||
*/
|
||||
#define UCBRS_MASK UCBRS_7 /**< Bitmask to retrieve the UCRBS field of the
|
||||
USCI modulation control register */
|
||||
#if (UCBRS_7 == 0x0E) || defined(DOXYGEN)
|
||||
#define UCBRS_POS 1 /**< Position of the UCRBS field in the
|
||||
UCAxMCTL register */
|
||||
#else
|
||||
/* The datasheet for the whole MCU family states the field is in bits 3-1,
|
||||
* but let's better be safe than sorry here */
|
||||
#error "UCBRS field in the UCAxMCTL register at unexpected position."
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief "Convert" a USCI A into an USCI B interface
|
||||
*
|
||||
* The USCI peripheral come in two flavors: USCI A and USCI B with the following
|
||||
* feature set. When comparing the memory map USCI B is a subset of USCI A
|
||||
* registers, which conveniently have the same offsets. It is therefore possible
|
||||
* to address USCI A registers as if it was a USCI B interface when operated
|
||||
* in SPI mode. This makes implementation of SPI easier.
|
||||
*
|
||||
* | Name | UART | SPI | I2C | IrDA |
|
||||
* |:------ |:----- |:----- |:----- |:----- |
|
||||
* | USCI A | ✔ | ✔ | ✗ | ✔ |
|
||||
* | USCI B | ✗ | ✔ | ✔ | ✗ |
|
||||
*/
|
||||
static inline msp_usci_b_t * msp430_usci_b_from_usci_a(msp_usci_a_t *usci_a)
|
||||
{
|
||||
uintptr_t usci_b = (uintptr_t)usci_a + offsetof(msp_usci_a_t, CTL0);
|
||||
return (msp_usci_b_t *)usci_b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Typing of base register objects
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief USCI_A0 register map
|
||||
*
|
||||
* @details Provided by linker
|
||||
*/
|
||||
extern msp_usci_a_t USCI_A0;
|
||||
/**
|
||||
* @brief USCI_A1 register map
|
||||
*
|
||||
* @details Provided by linker
|
||||
*/
|
||||
extern msp_usci_a_t USCI_A1;
|
||||
/**
|
||||
* @brief USCI_B0 register map
|
||||
*
|
||||
* @details Provided by linker
|
||||
*/
|
||||
extern msp_usci_a_t USCI_B0;
|
||||
/**
|
||||
* @brief USCI_B1 register map
|
||||
*
|
||||
* @details Provided by linker
|
||||
*/
|
||||
extern msp_usci_a_t USCI_B1;
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* F2XX_G2XX_MSP430_REGS_H */
|
||||
/** @} */
|
83
cpu/msp430/include/f2xx_g2xx/periph_cpu.h
Normal file
83
cpu/msp430/include/f2xx_g2xx/periph_cpu.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430_f2xx_g2xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CPU specific definitions for internal peripheral handling
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef F2XX_G2XX_PERIPH_CPU_H
|
||||
#define F2XX_G2XX_PERIPH_CPU_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "periph_cpu_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Override SPI mode selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_MODE_T /**< MSP430 F2xx/G2xx has a custom spi_mode_t */
|
||||
/**
|
||||
* @brief Support SPI modes
|
||||
*
|
||||
* | Field | Name | Description |
|
||||
* |:------ |:--------------------- |:----------------------------------------------------- |
|
||||
* | UCCKPH | Clock phase select | 0 = capture on second edge, 1 = capture on first |
|
||||
* | UCCKPL | Clock polarity select | 0 = clock is idle-low, 1 = clock is high idle-high |
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_MODE_0 = (UCCKPH), /**< CPOL=0, CPHA=0 */
|
||||
SPI_MODE_1 = 0, /**< CPOL=0, CPHA=1 */
|
||||
SPI_MODE_2 = (UCCKPL | UCCKPH), /**< CPOL=1, CPHA=0 */
|
||||
SPI_MODE_3 = (UCCKPL) /**< CPOL=1, CPHA=1 */
|
||||
} spi_mode_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Override SPI clock speed selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_CLK_T /**< MSP430 F2xx/G2xx has a custom spi_clock_t */
|
||||
/**
|
||||
* @brief Support SPI clock frequencies
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_CLK_100KHZ = 100000, /**< 100 kHz */
|
||||
SPI_CLK_400KHZ = 400000, /**< 400 kHz */
|
||||
SPI_CLK_1MHZ = 1000000, /**< 1 MHz */
|
||||
SPI_CLK_5MHZ = 5000000, /**< 5 MHz */
|
||||
SPI_CLK_10MHZ = SPI_CLK_5MHZ, /**< 10 MHz not supported, falling back to 5 MHz */
|
||||
} spi_clk_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name declare needed generic SPI functions
|
||||
* @{
|
||||
*/
|
||||
#define PERIPH_SPI_NEEDS_INIT_CS /**< use shared spi_init_cs() */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE /**< use shared spi_transfer_byte() */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REG /**< use shared spi_transfer_reg() */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REGS /**< use shared spi_transfer_regs() */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* F2XX_G2XX_PERIPH_CPU_H */
|
||||
/** @} */
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430_common
|
||||
* @ingroup cpu_msp430
|
||||
* @{
|
||||
*
|
||||
* @file
|
184
cpu/msp430/include/msp430_regs_common.h
Normal file
184
cpu/msp430/include/msp430_regs_common.h
Normal file
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Cortex CMSIS style definition of MSP430 registers
|
||||
*
|
||||
* @todo This file is incomplete, not all registers are listed. Further
|
||||
* There are probably some inconsistencies throughout the MSP430
|
||||
* family which need to be addressed.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef MSP430_REGS_COMMON_H
|
||||
#define MSP430_REGS_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Shortcut to specify 8-bit wide registers
|
||||
*/
|
||||
#define REG8 volatile uint8_t
|
||||
|
||||
/**
|
||||
* @brief Shortcut to specify 16-bit wide registers
|
||||
*/
|
||||
#define REG16 volatile uint16_t
|
||||
|
||||
/**
|
||||
* @name Timer SSEL Values
|
||||
*
|
||||
* @details When using the macros in the vendor header files such as TASSEL_0
|
||||
* the actually used clock is non-obvious. Hence, provide aliases
|
||||
* with obvious names.
|
||||
* @{
|
||||
*/
|
||||
#define TXSSEL_TXCLK TASSEL_0 /**< External TxCLK as clock source */
|
||||
#define TXSSEL_ACLK TASSEL_1 /**< Auxiliary clock as clock source */
|
||||
#define TXSSEL_SMCLK TASSEL_2 /**< Sub-system master clock as clock source */
|
||||
#define TXSSEL_INCLK TASSEL_3 /**< External INCLK as clock source */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Timer Input Divider Values
|
||||
*
|
||||
* @details The vendor header macros are again non-obvious in their naming, so
|
||||
* provide better alies names.
|
||||
* @{
|
||||
*/
|
||||
#define TXID_DIV_1 ID_0 /**< Input Divider: Divide by 1 */
|
||||
#define TXID_DIV_2 ID_1 /**< Input Divider: Divide by 2 */
|
||||
#define TXID_DIV_4 ID_2 /**< Input Divider: Divide by 4 */
|
||||
#define TXID_DIV_8 ID_3 /**< Input Divider: Divide by 4 */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Timer Mode Control Values
|
||||
*
|
||||
* @details The vendor header macros are again non-obvious in their naming, so
|
||||
* provide better alies names.
|
||||
* @{
|
||||
*/
|
||||
#define TXMC_STOP MC_0 /**< Stop Mode */
|
||||
#define TXMC_UP MC_1 /**< Up to CCR0 Mode*/
|
||||
#define TXMC_CONT MC_2 /**< Continuous Mode */
|
||||
#define TXMC_UP_DOWN MC_3 /**< Up/Down Mode */
|
||||
#define TXMC_MASK MC_3 /**< Bitmask to retrieve MC field */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Common MSP GPIO Port Registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 IN; /**< input data */
|
||||
REG8 OD; /**< output data */
|
||||
REG8 DIR; /**< pin direction */
|
||||
} msp_port_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO Port 1/2 (with interrupt functionality)
|
||||
*/
|
||||
typedef struct {
|
||||
msp_port_t base; /**< common GPIO port registers */
|
||||
REG8 IFG; /**< interrupt flag */
|
||||
REG8 IES; /**< interrupt edge select */
|
||||
REG8 IE; /**< interrupt enable */
|
||||
REG8 SEL; /**< alternative function select */
|
||||
} msp_port_p1_p2_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO Port 3..6 (without interrupt functionality)
|
||||
*/
|
||||
typedef struct {
|
||||
msp_port_t base; /**< common GPIO port registers */
|
||||
REG8 SEL; /**< alternative function select */
|
||||
} msp_port_p3_p6_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Timer interrupt status registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG16 TBIV; /**< TIMER_A interrupt status */
|
||||
REG16 reserved[7]; /**< reserved */
|
||||
REG16 TAIV; /**< TIMER_B interrupt status */
|
||||
} msp_timer_ivec_t;
|
||||
|
||||
/**
|
||||
* @brief Timer module registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG16 CTL; /**< timer control */
|
||||
REG16 CCTL[7]; /**< capture compare channel control */
|
||||
REG16 R; /**< current counter value */
|
||||
REG16 CCR[7]; /**< capture compare channel values */
|
||||
} msp_timer_t;
|
||||
|
||||
/**
|
||||
* @name MSP430 Common Peripheral Register Maps
|
||||
*
|
||||
* @details The addresses will be provided by the linker script using the
|
||||
* vendor files.
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Register map of GPIO PORT 1
|
||||
*/
|
||||
extern msp_port_p1_p2_t PORT_1;
|
||||
/**
|
||||
* @brief Register map of GPIO PORT 2
|
||||
*/
|
||||
extern msp_port_p1_p2_t PORT_2;
|
||||
/**
|
||||
* @brief Register map of GPIO PORT 3
|
||||
*/
|
||||
extern msp_port_p3_p6_t PORT_3;
|
||||
/**
|
||||
* @brief Register map of GPIO PORT 4
|
||||
*/
|
||||
extern msp_port_p3_p6_t PORT_4;
|
||||
/**
|
||||
* @brief Register map of GPIO PORT 5
|
||||
*/
|
||||
extern msp_port_p3_p6_t PORT_5;
|
||||
/**
|
||||
* @brief Register map of GPIO PORT 6
|
||||
*/
|
||||
extern msp_port_p3_p6_t PORT_6;
|
||||
|
||||
/**
|
||||
* @brief Register map of the timer interrupt control registers
|
||||
*/
|
||||
extern msp_timer_ivec_t TIMER_IVEC;
|
||||
|
||||
/**
|
||||
* @brief Register map of the timer A control registers
|
||||
*/
|
||||
extern msp_timer_t TIMER_A;
|
||||
|
||||
/**
|
||||
* @brief Register map of the timer B control registers
|
||||
*/
|
||||
extern msp_timer_t TIMER_B;
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSP430_REGS_COMMON_H */
|
||||
/** @} */
|
@ -7,9 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cpu_msp430fxyz TI MSP430F
|
||||
* @ingroup cpu
|
||||
* @brief Texas Instruments MSP430F family specific code
|
||||
* @ingroup cpu_msp430_x1xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
@ -18,8 +16,8 @@
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef PERIPH_CPU_H
|
||||
#define PERIPH_CPU_H
|
||||
#ifndef PERIPH_CPU_COMMON_H
|
||||
#define PERIPH_CPU_COMMON_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
@ -54,12 +52,14 @@ typedef uint16_t gpio_t;
|
||||
*/
|
||||
#define SPI_HWCS(x) (SPI_CS_UNDEF)
|
||||
|
||||
#ifndef DOXYGEN
|
||||
/**
|
||||
* @brief Override flank selection values
|
||||
* @name Override flank selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_GPIO_FLANK_T
|
||||
#define HAVE_GPIO_FLANK_T /**< MSP430 has a custom gpio_flank_t */
|
||||
/**
|
||||
* @brief Enumeration of supported GPIO flanks
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_FALLING = 0xff, /**< emit interrupt on falling flank */
|
||||
GPIO_RISING = 0x00, /**< emit interrupt on rising flank */
|
||||
@ -67,43 +67,6 @@ typedef enum {
|
||||
} gpio_flank_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Override SPI mode selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_MODE_T
|
||||
#ifndef SPI_USE_USCI
|
||||
typedef enum {
|
||||
SPI_MODE_0 = (USART_TCTL_CKPH), /**< CPOL=0, CPHA=0 */
|
||||
SPI_MODE_1 = 0, /**< CPOL=0, CPHA=1 */
|
||||
SPI_MODE_2 = (USART_TCTL_CKPL | USART_TCTL_CKPH), /**< CPOL=1, CPHA=0 */
|
||||
SPI_MODE_3 = (USART_TCTL_CKPL) /**< CPOL=1, CPHA=1 */
|
||||
} spi_mode_t;
|
||||
#else
|
||||
typedef enum {
|
||||
SPI_MODE_0 = (USCI_SPI_CTL0_CKPH), /**< CPOL=0, CPHA=0 */
|
||||
SPI_MODE_1 = 0, /**< CPOL=0, CPHA=1 */
|
||||
SPI_MODE_2 = (USCI_SPI_CTL0_CKPL | USCI_SPI_CTL0_CKPH), /**< CPOL=1, CPHA=0 */
|
||||
SPI_MODE_3 = (USCI_SPI_CTL0_CKPL) /**< CPOL=1, CPHA=1 */
|
||||
} spi_mode_t;
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Override SPI clock speed selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_CLK_T
|
||||
typedef enum {
|
||||
SPI_CLK_100KHZ = 100000, /**< 100KHz */
|
||||
SPI_CLK_400KHZ = 400000, /**< 400KHz */
|
||||
SPI_CLK_1MHZ = 1000000, /**< 1MHz */
|
||||
SPI_CLK_5MHZ = 5000000, /**< 5MHz */
|
||||
SPI_CLK_10MHZ = 0, /**< not supported */
|
||||
} spi_clk_t;
|
||||
/** @} */
|
||||
#endif /* ndef DOXYGEN */
|
||||
|
||||
/**
|
||||
* @brief Available ports on MSP430 platforms
|
||||
*/
|
||||
@ -124,23 +87,13 @@ enum {
|
||||
*/
|
||||
void gpio_periph_mode(gpio_t pin, bool enable);
|
||||
|
||||
/**
|
||||
* @brief declare needed generic SPI functions
|
||||
* @{
|
||||
*/
|
||||
#define PERIPH_SPI_NEEDS_INIT_CS
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REG
|
||||
#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;
|
||||
extern uint32_t msp430_dco_freq;
|
||||
|
||||
/**
|
||||
* @brief Possible clock sources to generate the main clock from
|
||||
@ -163,7 +116,7 @@ typedef enum {
|
||||
* between 450 kHz and 8 MHz
|
||||
*/
|
||||
MAIN_CLOCK_SOURCE_LFXT1CLK = SELM_3,
|
||||
} msp430_fxyz_main_clock_source_t;
|
||||
} msp430_main_clock_source_t;
|
||||
|
||||
/**
|
||||
* @brief Possible clock sources to generate the submain clock from
|
||||
@ -192,7 +145,7 @@ typedef enum {
|
||||
* in the config to avoid confusion.
|
||||
*/
|
||||
SUBMAIN_CLOCK_SOURCE_LFXT1CLK = SELS,
|
||||
} msp430_fxyz_submain_clock_source_t;
|
||||
} msp430_submain_clock_source_t;
|
||||
|
||||
/**
|
||||
* @brief Clock dividers for the main clock
|
||||
@ -214,7 +167,7 @@ typedef enum {
|
||||
* @brief Divide the main clock by 8
|
||||
*/
|
||||
MAIN_CLOCK_DIVIDE_BY_8 = DIVM_3,
|
||||
} msp430_fxyz_main_clock_divider_t;
|
||||
} msp430_main_clock_divider_t;
|
||||
|
||||
/**
|
||||
* @brief Clock dividers for the submain clock
|
||||
@ -236,7 +189,7 @@ typedef enum {
|
||||
* @brief Divide the main clock by 8
|
||||
*/
|
||||
SUBMAIN_CLOCK_DIVIDE_BY_8 = DIVS_3,
|
||||
} msp430_fxyz_submain_clock_divider_t;
|
||||
} msp430_submain_clock_divider_t;
|
||||
|
||||
/**
|
||||
* @brief Clock dividers for the auxiliary clock
|
||||
@ -258,7 +211,7 @@ typedef enum {
|
||||
* @brief Divide the main clock by 8
|
||||
*/
|
||||
AUXILIARY_CLOCK_DIVIDE_BY_8 = DIVA_3,
|
||||
} msp430_fxyz_auxiliary_clock_divider_t;
|
||||
} msp430_auxiliary_clock_divider_t;
|
||||
|
||||
/**
|
||||
* @brief MSP430Fxzy Basic Clock System Parameters
|
||||
@ -301,25 +254,25 @@ typedef struct {
|
||||
*
|
||||
* @details This is the clock the CPU will run at
|
||||
*/
|
||||
msp430_fxyz_main_clock_source_t main_clock_source;
|
||||
msp430_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;
|
||||
msp430_submain_clock_source_t submain_clock_source;
|
||||
/**
|
||||
* @brief Divider of the main clock
|
||||
*/
|
||||
msp430_fxyz_main_clock_divider_t main_clock_divier;
|
||||
msp430_main_clock_divider_t main_clock_divier;
|
||||
/**
|
||||
* @brief Divider of the submain clock
|
||||
*/
|
||||
msp430_fxyz_submain_clock_divider_t submain_clock_divier;
|
||||
msp430_submain_clock_divider_t submain_clock_divier;
|
||||
/**
|
||||
* @brief Divider of the auxiliary clock
|
||||
*/
|
||||
msp430_fxyz_auxiliary_clock_divider_t auxiliary_clock_divier;
|
||||
msp430_auxiliary_clock_divider_t auxiliary_clock_divier;
|
||||
/**
|
||||
* @brief An external resistor connected to source the current for the DCO
|
||||
*
|
||||
@ -334,14 +287,14 @@ typedef struct {
|
||||
* XT2IN and XT2OUT
|
||||
*/
|
||||
bool has_xt2;
|
||||
} msp430_fxyz_clock_params_t;
|
||||
} msp430_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
|
||||
* as specified by `static const msp430_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
|
||||
@ -368,18 +321,18 @@ void clock_init(void);
|
||||
*
|
||||
* @note This is only useful when implementing MSP430 peripheral drivers
|
||||
*/
|
||||
uint32_t msp430_fxyz_submain_clock_freq(void);
|
||||
uint32_t msp430_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);
|
||||
uint32_t msp430_auxiliary_clock_freq(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PERIPH_CPU_H */
|
||||
#endif /* PERIPH_CPU_COMMON_H */
|
||||
/** @} */
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430_common
|
||||
* @ingroup cpu_msp430
|
||||
* @{
|
||||
*
|
||||
* @file
|
113
cpu/msp430/include/x1xx/msp430_regs.h
Normal file
113
cpu/msp430/include/x1xx/msp430_regs.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430_x1xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Cortex CMSIS style definition of MSP430 registers
|
||||
*
|
||||
* @todo This file is incomplete, not all registers are listed. Further
|
||||
* There are probably some inconsistencies throughout the MSP430
|
||||
* family which need to be addressed.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef X1XX_MSP430_REGS_H
|
||||
#define X1XX_MSP430_REGS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "msp430_regs_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief USART (UART, SPI and I2C) Registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 CTL; /**< USART control */
|
||||
REG8 TCTL; /**< transmit control */
|
||||
REG8 RCTL; /**< receive control */
|
||||
REG8 MCTL; /**< modulation control */
|
||||
REG8 BR0; /**< baud rate control 0 */
|
||||
REG8 BR1; /**< baud rate control 1 */
|
||||
REG8 RXBUF; /**< receive buffer */
|
||||
REG8 TXBUF; /**< transmit buffer */
|
||||
} msp_usart_t;
|
||||
|
||||
/**
|
||||
* @brief USART Special Function Registers (SFR)
|
||||
*
|
||||
* Despite being part of the USART peripheral, the SFR registers location is
|
||||
* completely different. Even more confusing, the IE register of USART 1
|
||||
* follows the IE register of USART 0. Hence, the SFR register map of the two
|
||||
* USART peripherals will overlap (with the IE register of the second USART
|
||||
* being located at the first padding of the first USART). The padding bytes
|
||||
* are intentionally declared as `const` to aid in preventing accidentally
|
||||
* overwriting registers of the other USART's SFR registers.
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 IE; /**< USART Interrupt Enable Register */
|
||||
const uint8_t _pad1;/**< Padding */
|
||||
REG8 IFG; /**< USART Interrupt Flag Register */
|
||||
const uint8_t _pad2;/**< Padding */
|
||||
REG8 ME; /**< Module Enable Register */
|
||||
} msp_usart_sfr_t;
|
||||
|
||||
/**
|
||||
* @name USART clock selection
|
||||
*
|
||||
* The vendor header files expose clock configurations selection field as one
|
||||
* bitmask per bit. This is pretty hard to read in the code, so we provide
|
||||
* alias with better names.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define UXTCTL_SSEL_UCLKI 0 /**< Clock USART using UCLKI clock */
|
||||
#define UXTCTL_SSEL_ACLK SSEL0 /**< Clock USART using auxiliary clock */
|
||||
#define UXTCTL_SSEL_SMCLK SSEL1 /**< Clock USART using sub-system master clock */
|
||||
#define UXTCTL_SSEL_MASK (SSEL0 | SSEL1) /**< Mask to retrieve SSEL field */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Typing of base register objects
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief USART 0 SFR register map
|
||||
*/
|
||||
extern msp_usart_sfr_t USART_0_SFR;
|
||||
/**
|
||||
* @brief USART 1 SFR register map
|
||||
*/
|
||||
extern msp_usart_sfr_t USART_1_SFR;
|
||||
/**
|
||||
* @brief USART 0 register map
|
||||
*
|
||||
* @details The address is provided by the linker script
|
||||
*/
|
||||
extern msp_usart_t USART_0;
|
||||
/**
|
||||
* @brief USART 1 register map
|
||||
*
|
||||
* @details The address is provided by the linker script
|
||||
*/
|
||||
extern msp_usart_t USART_1;
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* X1XX_MSP430_REGS_H */
|
||||
/** @} */
|
83
cpu/msp430/include/x1xx/periph_cpu.h
Normal file
83
cpu/msp430/include/x1xx/periph_cpu.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430_x1xx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CPU specific definitions for internal peripheral handling
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef X1XX_PERIPH_CPU_H
|
||||
#define X1XX_PERIPH_CPU_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "periph_cpu_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Override SPI mode selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_MODE_T /**< MSP430 x1xx has a custom spi_mode_t */
|
||||
/**
|
||||
* @brief Support SPI modes
|
||||
*
|
||||
* | Field | Name | Description |
|
||||
* |:------ |:--------------------- |:----------------------------------------------------- |
|
||||
* | CKPH | Clock phase select | 0 = capture on second edge, 1 = capture on first |
|
||||
* | CKPL | Clock polarity select | 0 = clock is idle-low, 1 = clock is high idle-high |
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_MODE_0 = (CKPH), /**< CPOL=0, CPHA=0 */
|
||||
SPI_MODE_1 = 0, /**< CPOL=0, CPHA=1 */
|
||||
SPI_MODE_2 = (CKPL | CKPH), /**< CPOL=1, CPHA=0 */
|
||||
SPI_MODE_3 = (CKPL) /**< CPOL=1, CPHA=1 */
|
||||
} spi_mode_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Override SPI clock speed selection values
|
||||
* @{
|
||||
*/
|
||||
#define HAVE_SPI_CLK_T /**< MSP430 x1xx has a custom spi_clock_t */
|
||||
/**
|
||||
* @brief Support SPI clock frequencies
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_CLK_100KHZ = 100000, /**< 100 kHz */
|
||||
SPI_CLK_400KHZ = 400000, /**< 400 kHz */
|
||||
SPI_CLK_1MHZ = 1000000, /**< 1 MHz */
|
||||
SPI_CLK_5MHZ = 5000000, /**< 5 MHz */
|
||||
SPI_CLK_10MHZ = SPI_CLK_5MHZ, /**< 10 MHz not supported, falling back to 5 MHz */
|
||||
} spi_clk_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name declare needed generic SPI functions
|
||||
* @{
|
||||
*/
|
||||
#define PERIPH_SPI_NEEDS_INIT_CS /**< use shared spi_init_cs() */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_BYTE /**< use shared spi_transfer_byte() */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REG /**< use shared spi_transfer_reg() */
|
||||
#define PERIPH_SPI_NEEDS_TRANSFER_REGS /**< use shared spi_transfer_regs() */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* X1XX_PERIPH_CPU_H */
|
||||
/** @} */
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430_common
|
||||
* @ingroup cpu_msp430
|
||||
* @{
|
||||
*
|
||||
* @file
|
35
cpu/msp430/kconfigs/f2xx_g2xx/Kconfig
Normal file
35
cpu/msp430/kconfigs/f2xx_g2xx/Kconfig
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright (c) 2020 Freie Universität Berlin
|
||||
# 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 CPU_FAM_MSP430_F2XX_G2XX
|
||||
bool
|
||||
select CPU_MSP430
|
||||
select HAS_CPU_MSP430_F2XX_G2XX
|
||||
|
||||
## CPU Models
|
||||
config CPU_MODEL_MSP430F2617
|
||||
bool
|
||||
select CPU_FAM_MSP430_F2XX_G2XX
|
||||
|
||||
config CPU_MODEL_MSP430F2618
|
||||
bool
|
||||
select CPU_FAM_MSP430_F2XX_G2XX
|
||||
|
||||
## Definition of specific features
|
||||
config HAS_CPU_MSP430_F2XX_G2XX
|
||||
bool
|
||||
help
|
||||
Indicates that an 'MSP430 F2xx/G2xx' CPU is being used.
|
||||
|
||||
## Common CPU symbols
|
||||
config CPU_FAM
|
||||
default "msp430_f2xx_g2xx" if HAS_CPU_MSP430_F2XX_G2XX
|
||||
|
||||
config CPU_MODEL
|
||||
default "msp430f2617" if CPU_MODEL_MSP430F2617
|
||||
default "msp430f2618" if CPU_MODEL_MSP430F2618
|
35
cpu/msp430/kconfigs/x1xx/Kconfig
Normal file
35
cpu/msp430/kconfigs/x1xx/Kconfig
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright (c) 2020 Freie Universität Berlin
|
||||
# 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 CPU_FAM_MSP430_X1XX
|
||||
bool
|
||||
select CPU_MSP430
|
||||
select HAS_CPU_MSP430_X1XX
|
||||
|
||||
## CPU Models
|
||||
config CPU_MODEL_MSP430F1611
|
||||
bool
|
||||
select CPU_FAM_MSP430_X1XX
|
||||
|
||||
config CPU_MODEL_MSP430F1612
|
||||
bool
|
||||
select CPU_FAM_MSP430_X1XX
|
||||
|
||||
## Definition of specific features
|
||||
config HAS_CPU_MSP430_X1XX
|
||||
bool
|
||||
help
|
||||
Indicates that an 'MSP430 x1xx' cpu is being used.
|
||||
|
||||
## Common CPU symbols
|
||||
config CPU_FAM
|
||||
default "msp430_x1xx" if HAS_CPU_MSP430_X1XX
|
||||
|
||||
config CPU_MODEL
|
||||
default "msp430f1611" if CPU_MODEL_MSP430F1611
|
||||
default "msp430f1612" if CPU_MODEL_MSP430F1612
|
@ -20,3 +20,20 @@ SECTIONS
|
||||
_end_fw = . ;
|
||||
} > ROM
|
||||
}
|
||||
|
||||
/* provide address for register maps by taking the address of the first
|
||||
* register (as provided by the vendor files) */
|
||||
|
||||
PROVIDE(PORT_1 = P1IN);
|
||||
PROVIDE(PORT_2 = P2IN);
|
||||
PROVIDE(PORT_3 = P3IN);
|
||||
PROVIDE(PORT_3 = P3IN);
|
||||
PROVIDE(PORT_4 = P4IN);
|
||||
PROVIDE(PORT_5 = P5IN);
|
||||
PROVIDE(PORT_6 = P6IN);
|
||||
|
||||
/* no typo: TBIV indeed comes before TAIV in memory, see msp_timer_ivec_t */
|
||||
PROVIDE(TIMER_IVEC = TBIV);
|
||||
|
||||
PROVIDE(TIMER_A = TACTL);
|
||||
PROVIDE(TIMER_B = TBCTL);
|
6
cpu/msp430/ldscripts/msp430_f2xx_g2xx.ld
Normal file
6
cpu/msp430/ldscripts/msp430_f2xx_g2xx.ld
Normal file
@ -0,0 +1,6 @@
|
||||
/* provide address for USCI register map by taking the address of the first
|
||||
* register (as provided by the vendor files) */
|
||||
PROVIDE(USCI_A0 = UCA0ABCTL);
|
||||
PROVIDE(USCI_A1 = UCA1ABCTL);
|
||||
PROVIDE(USCI_B0 = UCB0CTL0);
|
||||
PROVIDE(USCI_B1 = UCB1CTL0);
|
7
cpu/msp430/ldscripts/msp430_x1xx.ld
Normal file
7
cpu/msp430/ldscripts/msp430_x1xx.ld
Normal file
@ -0,0 +1,7 @@
|
||||
/* provide address for UASRT register map by taking the address of the first
|
||||
* register (as provided by the vendor files) */
|
||||
PROVIDE(USART_0_SFR = IE1);
|
||||
PROVIDE(USART_1_SFR = IE2);
|
||||
|
||||
PROVIDE(USART_0 = U0CTL);
|
||||
PROVIDE(USART_1 = U1CTL);
|
@ -1,3 +1,4 @@
|
||||
INCLUDE msp430f1611.ld
|
||||
INCLUDE msp430_common.ld
|
||||
INCLUDE msp430_x1xx.ld
|
||||
INCLUDE xfa.ld
|
@ -1,3 +1,4 @@
|
||||
INCLUDE msp430f1612.ld
|
||||
INCLUDE msp430_common.ld
|
||||
INCLUDE msp430_x1xx.ld
|
||||
INCLUDE xfa.ld
|
@ -1,3 +1,4 @@
|
||||
INCLUDE msp430f1617.ld
|
||||
INCLUDE msp430_common.ld
|
||||
INCLUDE msp430_x1xx.ld
|
||||
INCLUDE xfa.ld
|
@ -1,3 +1,4 @@
|
||||
INCLUDE msp430f2617.ld
|
||||
INCLUDE msp430_common.ld
|
||||
INCLUDE msp430_f2xx_g2xx.ld
|
||||
INCLUDE xfa.ld
|
@ -1,3 +1,4 @@
|
||||
INCLUDE msp430f2618.ld
|
||||
INCLUDE msp430_common.ld
|
||||
INCLUDE msp430_f2xx_g2xx.ld
|
||||
INCLUDE xfa.ld
|
12
cpu/msp430/periph/Kconfig
Normal file
12
cpu/msp430/periph/Kconfig
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2023 Marian Buschsieweke
|
||||
#
|
||||
# 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 MODULE_PERIPH
|
||||
bool
|
||||
default y
|
||||
help
|
||||
MSP430 peripheral drivers.
|
23
cpu/msp430/periph/Makefile
Normal file
23
cpu/msp430/periph/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
MODULE = periph
|
||||
|
||||
# All supported MSP430 families use special serial IP block that implements
|
||||
# various serial bus interfaces using the same hardware block. For the
|
||||
# MSP430 x1xx family, the block is called USART. For the MSP430 F2xx/G2xx
|
||||
# family it is the (incompatible) USCI.
|
||||
ifeq (msp430_x1xx,$(CPU_FAM))
|
||||
SERIAL_IP_BLOCK := usart
|
||||
endif
|
||||
ifeq (msp430_f2xx_g2xx,$(CPU_FAM))
|
||||
SERIAL_IP_BLOCK := usci
|
||||
endif
|
||||
|
||||
# select family specific peripheral drivers.
|
||||
ifneq (,$(filter periph_uart,$(USEMODULE)))
|
||||
SRC += uart_$(SERIAL_IP_BLOCK).c
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_spi,$(USEMODULE)))
|
||||
SRC += spi_$(SERIAL_IP_BLOCK).c
|
||||
endif
|
||||
|
||||
include $(RIOTMAKE)/periph.mk
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430fxyz
|
||||
* @ingroup cpu_msp430
|
||||
* @{
|
||||
*
|
||||
* @file
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430fxyz
|
||||
* @ingroup cpu_msp430
|
||||
* @ingroup drivers_periph_gpio
|
||||
* @{
|
||||
*
|
||||
@ -19,8 +19,9 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "bitarithm.h"
|
||||
#include "container.h"
|
||||
#include "cpu.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
/**
|
||||
@ -36,20 +37,20 @@
|
||||
static msp_port_t *_port(gpio_t pin)
|
||||
{
|
||||
switch (pin >> 8) {
|
||||
case 1:
|
||||
return PORT_1;
|
||||
case 2:
|
||||
return PORT_2;
|
||||
case 3:
|
||||
return PORT_3;
|
||||
case 4:
|
||||
return PORT_4;
|
||||
case 5:
|
||||
return PORT_5;
|
||||
case 6:
|
||||
return PORT_6;
|
||||
default:
|
||||
return NULL;
|
||||
case 1:
|
||||
return &PORT_1.base;
|
||||
case 2:
|
||||
return &PORT_2.base;
|
||||
case 3:
|
||||
return &PORT_3.base;
|
||||
case 4:
|
||||
return &PORT_4.base;
|
||||
case 5:
|
||||
return &PORT_5.base;
|
||||
case 6:
|
||||
return &PORT_6.base;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,12 +59,15 @@ static inline uint8_t _pin(gpio_t pin)
|
||||
return (uint8_t)(pin & 0xff);
|
||||
}
|
||||
|
||||
static inline msp_port_isr_t *_isr_port(gpio_t pin)
|
||||
static inline msp_port_p1_p2_t *_isr_port(gpio_t pin)
|
||||
{
|
||||
msp_port_t *p = _port(pin);
|
||||
if ((p == PORT_1) || (p == PORT_2)) {
|
||||
return (msp_port_isr_t *)p;
|
||||
/* checking for (pin >> 8) <= 2 requires 6 byte of .text more than
|
||||
* checking the resulting address */
|
||||
msp_port_p1_p2_t *port = container_of(_port(pin), msp_port_p1_p2_t, base);
|
||||
if ((port == &PORT_1) || (port == &PORT_2)) {
|
||||
return port;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -90,12 +94,12 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
void gpio_periph_mode(gpio_t pin, bool enable)
|
||||
{
|
||||
REG8 *sel;
|
||||
msp_port_isr_t *isrport = _isr_port(pin);
|
||||
msp_port_p1_p2_t *isrport = _isr_port(pin);
|
||||
if (isrport) {
|
||||
sel = &(isrport->SEL);
|
||||
}
|
||||
else {
|
||||
msp_port_t *port = _port(pin);
|
||||
msp_port_p3_p6_t *port = container_of(_port(pin), msp_port_p3_p6_t, base);
|
||||
if (port) {
|
||||
sel = &(port->SEL);
|
||||
}
|
||||
@ -156,13 +160,13 @@ static gpio_isr_ctx_t isr_ctx[ISR_NUMOF];
|
||||
static int _ctx(gpio_t pin)
|
||||
{
|
||||
int i = bitarithm_lsb(_pin(pin));
|
||||
return (_port(pin) == PORT_1) ? i : (i + 8);
|
||||
return (_port(pin) == &PORT_1.base) ? i : (i + 8);
|
||||
}
|
||||
|
||||
int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
|
||||
gpio_cb_t cb, void *arg)
|
||||
{
|
||||
msp_port_isr_t *port = _isr_port(pin);
|
||||
msp_port_p1_p2_t *port = _isr_port(pin);
|
||||
|
||||
/* check if port, pull resistor and flank configuration are valid */
|
||||
if ((port == NULL) || (flank == GPIO_BOTH)) {
|
||||
@ -189,7 +193,7 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
|
||||
|
||||
void gpio_irq_enable(gpio_t pin)
|
||||
{
|
||||
msp_port_isr_t *port = _isr_port(pin);
|
||||
msp_port_p1_p2_t *port = _isr_port(pin);
|
||||
if (port) {
|
||||
port->IE |= _pin(pin);
|
||||
}
|
||||
@ -197,13 +201,13 @@ void gpio_irq_enable(gpio_t pin)
|
||||
|
||||
void gpio_irq_disable(gpio_t pin)
|
||||
{
|
||||
msp_port_isr_t *port = _isr_port(pin);
|
||||
msp_port_p1_p2_t *port = _isr_port(pin);
|
||||
if (port) {
|
||||
port->IE &= ~(_pin(pin));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void isr_handler(msp_port_isr_t *port, int ctx)
|
||||
static inline void isr_handler(msp_port_p1_p2_t *port, int ctx)
|
||||
{
|
||||
for (unsigned i = 0; i < PINS_PER_PORT; i++) {
|
||||
if ((port->IE & (1 << i)) && (port->IFG & (1 << i))) {
|
||||
@ -216,14 +220,14 @@ static inline void isr_handler(msp_port_isr_t *port, int ctx)
|
||||
ISR(PORT1_VECTOR, isr_port1)
|
||||
{
|
||||
__enter_isr();
|
||||
isr_handler((msp_port_isr_t *)PORT_1, 0);
|
||||
isr_handler(&PORT_1, 0);
|
||||
__exit_isr();
|
||||
}
|
||||
|
||||
ISR(PORT2_VECTOR, isr_port2)
|
||||
{
|
||||
__enter_isr();
|
||||
isr_handler((msp_port_isr_t *)PORT_2, 8);
|
||||
isr_handler(&PORT_2, 8);
|
||||
__exit_isr();
|
||||
}
|
||||
#endif /* MODULE_PERIPH_GPIO_IRQ */
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430_common
|
||||
* @ingroup cpu_msp430
|
||||
* @ingroup drivers_periph_pm
|
||||
* @{
|
||||
*
|
141
cpu/msp430/periph/spi_usart.c
Normal file
141
cpu/msp430/periph/spi_usart.c
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 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 cpu_msp430_x1xx
|
||||
* @ingroup drivers_periph_spi
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level SPI driver implementation
|
||||
*
|
||||
* This SPI driver implementation does only support one single SPI device for
|
||||
* now. This is sufficient, as most MSP430 x1xx CPU's only support two serial
|
||||
* devices - one used as UART and one as SPI.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mutex.h"
|
||||
#include "periph/spi.h"
|
||||
|
||||
/**
|
||||
* @brief Mutex for locking the SPI device
|
||||
*/
|
||||
static mutex_t spi_lock = MUTEX_INIT;
|
||||
|
||||
void spi_init(spi_t bus)
|
||||
{
|
||||
assert((unsigned)bus < SPI_NUMOF);
|
||||
|
||||
/* put SPI device in reset state */
|
||||
SPI_BASE->CTL = SWRST;
|
||||
SPI_BASE->CTL |= (CHAR | SYNC | MM);
|
||||
SPI_BASE->RCTL = 0;
|
||||
SPI_BASE->MCTL = 0;
|
||||
/* enable SPI mode */
|
||||
SPI_SFR->ME |= SPI_ME_BIT;
|
||||
|
||||
/* trigger the pin configuration */
|
||||
spi_init_pins(bus);
|
||||
}
|
||||
|
||||
void spi_init_pins(spi_t bus)
|
||||
{
|
||||
(void)bus;
|
||||
|
||||
gpio_periph_mode(SPI_PIN_MISO, true);
|
||||
gpio_periph_mode(SPI_PIN_MOSI, true);
|
||||
gpio_periph_mode(SPI_PIN_CLK, true);
|
||||
}
|
||||
|
||||
void spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
|
||||
{
|
||||
(void)bus;
|
||||
(void)cs;
|
||||
assert((unsigned)bus < SPI_NUMOF);
|
||||
assert(clk != SPI_CLK_10MHZ);
|
||||
|
||||
/* lock the bus */
|
||||
mutex_lock(&spi_lock);
|
||||
|
||||
/* calculate baudrate */
|
||||
uint32_t br = msp430_submain_clock_freq() / clk;
|
||||
/* make sure the is not smaller then 2 */
|
||||
if (br < 2) {
|
||||
br = 2;
|
||||
}
|
||||
SPI_BASE->BR0 = (uint8_t)br;
|
||||
SPI_BASE->BR1 = (uint8_t)(br >> 8);
|
||||
|
||||
/* configure bus mode */
|
||||
/* configure mode */
|
||||
SPI_BASE->TCTL = (UXTCTL_SSEL_SMCLK | STC | mode);
|
||||
/* release from software reset */
|
||||
SPI_BASE->CTL &= ~(SWRST);
|
||||
}
|
||||
|
||||
void spi_release(spi_t bus)
|
||||
{
|
||||
(void)bus;
|
||||
/* put SPI device back in reset state */
|
||||
SPI_BASE->CTL |= SWRST;
|
||||
|
||||
/* release the bus */
|
||||
mutex_unlock(&spi_lock);
|
||||
}
|
||||
|
||||
void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
|
||||
const void *out, void *in, size_t len)
|
||||
{
|
||||
(void)bus;
|
||||
|
||||
const uint8_t *out_buf = out;
|
||||
uint8_t *in_buf = in;
|
||||
|
||||
assert(out_buf || in_buf);
|
||||
|
||||
if (cs != SPI_CS_UNDEF) {
|
||||
gpio_clear((gpio_t)cs);
|
||||
}
|
||||
|
||||
/* if we only send out data, we do this the fast way... */
|
||||
if (!in_buf) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (!(SPI_SFR->IFG & SPI_IE_TX_BIT)) {}
|
||||
SPI_BASE->TXBUF = out_buf[i];
|
||||
}
|
||||
/* finally we need to wait, until all transfers are complete */
|
||||
while (!(SPI_SFR->IFG & SPI_IE_TX_BIT) || !(SPI_SFR->IFG & SPI_IE_RX_BIT)) {}
|
||||
SPI_BASE->RXBUF;
|
||||
}
|
||||
else if (!out_buf) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
SPI_BASE->TXBUF = 0;
|
||||
while (!(SPI_SFR->IFG & SPI_IE_RX_BIT)) {}
|
||||
in_buf[i] = (char)SPI_BASE->RXBUF;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (!(SPI_SFR->IFG & SPI_IE_TX_BIT)) {}
|
||||
SPI_BASE->TXBUF = out_buf[i];
|
||||
while (!(SPI_SFR->IFG & SPI_IE_RX_BIT)) {}
|
||||
in_buf[i] = (char)SPI_BASE->RXBUF;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!cont) && (cs != SPI_CS_UNDEF)) {
|
||||
gpio_set((gpio_t)cs);
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430fxyz
|
||||
* @ingroup cpu_msp430_f2xx_g2xx
|
||||
* @ingroup drivers_periph_spi
|
||||
* @{
|
||||
*
|
||||
@ -38,20 +38,9 @@ void spi_init(spi_t bus)
|
||||
{
|
||||
assert((unsigned)bus < SPI_NUMOF);
|
||||
|
||||
/* we need to differentiate between the legacy SPI device and USCI */
|
||||
#ifndef SPI_USE_USCI
|
||||
/* put SPI device in reset state */
|
||||
SPI_BASE->CTL = USART_CTL_SWRST;
|
||||
SPI_BASE->CTL |= (USART_CTL_CHAR | USART_CTL_SYNC | USART_CTL_MM);
|
||||
SPI_BASE->RCTL = 0;
|
||||
SPI_BASE->MCTL = 0;
|
||||
/* enable SPI mode */
|
||||
SPI_ME |= SPI_ME_BIT;
|
||||
#else
|
||||
/* reset SPI device */
|
||||
SPI_BASE->CTL1 = USCI_SPI_CTL1_SWRST;
|
||||
SPI_BASE->CTL1 |= (USCI_SPI_CTL1_SSEL_SMCLK);
|
||||
#endif
|
||||
SPI_BASE->CTL1 = UCSWRST;
|
||||
SPI_BASE->CTL1 |= UCSSEL_SMCLK;
|
||||
|
||||
/* trigger the pin configuration */
|
||||
spi_init_pins(bus);
|
||||
@ -77,7 +66,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 = msp430_fxyz_submain_clock_freq() / clk;
|
||||
uint32_t br = msp430_submain_clock_freq() / clk;
|
||||
/* make sure the is not smaller then 2 */
|
||||
if (br < 2) {
|
||||
br = 2;
|
||||
@ -86,29 +75,17 @@ void spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t clk)
|
||||
SPI_BASE->BR1 = (uint8_t)(br >> 8);
|
||||
|
||||
/* configure bus mode */
|
||||
#ifndef SPI_USE_USCI
|
||||
/* configure mode */
|
||||
SPI_BASE->TCTL = (USART_TCTL_SSEL_SMCLK | USART_TCTL_STC | mode);
|
||||
SPI_BASE->CTL0 = (UCSYNC | UCMST | UCMODE_0 | UCMSB | mode);
|
||||
/* release from software reset */
|
||||
SPI_BASE->CTL &= ~(USART_CTL_SWRST);
|
||||
#else
|
||||
/* configure mode */
|
||||
SPI_BASE->CTL0 = (USCI_SPI_CTL0_UCSYNC | USCI_SPI_CTL0_MST|
|
||||
USCI_SPI_CTL0_MODE_0 | USCI_SPI_CTL0_MSB | mode);
|
||||
/* release from software reset */
|
||||
SPI_BASE->CTL1 &= ~(USCI_SPI_CTL1_SWRST);
|
||||
#endif
|
||||
SPI_BASE->CTL1 &= ~(UCSWRST);
|
||||
}
|
||||
|
||||
void spi_release(spi_t bus)
|
||||
{
|
||||
(void)bus;
|
||||
/* put SPI device back in reset state */
|
||||
#ifndef SPI_USE_USCI
|
||||
SPI_BASE->CTL |= (USART_CTL_SWRST);
|
||||
#else
|
||||
SPI_BASE->CTL1 |= (USCI_SPI_CTL1_SWRST);
|
||||
#endif
|
||||
SPI_BASE->CTL1 |= UCSWRST;
|
||||
|
||||
/* release the bus */
|
||||
mutex_unlock(&spi_lock);
|
||||
@ -135,11 +112,7 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont,
|
||||
SPI_BASE->TXBUF = out_buf[i];
|
||||
}
|
||||
/* finally we need to wait, until all transfers are complete */
|
||||
#ifndef SPI_USE_USCI
|
||||
while (!(SPI_IF & SPI_IE_TX_BIT) || !(SPI_IF & SPI_IE_RX_BIT)) {}
|
||||
#else
|
||||
while (SPI_BASE->STAT & USCI_SPI_STAT_UCBUSY) {}
|
||||
#endif
|
||||
while (SPI_BASE->STAT & UCBUSY) {}
|
||||
SPI_BASE->RXBUF;
|
||||
}
|
||||
else if (!out_buf) {
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_msp430fxyz
|
||||
* @ingroup cpu_msp430
|
||||
* @ingroup drivers_periph_timer
|
||||
* @{
|
||||
*
|
||||
@ -52,18 +52,18 @@ int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg)
|
||||
}
|
||||
|
||||
/* reset the timer A configuration */
|
||||
TIMER_BASE->CTL = TIMER_CTL_CLR;
|
||||
TIMER_BASE->CTL = TACLR;
|
||||
/* save callback */
|
||||
isr_cb = cb;
|
||||
isr_arg = arg;
|
||||
/* configure timer to use the SMCLK with prescaler of 8 */
|
||||
TIMER_BASE->CTL = (TIMER_CTL_TASSEL_SMCLK | TIMER_CTL_ID_DIV8);
|
||||
TIMER_BASE->CTL = (TXSSEL_SMCLK | TXID_DIV_8);
|
||||
/* configure CC channels */
|
||||
for (int i = 0; i < TIMER_CHAN; i++) {
|
||||
TIMER_BASE->CCTL[i] = 0;
|
||||
}
|
||||
/* start the timer in continuous mode */
|
||||
TIMER_BASE->CTL |= TIMER_CTL_MC_CONT;
|
||||
TIMER_BASE->CTL |= TXMC_CONT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -73,8 +73,8 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value)
|
||||
return -1;
|
||||
}
|
||||
TIMER_BASE->CCR[channel] = value;
|
||||
TIMER_BASE->CCTL[channel] &= ~(TIMER_CCTL_CCIFG);
|
||||
TIMER_BASE->CCTL[channel] |= (TIMER_CCTL_CCIE);
|
||||
TIMER_BASE->CCTL[channel] &= ~(CCIFG);
|
||||
TIMER_BASE->CCTL[channel] |= CCIE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ int timer_clear(tim_t dev, int channel)
|
||||
if (dev != 0 || channel >= TIMER_CHAN) {
|
||||
return -1;
|
||||
}
|
||||
TIMER_BASE->CCTL[channel] &= ~(TIMER_CCTL_CCIE);
|
||||
TIMER_BASE->CCTL[channel] &= ~(CCIE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -96,20 +96,20 @@ unsigned int timer_read(tim_t dev)
|
||||
void timer_start(tim_t dev)
|
||||
{
|
||||
(void)dev;
|
||||
TIMER_BASE->CTL |= TIMER_CTL_MC_CONT;
|
||||
TIMER_BASE->CTL |= TXMC_CONT;
|
||||
}
|
||||
|
||||
void timer_stop(tim_t dev)
|
||||
{
|
||||
(void)dev;
|
||||
TIMER_BASE->CTL &= ~(TIMER_CTL_MC_MASK);
|
||||
TIMER_BASE->CTL &= ~(TXMC_MASK);
|
||||
}
|
||||
|
||||
ISR(TIMER_ISR_CC0, isr_timer_a_cc0)
|
||||
{
|
||||
__enter_isr();
|
||||
|
||||
TIMER_BASE->CCTL[0] &= ~(TIMER_CCTL_CCIE);
|
||||
TIMER_BASE->CCTL[0] &= ~(CCIE);
|
||||
isr_cb(isr_arg, 0);
|
||||
|
||||
__exit_isr();
|
||||
@ -119,8 +119,8 @@ ISR(TIMER_ISR_CCX, isr_timer_a_ccx)
|
||||
{
|
||||
__enter_isr();
|
||||
|
||||
int chan = (int)(TIMER_IVEC->TAIV >> 1);
|
||||
TIMER_BASE->CCTL[chan] &= ~(TIMER_CCTL_CCIE);
|
||||
int chan = (int)(TIMER_IVEC.TAIV >> 1);
|
||||
TIMER_BASE->CCTL[chan] &= ~(CCIE);
|
||||
isr_cb(isr_arg, chan);
|
||||
|
||||
__exit_isr();
|
127
cpu/msp430/periph/uart_usart.c
Normal file
127
cpu/msp430/periph/uart_usart.c
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430_x1xx
|
||||
* @ingroup drivers_periph_uart
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level UART driver implementation
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/uart.h"
|
||||
|
||||
/**
|
||||
* @brief Keep track of the interrupt context
|
||||
* @{
|
||||
*/
|
||||
static uart_rx_cb_t ctx_rx_cb;
|
||||
static void *ctx_isr_arg;
|
||||
/** @} */
|
||||
|
||||
static int init_base(uart_t uart, uint32_t baudrate);
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
{
|
||||
int res = init_base(uart, baudrate);
|
||||
if (res != UART_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* save interrupt context */
|
||||
ctx_rx_cb = rx_cb;
|
||||
ctx_isr_arg = arg;
|
||||
/* reset interrupt flags and enable RX interrupt */
|
||||
UART_SFR->IE &= ~(UART_IE_TX_BIT);
|
||||
UART_SFR->IFG &= ~(UART_IE_RX_BIT);
|
||||
UART_SFR->IFG |= (UART_IE_TX_BIT);
|
||||
UART_SFR->IE |= (UART_IE_RX_BIT);
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
static int init_base(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
if (uart != 0) {
|
||||
return UART_NODEV;
|
||||
}
|
||||
|
||||
/* get the default UART for now -> TODO: enable for multiple devices */
|
||||
msp_usart_t *dev = UART_BASE;
|
||||
|
||||
/* power off and reset device */
|
||||
uart_poweroff(uart);
|
||||
dev->CTL = SWRST;
|
||||
/* configure to 8N1 and using the SMCLK*/
|
||||
dev->CTL |= CHAR;
|
||||
dev->TCTL = (TXEPT | UXTCTL_SSEL_SMCLK);
|
||||
dev->RCTL = 0x00;
|
||||
/* baudrate configuration */
|
||||
uint16_t br = (uint16_t)(msp430_submain_clock_freq() / baudrate);
|
||||
dev->BR0 = (uint8_t)br;
|
||||
dev->BR1 = (uint8_t)(br >> 8);
|
||||
/* TODO: calculate value for modulation register */
|
||||
dev->MCTL = 0;
|
||||
/* configure pins -> TODO: move into GPIO driver (once implemented) */
|
||||
UART_PORT->SEL |= (UART_RX_PIN | UART_TX_PIN);
|
||||
msp_port_t *port = &UART_PORT->base;
|
||||
port->OD |= UART_RX_PIN;
|
||||
port->OD &= ~(UART_TX_PIN);
|
||||
port->DIR |= UART_TX_PIN;
|
||||
port->DIR &= ~(UART_RX_PIN);
|
||||
/* enable receiver and transmitter */
|
||||
uart_poweron(uart);
|
||||
/* and finally release the software reset bit */
|
||||
dev->CTL &= ~(SWRST);
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
{
|
||||
(void)uart;
|
||||
msp_usart_t *dev = UART_BASE;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (!(dev->TCTL & TXEPT)) {}
|
||||
dev->TXBUF = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweron(uart_t uart)
|
||||
{
|
||||
(void)uart;
|
||||
UART_SFR->ME |= UART_ME_BITS;
|
||||
}
|
||||
|
||||
void uart_poweroff(uart_t uart)
|
||||
{
|
||||
(void)uart;
|
||||
UART_SFR->ME &= ~(UART_ME_BITS);
|
||||
}
|
||||
|
||||
ISR(UART_RX_ISR, isr_uart_0_rx)
|
||||
{
|
||||
__enter_isr();
|
||||
|
||||
/* read character (resets interrupt flag) */
|
||||
char c = UART_BASE->RXBUF;
|
||||
|
||||
/* only call callback if there was no receive error */
|
||||
if(! (UART_BASE->RCTL & RXERR)) {
|
||||
ctx_rx_cb(ctx_isr_arg, c);
|
||||
}
|
||||
|
||||
__exit_isr();
|
||||
}
|
125
cpu/msp430/periph/uart_usci.c
Normal file
125
cpu/msp430/periph/uart_usci.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430_f2xx_g2xx
|
||||
* @ingroup drivers_periph_uart
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level UART driver implementation
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/uart.h"
|
||||
|
||||
/**
|
||||
* @brief Keep track of the interrupt context
|
||||
* @{
|
||||
*/
|
||||
static uart_rx_cb_t ctx_rx_cb;
|
||||
static void *ctx_isr_arg;
|
||||
/** @} */
|
||||
|
||||
static int init_base(uart_t uart, uint32_t baudrate);
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
{
|
||||
if (init_base(uart, baudrate) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* save interrupt context */
|
||||
ctx_rx_cb = rx_cb;
|
||||
ctx_isr_arg = arg;
|
||||
/* reset interrupt flags and enable RX interrupt */
|
||||
UART_IF &= ~(UART_IE_RX_BIT);
|
||||
UART_IF |= (UART_IE_TX_BIT);
|
||||
UART_IE |= (UART_IE_RX_BIT);
|
||||
UART_IE &= ~(UART_IE_TX_BIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_base(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
if (uart != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get the default UART for now -> TODO: enable for multiple devices */
|
||||
msp_usci_a_t *dev = UART_BASE;
|
||||
|
||||
/* put device in reset mode while configuration is going on */
|
||||
dev->CTL1 = UCSWRST;
|
||||
/* configure to UART, using SMCLK in 8N1 mode */
|
||||
dev->CTL1 |= UCSSEL_SMCLK;
|
||||
dev->CTL0 = 0;
|
||||
dev->STAT = 0;
|
||||
/* configure baudrate */
|
||||
uint32_t base = ((msp430_submain_clock_freq() << 7) / baudrate);
|
||||
uint16_t br = (uint16_t)(base >> 7);
|
||||
uint8_t brs = (((base & 0x3f) * 8) >> 7);
|
||||
dev->BR0 = (uint8_t)br;
|
||||
dev->BR1 = (uint8_t)(br >> 8);
|
||||
dev->MCTL = (brs << UCBRS_POS);
|
||||
/* pin configuration -> TODO: move to GPIO driver once implemented */
|
||||
UART_RX_PORT->SEL |= UART_RX_PIN;
|
||||
UART_TX_PORT->SEL |= UART_TX_PIN;
|
||||
UART_RX_PORT->base.DIR &= ~(UART_RX_PIN);
|
||||
UART_TX_PORT->base.DIR |= UART_TX_PIN;
|
||||
/* releasing the software reset bit starts the UART */
|
||||
dev->CTL1 &= ~(UCSWRST);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
{
|
||||
(void)uart;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (!(UART_IF & UART_IE_TX_BIT)) {}
|
||||
UART_BASE->TXBUF = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweron(uart_t uart)
|
||||
{
|
||||
(void)uart;
|
||||
/* n/a */
|
||||
}
|
||||
|
||||
void uart_poweroff(uart_t uart)
|
||||
{
|
||||
(void)uart;
|
||||
/* n/a */
|
||||
}
|
||||
|
||||
ISR(UART_RX_ISR, isr_uart_0_rx)
|
||||
{
|
||||
__enter_isr();
|
||||
|
||||
uint8_t stat = UART_BASE->STAT;
|
||||
uint8_t data = (uint8_t)UART_BASE->RXBUF;
|
||||
|
||||
if (stat & (UCFE | UCOE | UCPE | UCBRK)) {
|
||||
/* some error which we do not handle, just do a pseudo read to reset the
|
||||
* status register */
|
||||
(void)data;
|
||||
}
|
||||
else {
|
||||
ctx_rx_cb(ctx_isr_arg, data);
|
||||
}
|
||||
|
||||
__exit_isr();
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
MODULE = msp430_common
|
||||
|
||||
DIRS = periph
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -1,2 +0,0 @@
|
||||
# msp430 uses newlib by default
|
||||
DEFAULT_MODULE += newlib
|
@ -1,3 +0,0 @@
|
||||
MODULE = msp430_common_periph
|
||||
|
||||
include $(RIOTMAKE)/periph.mk
|
@ -1,50 +0,0 @@
|
||||
# Copyright (c) 2020 Freie Universität Berlin
|
||||
# 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 CPU_FAM_MSP430F
|
||||
bool
|
||||
select CPU_CORE_MSP430
|
||||
select HAS_CPU_MSP430FXYZ
|
||||
|
||||
## CPU Models
|
||||
config CPU_MODEL_MSP430F1611
|
||||
bool
|
||||
select CPU_FAM_MSP430F
|
||||
|
||||
config CPU_MODEL_MSP430F1612
|
||||
bool
|
||||
select CPU_FAM_MSP430F
|
||||
|
||||
config CPU_MODEL_MSP430F2617
|
||||
bool
|
||||
select CPU_FAM_MSP430F
|
||||
|
||||
config CPU_MODEL_MSP430F2618
|
||||
bool
|
||||
select CPU_FAM_MSP430F
|
||||
|
||||
## Definition of specific features
|
||||
config HAS_CPU_MSP430FXYZ
|
||||
bool
|
||||
help
|
||||
Indicates that an 'msp430fxyz' cpu is being used.
|
||||
|
||||
## Common CPU symbols
|
||||
config CPU_FAM
|
||||
default "msp430f" if CPU_FAM_MSP430F
|
||||
|
||||
config CPU_MODEL
|
||||
default "msp430f1611" if CPU_MODEL_MSP430F1611
|
||||
default "msp430f1612" if CPU_MODEL_MSP430F1612
|
||||
default "msp430f2617" if CPU_MODEL_MSP430F2617
|
||||
default "msp430f2618" if CPU_MODEL_MSP430F2618
|
||||
|
||||
config CPU
|
||||
default "msp430fxyz" if CPU_FAM_MSP430F
|
||||
|
||||
source "$(RIOTCPU)/msp430_common/Kconfig"
|
@ -1,7 +0,0 @@
|
||||
MODULE =cpu
|
||||
|
||||
include $(RIOTCPU)/$(CPU)/Makefile.include
|
||||
|
||||
DIRS = $(RIOTCPU)/msp430_common periph
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -1 +0,0 @@
|
||||
include $(RIOTCPU)/msp430_common/Makefile.default
|
@ -1 +0,0 @@
|
||||
include $(RIOTCPU)/msp430_common/Makefile.dep
|
@ -1,3 +0,0 @@
|
||||
CPU_FAM = msp430f
|
||||
|
||||
include $(RIOTCPU)/msp430_common/Makefile.features
|
@ -1 +0,0 @@
|
||||
include $(RIOTCPU)/msp430_common/Makefile.include
|
@ -1,445 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430fxyz
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Cortex CMSIS style definition of MSP430 registers
|
||||
*
|
||||
* @todo This file is incomplete, not all registers are listed. Further
|
||||
* There are probably some inconsistencies throughout the MSP430
|
||||
* family which need to be addressed.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef MSP430_REGS_H
|
||||
#define MSP430_REGS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Shortcut to specify 8-bit wide registers
|
||||
*/
|
||||
#define REG8 volatile uint8_t
|
||||
|
||||
/**
|
||||
* @brief Shortcut to specify 16-bit wide registers
|
||||
*/
|
||||
#define REG16 volatile uint16_t
|
||||
|
||||
/**
|
||||
* @brief Special function registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 IE1; /**< interrupt enable 1 */
|
||||
REG8 IE2; /**< interrupt enable 2 */
|
||||
REG8 IFG1; /**< interrupt flag 1 */
|
||||
REG8 IFG2; /**< interrupt flag 2 */
|
||||
REG8 ME1; /**< module enable 1 */
|
||||
REG8 ME2; /**< module enable 2 */
|
||||
} msp_sfr_t;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O Port w/o interrupt functionality (P3-P6)
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 IN; /**< input data */
|
||||
REG8 OD; /**< output data */
|
||||
REG8 DIR; /**< pin direction */
|
||||
REG8 SEL; /**< alternative function select */
|
||||
} msp_port_t;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O Port with interrupt functionality (P1 & P2)
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 IN; /**< input data */
|
||||
REG8 OD; /**< output data */
|
||||
REG8 DIR; /**< pin direction */
|
||||
REG8 IFG; /**< interrupt flag */
|
||||
REG8 IES; /**< interrupt edge select */
|
||||
REG8 IE; /**< interrupt enable */
|
||||
REG8 SEL; /**< alternative function select */
|
||||
} msp_port_isr_t;
|
||||
|
||||
/**
|
||||
* @brief USART (UART, SPI and I2C) registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 CTL; /**< USART control */
|
||||
REG8 TCTL; /**< transmit control */
|
||||
REG8 RCTL; /**< receive control */
|
||||
REG8 MCTL; /**< modulation control */
|
||||
REG8 BR0; /**< baud rate control 0 */
|
||||
REG8 BR1; /**< baud rate control 1 */
|
||||
REG8 RXBUF; /**< receive buffer */
|
||||
REG8 TXBUF; /**< transmit buffer */
|
||||
} msp_usart_t;
|
||||
|
||||
/**
|
||||
* @brief USCI universal serial control interface registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 ABCTL; /**< auto baud rate control */
|
||||
REG8 IRTCTL; /**< IrDA transmit control */
|
||||
REG8 IRRCTL; /**< IrDA receive control */
|
||||
REG8 ACTL0; /**< A control 0 */
|
||||
REG8 ACTL1; /**< A control 1 */
|
||||
REG8 ABR0; /**< A baud rate control 0 */
|
||||
REG8 ABR1; /**< A baud rate control 1 */
|
||||
REG8 AMCTL; /**< A modulation control */
|
||||
REG8 ASTAT; /**< A status */
|
||||
REG8 ARXBUF; /**< A receive buffer */
|
||||
REG8 ATXBUF; /**< A transmit buffer */
|
||||
REG8 BCTL0; /**< B control 0 */
|
||||
REG8 BCTL1; /**< B control 1 */
|
||||
REG8 BBR0; /**< B baud rate 0 */
|
||||
REG8 BBR1; /**< B baud rate 1 */
|
||||
REG8 BI2CIE; /**< I2C interrupt enable */
|
||||
REG8 BSTAT; /**< B status */
|
||||
REG8 BRXBUF; /**< B receive buffer */
|
||||
REG8 BTXBUF; /**< B transmit buffer */
|
||||
} msp_usci_t;
|
||||
|
||||
/**
|
||||
* @brief USCI SPI specific registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG8 CTL0; /**< control 0 */
|
||||
REG8 CTL1; /**< control 1 */
|
||||
REG8 BR0; /**< baud rate 0 */
|
||||
REG8 BR1; /**< baud rate 1 */
|
||||
REG8 reserved; /**< reserved */
|
||||
REG8 STAT; /**< status */
|
||||
REG8 RXBUF; /**< receive buffer */
|
||||
REG8 TXBUF; /**< transmit buffer */
|
||||
} msp_usci_spi_t;
|
||||
|
||||
/**
|
||||
* @brief Timer interrupt status registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG16 TBIV; /**< TIMER_A interrupt status */
|
||||
REG16 reserved[7]; /**< reserved */
|
||||
REG16 TAIV; /**< TIMER_B interrupt status */
|
||||
} msp_timer_ivec_t;
|
||||
|
||||
/**
|
||||
* @brief Timer module registers
|
||||
*/
|
||||
typedef struct {
|
||||
REG16 CTL; /**< timer control */
|
||||
REG16 CCTL[7]; /**< capture compare channel control */
|
||||
REG16 R; /**< current counter value */
|
||||
REG16 CCR[7]; /**< capture compare channel values */
|
||||
} msp_timer_t;
|
||||
|
||||
/**
|
||||
* @brief SFR interrupt enable 1 register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define SFR_IE1_OFIE (0x02)
|
||||
#define SFR_IE1_URXIE0 (0x40)
|
||||
#define SFR_IE1_UTXIE0 (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SFR interrupt enable 2 register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define SFR_IE2_UCA0RXIE (0x01)
|
||||
#define SFR_IE2_UCA0TXIE (0x02)
|
||||
#define SFR_IE2_URXIE2 (0x10)
|
||||
#define SFR_IE2_UTXIE2 (0x20)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SFR interrupt flag 1 register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define SFR_IFG1_OFIFG (0x02)
|
||||
#define SFR_IFG1_URXIFG0 (0x40)
|
||||
#define SFR_IFG1_UTXIFG0 (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SFR interrupt flag 2 register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define SFR_IFG2_UCA0RXIFG (0x01)
|
||||
#define SFR_IFG2_UCA0TXIFG (0x02)
|
||||
#define SFR_IFG2_URXIFG1 (0x10)
|
||||
#define SFR_IFG2_UTXIFG1 (0x20)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SFR module enable register 1
|
||||
* @{
|
||||
*/
|
||||
#define SFR_ME1_USPIE0 (0x40)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief SFR module enable register 2
|
||||
* @{
|
||||
*/
|
||||
#define SFR_ME2_USPIE1 (0x10)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USART control register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define USART_CTL_SWRST (0x01)
|
||||
#define USART_CTL_MM (0x02)
|
||||
#define USART_CTL_SYNC (0x04)
|
||||
#define USART_CTL_LISTEN (0x08)
|
||||
#define USART_CTL_CHAR (0x10)
|
||||
#define USART_CTL_SPB (0x20)
|
||||
#define USART_CTL_PEV (0x40)
|
||||
#define USART_CTL_PENA (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USART transmit control register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define USART_TCTL_TXEPT (0x01)
|
||||
#define USART_TCTL_STC (0x02)
|
||||
#define USART_TCTL_TXWAKE (0x04)
|
||||
#define USART_TCTL_URXSE (0x08)
|
||||
#define USART_TCTL_SSEL_MASK (0x30)
|
||||
#define USART_TCTL_SSEL_UCLKI (0x00)
|
||||
#define USART_TCTL_SSEL_ACLK (0x10)
|
||||
#define USART_TCTL_SSEL_SMCLK (0x20)
|
||||
#define USART_TCTL_CKPL (0x40)
|
||||
#define USART_TCTL_CKPH (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USART receive control register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define USART_RCTL_RXERR (0x01)
|
||||
#define USART_RCTL_RXWAKE (0x02)
|
||||
#define USART_RCTL_URXWIE (0x04)
|
||||
#define USART_RCTL_URXEIE (0x08)
|
||||
#define USART_RCTL_BRK (0x10)
|
||||
#define USART_RCTL_OE (0x20)
|
||||
#define USART_RCTL_PE (0x40)
|
||||
#define USART_RCTL_FE (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USCI control A register 0 bitmap
|
||||
* @{
|
||||
*/
|
||||
#define USCI_ACTL0_UCSYNC (0x01)
|
||||
#define USCI_ACTL0_MODE_MASK (0x06)
|
||||
#define USCI_ACTL0_MODE_UART (0x00)
|
||||
#define USCI_ACTL0_MODE_ILMM (0x02)
|
||||
#define USCI_ACTL0_MODE_ABMM (0x04)
|
||||
#define USCI_ACTL0_MODE_UART_ABR (0x06)
|
||||
#define USCI_ACTL0_SPB (0x08)
|
||||
#define USCI_ACTL0_7BIT (0x10)
|
||||
#define USCI_ACTL0_MSB (0x20)
|
||||
#define USCI_ACTL0_PAR (0x40)
|
||||
#define USCI_ACTL0_PEN (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USCI control register 0 bitmap SPI mode
|
||||
* @{
|
||||
*/
|
||||
#define USCI_SPI_CTL0_UCSYNC (0x01)
|
||||
#define USCI_SPI_CTL0_MODE_3 (0x06)
|
||||
#define USCI_SPI_CTL0_MODE_0 (0x00)
|
||||
#define USCI_SPI_CTL0_MODE_1 (0x02)
|
||||
#define USCI_SPI_CTL0_MODE_2 (0x04)
|
||||
#define USCI_SPI_CTL0_MST (0x08)
|
||||
#define USCI_SPI_CTL0_7BIT (0x10)
|
||||
#define USCI_SPI_CTL0_MSB (0x20)
|
||||
#define USCI_SPI_CTL0_CKPL (0x40)
|
||||
#define USCI_SPI_CTL0_CKPH (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USCI status register bitmap SPI mode
|
||||
* @{
|
||||
*/
|
||||
#define USCI_SPI_STAT_UCBUSY (0x01)
|
||||
#define USCI_SPI_STAT_UCOE (0x20)
|
||||
#define USCI_SPI_STAT_UCFE (0x40)
|
||||
#define USCI_SPI_STAT_UCLISTEN (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USCI control A register 1 bitmap
|
||||
* @{
|
||||
*/
|
||||
#define USCI_ACTL1_SWRST (0x01)
|
||||
#define USCI_ACTL1_TXBRK (0x02)
|
||||
#define USCI_ACTL1_TXADDR (0x04)
|
||||
#define USCI_ACTL1_DORM (0x08)
|
||||
#define USCI_ACTL1_BRKIE (0x10)
|
||||
#define USCI_ACTL1_RXEIE (0x20)
|
||||
#define USCI_ACTL1_SSEL_MASK (0xc0)
|
||||
#define USCI_ACTL1_SSEL_UCLK (0x00)
|
||||
#define USCI_ACTL1_SSEL_ACLK (0x40)
|
||||
#define USCI_ACTL1_SSEL_SMCLK (0xc0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USCI control register 1 bitmap SPI mode
|
||||
* @{
|
||||
*/
|
||||
#define USCI_SPI_CTL1_SWRST (0x01)
|
||||
#define USCI_SPI_CTL1_SSEL_MASK (0xc0)
|
||||
#define USCI_SPI_CTL1_SSEL_NA (0x00)
|
||||
#define USCI_SPI_CTL1_SSEL_ACLK (0x40)
|
||||
#define USCI_SPI_CTL1_SSEL_SMCLK (0xc0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USCI modulation A control register
|
||||
* @{
|
||||
*/
|
||||
#define USCI_AMCTL_OS16 (0x01)
|
||||
#define USCI_AMCTL_BRS_MASK (0xe0)
|
||||
#define USCI_AMCTL_BRS_SHIFT (1U)
|
||||
#define USCI_AMCTL_BRF_MASK (0xf0)
|
||||
#define USCI_AMCTL_BRF_SHIFT (4U)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief USCI status A register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define USCI_ASTAT_BUSY (0x01)
|
||||
#define USCI_ASTAT_IDLE (0x02)
|
||||
#define USCI_ASTAT_ADDR (0x02)
|
||||
#define USCI_ASTAT_RXERR (0x04)
|
||||
#define USCI_ASTAT_BRK (0x08)
|
||||
#define USCI_ASTAT_PE (0x10)
|
||||
#define USCI_ASTAT_OE (0x20)
|
||||
#define USCI_ASTAT_FE (0x40)
|
||||
#define USCI_ASTAT_LISTEN (0x80)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Timer Control register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_CTL_IFG (0x0001)
|
||||
#define TIMER_CTL_IE (0x0002)
|
||||
#define TIMER_CTL_CLR (0x0004)
|
||||
#define TIMER_CTL_MC_MASK (0x0030)
|
||||
#define TIMER_CTL_MC_STOP (0x0000)
|
||||
#define TIMER_CTL_MC_UP (0x0010)
|
||||
#define TIMER_CTL_MC_CONT (0x0020)
|
||||
#define TIMER_CTL_MC_UPDOWN (0x0030)
|
||||
#define TIMER_CTL_ID_MASK (0x00c0)
|
||||
#define TIMER_CTL_ID_DIV1 (0x0000)
|
||||
#define TIMER_CTL_ID_DIV2 (0x0040)
|
||||
#define TIMER_CTL_ID_DIV4 (0x0080)
|
||||
#define TIMER_CTL_ID_DIV8 (0x00c0)
|
||||
#define TIMER_CTL_TASSEL_MASK (0x0300)
|
||||
#define TIMER_CTL_TASSEL_TCLK (0x0000)
|
||||
#define TIMER_CTL_TASSEL_ACLK (0x0100)
|
||||
#define TIMER_CTL_TASSEL_SMCLK (0x0200)
|
||||
#define TIMER_CTL_TASSEL_INV_TCLK (0x0300)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Timer Channel Control register bitmap
|
||||
* @{
|
||||
*/
|
||||
#define TIMER_CCTL_CCIFG (0x0001)
|
||||
#define TIMER_CCTL_COV (0x0002)
|
||||
#define TIMER_CCTL_OUT (0x0004)
|
||||
#define TIMER_CCTL_CCI (0x0008)
|
||||
#define TIMER_CCTL_CCIE (0x0010)
|
||||
#define TIMER_CCTL_OUTMOD_MASK (0x00e0)
|
||||
#define TIMER_CCTL_OUTMOD_OUTVAL (0x0000)
|
||||
#define TIMER_CCTL_OUTMOD_SET (0x0020)
|
||||
#define TIMER_CCTL_OUTMOD_TOG_RESET (0x0040)
|
||||
#define TIMER_CCTL_OUTMOD_SET_RESET (0x0060)
|
||||
#define TIMER_CCTL_OUTMOD_TOGGLE (0x0080)
|
||||
#define TIMER_CCTL_OUTMOD_RESET (0x00a0)
|
||||
#define TIMER_CCTL_OUTMOD_TOG_SET (0x00c0)
|
||||
#define TIMER_CCTL_OUTMOD_RESET_SET (0x00e0)
|
||||
#define TIMER_CCTL_CAP (0x0100)
|
||||
#define TIMER_CCTL_CLLD_MASK (0x0600)
|
||||
#define TIMER_CCTL_SCS (0x0800)
|
||||
#define TIMER_CCTL_CCIS_MASK (0x3000)
|
||||
#define TIMER_CCTL_CM_MASK (0xc000)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Base register address definitions
|
||||
* @{
|
||||
*/
|
||||
#define SFR_BASE ((uint16_t)0x0000)
|
||||
#define PORT_1_BASE ((uint16_t)0x0020)
|
||||
#define PORT_2_BASE ((uint16_t)0x0028)
|
||||
#define PORT_3_BASE ((uint16_t)0x0018)
|
||||
#define PORT_4_BASE ((uint16_t)0x001c)
|
||||
#define PORT_5_BASE ((uint16_t)0x0030)
|
||||
#define PORT_6_BASE ((uint16_t)0x0034)
|
||||
#define CLK_BASE ((uint16_t)0x0053)
|
||||
#define USART_0_BASE ((uint16_t)0x0070)
|
||||
#define USART_1_BASE ((uint16_t)0x0078)
|
||||
#define TIMER_IVEC_BASE ((uint16_t)0x011e)
|
||||
#define TIMER_A_BASE ((uint16_t)0x0160)
|
||||
#define TIMER_B_BASE ((uint16_t)0x0180)
|
||||
#define WD_BASE ((uint16_t)0x0120)
|
||||
#define USCI_0_BASE ((uint16_t)0x005d)
|
||||
#define USCI_0_A_BASE ((uint16_t)0x0060)
|
||||
#define USCI_0_B_BASE ((uint16_t)0x0068)
|
||||
#define USCI_1_BASE ((uint16_t)0x00cd)
|
||||
#define USCI_1_A_BASE ((uint16_t)0x00d0)
|
||||
#define USCI_1_B_BASE ((uint16_t)0x00d8)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Typing of base register objects
|
||||
* @{
|
||||
*/
|
||||
#define SFR ((msp_sfr_t *)SFR_BASE)
|
||||
#define PORT_1 ((msp_port_t *)PORT_1_BASE)
|
||||
#define PORT_2 ((msp_port_t *)PORT_2_BASE)
|
||||
#define PORT_3 ((msp_port_t *)PORT_3_BASE)
|
||||
#define PORT_4 ((msp_port_t *)PORT_4_BASE)
|
||||
#define PORT_5 ((msp_port_t *)PORT_5_BASE)
|
||||
#define PORT_6 ((msp_port_t *)PORT_6_BASE)
|
||||
#define CLK ((msp_clk_t *)CLK_BASE)
|
||||
#define USART_0 ((msp_usart_t *)USART_0_BASE)
|
||||
#define USART_1 ((msp_usart_t *)USART_1_BASE)
|
||||
#define TIMER_IVEC ((msp_timer_ivec_t *)TIMER_IVEC_BASE)
|
||||
#define TIMER_A ((msp_timer_t *)TIMER_A_BASE)
|
||||
#define TIMER_B ((msp_timer_t *)TIMER_B_BASE)
|
||||
#define WD ((msp_wd_t *)WD_BASE)
|
||||
#define USCI_0 ((msp_usci_t *)USCI_0_BASE)
|
||||
#define USCI_1 ((msp_usci_t *)USCI_1_BASE)
|
||||
#define USCI_0_A_SPI ((msp_usci_spi_t *)USCI_0_A_BASE)
|
||||
#define USCI_0_B_SPI ((msp_usci_spi_t *)USCI_0_B_BASE)
|
||||
#define USCI_1_A ((msp_usci_t *)USCI_1_A_BASE)
|
||||
#define USCI_1_B ((msp_usci_t *)USCI_1_B_BASE)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MSP430_REGS_H */
|
||||
/** @} */
|
@ -1,225 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 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 cpu_msp430fxyz
|
||||
* @ingroup drivers_periph_uart
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Low-level UART driver implementation
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_cpu.h"
|
||||
#include "periph_conf.h"
|
||||
#include "periph/uart.h"
|
||||
|
||||
/**
|
||||
* @brief Keep track of the interrupt context
|
||||
* @{
|
||||
*/
|
||||
static uart_rx_cb_t ctx_rx_cb;
|
||||
static void *ctx_isr_arg;
|
||||
/** @} */
|
||||
|
||||
static int init_base(uart_t uart, uint32_t baudrate);
|
||||
|
||||
/* per default, we use the legacy MSP430 USART module for UART functionality */
|
||||
#ifndef UART_USE_USCI
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
{
|
||||
int res = init_base(uart, baudrate);
|
||||
if (res != UART_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* save interrupt context */
|
||||
ctx_rx_cb = rx_cb;
|
||||
ctx_isr_arg = arg;
|
||||
/* reset interrupt flags and enable RX interrupt */
|
||||
UART_IE &= ~(UART_IE_TX_BIT);
|
||||
UART_IF &= ~(UART_IE_RX_BIT);
|
||||
UART_IF |= (UART_IE_TX_BIT);
|
||||
UART_IE |= (UART_IE_RX_BIT);
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
static int init_base(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
if (uart != 0) {
|
||||
return UART_NODEV;
|
||||
}
|
||||
|
||||
/* get the default UART for now -> TODO: enable for multiple devices */
|
||||
msp_usart_t *dev = UART_BASE;
|
||||
|
||||
/* power off and reset device */
|
||||
uart_poweroff(uart);
|
||||
dev->CTL = USART_CTL_SWRST;
|
||||
/* configure to 8N1 and using the SMCLK*/
|
||||
dev->CTL |= USART_CTL_CHAR;
|
||||
dev->TCTL = (USART_TCTL_TXEPT | USART_TCTL_SSEL_SMCLK);
|
||||
dev->RCTL = 0x00;
|
||||
/* baudrate configuration */
|
||||
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 */
|
||||
dev->MCTL = 0;
|
||||
/* configure pins -> TODO: move into GPIO driver (once implemented) */
|
||||
UART_PORT->SEL |= (UART_RX_PIN | UART_TX_PIN);
|
||||
UART_PORT->OD |= UART_RX_PIN;
|
||||
UART_PORT->OD &= ~(UART_TX_PIN);
|
||||
UART_PORT->DIR |= UART_TX_PIN;
|
||||
UART_PORT->DIR &= ~(UART_RX_PIN);
|
||||
/* enable receiver and transmitter */
|
||||
uart_poweron(uart);
|
||||
/* and finally release the software reset bit */
|
||||
dev->CTL &= ~(USART_CTL_SWRST);
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
{
|
||||
(void)uart;
|
||||
msp_usart_t *dev = UART_BASE;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (!(dev->TCTL & USART_TCTL_TXEPT)) {}
|
||||
dev->TXBUF = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweron(uart_t uart)
|
||||
{
|
||||
(void)uart;
|
||||
UART_ME |= UART_ME_BITS;
|
||||
}
|
||||
|
||||
void uart_poweroff(uart_t uart)
|
||||
{
|
||||
(void)uart;
|
||||
UART_ME &= ~(UART_ME_BITS);
|
||||
}
|
||||
|
||||
ISR(UART_RX_ISR, isr_uart_0_rx)
|
||||
{
|
||||
__enter_isr();
|
||||
|
||||
/* read character (resets interrupt flag) */
|
||||
char c = UART_BASE->RXBUF;
|
||||
|
||||
/* only call callback if there was no receive error */
|
||||
if(! (UART_BASE->RCTL & RXERR)) {
|
||||
ctx_rx_cb(ctx_isr_arg, c);
|
||||
}
|
||||
|
||||
__exit_isr();
|
||||
}
|
||||
|
||||
/* we use alternative UART code in case the board used the USCI module for UART
|
||||
* in case of the (older) USART module */
|
||||
#else
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
{
|
||||
if (init_base(uart, baudrate) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* save interrupt context */
|
||||
ctx_rx_cb = rx_cb;
|
||||
ctx_isr_arg = arg;
|
||||
/* reset interrupt flags and enable RX interrupt */
|
||||
UART_IF &= ~(UART_IE_RX_BIT);
|
||||
UART_IF |= (UART_IE_TX_BIT);
|
||||
UART_IE |= (UART_IE_RX_BIT);
|
||||
UART_IE &= ~(UART_IE_TX_BIT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_base(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
if (uart != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get the default UART for now -> TODO: enable for multiple devices */
|
||||
msp_usci_t *dev = UART_BASE;
|
||||
|
||||
/* put device in reset mode while configuration is going on */
|
||||
dev->ACTL1 = USCI_ACTL1_SWRST;
|
||||
/* configure to UART, using SMCLK in 8N1 mode */
|
||||
dev->ACTL1 |= USCI_ACTL1_SSEL_SMCLK;
|
||||
dev->ACTL0 = 0;
|
||||
dev->ASTAT = 0;
|
||||
/* configure 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;
|
||||
dev->ABR1 = (uint8_t)(br >> 8);
|
||||
dev->AMCTL = (brs << USCI_AMCTL_BRS_SHIFT);
|
||||
/* pin configuration -> TODO: move to GPIO driver once implemented */
|
||||
UART_RX_PORT->SEL |= UART_RX_PIN;
|
||||
UART_TX_PORT->SEL |= UART_TX_PIN;
|
||||
UART_RX_PORT->DIR &= ~(UART_RX_PIN);
|
||||
UART_TX_PORT->DIR |= UART_TX_PIN;
|
||||
/* releasing the software reset bit starts the UART */
|
||||
dev->ACTL1 &= ~(USCI_ACTL1_SWRST);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
{
|
||||
(void)uart;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (!(UART_IF & UART_IE_TX_BIT)) {}
|
||||
UART_BASE->ATXBUF = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweron(uart_t uart)
|
||||
{
|
||||
(void)uart;
|
||||
/* n/a */
|
||||
}
|
||||
|
||||
void uart_poweroff(uart_t uart)
|
||||
{
|
||||
(void)uart;
|
||||
/* n/a */
|
||||
}
|
||||
|
||||
ISR(UART_RX_ISR, isr_uart_0_rx)
|
||||
{
|
||||
__enter_isr();
|
||||
|
||||
uint8_t stat = UART_BASE->ASTAT;
|
||||
uint8_t data = (uint8_t)UART_BASE->ARXBUF;
|
||||
|
||||
if (stat & (USCI_ASTAT_FE | USCI_ASTAT_OE | USCI_ASTAT_PE | USCI_ASTAT_BRK)) {
|
||||
/* some error which we do not handle, just do a pseudo read to reset the
|
||||
* status register */
|
||||
(void)data;
|
||||
}
|
||||
else {
|
||||
ctx_rx_cb(ctx_isr_arg, data);
|
||||
}
|
||||
|
||||
__exit_isr();
|
||||
}
|
||||
|
||||
#endif
|
@ -201,23 +201,6 @@ typedef struct {
|
||||
} pwm_conf_t;
|
||||
#endif
|
||||
|
||||
#if !defined(CPU_MODEL_NRF52832XXAA)
|
||||
/**
|
||||
* @brief Structure for UART configuration data
|
||||
*/
|
||||
typedef struct {
|
||||
NRF_UARTE_Type *dev; /**< UART with EasyDMA device base
|
||||
* register address */
|
||||
gpio_t rx_pin; /**< RX pin */
|
||||
gpio_t tx_pin; /**< TX pin */
|
||||
#ifdef MODULE_PERIPH_UART_HW_FC
|
||||
gpio_t rts_pin; /**< RTS pin */
|
||||
gpio_t cts_pin; /**< CTS pin */
|
||||
#endif
|
||||
uint8_t irqn; /**< IRQ channel */
|
||||
} uart_conf_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Size of the UART TX buffer for non-blocking mode.
|
||||
*/
|
||||
|
43
cpu/nrf53/Kconfig
Normal file
43
cpu/nrf53/Kconfig
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (c) 2023 Mesotic SAS
|
||||
#
|
||||
# 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.
|
||||
|
||||
# For now, define all features here
|
||||
# We will rely on nrf5x_common later when we support more peripherals
|
||||
config CPU_FAM_NRF53
|
||||
bool
|
||||
select HAS_CPU_NRF53
|
||||
select HAS_PERIPH_CPUID
|
||||
select HAS_PERIPH_GPIO
|
||||
select HAS_PERIPH_GPIO_IRQ
|
||||
select HAS_PERIPH_TIMER_PERIODIC
|
||||
select HAS_PERIPH_UART_MODECFG
|
||||
|
||||
## CPU Models
|
||||
config CPU_MODEL_NRF5340_APP
|
||||
bool
|
||||
select CPU_CORE_CORTEX_M33
|
||||
select CPU_FAM_NRF53
|
||||
|
||||
## CPU common symbols
|
||||
config CPU_FAM
|
||||
default "nrf53" if CPU_FAM_NRF53
|
||||
|
||||
config CPU_MODEL
|
||||
default "nrf5340_app" if CPU_MODEL_NRF5340_APP
|
||||
|
||||
|
||||
config CPU
|
||||
default "nrf53" if CPU_FAM_NRF53
|
||||
|
||||
## Definition of specific features
|
||||
config HAS_CPU_NRF53
|
||||
bool
|
||||
help
|
||||
Indicates that the current cpu is 'nrf53'.
|
||||
|
||||
rsource "vectors/Kconfig"
|
||||
|
||||
source "$(RIOTCPU)/nrf5x_common/Kconfig"
|
7
cpu/nrf53/Makefile
Normal file
7
cpu/nrf53/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
# define the module that is build
|
||||
MODULE = cpu
|
||||
|
||||
# add a list of subdirectories, that should also be build
|
||||
DIRS = periph $(RIOTCPU)/cortexm_common $(RIOTCPU)/nrf5x_common vectors
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
4
cpu/nrf53/Makefile.dep
Normal file
4
cpu/nrf53/Makefile.dep
Normal file
@ -0,0 +1,4 @@
|
||||
USEMODULE += nrf53_vectors
|
||||
|
||||
include $(RIOTCPU)/nrf5x_common/Makefile.dep
|
||||
include $(RIOTCPU)/cortexm_common/Makefile.dep
|
4
cpu/nrf53/Makefile.features
Normal file
4
cpu/nrf53/Makefile.features
Normal file
@ -0,0 +1,4 @@
|
||||
CPU_CORE = cortex-m33
|
||||
CPU_FAM = nrf53
|
||||
|
||||
include $(RIOTCPU)/nrf5x_common/Makefile.features
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user