Merge pull request #52 from awygle/msp430x

Initial MSP430X Port.
This commit is contained in:
Uladzimir Pylinski 2016-04-09 15:58:32 +03:00
commit 2071319b33
25 changed files with 4949 additions and 0 deletions

View File

@ -0,0 +1,205 @@
##############################################################################
# Build global options
# NOTE: Can be overridden externally.
#
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPTIMIZE = 1
# Debugging format.
DEBUG =
#DEBUG = stabs
# Memory/data model
MODEL = large
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
OBJDIR = .
# Compiler flag to set the C Standard level.
# c89 = "ANSI" C
# gnu89 = c89 plus GCC extensions
# c99 = ISO C99 standard (not yet fully implemented)
# gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu11
# Compiler options here.
ifeq ($(USE_OPT),)
USE_OPT = -O$(OPTIMIZE) -g$(DEBUG)
USE_OPT += -fsigned-char -fshort-enums
endif
# C specific options here (added to USE_OPT).
ifeq ($(USE_COPT),)
USE_COPT =
endif
# C++ specific options here (added to USE_OPT).
ifeq ($(USE_CPPOPT),)
USE_CPPOPT = -fno-rtti
endif
# Enable this if you want the linker to remove unused code and data
ifeq ($(USE_LINK_GC),)
USE_LINK_GC = yes
endif
# Linker extra options here.
ifeq ($(USE_LDOPT),)
USE_LDOPT =
endif
# Enable this if you want link time optimizations (LTO)
ifeq ($(USE_LTO),)
USE_LTO = no
endif
# Enable the selected hardware multiplier
ifeq ($(USE_HWMULT),)
USE_HWMULT = f5series
endif
# Enable this if you want to see the full log while compiling.
ifeq ($(USE_VERBOSE_COMPILE),)
USE_VERBOSE_COMPILE = yes
endif
# If enabled, this option makes the build process faster by not compiling
# modules not used in the current configuration.
ifeq ($(USE_SMART_BUILD),)
USE_SMART_BUILD = yes
endif
#
# Build global options
##############################################################################
##############################################################################
# Architecture or project specific options
#
# Stack size to be allocated to the idle thread stack. This stack is
# the stack used by the main() thread.
ifeq ($(USE_IDLE_STACKSIZE),)
USE_IDLE_STACKSIZE = 0xC00
endif
#
# Architecture or project specific options
##############################################################################
##############################################################################
# Project, sources and paths
#
# Define project name here
PROJECT = nil
# Imported source files and paths
CHIBIOS = ../../../../ChibiOS-RT
CHIBIOS_CONTRIB = ../../..
# Startup files.
include $(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC/mk/startup_msp430fr5xxx.mk
# HAL-OSAL files (optional).
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS_CONTRIB)/os/hal/boards/EXP430FR5969/board.mk
include $(CHIBIOS_CONTRIB)/os/hal/ports/MSP430X/platform.mk
include $(CHIBIOS)/os/hal/osal/nil/osal.mk
# RTOS files (optional).
include $(CHIBIOS)/os/nil/nil.mk
include $(CHIBIOS_CONTRIB)/os/common/ports/MSP430X/compilers/GCC/mk/port.mk
# Other files (optional).
include $(CHIBIOS)/test/nil/test.mk
# Define linker script file here
LDSCRIPT = $(STARTUPLD)/msp430fr5969.ld
# C sources
CSRC = $(STARTUPSRC) \
$(KERNSRC) \
$(PORTSRC) \
$(OSALSRC) \
$(HALSRC) \
$(PLATFORMSRC) \
$(BOARDSRC) \
$(TESTSRC) \
main.c
# C++ sources
CPPSRC =
# List ASM source files here
ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
$(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \
$(CHIBIOS)/os/various
#
# Project, sources and paths
##############################################################################
##############################################################################
# Compiler settings
#
MCU = msp430fr5969
TRGT = msp430-elf-
CC = $(TRGT)gcc
CPPC = $(TRGT)g++
# Enable loading with g++ only if you need C++ runtime support.
# NOTE: You can use C++ even without C++ support if you are careful. C++
# runtime support makes code size explode.
LD = $(TRGT)gcc
#LD = $(TRGT)g++
CP = $(TRGT)objcopy
AS = $(TRGT)gcc -x assembler-with-cpp
AR = $(TRGT)ar
OD = $(TRGT)objdump
SZ = $(TRGT)size
HEX = $(CP) -O ihex
BIN = $(CP) -O binary
# MSP430-specific options here
MOPT = -m$(MODEL)
# Define C warning options here
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes
# Define C++ warning options here
CPPWARN = -Wall -Wextra -Wundef
#
# Compiler settings
##############################################################################
##############################################################################
# Start of user section
#
# List all user C define here, like -D_DEBUG=1
UDEFS =
# Define ASM defines here
UADEFS =
# List all user directories here
UINCDIR =
# List the user directory to look for the libraries here
ULIBDIR =
# List all user libraries here
ULIBS =
#
# End of user defines
##############################################################################
RULESPATH = $(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC
include $(RULESPATH)/rules.mk

View File

@ -0,0 +1,274 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file nilconf.h
* @brief Configuration file template.
* @details A copy of this file must be placed in each project directory, it
* contains the application specific kernel settings.
*
* @addtogroup config
* @details Kernel related settings and hooks.
* @{
*/
#ifndef CHCONF_H
#define CHCONF_H
#define _CHIBIOS_NIL_CONF_
/*===========================================================================*/
/**
* @name Kernel parameters and options
* @{
*/
/*===========================================================================*/
/**
* @brief Number of user threads in the application.
* @note This number is not inclusive of the idle thread which is
* Implicitly handled.
*/
#define CH_CFG_NUM_THREADS 2
/** @} */
/*===========================================================================*/
/**
* @name System timer settings
* @{
*/
/*===========================================================================*/
/**
* @brief System time counter resolution.
* @note Allowed values are 16 or 32 bits.
*/
#define CH_CFG_ST_RESOLUTION 16
/**
* @brief System tick frequency.
* @note This value together with the @p CH_CFG_ST_RESOLUTION
* option defines the maximum amount of time allowed for
* timeouts.
*/
#define CH_CFG_ST_FREQUENCY 1000
/**
* @brief Time delta constant for the tick-less mode.
* @note If this value is zero then the system uses the classic
* periodic tick. This value represents the minimum number
* of ticks that is safe to specify in a timeout directive.
* The value one is not valid, timeouts are rounded up to
* this value.
*/
#define CH_CFG_ST_TIMEDELTA 0
/** @} */
/*===========================================================================*/
/**
* @name Subsystem options
* @{
*/
/*===========================================================================*/
/**
* @brief Semaphores APIs.
* @details If enabled then the Semaphores APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_SEMAPHORES TRUE
/**
* @brief Mutexes APIs.
* @details If enabled then the mutexes APIs are included in the kernel.
*
* @note Feature not currently implemented.
* @note The default is @p FALSE.
*/
#define CH_CFG_USE_MUTEXES FALSE
/**
* @brief Events Flags APIs.
* @details If enabled then the event flags APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_EVENTS TRUE
/**
* @brief Mailboxes APIs.
* @details If enabled then the asynchronous messages (mailboxes) APIs are
* included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_SEMAPHORES.
*/
#define CH_CFG_USE_MAILBOXES TRUE
/**
* @brief Core Memory Manager APIs.
* @details If enabled then the core memory manager APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_MEMCORE TRUE
/**
* @brief Heap Allocator APIs.
* @details If enabled then the memory heap allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_HEAP TRUE
/**
* @brief Memory Pools Allocator APIs.
* @details If enabled then the memory pools allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#define CH_CFG_USE_MEMPOOLS TRUE
/**
* @brief Managed RAM size.
* @details Size of the RAM area to be managed by the OS. If set to zero
* then the whole available RAM is used. The core memory is made
* available to the heap allocator and/or can be used directly through
* the simplified core memory allocator.
*
* @note In order to let the OS manage the whole RAM the linker script must
* provide the @p __heap_base__ and @p __heap_end__ symbols.
* @note Requires @p CH_CFG_USE_MEMCORE.
*/
#define CH_CFG_MEMCORE_SIZE 0
/** @} */
/*===========================================================================*/
/**
* @name Debug options
* @{
*/
/*===========================================================================*/
/**
* @brief Debug option, kernel statistics.
*
* @note Feature not currently implemented.
* @note The default is @p FALSE.
*/
#define CH_DBG_STATISTICS FALSE
/**
* @brief Debug option, system state check.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
/**
* @brief Debug option, parameters checks.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_ENABLE_CHECKS FALSE
/**
* @brief System assertions.
*
* @note The default is @p FALSE.
*/
#define CH_DBG_ENABLE_ASSERTS FALSE
/**
* @brief Stack check.
*
*@note The default is @p FALSE.
*/
#define CH_DBG_ENABLE_STACK_CHECK TRUE
/** @} */
/*===========================================================================*/
/**
* @name Kernel hooks
* @{
*/
/*===========================================================================*/
/**
* @brief System initialization hook.
*/
#if !defined(CH_CFG_SYSTEM_INIT_HOOK) || defined(__DOXYGEN__)
#define CH_CFG_SYSTEM_INIT_HOOK() { \
}
#endif
/**
* @brief Threads descriptor structure extension.
* @details User fields added to the end of the @p thread_t structure.
*/
#define CH_CFG_THREAD_EXT_FIELDS \
/* Add threads custom fields here.*/
/**
* @brief Threads initialization hook.
*/
#define CH_CFG_THREAD_EXT_INIT_HOOK(tr) { \
/* Add custom threads initialization code here.*/ \
}
/**
* @brief Idle thread enter hook.
* @note This hook is invoked within a critical zone, no OS functions
* should be invoked from here.
* @note This macro can be used to activate a power saving mode.
*/
#define CH_CFG_IDLE_ENTER_HOOK() { \
}
/**
* @brief Idle thread leave hook.
* @note This hook is invoked within a critical zone, no OS functions
* should be invoked from here.
* @note This macro can be used to deactivate a power saving mode.
*/
#define CH_CFG_IDLE_LEAVE_HOOK() { \
}
/**
* @brief System halt hook.
*/
#if !defined(CH_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
}
#endif
/** @} */
/*===========================================================================*/
/* Port-specific settings (override port settings defaulted in nilcore.h). */
/*===========================================================================*/
#endif /* _CHCONF_H_ */
/** @} */

View File

@ -0,0 +1,381 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file templates/halconf.h
* @brief HAL configuration header.
* @details HAL configuration file, this file allows to enable or disable the
* various device drivers from your application. You may also use
* this file in order to override the device drivers default settings.
*
* @addtogroup HAL_CONF
* @{
*/
#ifndef HALCONF_H
#define HALCONF_H
#include "mcuconf.h"
/**
* @brief Enables the PAL subsystem.
*/
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
#define HAL_USE_PAL TRUE
#endif
/**
* @brief Enables the ADC subsystem.
*/
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
#define HAL_USE_ADC FALSE
#endif
/**
* @brief Enables the DAC subsystem.
*/
#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
#define HAL_USE_DAC FALSE
#endif
/**
* @brief Enables the CAN subsystem.
*/
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
#define HAL_USE_CAN FALSE
#endif
/**
* @brief Enables the EXT subsystem.
*/
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
#define HAL_USE_EXT FALSE
#endif
/**
* @brief Enables the GPT subsystem.
*/
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
#define HAL_USE_GPT FALSE
#endif
/**
* @brief Enables the I2C subsystem.
*/
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
#define HAL_USE_I2C FALSE
#endif
/**
* @brief Enables the I2S subsystem.
*/
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
#define HAL_USE_I2S FALSE
#endif
/**
* @brief Enables the ICU subsystem.
*/
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
#define HAL_USE_ICU FALSE
#endif
/**
* @brief Enables the MAC subsystem.
*/
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
#define HAL_USE_MAC FALSE
#endif
/**
* @brief Enables the MMC_SPI subsystem.
*/
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
#define HAL_USE_MMC_SPI FALSE
#endif
/**
* @brief Enables the PWM subsystem.
*/
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
#define HAL_USE_PWM FALSE
#endif
/**
* @brief Enables the RTC subsystem.
*/
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
#define HAL_USE_RTC FALSE
#endif
/**
* @brief Enables the SDC subsystem.
*/
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
#define HAL_USE_SDC FALSE
#endif
/**
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL TRUE
#endif
/**
* @brief Enables the SERIAL over USB subsystem.
*/
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL_USB FALSE
#endif
/**
* @brief Enables the SPI subsystem.
*/
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI FALSE
#endif
/**
* @brief Enables the UART subsystem.
*/
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
#define HAL_USE_UART FALSE
#endif
/**
* @brief Enables the USB subsystem.
*/
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
#define HAL_USE_USB FALSE
#endif
/**
* @brief Enables the WDG subsystem.
*/
#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
#define HAL_USE_WDG FALSE
#endif
/*===========================================================================*/
/* ADC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
#define ADC_USE_WAIT FALSE
#endif
/**
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define ADC_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
/* CAN driver related settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE FALSE
#endif
/*===========================================================================*/
/* I2C driver related settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the I2C bus.
*/
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define I2C_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
/* MAC driver related settings. */
/*===========================================================================*/
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
#define MAC_USE_ZERO_COPY FALSE
#endif
/**
* @brief Enables an event sources for incoming packets.
*/
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
#define MAC_USE_EVENTS FALSE
#endif
/*===========================================================================*/
/* MMC_SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
* This option is recommended also if the SPI driver does not
* use a DMA channel and heavily loads the CPU.
*/
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
#define MMC_NICE_WAITING FALSE
#endif
/*===========================================================================*/
/* SDC driver related settings. */
/*===========================================================================*/
/**
* @brief Number of initialization attempts before rejecting the card.
* @note Attempts are performed at 10mS intervals.
*/
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
#define SDC_INIT_RETRY 100
#endif
/**
* @brief Include support for MMC cards.
* @note MMC support is not yet implemented so this option must be kept
* at @p FALSE.
*/
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
#define SDC_MMC_SUPPORT FALSE
#endif
/**
* @brief Delays insertions.
* @details If enabled this options inserts delays into the MMC waiting
* routines releasing some extra CPU time for the threads with
* lower priority, this may slow down the driver a bit however.
*/
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
#define SDC_NICE_WAITING FALSE
#endif
/*===========================================================================*/
/* SERIAL driver related settings. */
/*===========================================================================*/
/**
* @brief Default bit rate.
* @details Configuration parameter, this is the baud rate selected for the
* default configuration.
*/
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
#define SERIAL_DEFAULT_BITRATE 38400
#endif
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
* @note The default is 16 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16
#endif
/*===========================================================================*/
/* SERIAL_USB driver related setting. */
/*===========================================================================*/
/**
* @brief Serial over USB buffers size.
* @details Configuration parameter, the buffer size must be a multiple of
* the USB data endpoint maximum packet size.
* @note The default is 256 bytes for both the transmission and receive
* buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_SIZE 256
#endif
/**
* @brief Serial over USB number of buffers.
* @note The default is 2 buffers.
*/
#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_NUMBER 2
#endif
/*===========================================================================*/
/* SPI driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT FALSE
#endif
/**
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
/* UART driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
#define UART_USE_WAIT FALSE
#endif
/**
* @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define UART_USE_MUTUAL_EXCLUSION FALSE
#endif
/*===========================================================================*/
/* USB driver related settings. */
/*===========================================================================*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
#define USB_USE_WAIT FALSE
#endif
#endif /* _HALCONF_H_ */
/** @} */

View File

@ -0,0 +1,76 @@
/*
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "hal.h"
#include "ch.h"
#include "ch_test.h"
#include "test_root.h"
/*
* Thread 2.
*/
THD_WORKING_AREA(waThread2, 2048);
THD_FUNCTION(Thread2, arg) {
(void)arg;
/*
* Activate the serial driver 0 using the driver default configuration.
*/
sdStart(&SD0, NULL);
while (chnGetTimeout(&SD0, TIME_INFINITE)) {
chnWrite(&SD0, (const uint8_t *)"Hello World!\r\n", 14);
test_execute((void*)&SD0);
chThdSleepMilliseconds(2000);
}
}
/*
* Threads static table, one entry per thread. The number of entries must
* match NIL_CFG_NUM_THREADS.
*/
THD_TABLE_BEGIN
THD_TABLE_ENTRY(wa_test_support, "test_support", test_support,
(void *)&nil.threads[1])
THD_TABLE_ENTRY(waThread2, "hello", Thread2, NULL)
THD_TABLE_END
/*
* Application entry point.
*/
int main(void) {
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
WDTCTL = WDTPW | WDTHOLD;
halInit();
chSysInit();
/* This is now the idle thread loop, you may perform here a low priority
task but you must never try to sleep or wait in this loop. Note that
this tasks runs at the lowest priority level so any instruction added
here will be executed after all other tasks have been started.*/
while (true) {
}
}

View File

@ -0,0 +1,55 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef MCUCONF_H
#define MCUCONF_H
/*
* MSP430X drivers configuration.
* The following settings override the default settings present in
* the various device driver implementation headers.
* Note that the settings for each driver only have effect if the driver
* is enabled in halconf.h.
*
*/
#define MSP430X_MCUCONF
/* HAL driver system settings */
#define MSP430X_ACLK_SRC MSP430X_VLOCLK
#define MSP430X_LFXTCLK_FREQ 0
#define MSP430X_HFXTCLK_FREQ 0
#define MSP430X_DCOCLK_FREQ 8000000
#define MSP430X_MCLK_DIV 1
#define MSP430X_SMCLK_DIV 32
/*
* SERIAL driver system settings.
*/
#define MSP430X_SERIAL_USE_USART0 TRUE
#define MSP430X_USART0_CLK_SRC MSP430X_SMCLK_SRC
#define MSP430X_SERIAL_USE_USART1 FALSE
#define MSP430X_SERIAL_USE_USART2 FALSE
#define MSP430X_SERIAL_USE_USART3 FALSE
/*
* ST driver system settings.
*/
#define MSP430X_ST_CLK_SRC MSP430X_SMCLK_SRC
#define MSP430X_ST_TIMER_TYPE B
#define MSP430X_ST_TIMER_INDEX 0
#endif /* _MCUCONF_H_ */

View File

@ -0,0 +1,103 @@
/*
ChibiOS/HAL - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/nilcore.c
* @brief MSP430X port code.
*
* @addtogroup MSP430X_CORE
* @{
*/
#include "ch.h"
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
/**
* @brief Performs a context switch between two threads.
* @details This is the most critical code in any port, this function
* is responsible for the context switch between 2 threads.
* @note The implementation of this code affects <b>directly</b> the context
* switch performance so optimize here as much as you can.
*
* @param[in] ntp the thread to be switched in
* @param[in] otp the thread to be switched out
*/
#if !defined(__DOXYGEN__) && defined(__OPTIMIZE__)
__attribute__((naked))
#endif
void _port_switch(thread_t *ntp, thread_t *otp) {
#if !defined(__OPTIMIZE__)
asm volatile ("add #4, r1");
#endif
(void)(ntp);
(void)(otp);
#if defined(__MSP430X_LARGE__)
asm volatile ("pushm.a #7, R10");
asm volatile ("mova r1, @R13");
asm volatile ("mova @R12, r1");
asm volatile ("popm.a #7, R10");
asm volatile ("reta");
#else
asm volatile ("pushm.w #7, R10");
asm volatile ("mov r1, @R13");
asm volatile ("mov @R12, r1");
asm volatile ("popm.w #7, R10");
asm volatile ("ret");
#endif
}
/**
* @brief Start a thread by invoking its work function.
* @details If the work function returns @p chThdExit() is automatically
* invoked.
*/
void _port_thread_start(void) {
/* See PORT_SETUP_CONTEXT in nilcore.h */
chSysUnlock();
#if defined(__MSP430X_LARGE__)
asm volatile ("mova R5, R12");
asm volatile ("calla R4");
#else
asm volatile ("mov R5, R12");
asm volatile ("call R4");
#endif
chSysHalt(0);
}
/** @} */

View File

@ -0,0 +1,437 @@
/*
ChibiOS/HAL - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/nilcore.h
* @brief MSP430X port macros and structures.
*
* @addtogroup MSP430X_CORE
* @{
*/
#ifndef CHCORE_H
#define CHCORE_H
#include <msp430.h>
#include <in430.h>
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/**
* @name Architecture and Compiler
* @{
*/
/**
* @brief Macro defining the port architecture.
*/
#define PORT_ARCHITECTURE_MSP430X
/**
* @brief Name of the implemented architecture.
*/
#define PORT_ARCHITECTURE_NAME "MSP430X"
/**
* @brief Name of the architecture variant.
*/
#define PORT_CORE_VARIANT_NAME "MSP430Xv2"
/* The following code is not processed when the file is included from an
* asm module because those intrinsic macrosa re not necessarily defined
* by the assembler too.*/
#if !defined(_FROM_ASM_)
/**
* @brief Compiler name and version.
*/
#if defined(__GNUC__) || defined(__DOXYGEN__)
#define PORT_COMPILER_NAME "GCC " __VERSION__
#else
#error "unsupported compiler"
#endif
#endif /* !defined(_FROM_ASM_) */
/**
* @brief Port-specific information string.
*/
#define PORT_INFO "16 bits code addressing"
/**
* @brief This port supports a realtime counter.
*/
#define PORT_SUPPORTS_RT FALSE
/** @} */
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
* by @p PORT_INT_REQUIRED_STACK.
* @note In this port it is set to 8.
*/
#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
#define PORT_IDLE_THREAD_STACK_SIZE 8
#endif
/**
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
* @note In this port the default is 32 bytes per thread.
*/
#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
#define PORT_INT_REQUIRED_STACK 32
#endif
/**
* @brief Enables an alternative timer implementation.
* @details Usually the port uses a timer interface defined in the file
* @p nilcore_timer.h, if this option is enabled then the file
* @p nilcore_timer_alt.h is included instead.
*/
#if !defined(PORT_USE_ALT_TIMER)
#define PORT_USE_ALT_TIMER FALSE
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
/* The following code is not processed when the file is included from an
asm module.*/
#if !defined(_FROM_ASM_)
/**
* @brief Type of stack and memory alignment enforcement.
*/
typedef uint16_t stkalign_t;
/**
* @brief Type of natural register size - depends on memory model.
*/
#if defined(__MSP430X_LARGE__)
typedef unsigned __int20 reg_t;
#else
typedef uint16_t reg_t;
#endif
/**
* @brief Natural alignment constant.
* @note It is the minimum alignment for pointer-size variables.
*/
#define PORT_NATURAL_ALIGN 2U
/**
* @brief Stack alignment constant.
* @note It is the alignement required for the stack pointer.
*/
#define PORT_STACK_ALIGN 2U
/**
* @brief Working Areas alignment constant.
* @note It is the alignment to be enforced for thread working areas.
*/
#define PORT_WORKING_AREA_ALIGN 2U
/** @} */
/**
* @brief System saved context.
* @details This structure represents the inner stack frame during a context
* switching.
*/
struct port_intctx {
reg_t r4;
reg_t r5;
reg_t r6;
reg_t r7;
reg_t r8;
reg_t r9;
reg_t r10;
reg_t r0; /* program counter */
};
/**
* @brief Platform dependent part of the @p thread_t structure.
* @details This structure usually contains just the saved stack pointer
* defined as a pointer to a @p port_intctx structure.
*/
struct port_context {
struct port_intctx *sp;
};
#endif /* !defined(_FROM_ASM_) */
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/**
* @brief Platform dependent thread stack setup.
* @details This code usually setup the context switching frame represented
* by an @p port_intctx structure.
*/
#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
(tp)->ctx.sp = (struct port_intctx*)(((uint8_t *)(wtop)) - \
sizeof(struct port_intctx)); \
(tp)->ctx.sp->r4 = (reg_t)pf; \
(tp)->ctx.sp->r5 = (reg_t)arg; \
(tp)->ctx.sp->r0 = (reg_t)_port_thread_start; \
}
/**
* @brief Static working area allocation.
* @details This macro is used to allocate a static thread working area
* aligned as both position and size.
*
* @param[in] s the name to be assigned to the stack array
* @param[in] n the stack size to be assigned to the thread
*/
#define PORT_WORKING_AREA(s, n) \
stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
/**
* @brief Computes the thread working area global size.
* @note There is no need to perform alignments in this macro.
*/
#define PORT_WA_SIZE(n) ((sizeof(struct port_intctx) - 1) + \
(n) + (PORT_INT_REQUIRED_STACK))
/**
* @brief IRQ prologue code.
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
*/
#define PORT_IRQ_PROLOGUE()
/**
* @brief IRQ epilogue code.
* @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
#define PORT_IRQ_EPILOGUE() chSchRescheduleS()
/**
* @brief IRQ handler function declaration.
* @note @p id can be a function name or a vector number depending on the
* port implementation.
*/
#define PORT_IRQ_HANDLER(id) __attribute__ ((interrupt(id))) \
void ISR_ ## id (void)
/**
* @brief Fast IRQ handler function declaration.
* @note @p id can be a function name or a vector number depending on the
* port implementation.
*/
#define PORT_FAST_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
/**
* @brief Performs a context switch between two threads.
* @details This is the most critical code in any port, this function
* is responsible for the context switch between 2 threads.
* @note The implementation of this code affects <b>directly</b> the context
* switch performance so optimize here as much as you can.
*
* @param[in] ntp the thread to be switched in
* @param[in] otp the thread to be switched out
*/
#define port_switch(ntp, otp) _port_switch(ntp, otp)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
/* The following code is not processed when the file is included from an
asm module.*/
#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {
#endif
void _port_irq_epilogue(void);
void _port_switch(thread_t *ntp, thread_t *otp);
void _port_thread_start(void);
#ifdef __cplusplus
}
#endif
#endif /* !defined(_FROM_ASM_) */
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
/* The following code is not processed when the file is included from an
asm module.*/
#if !defined(_FROM_ASM_)
/**
* @brief Port-related initialization code.
*/
static inline void port_init(void) {
}
/**
* @brief Returns a word encoding the current interrupts status.
*
* @return The interrupts status.
*/
static inline syssts_t port_get_irq_status(void) {
return __get_SR_register();
}
/**
* @brief Checks the interrupt status.
*
* @param[in] sts the interrupt status word
*
* @return The interrupt status.
* @retvel false the word specified a disabled interrupts status.
* @retvel true the word specified an enabled interrupts status.
*/
static inline bool port_irq_enabled(syssts_t sts) {
return sts & GIE;
}
/**
* @brief Determines the current execution context.
*
* @return The execution context.
* @retval false not running in ISR mode.
* @retval true running in ISR mode.
*/
static inline bool port_is_isr_context(void) {
/* Efficiency would be enhanced by not doing this,
* because of implementation details */
return __get_SR_register() & GIE;
}
/**
* @brief Kernel-lock action.
*/
static inline void port_lock(void) {
_disable_interrupts();
asm volatile("nop");
}
/**
* @brief Kernel-unlock action.
*/
static inline void port_unlock(void) {
asm volatile("nop");
_enable_interrupts();
}
/**
* @brief Kernel-lock action from an interrupt handler.
* @note This function is empty in this port.
*/
static inline void port_lock_from_isr(void) {
}
/**
* @brief Kernel-unlock action from an interrupt handler.
* @note This function is empty in this port.
*/
static inline void port_unlock_from_isr(void) {
}
/**
* @brief Disables all the interrupt sources.
*/
static inline void port_disable(void) {
_disable_interrupts();
asm volatile("nop");
}
/**
* @brief Disables the interrupt sources below kernel-level priority.
*/
static inline void port_suspend(void) {
_disable_interrupts();
asm volatile("nop");
}
/**
* @brief Enables all the interrupt sources.
*/
static inline void port_enable(void) {
asm volatile("nop");
_enable_interrupts();
}
/**
* @brief Enters an architecture-dependent IRQ-waiting mode.
* @details The function is meant to return when an interrupt becomes pending.
* The simplest implementation is an empty function or macro but this
* would not take advantage of architecture-specific power saving
* modes.
*/
static inline void port_wait_for_interrupt(void) {
}
/**
* @brief Returns the current value of the realtime counter.
*
* @return The realtime counter value.
*/
static inline rtcnt_t port_rt_get_counter_value(void) {
/* TODO implement realtime counter */
return 0;
}
#endif /* !defined(_FROM_ASM_) */
/*===========================================================================*/
/* Module late inclusions. */
/*===========================================================================*/
#if !defined(_FROM_ASM_)
#if CH_CFG_ST_TIMEDELTA > 0
#if !PORT_USE_ALT_TIMER
#include "chcore_timer.h"
#else /* PORT_USE_ALT_TIMER */
#include "chcore_timer_alt.h"
#endif /* PORT_USE_ALT_TIMER */
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
#endif /* !defined(_FROM_ASM_) */
#endif /* CHCORE_H */
/** @} */

View File

@ -0,0 +1,119 @@
/*
ChibiOS/HAL - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/chcore_timer.h
* @brief System timer header file.
*
* @addtogroup MSP430X_TIMER
* @{
*/
#ifndef CHCORE_TIMER_H
#define CHCORE_TIMER_H
#include "hal_st.h"
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief Starts the alarm.
* @note Makes sure that no spurious alarms are triggered after
* this call.
*
* @param[in] abstime the time to be set for the first alarm
*
* @notapi
*/
static inline void port_timer_start_alarm(systime_t abstime) {
stStartAlarm(abstime);
}
/**
* @brief Stops the alarm interrupt.
*
* @notapi
*/
static inline void port_timer_stop_alarm(void) {
stStopAlarm();
}
/**
* @brief Sets the alarm time.
*
* @param[in] abstime the time to be set for the next alarm
*
* @notapi
*/
static inline void port_timer_set_alarm(systime_t abstime) {
stSetAlarm(abstime);
}
/**
* @brief Returns the system time.
*
* @return The system time.
*
* @notapi
*/
static inline systime_t port_timer_get_time(void) {
return stGetCounter();
}
/**
* @brief Returns the current alarm time.
*
* @return The currently set alarm time.
*
* @notapi
*/
static inline systime_t port_timer_get_alarm(void) {
return stGetAlarm();
}
#endif /* CHCORE_TIMER_H */
/** @} */

View File

@ -0,0 +1,99 @@
/*
ChibiOS/HAL - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/compilers/GCC/chtypes.h
* @brief MSP430X port system types.
*
* @addtogroup MSP430X_GCC_CORE
* @{
*/
#ifndef CHTYPES_H
#define CHTYPES_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
/**
* @name Common constants
*/
/**
* @brief Generic 'false' boolean constant.
*/
#if !defined(FALSE) || defined(__DOXYGEN__)
#define FALSE 0
#endif
/**
* @brief Generic 'true' boolean constant.
*/
#if !defined(TRUE) || defined(__DOXYGEN__)
#define TRUE 1
#endif
/** @} */
/**
* @name Kernel types
* @{
*/
typedef uint16_t rtcnt_t; /**< Realtime counter. */
typedef uint64_t rttime_t; /**< Realtime accumulator. */
typedef uint16_t syssts_t; /**< System status word. */
typedef uint8_t tmode_t; /**< Thread flags. */
typedef uint8_t tstate_t; /**< Thread state. */
typedef uint8_t trefs_t; /**< Thread references counter. */
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
typedef uint8_t tprio_t; /**< Thread priority. */
typedef int16_t msg_t; /**< Inter-thread message. */
typedef int32_t eventid_t; /**< Numeric event identifier. */
typedef uint8_t eventmask_t; /**< Mask of event identifiers. */
typedef int16_t cnt_t; /**< Generic signed counter. */
typedef uint16_t ucnt_t; /**< Generic unsigned counter. */
/**
* @brief ROM constant modifier.
* @note It is set to use the "const" keyword in this port.
*/
#define ROMCONST const
/**
* @brief Makes functions not inlineable.
* @note If the compiler does not support such attribute then the
* realtime counter precision could be degraded.
*/
#define NOINLINE __attribute__((noinline))
/**
* @brief Optimized thread function declaration macro.
*/
#define PORT_THD_FUNCTION(tname, arg) \
void tname(void *arg)
/**
* @brief Packed variable specifier.
*/
#define PACKED_VAR __attribute__((packed))
/**
* @brief Memory alignment enforcement for variables.
*/
#define ALIGNED_VAR(n) __attribute__((aligned(n)))
#endif /* _NILTYPES_H_ */
/** @} */

View File

@ -0,0 +1,7 @@
# List of the ChibiOS/RT MSP430X port files.
PORTSRC = ${CHIBIOS_CONTRIB}/os/common/ports/MSP430X/chcore.c
PORTASM =
PORTINC = ${CHIBIOS_CONTRIB}/os/common/ports/MSP430X \
${CHIBIOS_CONTRIB}/os/common/ports/MSP430X/compilers/GCC

View File

@ -0,0 +1,390 @@
/* This file supports MSP430FR5969 devices. */
/* Version: 1.0 */
/* ChibiOS linker script, for normal executables */
OUTPUT_ARCH(msp430)
ENTRY(_start)
MEMORY {
SFR : ORIGIN = 0x0000, LENGTH = 0x0010 /* END=0x0010, size 16 */
PERIPHERAL_8BIT : ORIGIN = 0x0010, LENGTH = 0x00F0 /* END=0x0100, size 240 */
PERIPHERAL_16BIT : ORIGIN = 0x0100, LENGTH = 0x0100 /* END=0x0200, size 256 */
RAM : ORIGIN = 0x1C00, LENGTH = 0x0800 /* END=0x23FF, size 2048 */
INFOMEM : ORIGIN = 0x1800, LENGTH = 0x0200 /* END=0x19FF, size 512 as 4 128-byte segments */
INFOA : ORIGIN = 0x1980, LENGTH = 0x0080 /* END=0x19FF, size 128 */
INFOB : ORIGIN = 0x1900, LENGTH = 0x0080 /* END=0x197F, size 128 */
INFOC : ORIGIN = 0x1880, LENGTH = 0x0080 /* END=0x18FF, size 128 */
INFOD : ORIGIN = 0x1800, LENGTH = 0x0080 /* END=0x187F, size 128 */
FRAM (rxw) : ORIGIN = 0x4400, LENGTH = 0xBB80 /* END=0xFF7F, size 48000 */
VECT1 : ORIGIN = 0xFF90, LENGTH = 0x0002
VECT2 : ORIGIN = 0xFF92, LENGTH = 0x0002
VECT3 : ORIGIN = 0xFF94, LENGTH = 0x0002
VECT4 : ORIGIN = 0xFF96, LENGTH = 0x0002
VECT5 : ORIGIN = 0xFF98, LENGTH = 0x0002
VECT6 : ORIGIN = 0xFF9A, LENGTH = 0x0002
VECT7 : ORIGIN = 0xFF9C, LENGTH = 0x0002
VECT8 : ORIGIN = 0xFF9E, LENGTH = 0x0002
VECT9 : ORIGIN = 0xFFA0, LENGTH = 0x0002
VECT10 : ORIGIN = 0xFFA2, LENGTH = 0x0002
VECT11 : ORIGIN = 0xFFA4, LENGTH = 0x0002
VECT12 : ORIGIN = 0xFFA6, LENGTH = 0x0002
VECT13 : ORIGIN = 0xFFA8, LENGTH = 0x0002
VECT14 : ORIGIN = 0xFFAA, LENGTH = 0x0002
VECT15 : ORIGIN = 0xFFAC, LENGTH = 0x0002
VECT16 : ORIGIN = 0xFFAE, LENGTH = 0x0002
VECT17 : ORIGIN = 0xFFB0, LENGTH = 0x0002
VECT18 : ORIGIN = 0xFFB2, LENGTH = 0x0002
VECT19 : ORIGIN = 0xFFB4, LENGTH = 0x0002
VECT20 : ORIGIN = 0xFFB6, LENGTH = 0x0002
VECT21 : ORIGIN = 0xFFB8, LENGTH = 0x0002
VECT22 : ORIGIN = 0xFFBA, LENGTH = 0x0002
VECT23 : ORIGIN = 0xFFBC, LENGTH = 0x0002
VECT24 : ORIGIN = 0xFFBE, LENGTH = 0x0002
VECT25 : ORIGIN = 0xFFC0, LENGTH = 0x0002
VECT26 : ORIGIN = 0xFFC2, LENGTH = 0x0002
VECT27 : ORIGIN = 0xFFC4, LENGTH = 0x0002
VECT28 : ORIGIN = 0xFFC6, LENGTH = 0x0002
VECT29 : ORIGIN = 0xFFC8, LENGTH = 0x0002
VECT30 : ORIGIN = 0xFFCA, LENGTH = 0x0002
VECT31 : ORIGIN = 0xFFCC, LENGTH = 0x0002
VECT32 : ORIGIN = 0xFFCE, LENGTH = 0x0002
VECT33 : ORIGIN = 0xFFD0, LENGTH = 0x0002
VECT34 : ORIGIN = 0xFFD2, LENGTH = 0x0002
VECT35 : ORIGIN = 0xFFD4, LENGTH = 0x0002
VECT36 : ORIGIN = 0xFFD6, LENGTH = 0x0002
VECT37 : ORIGIN = 0xFFD8, LENGTH = 0x0002
VECT38 : ORIGIN = 0xFFDA, LENGTH = 0x0002
VECT39 : ORIGIN = 0xFFDC, LENGTH = 0x0002
VECT40 : ORIGIN = 0xFFDE, LENGTH = 0x0002
VECT41 : ORIGIN = 0xFFE0, LENGTH = 0x0002
VECT42 : ORIGIN = 0xFFE2, LENGTH = 0x0002
VECT43 : ORIGIN = 0xFFE4, LENGTH = 0x0002
VECT44 : ORIGIN = 0xFFE6, LENGTH = 0x0002
VECT45 : ORIGIN = 0xFFE8, LENGTH = 0x0002
VECT46 : ORIGIN = 0xFFEA, LENGTH = 0x0002
VECT47 : ORIGIN = 0xFFEC, LENGTH = 0x0002
VECT48 : ORIGIN = 0xFFEE, LENGTH = 0x0002
VECT49 : ORIGIN = 0xFFF0, LENGTH = 0x0002
VECT50 : ORIGIN = 0xFFF2, LENGTH = 0x0002
VECT51 : ORIGIN = 0xFFF4, LENGTH = 0x0002
VECT52 : ORIGIN = 0xFFF6, LENGTH = 0x0002
VECT53 : ORIGIN = 0xFFF8, LENGTH = 0x0002
VECT54 : ORIGIN = 0xFFFA, LENGTH = 0x0002
VECT55 : ORIGIN = 0xFFFC, LENGTH = 0x0002
RESETVEC : ORIGIN = 0xFFFE, LENGTH = 0x0002
BSL : ORIGIN = 0x1000, LENGTH = 0x0800
HIFRAM (rxw) : ORIGIN = 0x00010000, LENGTH = 0x00003FFF
}
PHDRS {
vectors PT_LOAD ;
stack PT_LOAD ;
rodata PT_LOAD ;
data PT_LOAD ;
text PT_LOAD ;
upper_rodata PT_LOAD ;
upper_data PT_LOAD ;
upper_text PT_LOAD ;
}
SECTIONS
{
__interrupt_vector_1 : { KEEP (*(__interrupt_vector_1 )) } > VECT1 :vectors =0x3C00
__interrupt_vector_2 : { KEEP (*(__interrupt_vector_2 )) } > VECT2 =0x3C00
__interrupt_vector_3 : { KEEP (*(__interrupt_vector_3 )) } > VECT3 =0x3C00
__interrupt_vector_4 : { KEEP (*(__interrupt_vector_4 )) } > VECT4 =0x3C00
__interrupt_vector_5 : { KEEP (*(__interrupt_vector_5 )) } > VECT5 =0x3C00
__interrupt_vector_6 : { KEEP (*(__interrupt_vector_6 )) } > VECT6 =0x3C00
__interrupt_vector_7 : { KEEP (*(__interrupt_vector_7 )) } > VECT7 =0x3C00
__interrupt_vector_8 : { KEEP (*(__interrupt_vector_8 )) } > VECT8 =0x3C00
__interrupt_vector_9 : { KEEP (*(__interrupt_vector_9 )) } > VECT9 =0x3C00
__interrupt_vector_10 : { KEEP (*(__interrupt_vector_10)) } > VECT10 =0x3C00
__interrupt_vector_11 : { KEEP (*(__interrupt_vector_11)) } > VECT11 =0x3C00
__interrupt_vector_12 : { KEEP (*(__interrupt_vector_12)) } > VECT12 =0x3C00
__interrupt_vector_13 : { KEEP (*(__interrupt_vector_13)) } > VECT13 =0x3C00
__interrupt_vector_14 : { KEEP (*(__interrupt_vector_14)) } > VECT14 =0x3C00
__interrupt_vector_15 : { KEEP (*(__interrupt_vector_15)) } > VECT15 =0x3C00
__interrupt_vector_16 : { KEEP (*(__interrupt_vector_16)) } > VECT16 =0x3C00
__interrupt_vector_17 : { KEEP (*(__interrupt_vector_17)) } > VECT17 =0x3C00
__interrupt_vector_18 : { KEEP (*(__interrupt_vector_18)) } > VECT18 =0x3C00
__interrupt_vector_19 : { KEEP (*(__interrupt_vector_19)) } > VECT19 =0x3C00
__interrupt_vector_20 : { KEEP (*(__interrupt_vector_20)) } > VECT20 =0x3C00
__interrupt_vector_21 : { KEEP (*(__interrupt_vector_21)) } > VECT21 =0x3C00
__interrupt_vector_22 : { KEEP (*(__interrupt_vector_22)) } > VECT22 =0x3C00
__interrupt_vector_23 : { KEEP (*(__interrupt_vector_23)) } > VECT23 =0x3C00
__interrupt_vector_24 : { KEEP (*(__interrupt_vector_24)) } > VECT24 =0x3C00
__interrupt_vector_25 : { KEEP (*(__interrupt_vector_25)) } > VECT25 =0x3C00
__interrupt_vector_26 : { KEEP (*(__interrupt_vector_26)) } > VECT26 =0x3C00
__interrupt_vector_27 : { KEEP (*(__interrupt_vector_27)) } > VECT27 =0x3C00
__interrupt_vector_28 : { KEEP (*(__interrupt_vector_28)) } > VECT28 =0x3C00
__interrupt_vector_29 : { KEEP (*(__interrupt_vector_29)) } > VECT29 =0x3C00
__interrupt_vector_30 : { KEEP (*(__interrupt_vector_30)) } > VECT30 =0x3C00
__interrupt_vector_31 : { KEEP (*(__interrupt_vector_31)) KEEP (*(__interrupt_vector_aes256)) } > VECT31 =0x3C00
__interrupt_vector_32 : { KEEP (*(__interrupt_vector_32)) KEEP (*(__interrupt_vector_rtc)) } > VECT32 =0x3C00
__interrupt_vector_33 : { KEEP (*(__interrupt_vector_33)) KEEP (*(__interrupt_vector_port4)) } > VECT33 =0x3C00
__interrupt_vector_34 : { KEEP (*(__interrupt_vector_34)) KEEP (*(__interrupt_vector_port3)) } > VECT34 =0x3C00
__interrupt_vector_35 : { KEEP (*(__interrupt_vector_35)) KEEP (*(__interrupt_vector_timer3_a1)) } > VECT35 =0x3C00
__interrupt_vector_36 : { KEEP (*(__interrupt_vector_36)) KEEP (*(__interrupt_vector_timer3_a0)) } > VECT36 =0x3C00
__interrupt_vector_37 : { KEEP (*(__interrupt_vector_37)) KEEP (*(__interrupt_vector_port2)) } > VECT37 =0x3C00
__interrupt_vector_38 : { KEEP (*(__interrupt_vector_38)) KEEP (*(__interrupt_vector_timer2_a1)) } > VECT38 =0x3C00
__interrupt_vector_39 : { KEEP (*(__interrupt_vector_39)) KEEP (*(__interrupt_vector_timer2_a0)) } > VECT39 =0x3C00
__interrupt_vector_40 : { KEEP (*(__interrupt_vector_40)) KEEP (*(__interrupt_vector_port1)) } > VECT40 =0x3C00
__interrupt_vector_41 : { KEEP (*(__interrupt_vector_41)) KEEP (*(__interrupt_vector_timer1_a1)) } > VECT41 =0x3C00
__interrupt_vector_42 : { KEEP (*(__interrupt_vector_42)) KEEP (*(__interrupt_vector_timer1_a0)) } > VECT42 =0x3C00
__interrupt_vector_43 : { KEEP (*(__interrupt_vector_43)) KEEP (*(__interrupt_vector_dma)) } > VECT43 =0x3C00
__interrupt_vector_44 : { KEEP (*(__interrupt_vector_44)) KEEP (*(__interrupt_vector_usci_a1)) } > VECT44 =0x3C00
__interrupt_vector_45 : { KEEP (*(__interrupt_vector_45)) KEEP (*(__interrupt_vector_timer0_a1)) } > VECT45 =0x3C00
__interrupt_vector_46 : { KEEP (*(__interrupt_vector_46)) KEEP (*(__interrupt_vector_timer0_a0)) } > VECT46 =0x3C00
__interrupt_vector_47 : { KEEP (*(__interrupt_vector_47)) KEEP (*(__interrupt_vector_adc12)) } > VECT47 =0x3C00
__interrupt_vector_48 : { KEEP (*(__interrupt_vector_48)) KEEP (*(__interrupt_vector_usci_b0)) } > VECT48 =0x3C00
__interrupt_vector_49 : { KEEP (*(__interrupt_vector_49)) KEEP (*(__interrupt_vector_usci_a0)) } > VECT49 =0x3C00
__interrupt_vector_50 : { KEEP (*(__interrupt_vector_50)) KEEP (*(__interrupt_vector_wdt)) } > VECT50 =0x3C00
__interrupt_vector_51 : { KEEP (*(__interrupt_vector_51)) KEEP (*(__interrupt_vector_timer0_b1)) } > VECT51 =0x3C00
__interrupt_vector_52 : { KEEP (*(__interrupt_vector_52)) KEEP (*(__interrupt_vector_timer0_b0)) } > VECT52 =0x3C00
__interrupt_vector_53 : { KEEP (*(__interrupt_vector_53)) KEEP (*(__interrupt_vector_comp_e)) } > VECT53 =0x3C00
__interrupt_vector_54 : { KEEP (*(__interrupt_vector_54)) KEEP (*(__interrupt_vector_unmi)) } > VECT54 =0x3C00
__interrupt_vector_55 : { KEEP (*(__interrupt_vector_55)) KEEP (*(__interrupt_vector_sysnmi)) } > VECT55 =0x3C00
__reset_vector :
{
KEEP (*(__interrupt_vector_56))
KEEP (*(__interrupt_vector_reset))
KEEP (*(.resetvec))
} > RESETVEC
.stack :
{
__main_thread_stack_base__ = .;
*(.stack)
. += __idle_stack_size__;
PROVIDE (__stack = .);
. = ALIGN(2);
__main_thread_stack_end__ = .;
} > FRAM :stack
.rodata :
{
. = ALIGN(2);
*(.plt)
*(.rodata .rodata.* .gnu.linkonce.r.* .const .const:*)
*(.rodata1)
*(.lower.rodata.* .lower.rodata)
*(.eh_frame_hdr)
KEEP (*(.eh_frame))
KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
PROVIDE (__fini_array_end = .);
LONG(0); /* Sentinel. */
/* gcc uses crtbegin.o to find the start of the constructors, so
we make sure it is first. Because this is a wildcard, it
doesn't matter if the user does not actually link against
crtbegin.o; the linker won't look for a file to match a
wildcard. The wildcard also means that it doesn't matter which
directory crtbegin.o is in. */
KEEP (*crtbegin*.o(.ctors))
/* We don't want to include the .ctor section from from the
crtend.o file until after the sorted ctors. The .ctor section
from the crtend file contains the end of ctors marker and it
must be last */
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
KEEP (*crtbegin*.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} > FRAM :rodata
.data :
{
. = ALIGN(2);
PROVIDE (__datastart = .);
KEEP (*(.jcr))
*(.data.rel.ro.local) *(.data.rel.ro*)
*(.dynamic)
*(.data .data.* .gnu.linkonce.d.*)
KEEP (*(.gnu.linkonce.d.*personality*))
SORT(CONSTRUCTORS)
*(.data1)
*(.got.plt) *(.got)
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
. = ALIGN(2);
*(.sdata .sdata.* .gnu.linkonce.s.* D_2 D_1)
. = ALIGN(2);
*(.lower.data.* .lower.data)
. = ALIGN(2);
_edata = .;
PROVIDE (edata = .);
PROVIDE (__dataend = .);
} > FRAM :data
/* Note that crt0 assumes this is a multiple of two; all the
start/stop symbols are also assumed word-aligned. */
PROVIDE(__romdatastart = LOADADDR(.data));
PROVIDE (__romdatacopysize = SIZEOF(.data));
.bss :
{
. = ALIGN(2);
PROVIDE (__bssstart = .);
*(.dynbss)
*(.sbss .sbss.*)
*(.bss .bss.* .gnu.linkonce.b.*)
*(.lower.bss.* .lower.bss)
. = ALIGN(2);
*(COMMON)
PROVIDE (__bssend = .);
} > FRAM
PROVIDE (__bsssize = SIZEOF(.bss));
/* This section contains data that is not initialised at startup. */
.noinit (NOLOAD) :
{
. = ALIGN(2);
PROVIDE (__noinit_start = .);
*(.noinit)
. = ALIGN(2);
PROVIDE (__noinit_end = .);
} > FRAM /* Because I think this has to go right above .bss */
_end = .;
PROVIDE (end = .);
.text :
{
PROVIDE (_start = .);
. = ALIGN(2);
KEEP (*(SORT(.crt_*)))
. = ALIGN(2);
KEEP (*(.lowtext))
. = ALIGN(2);
*(.lower.text.* .lower.text)
. = ALIGN(2);
*(.text .stub .text.* .gnu.linkonce.t.* .text:*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.interp .hash .dynsym .dynstr .gnu.version*)
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(2);
KEEP (*(.init))
KEEP (*(.fini))
KEEP (*(.tm_clone_table))
} > FRAM :text
.upper.rodata :
{
*(.upper.rodata.* .upper.rodata)
} > HIFRAM :upper_rodata
.upper.data :
{
__upper_data_init = LOADADDR (.upper.data);
/* Status word. */
SHORT(1);
__high_datastart = .;
*(.upper.data.* .upper.data)
__high_dataend = .;
} > HIFRAM :upper_data
__rom_highdatacopysize = SIZEOF(.upper.data) - 2;
__rom_highdatastart = LOADADDR(.upper.data) + 2;
.upper.bss :
{
. = ALIGN(2);
__high_bssstart = .;
*(.upper.bss.* .upper.bss)
. = ALIGN(2);
__high_bssend = .;
} > HIFRAM
.upper.text :
{
. = ALIGN(2);
*(.upper.text.* .upper.text)
} > HIFRAM :upper_text
.infoA : {} > INFOA /* MSP430 INFO FLASH MEMORY SEGMENTS */
.infoB : {} > INFOB
.infoC : {} > INFOC
.infoD : {} > INFOD
/* The rest are all not normally part of the runtime image. */
.MP430.attributes 0 :
{
KEEP (*(.MSP430.attributes))
KEEP (*(.gnu.attributes))
KEEP (*(__TI_build_attributes))
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1. */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions. */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2. */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2. */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions. */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
/DISCARD/ : { *(.note.GNU-stack) }
}
INCLUDE msp430fr5969_symbols.ld

View File

@ -0,0 +1,10 @@
# List of the ChibiOS generic MSP430X startup and linker files.
STARTUPSRC =
#$(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC/vectors.c
STARTUPASM =
STARTUPINC = $(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC
STARTUPLD = $(CHIBIOS_CONTRIB)/os/common/startup/MSP430X/compilers/GCC/ld

View File

@ -0,0 +1,269 @@
# ARM Cortex-Mx common makefile scripts and rules.
##############################################################################
# Processing options coming from the upper Makefile.
#
# Compiler options
OPT = $(USE_OPT)
COPT = $(USE_COPT)
CPPOPT = $(USE_CPPOPT)
# Garbage collection
ifeq ($(USE_LINK_GC),yes)
OPT += -ffunction-sections -fdata-sections -fno-common
LDOPT := ,--gc-sections
else
LDOPT :=
endif
# Linker extra options
ifneq ($(USE_LDOPT),)
LDOPT := $(LDOPT),$(USE_LDOPT)
endif
# Link time optimizations
ifeq ($(USE_LTO),yes)
OPT += -flto
endif
# HWMULT-related options
ifeq ($(USE_HWMULT),)
USE_HWMULT = none
endif
ifneq ($(USE_HWMULT),none)
OPT += -mhwmult=$(USE_HWMULT)
endif
# Idle thread stack size
ifeq ($(USE_IDLE_STACKSIZE),)
LDOPT := $(LDOPT),--defsym=__idle_stack_size__=0x40
else
LDOPT := $(LDOPT),--defsym=__idle_stack_size__=$(USE_IDLE_STACKSIZE)
endif
# Output directory and files
ifeq ($(BUILDDIR),)
BUILDDIR = build
endif
ifeq ($(BUILDDIR),.)
BUILDDIR = build
endif
OUTFILES = $(BUILDDIR)/$(PROJECT).elf \
$(BUILDDIR)/$(PROJECT).hex \
$(BUILDDIR)/$(PROJECT).bin \
$(BUILDDIR)/$(PROJECT).dmp \
$(BUILDDIR)/$(PROJECT).list
ifdef SREC
OUTFILES += $(BUILDDIR)/$(PROJECT).srec
endif
# Source files groups and paths
ACSRC = $(CSRC)
ACPPSRC = $(CPPSRC)
ASRC = $(CSRC)$(CPPSRC)
SRCPATHS = $(sort $(dir $(ASMXSRC)) $(dir $(ASMSRC)) $(dir $(ASRC)) $(dir $(TSRC)))
# Various directories
OBJDIR = $(BUILDDIR)/obj
LSTDIR = $(BUILDDIR)/lst
# Object files groups
ACOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ACSRC:.c=.o)))
ACPPOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ACPPSRC:.cpp=.o)))
ASMOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o)))
ASMXOBJS = $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o)))
OBJS = $(ASMXOBJS) $(ASMOBJS) $(ACOBJS) $(TCOBJS) $(ACPPOBJS) $(TCPPOBJS)
# Paths
IINCDIR = $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR))
LLIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))
# Macros
DEFS = $(DDEFS) $(UDEFS)
ADEFS = $(DADEFS) $(UADEFS)
# Libs
LIBS = $(DLIBS) $(ULIBS)
# Various settings
MCFLAGS = -mmcu=$(MCU) $(MOPT)
ODFLAGS = -x --syms
ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS)
ASXFLAGS = $(MCFLAGS) -Wa,-amhls=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS)
CFLAGS = $(MCFLAGS) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS)
CPPFLAGS = $(MCFLAGS) $(OPT) $(CPPOPT) $(CPPWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cpp=.lst)) $(DEFS)
LDFLAGS = $(MCFLAGS) $(OPT) -minrt $(LLIBDIR) -Wl,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--library-path=$(RULESPATH)/ld,--script=$(LDSCRIPT)$(LDOPT)
# Temporary specfile to deal with messed-up msp430-elf default spec file
SPECFILE := $(shell mktemp -u)
# Generate dependency information
ASFLAGS += -MD -MP -MF .dep/$(@F).d
CFLAGS += -MD -MP -MF .dep/$(@F).d
CPPFLAGS += -MD -MP -MF .dep/$(@F).d
# Paths where to search for sources
VPATH = $(SRCPATHS)
#
# Makefile rules
#
all: PRE_MAKE_ALL_RULE_HOOK $(OBJS) $(OUTFILES) POST_MAKE_ALL_RULE_HOOK
PRE_MAKE_ALL_RULE_HOOK:
POST_MAKE_ALL_RULE_HOOK:
$(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR)
$(BUILDDIR):
ifneq ($(USE_VERBOSE_COMPILE),yes)
@echo Compiler Options
@echo $(CC) -c $(CFLAGS) -I. $(IINCDIR) main.c -o main.o
@echo
endif
@mkdir -p $(BUILDDIR)
$(OBJDIR):
@mkdir -p $(OBJDIR)
$(LSTDIR):
@mkdir -p $(LSTDIR)
$(ACPPOBJS) : $(OBJDIR)/%.o : %.cpp Makefile
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
$(CPPC) -c $(CPPFLAGS) $(AOPT) -I. $(IINCDIR) $< -o $@
else
@echo Compiling $(<F)
@$(CPPC) -c $(CPPFLAGS) $(AOPT) -I. $(IINCDIR) $< -o $@
endif
$(TCPPOBJS) : $(OBJDIR)/%.o : %.cpp Makefile
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
$(CPPC) -c $(CPPFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
else
@echo Compiling $(<F)
@$(CPPC) -c $(CPPFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
endif
$(ACOBJS) : $(OBJDIR)/%.o : %.c Makefile
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
$(CC) -c $(CFLAGS) $(AOPT) -I. $(IINCDIR) $< -o $@
else
@echo Compiling $(<F)
@$(CC) -c $(CFLAGS) $(AOPT) -I. $(IINCDIR) $< -o $@
endif
$(TCOBJS) : $(OBJDIR)/%.o : %.c Makefile
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
$(CC) -c $(CFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
else
@echo Compiling $(<F)
@$(CC) -c $(CFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
endif
$(ASMOBJS) : $(OBJDIR)/%.o : %.s Makefile
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
$(AS) -c $(ASFLAGS) -I. $(IINCDIR) $< -o $@
else
@echo Compiling $(<F)
@$(AS) -c $(ASFLAGS) -I. $(IINCDIR) $< -o $@
endif
$(ASMXOBJS) : $(OBJDIR)/%.o : %.S Makefile
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
$(CC) -c $(ASXFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
else
@echo Compiling $(<F)
@$(CC) -c $(ASXFLAGS) $(TOPT) -I. $(IINCDIR) $< -o $@
endif
# This is gcc-specific - if LD isn't gcc it will fail
$(SPECFILE) :
$(LD) -dumpspecs > $(SPECFILE)
sed -i 's/%{!T.*}//' $(SPECFILE)
$(BUILDDIR)/$(PROJECT).elf: $(OBJS) $(LDSCRIPT) $(SPECFILE)
ifeq ($(USE_VERBOSE_COMPILE),yes)
@echo
$(LD) $(LDFLAGS) -specs=$(SPECFILE) $(OBJS) $(LIBS) -o $@
else
@echo Linking $@
@$(LD) $(LDFLAGS) -specs=$(SPECFILE) $(OBJS) $(LIBS) -o $@
endif
%.hex: %.elf
ifeq ($(USE_VERBOSE_COMPILE),yes)
$(HEX) $< $@
else
@echo Creating $@
@$(HEX) $< $@
endif
%.bin: %.elf
ifeq ($(USE_VERBOSE_COMPILE),yes)
$(BIN) $< $@
else
@echo Creating $@
@$(BIN) $< $@
endif
%.srec: %.elf
ifdef SREC
ifeq ($(USE_VERBOSE_COMPILE),yes)
$(SREC) $< $@
else
@echo Creating $@
@$(SREC) $< $@
endif
endif
%.dmp: %.elf
ifeq ($(USE_VERBOSE_COMPILE),yes)
$(OD) $(ODFLAGS) $< > $@
$(SZ) $<
else
@echo Creating $@
@$(OD) $(ODFLAGS) $< > $@
@echo
@$(SZ) $<
endif
%.list: %.elf
ifeq ($(USE_VERBOSE_COMPILE),yes)
$(OD) -S $< > $@
else
@echo Creating $@
@$(OD) -S $< > $@
@echo
@echo Done
endif
lib: $(OBJS) $(BUILDDIR)/lib$(PROJECT).a
$(BUILDDIR)/lib$(PROJECT).a: $(OBJS)
@$(AR) -r $@ $^
@echo
@echo Done
clean:
@echo Cleaning
-rm -fR .dep $(BUILDDIR)
@echo
@echo Done
#
# Include the dependency files, should be the last of the makefile
#
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# *** EOF ***

View File

@ -0,0 +1,46 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "hal.h"
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
* This variable is used by the HAL when initializing the PAL driver.
*/
#if HAL_USE_PAL || defined(__DOXYGEN__)
const PALConfig pal_default_config =
{
{VAL_IOPORT1_OUT, VAL_IOPORT1_DIR, VAL_IOPORT1_REN, VAL_IOPORT1_SEL0,
VAL_IOPORT1_SEL1, VAL_IOPORT1_IES, VAL_IOPORT1_IE},
{VAL_IOPORT2_OUT, VAL_IOPORT2_DIR, VAL_IOPORT2_REN, VAL_IOPORT2_SEL0,
VAL_IOPORT2_SEL1, VAL_IOPORT2_IES, VAL_IOPORT2_IE},
{VAL_IOPORT0_OUT, VAL_IOPORT0_DIR, VAL_IOPORT0_REN, VAL_IOPORT0_SEL0,
VAL_IOPORT0_SEL1, VAL_IOPORT0_IES, VAL_IOPORT0_IE}
}; /* Set UART TX pin correctly */
#endif /* HAL_USE_PAL */
/**
* Board-specific initialization code.
*/
void boardInit(void) {
/*
* External interrupts setup, all disabled initially.
*/
_disable_interrupts();
}

View File

@ -0,0 +1,129 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef _BOARD_H_
#define _BOARD_H_
/*
* Setup for the Arduino Uno or board.
*/
/*
* Board identifier.
*/
#define BOARD_EXP430FR5959
#define BOARD_NAME "MSP430FR5969 LaunchPad"
/*
* IO lines assignments.
*/
#define LINE_LED_G PAL_LINE(IOPORT1, 0U)
#define LINE_LED_R PAL_LINE(IOPORT2, 14U)
#define LINE_SW_S1 PAL_LINE(IOPORT2, 13U)
#define LINE_SW_S2 PAL_LINE(IOPORT1, 1U)
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.
* Please refer to the MSP430X Family Users Guide for details.
*/
/*
* Port A setup:
*
* P1.0 - Green LED (output low)
* P1.1 - Switch S2 (input pullup falling-edge interrupt)
* P1.2 - BoosterPack BP19 (input pullup)
* P1.3 - BoosterPack BP11 (input pullup)
* P1.4 - BoosterPack BP12 (input pullup)
* P1.5 - BoosterPack BP13 (input pullup)
* P1.6 - BoosterPack BP15 (input pullup)
* P1.7 - BoosterPack BP14 (input pullup)
* P2.0 - Application UART TX (alternate 2)
* P2.1 - Application UART RX (alternate 2)
* P2.2 - BoosterPack BP7 (input pullup)
* P2.3 - N/C (input pullup)
* P2.4 - BoosterPack BP6 (input pullup)
* P2.5 - BoosterPack BP4 (input pullup)
* P2.6 - BoosterPack BP3 (input pullup)
* P2.7 - N/C (input pullup)
*/
#define VAL_IOPORT1_OUT 0xFCFE
#define VAL_IOPORT1_DIR 0x0001
#define VAL_IOPORT1_REN 0xFCFE
#define VAL_IOPORT1_SEL0 0x0000
#define VAL_IOPORT1_SEL1 0x0300
#define VAL_IOPORT1_IES 0x0002
#define VAL_IOPORT1_IE 0x0002
/*
* Port B setup:
*
* P3.0 - BoosterPack BP18 (input pullup)
* P3.1 - N/C (input pullup)
* P3.2 - N/C (input pullup)
* P3.3 - N/C (input pullup)
* P3.4 - BoosterPack BP8 (input pullup)
* P3.5 - BoosterPack BP9 (input pullup)
* P3.6 - BoosterPack BP10 (input pullup)
* P3.7 - N/C (input pullup)
* P4.0 - Application UART CTS (input pullup falling-edge interrupt)
* P4.1 - Application UART RTS (output high)
* P4.2 - BoosterPack BP2 (input pullup)
* P4.3 - BoosterPack BP5 (input pullup)
* P4.4 - N/C (input pullup)
* P4.5 - Switch S1 (input pullup falling-edge interrupt)
* P4.6 - Red LED (output low)
* P4.7 - N/C (input pullup)
*/
#define VAL_IOPORT2_OUT 0xBFFF
#define VAL_IOPORT2_DIR 0x4200
#define VAL_IOPORT2_REN 0xBDFF
#define VAL_IOPORT2_SEL0 0x0000
#define VAL_IOPORT2_SEL1 0x0000
#define VAL_IOPORT2_IES 0x2100
#define VAL_IOPORT2_IE 0x2100
/*
* Port J setup:
*
* PJ.0 - TDO (input pullup)
* PJ.1 - TDI (input pullup)
* PJ.2 - TMS (input pullup)
* PJ.3 - TCK (input pullup)
* PJ.4 - LFXIN (alternate 1)
* PJ.5 - LFXOUT (alternate 1)
* PJ.6 - HFXIN (N/C) (input pullup)
* PJ.7 - HFXOUT (N/C) (input pullup)
*/
#define VAL_IOPORT0_OUT 0x00FF
#define VAL_IOPORT0_DIR 0x0000
#define VAL_IOPORT0_REN 0x00CF
#define VAL_IOPORT0_SEL0 0x0030
#define VAL_IOPORT0_SEL1 0x0000
#define VAL_IOPORT0_IES 0x0000
#define VAL_IOPORT0_IE 0x0000
#if !defined(_FROM_ASM_)
#ifdef __cplusplus
extern "C" {
#endif
void boardInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _FROM_ASM_ */
#endif /* _BOARD_H_ */

View File

@ -0,0 +1,5 @@
# List of all the board related files.
BOARDSRC = ${CHIBIOS_CONTRIB}/os/hal/boards/EXP430FR5969/board.c
# Required include directories
BOARDINC = ${CHIBIOS_CONTRIB}/os/hal/boards/EXP430FR5969

View File

@ -0,0 +1,87 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/hal_lld.c
* @brief MSP430X HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
#include "hal.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*
* @notapi
*/
void hal_lld_init(void) {
/* Disable watchdog */
/* TODO Real watchdog support */
WDTCTL = WDTPW | WDTHOLD;
/* Init clock system */
CSCTL0 = CSKEY; /* unlock clock system */
CSCTL1 = MSP430X_DCOSEL;
CSCTL2 = (MSP430X_ACLK_SRC << 8) | (MSP430X_SMCLK_SRC << 4) | (MSP430X_MCLK_SRC);
CSCTL3 = (DIVIDER(MSP430X_ACLK_DIV) << 8) | (DIVIDER(MSP430X_SMCLK_DIV) << 4) | (DIVIDER(MSP430X_MCLK_DIV));
CSCTL4 = (MSP430X_HFXTCLK_DRIVE << 14) | (MSP430X_HFXTCLK_BYPASS << 12) | (MSP430X_HFFREQ << 10) | HFXTOFF | \
(MSP430X_LFXTCLK_DRIVE << 6) | (MSP430X_LFXTCLK_BYPASS << 4) | VLOOFF | LFXTOFF;
CSCTL6 = (MODCLKREQEN) | (SMCLKREQEN) | (MCLKREQEN) | (ACLKREQEN);
#if defined(MSP430X_USE_HFXT) && defined(MSP430X_USE_LFXT)
do {
CSCTL5 &= ~(HFXTOFFG | LFXTOFFG);
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG);
#elif defined(MSP430X_USE_HFXT)
do {
CSCTL5 &= ~(HFXTOFFG);
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG);
#elif defined(MSP430X_USE_LFXT)
do {
CSCTL5 &= ~(LFXTOFFG);
SFRIFG1 &= ~OFIFG;
} while (SFRIFG1 & OFIFG);
#endif
CSCTL0_H = 0xFF; /* Lock clock system */
}
/** @} */

View File

@ -0,0 +1,245 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/hal_lld.h
* @brief MSP430X HAL subsystem low level driver header.
*
* @addtogroup HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Defines the support for realtime counters in the HAL.
*/
/* someday*/
#define HAL_IMPLEMENTS_COUNTERS FALSE
/**
* @name Platform identification macros
* @{
*/
#define PLATFORM_NAME "MSP430X"
/** @} */
#define MSP430X_LFXTCLK 0
#define MSP430X_VLOCLK 1
#define MSP430X_LFMODCLK 2
#define MSP430X_DCOCLK 3
#define MSP430X_MODCLK 4
#define MSP430X_HFXTCLK 5
#if !defined(MSP430X_LFXTCLK_FREQ)
#define MSP430X_LFXTCLK_FREQ 32768
#warning "LFXTCLK freqency not defined - assuming 32768 Hz"
#endif
#define MSP430X_VLOCLK_FREQ 10000
#define MSP430X_MODCLK_FREQ 5000000
#define MSP430X_LFMODCLK_FREQ (MSP430X_MODCLK_FREQ/128)
#if !defined(MSP430X_DCOCLK_FREQ)
#define MSP430X_DCOCLK_FREQ 8000000
#warning "DCOCLK frequency not defined - assuming 8 MHz"
#endif
#if !defined(MSP430X_HFXTCLK_FREQ)
#define MSP430X_HFXTCLK_FREQ 0
#warning "HFXTCLK frequency not defined - assuming disabled"
#endif
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name MSP430X configuration options
* @{
*/
/* Clock dividers */
#if !defined(MSP430X_ACLK_DIV)
#define MSP430X_ACLK_DIV 1
#endif
#if !defined(MSP430X_MCLK_DIV)
#define MSP430X_MCLK_DIV 8
#endif
#if !defined(MSP430X_SMCLK_DIV)
#define MSP430X_SMCLK_DIV 8
#endif
/* Clock sources */
#if !defined(MSP430X_ACLK_SRC)
#define MSP430X_ACLK_SRC MSP430X_LFXTCLK
#endif
#if !defined(MSP430X_MCLK_SRC)
#define MSP430X_MCLK_SRC MSP430X_DCOCLK
#endif
#if !defined(MSP430X_SMCLK_SRC)
#define MSP430X_SMCLK_SRC MSP430X_DCOCLK
#endif
/* HFXT and LFXT settings */
#if !defined(MSP430X_LFXTCLK_BYPASS)
#define MSP430X_LFXTCLK_BYPASS 0
#endif
#if !defined(MSP430X_LFXTCLK_DRIVE)
#define MSP430X_LFXTCLK_DRIVE 3
#endif
#if !defined(MSP430X_HFXTCLK_BYPASS)
#define MSP430X_HFXTCLK_BYPASS 0
#endif
#if !defined(MSP430X_HFXTCLK_DRIVE)
#define MSP430X_HFXTCLK_DRIVE 3
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*
* Configuration-related checks.
*/
#if (MSP430X_ACLK_SRC == MSP430X_LFXTCLK) || (MSP430X_MCLK_SRC == MSP430X_LFXTCLK) || (MSP430X_SMCLK_SRC == MSP430X_LFXTCLK)
#define MSP430X_USE_LFXTCLK
#endif
#if (MSP430X_MCLK_SRC == MSP430X_HFXTCLK) || (MSP430X_SMCLK_SRC == MSP430X_HFXTCLK)
#define MSP430X_USE_HFXTCLK
#endif
#if defined(MSP430X_USE_HFXTCLK) && MSP430X_HFXTCLK_FREQ == 0
#error "HFXT requested as clock source but disabled"
#endif
/* Clock speeds */
#if (MSP430X_ACLK_SRC == MSP430X_LFXTCLK)
#define MSP430X_ACLK_FREQ (MSP430X_LFXTCLK_FREQ / MSP430X_ACLK_DIV)
#elif (MSP430X_ACLK_SRC == MSP430X_VLOCLK)
#define MSP430X_ACLK_FREQ (MSP430X_VLOCLK_FREQ / MSP430X_ACLK_DIV)
#elif (MSP430X_ACLK_SRC == MSP430X_LFMODCLK)
#define MSP430X_ACLK_FREQ (MSP430X_LFMODCLK_FREQ / MSP430X_ACLK_DIV)
#else
#error "ACLK source invalid!"
#endif
#if (MSP430X_MCLK_SRC == MSP430X_LFXTCLK)
#define MSP430X_MCLK_FREQ (MSP430X_LFXTCLK_FREQ / MSP430X_MCLK_DIV)
#elif (MSP430X_MCLK_SRC == MSP430X_VLOCLK)
#define MSP430X_MCLK_FREQ (MSP430X_VLOCLK_FREQ / MSP430X_MCLK_DIV)
#elif (MSP430X_MCLK_SRC == MSP430X_LFMODCLK)
#define MSP430X_MCLK_FREQ (MSP430X_LFMODCLK_FREQ / MSP430X_MCLK_DIV)
#elif (MSP430X_MCLK_SRC == MSP430X_DCOCLK)
#define MSP430X_MCLK_FREQ (MSP430X_DCOCLK_FREQ / MSP430X_MCLK_DIV)
#elif (MSP430X_MCLK_SRC == MSP430X_MODCLK)
#define MSP430X_MCLK_FREQ (MSP430X_MODCLK_FREQ / MSP430X_MCLK_DIV)
#elif (MSP430X_MCLK_SRC == MSP430X_HFXTCLK)
#define MSP430X_MCLK_FREQ (MSP430X_HFXTCLK_FREQ / MSP430X_MCLK_DIV)
#else
#error "MCLK source invalid!"
#endif
#if (MSP430X_SMCLK_SRC == MSP430X_LFXTCLK)
#define MSP430X_SMCLK_FREQ (MSP430X_LFXTCLK_FREQ / MSP430X_SMCLK_DIV)
#elif (MSP430X_SMCLK_SRC == MSP430X_VLOCLK)
#define MSP430X_SMCLK_FREQ (MSP430X_VLOCLK_FREQ / MSP430X_SMCLK_DIV)
#elif (MSP430X_SMCLK_SRC == MSP430X_LFMODCLK)
#define MSP430X_SMCLK_FREQ (MSP430X_LFMODCLK_FREQ / MSP430X_SMCLK_DIV)
#elif (MSP430X_SMCLK_SRC == MSP430X_DCOCLK)
#define MSP430X_SMCLK_FREQ (MSP430X_DCOCLK_FREQ / MSP430X_SMCLK_DIV)
#elif (MSP430X_SMCLK_SRC == MSP430X_MODCLK)
#define MSP430X_SMCLK_FREQ (MSP430X_MODCLK_FREQ / MSP430X_SMCLK_DIV)
#elif (MSP430X_SMCLK_SRC == MSP430X_HFXTCLK)
#define MSP430X_SMCLK_FREQ (MSP430X_HFXTCLK_FREQ / MSP430X_SMCLK_DIV)
#else
#error "SMCLK source invalid!"
#endif
#if !defined(MSP430X_MCUCONF)
#error "Using an incorrect mcuconf.h file, MSP430X_MCUCONF not defined"
#endif
/* HFXT-specific settings */
#if MSP430X_HFXTCLK_FREQ <= 4000000
#define MSP430X_HFFREQ HFFREQ_0
#elif MSP430X_HFXTCLK_FREQ <= 8000000
#define MSP430X_HFFREQ HFFREQ_1
#elif MSP430X_HFXTCLK_FREQ <= 16000000
#define MSP430X_HFFREQ HFFREQ_2
#elif MSP430X_HFXTCLK_FREQ <= 24000000
#define MSP430X_HFFREQ HFFREQ_3
#else
#error "HFXT frequency too high - must be <= 24000000"
#endif
/* DCO-specific settings */
#if MSP430X_DCOCLK_FREQ == 1000000
#define MSP430X_DCOSEL DCOFSEL_0
#elif MSP430X_DCOCLK_FREQ == 2670000
#define MSP430X_DCOSEL DCOFSEL_1
#elif MSP430X_DCOCLK_FREQ == 3330000
#define MSP430X_DCOSEL DCOFSEL_2
#elif MSP430X_DCOCLK_FREQ == 4000000
#define MSP430X_DCOSEL DCOFSEL_3
#elif MSP430X_DCOCLK_FREQ == 5330000
#define MSP430X_DCOSEL DCOFSEL_4
#elif MSP430X_DCOCLK_FREQ == 6670000
#define MSP430X_DCOSEL DCOFSEL_5
#elif MSP430X_DCOCLK_FREQ == 8000000
#define MSP430X_DCOSEL DCOFSEL_6
#elif MSP430X_DCOCLK_FREQ == 16000000
#define MSP430X_DCOSEL (DCORSEL | DCOFSEL_4)
#elif MSP430X_DCOCLK_FREQ == 21000000
#define MSP430X_DCOSEL (DCORSEL | DCOFSEL_5)
#elif MSP430X_DCOCLK_FREQ == 24000000
#define MSP430X_DCOSEL (DCORSEL | DCOFSEL_6)
#else
#error "DCO frequency invalid"
#endif
#if MSP430X_LFXTCLK_FREQ > 50000
#error "LFXT frequency too high - must be <= 5000"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
#define DIVIDER(x) DIV_HELPER(x)
#define DIV_HELPER(x) DIVM__ ## x
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@ -0,0 +1,215 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/hal_pal_lld.c
* @brief MSP430X PAL subsystem low level driver source.
*
* @addtogroup PAL
* @{
*/
#include "hal.h"
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief MSP430X I/O ports configuration.
* @details GPIO registers initialization
*
* @param[in] config the MSP430X ports configuration
*
* @notapi
*/
void _pal_lld_init(const PALConfig *config) {
#if defined(PA_BASE) || defined(__DOXYGEN__)
PAOUT = config->porta.out;
PADIR = config->porta.dir;
PAREN = config->porta.ren;
PASEL0 = config->porta.sel0;
PASEL1 = config->porta.sel1;
PAIES = config->porta.ies;
PAIE = config->porta.ie;
#endif
#if defined(PB_BASE) || defined(__DOXYGEN__)
PBOUT = config->portb.out;
PBDIR = config->portb.dir;
PBREN = config->portb.ren;
PBSEL0 = config->portb.sel0;
PBSEL1 = config->portb.sel1;
PBIES = config->portb.ies;
PBIE = config->portb.ie;
#endif
#if defined(PC_BASE) || defined(__DOXYGEN__)
PCOUT = config->portc.out;
PCDIR = config->portc.dir;
PCREN = config->portc.ren;
PCSEL0 = config->portc.sel0;
PCSEL1 = config->portc.sel1;
PCIES = config->portc.ies;
PCIE = config->portc.ie;
#endif
#if defined(PD_BASE) || defined(__DOXYGEN__)
PDOUT = config->portd.out;
PDDIR = config->portd.dir;
PDREN = config->portd.ren;
PDSEL0 = config->portd.sel0;
PDSEL1 = config->portd.sel1;
PDIES = config->portd.ies;
PDIE = config->portd.ie;
#endif
#if defined(PE_BASE) || defined(__DOXYGEN__)
PEOUT = config->porte.out;
PEDIR = config->porte.dir;
PEREN = config->porte.ren;
PESEL0 = config->porte.sel0;
PESEL1 = config->porte.sel1;
PEIES = config->porte.ies;
PEIE = config->porte.ie;
#endif
#if defined(PF_BASE) || defined(__DOXYGEN__)
PFOUT = config->portf.out;
PFDIR = config->portf.dir;
PFREN = config->portf.ren;
PFSEL0 = config->portf.sel0;
PFSEL1 = config->portf.sel1;
PFIES = config->portf.ies;
PFIE = config->portf.ie;
#endif
PJOUT = config->portj.out;
PJDIR = config->portj.dir;
PJREN = config->portj.ren;
PJSEL0 = config->portj.sel0;
PJSEL1 = config->portj.sel1;
PM5CTL0 &= ~LOCKLPM5;
}
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note @p PAL_MODE_UNCONNECTED is implemented as input with pullup.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @notapi
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode) {
switch (mode) {
case PAL_MODE_RESET:
case PAL_MODE_INPUT:
port->dir &= ~mask;
port->ren &= ~mask;
if ((port->sel0 & mask) && (port->sel1 & mask))
port->selc = mask;
else {
port->sel0 &= ~mask;
port->sel1 &= ~mask;
}
break;
case PAL_MODE_UNCONNECTED:
case PAL_MODE_INPUT_PULLUP:
port->dir &= ~mask;
port->ren |= mask;
port->out |= mask;
if ((port->sel0 & mask) && (port->sel1 & mask))
port->selc = mask;
else {
port->sel0 &= ~mask;
port->sel1 &= ~mask;
}
break;
case PAL_MODE_INPUT_PULLDOWN:
port->dir &= ~mask;
port->ren |= mask;
port->out &= ~mask;
if ((port->sel0 & mask) && (port->sel1 & mask))
port->selc = mask;
else {
port->sel0 &= ~mask;
port->sel1 &= ~mask;
}
break;
case PAL_MODE_OUTPUT_PUSHPULL:
port->dir |= mask;
if ((port->sel0 & mask) && (port->sel1 & mask))
port->selc = mask;
else {
port->sel0 &= ~mask;
port->sel1 &= ~mask;
}
break;
case PAL_MSP430X_ALTERNATE_1:
if (!(port->sel0 & mask) && (port->sel1 & mask))
port->selc = mask;
else {
port->sel0 |= mask;
port->sel1 &= ~mask;
}
break;
case PAL_MSP430X_ALTERNATE_2:
if ((port->sel0 & mask) && !(port->sel1 & mask))
port->selc = mask;
else {
port->sel0 &= ~mask;
port->sel1 |= mask;
}
break;
case PAL_MSP430X_ALTERNATE_3:
if (!(port->sel0 & mask) && !(port->sel1 & mask))
port->selc = mask;
else {
port->sel0 |= mask;
port->sel1 |= mask;
}
break;
}
}
#endif /* HAL_USE_PAL == TRUE */
/** @} */

View File

@ -0,0 +1,390 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/hal_pal_lld.h
* @brief MSP430X PAL subsystem low level driver header.
*
* @addtogroup PAL
* @{
*/
#ifndef HAL_PAL_LLD_H
#define HAL_PAL_LLD_H
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
#undef PAL_MODE_INPUT_ANALOG /* configure this through the ALTERNATE macros */
#undef PAL_MODE_OUTPUT_OPENDRAIN
/**
* @name MSP430X-specific I/O mode flags
* @{
*/
/**
* @brief Alternate mode 1
*/
#define PAL_MSP430X_ALTERNATE_1 8
/**
* @brief Alternate mode 2
*/
#define PAL_MSP430X_ALTERNATE_2 9
/**
* @brief Alternate mode 3
*/
#define PAL_MSP430X_ALTERNATE_3 10
#define ALTERNATE_HELP(n) (PAL_MSP430X_ALTERNATE_ ## n)
/**
* @brief Alternate function.
*
* @param[in] n alternate function selector - 1 through 3
*/
#define PAL_MODE_ALTERNATE(n) (ALTERNATE_HELP(n))
/** @} */
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @name Port related definitions
* @{
*/
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 16U
/**
* @brief Whole port mask.
* @details This macro specifies all the valid bits into a port.
*/
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFU)
/** @} */
/**
* @name Line handling macros
* @{
*/
/**
* @brief Forms a line identifier.
* @details A port/pad pair are encoded into an @p ioline_t type. The encoding
* of this type is platform-dependent.
* @note In this driver the pad number is encoded in the upper 4 bits of
* the GPIO address which are guaranteed to be zero.
*/
#define PAL_LINE(port, pad) \
((ioline_t)((uint16_t)(port)) | (((uint16_t)(pad)) << 12))
/**
* @brief Decodes a port identifier from a line identifier.
*/
#define PAL_PORT(line) \
((msp430x_gpio_registers_t *)(((uint16_t)(line)) & 0x0FFFU))
/**
* @brief Decodes a pad identifier from a line identifier.
*/
#define PAL_PAD(line) \
((uint16_t)((uint16_t)(line) >> 12))
/**
* @brief Value identifying an invalid line.
*/
#define PAL_NOLINE 0U
/** @} */
/**
* @brief MSP430X register initialization
*/
typedef struct {
/** Initial value for OUT register.*/
uint16_t out;
/** Initial value for DIR register.*/
uint16_t dir;
/** Initial value for REN register.*/
uint16_t ren;
/** Initial value for SEL0 register.*/
uint16_t sel0;
/** Initial value for SEL1 register.*/
uint16_t sel1;
/** Initial value for IES register.*/
uint16_t ies;
/** Initial value for IE register.*/
uint16_t ie;
} msp430x_gpio_setup_t;
/**
* @brief MSP430X registers block
* @note Some ports do not support all of these fields.
*/
typedef struct {
volatile uint16_t in;
volatile uint16_t out;
volatile uint16_t dir;
volatile uint16_t _padding;
volatile uint16_t ren;
volatile uint16_t sel0;
volatile uint16_t sel1;
volatile uint16_t _padding1;
volatile uint16_t _padding2;
volatile uint16_t _padding3;
volatile uint16_t _padding4;
volatile uint16_t selc;
volatile uint16_t ies;
volatile uint16_t ie;
volatile uint16_t ifg;
} msp430x_gpio_registers_t;
/**
* @brief MSP430X I/O ports static initializer.
* @details An instance of this structure must be passed to @p palInit() at
* system startup time in order to initialized the digital I/O
* subsystem. This represents only the initial setup, specific pads
* or whole ports can be reprogrammed at later time.
*/
typedef struct {
#if defined(PA_BASE) || defined(__DOXYGEN__)
msp430x_gpio_setup_t porta;
#endif
#if defined(PB_BASE) || defined(__DOXYGEN__)
msp430x_gpio_setup_t portb;
#endif
#if defined(PC_BASE) || defined(__DOXYGEN__)
msp430x_gpio_setup_t portc;
#endif
#if defined(PD_BASE) || defined(__DOXYGEN__)
msp430x_gpio_setup_t portd;
#endif
#if defined(PE_BASE) || defined(__DOXYGEN__)
msp430x_gpio_setup_t porte;
#endif
#if defined(PF_BASE) || defined(__DOXYGEN__)
msp430x_gpio_setup_t portf;
#endif
msp430x_gpio_setup_t portj;
} PALConfig;
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint16_t ioportmask_t;
/**
* @brief Digital I/O modes.
*/
typedef uint16_t iomode_t;
/**
* @brief Type of an I/O line.
*/
typedef uint16_t ioline_t;
/**
* @brief Port Identifier.
* @details This type can be a scalar or some kind of pointer, do not make
* any assumption about it, use the provided macros when populating
* variables of this type.
*/
typedef msp430x_gpio_registers_t * ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief GPIO port A identifier.
*/
#if defined(PA_BASE) || defined(__DOXYGEN__)
#define IOPORT1 ((volatile msp430x_gpio_registers_t *)PA_BASE)
#endif
/**
* @brief GPIO port B identifier.
*/
#if defined(PB_BASE) || defined(__DOXYGEN__)
#define IOPORT2 ((volatile msp430x_gpio_registers_t *)PB_BASE)
#endif
/**
* @brief GPIO port C identifier.
*/
#if defined(PC_BASE) || defined(__DOXYGEN__)
#define IOPORT3 ((volatile msp430x_gpio_registers_t *)PC_BASE)
#endif
/**
* @brief GPIO port D identifier.
*/
#if defined(PD_BASE) || defined(__DOXYGEN__)
#define IOPORT4 ((volatile msp430x_gpio_registers_t *)PD_BASE)
#endif
/**
* @brief GPIO port E identifier.
*/
#if defined(PE_BASE) || defined(__DOXYGEN__)
#define IOPORT5 ((volatile msp430x_gpio_registers_t *)PE_BASE)
#endif
/**
* @brief GPIO port F identifier.
*/
#if defined(PF_BASE) || defined(__DOXYGEN__)
#define IOPORT6 ((volatile msp430x_gpio_registers_t *)PF_BASE
#endif
/**
* @brief GPIO port J identifier.
*/
#define IOPORT0 ((volatile msp430x_gpio_registers_t *)PJ_BASE)
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*
* @param[in] config architecture-dependent ports configuration
*
* @notapi
*/
#define pal_lld_init(config) _pal_lld_init(config)
/**
* @brief Reads the physical I/O port states.
*
* @param[in] port port identifier
* @return The port bits.
*
* @notapi
*/
#define pal_lld_readport(port) ((port)->in)
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
*
* @param[in] port port identifier
* @return The latched logical states.
*
* @notapi
*/
#define pal_lld_readlatch(port) ((port)->out)
/**
* @brief Writes a bits mask on a I/O port.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*
* @notapi
*/
#define pal_lld_writeport(port, bits) ((port)->out = (bits))
/**
* @brief Sets a bits mask on a I/O port.
*
* @param[in] port port identifier
* @param[in] bits bits to be ORed on the specified port
*
* @notapi
*/
#define pal_lld_setport(port, bits) ((port)->out |= (bits))
/**
* @brief Clears a bits mask on a I/O port.
*
* @param[in] port port identifier
* @param[in] bits bits to be cleared on the specified port
*
* @notapi
*/
#define pal_lld_clearport(port, bits) ((port)->out &= ~(bits))
/**
* @brief Toggles a bits mask on a I/O port.
*
* @param[in] port port identifier
* @param[in] bits bits to be XORed on the specified port
*
* @notapi
*/
#define pal_lld_toggleport(port, bits) ((port)->out ^= (bits))
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @param[in] mode group mode
*
* @notapi
*/
#define pal_lld_setgroupmode(port, mask, offset, mode) \
_pal_lld_setgroupmode(port, mask << offset, mode)
/**
* @brief Clears a pad logical state to @p PAL_LOW.
* @details This function is implemented in a way which should
* produce a BIC instruction rather than an AND
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*
* @notapi
*/
#define pal_lld_clearpad(port, pad) ((port)->out &= ~(BIT ## pad))
#if !defined(__DOXYGEN__)
extern const PALConfig pal_default_config;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _pal_lld_init(const PALConfig *config);
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_PAL == TRUE */
#endif /* _PAL_LLD_H_ */
/** @} */

View File

@ -0,0 +1,657 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/hal_serial_lld.c
* @brief MSP430X serial subsystem low level driver source.
*
* @addtogroup SERIAL
* @{
*/
#include "hal.h"
#if (HAL_USE_SERIAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/** @brief USART0 serial driver identifier.*/
#if (MSP430X_SERIAL_USE_USART0 == TRUE) || defined(__DOXYGEN__)
#ifndef __MSP430_HAS_EUSCI_A0__
#error "Cannot find USCI module to use for SD0"
#endif
SerialDriver SD0;
#endif
/** @brief USART1 serial driver identifier.*/
#if (MSP430X_SERIAL_USE_USART1 == TRUE) || defined(__DOXYGEN__)
#ifndef __MSP430_HAS_EUSCI_A1__
#error "Cannot find USCI module to use for SD1"
#endif
SerialDriver SD1;
#endif
/** @brief USART2 serial driver identifier.*/
#if (MSP430X_SERIAL_USE_USART2 == TRUE) || defined(__DOXYGEN__)
#ifndef __MSP430_HAS_EUSCI_A2__
#error "Cannot find USCI module to use for SD2"
#endif
SerialDriver SD2;
#endif
/** @brief USART3 serial driver identifier.*/
#if (MSP430X_SERIAL_USE_USART3 == TRUE) || defined(__DOXYGEN__)
#ifndef __MSP430_HAS_EUSCI_A3__
#error "Cannot find USCI module to use for SD3"
#endif
SerialDriver SD3;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/**
* @brief Driver default configuration.
*/
static const SerialConfig default_config = {
SERIAL_DEFAULT_BITRATE
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief UCBRS calculation.
* @details This function calculates the UCBRS value for oversampled baud
* rates.
*
* @param[in] frac Fractional part of baud rate division, times 10000.
*/
static uint8_t UCBRS(uint16_t frac) {
/* TODO there must be a better way */
if (frac < 529)
return 0x00;
else if (frac < 715)
return 0x01;
else if (frac < 835)
return 0x02;
else if (frac < 1001)
return 0x04;
else if (frac < 1252)
return 0x08;
else if (frac < 1430)
return 0x10;
else if (frac < 1670)
return 0x20;
else if (frac < 2147)
return 0x11;
else if (frac < 2224)
return 0x21;
else if (frac < 2503)
return 0x22;
else if (frac < 3000)
return 0x44;
else if (frac < 3335)
return 0x25;
else if (frac < 3575)
return 0x49;
else if (frac < 3753)
return 0x4A;
else if (frac < 4003)
return 0x52;
else if (frac < 4286)
return 0x92;
else if (frac < 4378)
return 0x53;
else if (frac < 5002)
return 0x55;
else if (frac < 5715)
return 0xAA;
else if (frac < 6003)
return 0x6B;
else if (frac < 6254)
return 0xAD;
else if (frac < 6432)
return 0xB5;
else if (frac < 6667)
return 0xB6;
else if (frac < 7001)
return 0xD6;
else if (frac < 7147)
return 0xB7;
else if (frac < 7503)
return 0xBB;
else if (frac < 7861)
return 0xDD;
else if (frac < 8004)
return 0xED;
else if (frac < 8333)
return 0xEE;
else if (frac < 8464)
return 0xBF;
else if (frac < 8572)
return 0xDF;
else if (frac < 8751)
return 0xEF;
else if (frac < 9004)
return 0xF7;
else if (frac < 9170)
return 0xFB;
else if (frac < 9288)
return 0xFD;
else
return 0xFE;
}
/**
* @brief Modulation control word calculator.
* @details This function calculates the modulation control word from the
* input clock frequency and the requested baud rate.
*
* @param[in] baud Requested baud rate
* @param[in] freq Frequency of the clock driving the USCI module
*/
static uint16_t UCAxMCTLW(uint32_t baud, uint32_t freq) {
uint16_t n = freq/baud;
/*uint16_t frac = (freq * 10000 / baud) - ((freq / baud) * 10000);*/
uint16_t frac = (freq - (n * baud)) * 10000 / baud;
if (n > 16) {
while (n > 16) {
n -= 16;
}
return (UCBRS(frac) << 8) | (n << 4) | UCOS16;
}
return UCBRS(frac) << 8;
}
/**
* @brief UCBRW calculation.
* @details This function calculates the UCBRW value for all baud
* rates.
*
* @param[in] baud Requested baud rate
* @param[in] freq Frequency of the clock driving the USCI module
*/
static uint16_t UCAxBRW(uint32_t baud, uint32_t freq) {
uint16_t n = freq/baud;
if (n > 16) {
return n >> 4;
}
return n;
}
#if (MSP430X_SERIAL_USE_USART0 == TRUE) || defined(__DOXYGEN__)
static void usart0_init(const SerialConfig *config) {
UCA0BRW = UCAxBRW(config->sc_bitrate, MSP430X_USART0_CLK_FREQ);
UCA0MCTLW = UCAxMCTLW(config->sc_bitrate, MSP430X_USART0_CLK_FREQ);
UCA0STATW = 0;
UCA0ABCTL = 0;
UCA0IRCTL = 0;
UCA0CTLW0 = (MSP430X_USART0_PARITY << 14) | (MSP430X_USART0_ORDER << 13) | \
(MSP430X_USART0_SIZE << 12) | (MSP430X_USART0_STOP << 11) | \
(MSP430X_USART0_UCSSEL);
UCA0IE = UCRXIE;
}
#endif
#if (MSP430X_SERIAL_USE_USART1 == TRUE) || defined(__DOXYGEN__)
static void usart1_init(const SerialConfig *config) {
UCA1BRW = UCAxBRW(config->sc_bitrate, MSP430X_USART1_CLK_FREQ);
UCA1MCTLW = UCAxMCTLW(config->sc_bitrate, MSP430X_USART1_CLK_FREQ);
UCA1STATW = 0;
UCA1ABCTL = 0;
UCA1IRCTL = 0;
UCA1IE = UCRXIE;
UCA1CTLW0 = (MSP430X_USART1_PARITY << 14) | (MSP430X_USART1_ORDER << 13) | \
(MSP430X_USART1_SIZE << 12) | (MSP430X_USART1_STOP << 11) | \
(MSP430X_USART1_UCSSEL);
}
#endif
#if (MSP430X_SERIAL_USE_USART2 == TRUE) || defined(__DOXYGEN__)
static void usart2_init(const SerialConfig *config) {
UCA2BRW = UCAxBRW(config->sc_bitrate, MSP430X_USART2_CLK_FREQ);
UCA2MCTLW = UCAxMCTLW(config->sc_bitrate);
UCA2STATW = 0;
UCA2ABCTL = 0;
UCA2IRCTL = 0;
UCA2IE = UCRXIE;
UCA2CTLW0 = (MSP430X_USART2_PARITY << 14) | (MSP430X_USART2_ORDER << 13) | \
(MSP430X_USART2_SIZE << 12) | (MSP430X_USART2_STOP << 11) | \
(MSP430X_USART2_UCSSEL);
}
#endif
#if (MSP430X_SERIAL_USE_USART3 == TRUE) || defined(__DOXYGEN__)
static void usart3_init(const SerialConfig *config) {
UCA3BRW = UCAxBRW(config->sc_bitrate, MSP430X_USART3_CLK_FREQ);
UCA3MCTLW = UCAxMCTLW(config->sc_bitrate, MSP430X_USART3_CLK_FREQ);
UCA3STATW = 0;
UCA3ABCTL = 0;
UCA3IRCTL = 0;
UCA3IE = UCRXIE;
UCA3CTLW0 = (MSP430X_USART3_PARITY << 14) | (MSP430X_USART3_ORDER << 13) | \
(MSP430X_USART3_SIZE << 12) | (MSP430X_USART3_STOP << 11) | \
(MSP430X_USART3_UCSSEL);
}
#endif
#if (MSP430X_SERIAL_USE_USART0 == TRUE) || defined(__DOXYGEN__)
static void notify0(io_queue_t *qp) {
(void)qp;
UCA0IE |= UCTXIE;
}
#endif
#if (MSP430X_SERIAL_USE_USART1 == TRUE) || defined(__DOXYGEN__)
static void notify1(io_queue_t *qp) {
(void)qp;
UCA1IE |= UCTXIE;
}
#endif
#if (MSP430X_SERIAL_USE_USART2 == TRUE) || defined(__DOXYGEN__)
static void notify2(io_queue_t *qp) {
(void)qp;
UCA2IE |= UCTXIE;
}
#endif
#if (MSP430X_SERIAL_USE_USART3 == TRUE) || defined(__DOXYGEN__)
static void notify3(io_queue_t *qp) {
(void)qp;
UCA3IE |= UCTXIE;
}
#endif
/**
* @brief Error handling routine.
*
* @param[in] sra USCI status register containing errors
* @param[in] sdp pointer to a @p SerialDriver object
*/
static void set_error(uint16_t sra, SerialDriver *sdp) {
eventflags_t sts = 0;
if (sra & UCOE)
sts |= SD_OVERRUN_ERROR;
if (sra & UCPE)
sts |= SD_PARITY_ERROR;
if (sra & UCFE)
sts |= SD_FRAMING_ERROR;
osalSysLockFromISR();
chnAddFlagsI(sdp, sts);
osalSysUnlockFromISR();
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if MSP430X_SERIAL_USE_USART0 || defined(__DOXYGEN__)
/**
* @brief USART0 interrupt handler.
*
* @isr
*/
PORT_IRQ_HANDLER(USCI_A0_VECTOR) {
msg_t b;
OSAL_IRQ_PROLOGUE();
switch (__even_in_range(UCA0IV,USCI_UART_UCTXCPTIFG)) {
case USCI_UART_UCRXIFG: /* RX interrupt */
/* Detect errors */
if (UCA0STATW & UCRXERR)
set_error(UCA0STATW, &SD0);
/* Data available */
osalSysLockFromISR();
sdIncomingDataI(&SD0, UCA0RXBUF);
osalSysUnlockFromISR();
break;
case USCI_UART_UCTXIFG: /* TX interrupt */
/* Transmission buffer empty */
osalSysLockFromISR();
b = sdRequestDataI(&SD0);
if (b < Q_OK) {
chnAddFlagsI(&SD0, CHN_OUTPUT_EMPTY);
UCA0IE = (UCA0IE & ~UCTXIE) | UCTXCPTIE;
UCA0IFG |= UCTXIFG; /* If we don't write to TXBUF, IFG won't get set */
}
else
UCA0TXBUF = b;
osalSysUnlockFromISR();
break;
case USCI_UART_UCTXCPTIFG: /* TX complete interrupt */
/* Physical transmission end */
osalSysLockFromISR();
if (oqIsEmptyI(&SD0.oqueue))
chnAddFlagsI(&SD0, CHN_TRANSMISSION_END);
UCA0IE &= ~UCTXCPTIE;
break;
default: /* other interrupts */
while (1);
break;
}
OSAL_IRQ_EPILOGUE();
}
#endif
#if MSP430X_SERIAL_USE_USART1 || defined(__DOXYGEN__)
/**
* @brief USART1 interrupt handler.
*
* @isr
*/
PORT_IRQ_HANDLER(USCI_A1_VECTOR) {
msg_t b;
OSAL_IRQ_PROLOGUE();
switch (__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG)) {
case USCI_UART_UCRXIFG: /* RX interrupt */
/* Detect errors */
if (UCA1STATW & UCRXERR)
set_error(UCA1STATW, &SD1);
/* Data available */
osalSysLockFromISR();
sdIncomingDataI(&SD1, UCA1RXBUF);
osalSysUnlockFromISR();
break;
case USCI_UART_UCTXIFG: /* TX interrupt */
/* Transmission buffer empty */
osalSysLockFromISR();
b = sdRequestDataI(&SD1);
if (b < Q_OK) {
chnAddFlagsI(&SD1, CHN_OUTPUT_EMPTY);
UCA1IE = (UCA1IE & ~UCTXIE) | UCTXCPTIE;
UCA1IFG |= UCTXIFG; /* If we don't write to TXBUF, IFG won't get set */
}
else
UCA1TXBUF = b;
osalSysUnlockFromISR();
break;
case USCI_UART_UCTXCPTIFG: /* TX complete interrupt */
/* Physical transmission end */
osalSysLockFromISR();
if (oqIsEmptyI(&SD1.oqueue))
chnAddFlagsI(&SD1, CHN_TRANSMISSION_END);
UCA1IE &= ~UCTXCPTIE;
break;
default: /* other interrupts */
while (1);
break;
}
OSAL_IRQ_EPILOGUE();
}
#endif
#if MSP430X_SERIAL_USE_USART2 || defined(__DOXYGEN__)
/**
* @brief USART2 interrupt handler.
*
* @isr
*/
PORT_IRQ_HANDLER(USCI_A2_VECTOR) {
msg_t b;
OSAL_IRQ_PROLOGUE();
switch (__even_in_range(UCA2IV,USCI_UART_UCTXCPTIFG)) {
case USCI_UART_UCRXIFG: /* RX interrupt */
/* Detect errors */
if (UCA2STATW & UCRXERR)
set_error(UCA2STATW, &SD2);
/* Data available */
osalSysLockFromISR();
sdIncomingDataI(&SD2, UCA2RXBUF);
osalSysUnlockFromISR();
break;
case USCI_UART_UCTXIFG: /* TX interrupt */
/* Transmission buffer empty */
osalSysLockFromISR();
b = sdRequestDataI(&SD2);
if (b < Q_OK) {
chnAddFlagsI(&SD2, CHN_OUTPUT_EMPTY);
UCA2IE = (UCA2IE & ~UCTXIE) | UCTXCPTIE;
UCA2IFG |= UCTXIFG; /* If we don't write to TXBUF, IFG won't get set */
}
else
UCA2TXBUF = b;
osalSysUnlockFromISR();
break;
case USCI_UART_UCTXCPTIFG: /* TX complete interrupt */
/* Physical transmission end */
osalSysLockFromISR();
if (oqIsEmptyI(&SD2.oqueue))
chnAddFlagsI(&SD2, CHN_TRANSMISSION_END);
UCA2IE &= ~UCTXCPTIE;
break;
default: /* other interrupts */
while (1);
break;
}
OSAL_IRQ_EPILOGUE();
}
#endif
#if MSP430X_SERIAL_USE_USART3 || defined(__DOXYGEN__)
/**
* @brief USART3 interrupt handler.
*
* @isr
*/
PORT_IRQ_HANDLER(USCI_A3_VECTOR) {
msg_t b;
OSAL_IRQ_PROLOGUE();
switch (__even_in_range(UCA3IV,USCI_UART_UCTXCPTIFG)) {
case USCI_UART_UCRXIFG: /* RX interrupt */
/* Detect errors */
if (UCA3STATW & UCRXERR)
set_error(UCA3STATW, &SD3);
/* Data available */
osalSysLockFromISR();
sdIncomingDataI(&SD3, UCA3RXBUF);
osalSysUnlockFromISR();
break;
case USCI_UART_UCTXIFG: /* TX interrupt */
/* Transmission buffer empty */
osalSysLockFromISR();
b = sdRequestDataI(&SD3);
if (b < Q_OK) {
chnAddFlagsI(&SD3, CHN_OUTPUT_EMPTY);
UCA3IE = (UCA3IE & ~UCTXIE) | UCTXCPTIE;
UCA3IFG |= UCTXIFG; /* If we don't write to TXBUF, IFG won't get set */
}
else
UCA3TXBUF = b;
osalSysUnlockFromISR();
break;
case USCI_UART_UCTXCPTIFG: /* TX complete interrupt */
/* Physical transmission end */
osalSysLockFromISR();
if (oqIsEmptyI(&SD3.oqueue))
chnAddFlagsI(&SD3, CHN_TRANSMISSION_END);
UCA3IE &= ~UCTXCPTIE;
break;
default: /* other interrupts */
while (1);
break;
}
OSAL_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*
* @notapi
*/
void sd_lld_init(void) {
#if MSP430X_SERIAL_USE_USART0 == TRUE
sdObjectInit(&SD0, NULL, notify0);
#endif
#if MSP430X_SERIAL_USE_USART1 == TRUE
sdObjectInit(&SD1, NULL, notify1);
#endif
#if MSP430X_SERIAL_USE_USART2 == TRUE
sdObjectInit(&SD2, NULL, notify2);
#endif
#if MSP430X_SERIAL_USE_USART3 == TRUE
sdObjectInit(&SD3, NULL, notify3);
#endif
}
/**
* @brief Low level serial driver configuration and (re)start.
*
* @param[in] sdp pointer to a @p SerialDriver object
* @param[in] config the architecture-dependent serial driver configuration.
* If this parameter is set to @p NULL then a default
* configuration is used.
*
* @notapi
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL) {
config = &default_config;
}
if (sdp->state == SD_STOP) {
#if MSP430X_SERIAL_USE_USART0 == TRUE
if (&SD0 == sdp) {
usart0_init(config);
}
#endif
#if MSP430X_SERIAL_USE_USART1 == TRUE
if (&SD1 == sdp) {
usart1_init(config);
}
#endif
#if MSP430X_SERIAL_USE_USART2 == TRUE
if (&SD2 == sdp) {
usart2_init(config);
}
#endif
#if MSP430X_SERIAL_USE_USART3 == TRUE
if (&SD3 == sdp) {
usart3_init(config);
}
#endif
}
}
/**
* @brief Low level serial driver stop.
* @details De-initializes the USART, stops the associated clock, resets the
* interrupt vector.
*
* @param[in] sdp pointer to a @p SerialDriver object
*
* @notapi
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->state == SD_READY) {
#if MSP430X_SERIAL_USE_USART0 == TRUE
if (&SD0 == sdp) {
UCA0CTLW0 = UCSWRST;
}
#endif
#if MSP430X_SERIAL_USE_USART1 == TRUE
if (&SD1 == sdp) {
UCA1CTLW0 = UCSWRST;
}
#endif
#if MSP430X_SERIAL_USE_USART2 == TRUE
if (&SD2 == sdp) {
UCA2CTLW0 = UCSWRST;
}
#endif
#if MSP430X_SERIAL_USE_USART3 == TRUE
if (&SD3 == sdp) {
UCA3CTLW0 = UCSWRST;
}
#endif
}
}
#endif /* HAL_USE_SERIAL == TRUE */
/** @} */

View File

@ -0,0 +1,320 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/hal_serial_lld.h
* @brief MSP430X serial subsystem low level driver header.
*
* @addtogroup SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if (HAL_USE_SERIAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define NONE 0
#define ODD 2
#define EVEN 3
#define MSB 1
#define LSB 0
#define SEVEN 1
#define EIGHT 0
#define ONE 0
#define TWO 1
#define MSP430X_SERIAL_SMCLK UCSSEL__SMCLK
#define MSP430X_SERIAL_UCLK UCSSEL__UCLK
#define MSP430X_SERIAL_ACLK UCSSEL__ACLK
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name USART0 configuration options
* @{
*/
/**
* @brief USART0 driver enable switch.
* @details If set to @p TRUE the support for USART1 is included.
* @note The default is @p FALSE.
*/
#if !defined(MSP430X_SERIAL_USE_USART0) || defined(__DOXYGEN__)
#define MSP430X_SERIAL_USE_USART0 FALSE
#endif
/** @} */
/**
* @name USART1 configuration options
* @{
*/
/**
* @brief USART1 driver enable switch.
* @details If set to @p TRUE the support for USART1 is included.
* @note The default is @p FALSE.
*/
#if !defined(MSP430X_SERIAL_USE_USART1) || defined(__DOXYGEN__)
#define MSP430X_SERIAL_USE_USART1 FALSE
#endif
/** @} */
/**
* @name USART2 configuration options
* @{
*/
/**
* @brief USART2 driver enable switch.
* @details If set to @p TRUE the support for USART1 is included.
* @note The default is @p FALSE.
*/
#if !defined(MSP430X_SERIAL_USE_USART2) || defined(__DOXYGEN__)
#define MSP430X_SERIAL_USE_USART2 FALSE
#endif
/** @} */
/**
* @name USART3 configuration options
* @{
*/
/**
* @brief USART3 driver enable switch.
* @details If set to @p TRUE the support for USART1 is included.
* @note The default is @p FALSE.
*/
#if !defined(MSP430X_SERIAL_USE_USART3) || defined(__DOXYGEN__)
#define MSP430X_SERIAL_USE_USART3 FALSE
#endif
#if MSP430X_SERIAL_USE_USART0
#if !defined(MSP430X_USART0_PARITY)
#define MSP430X_USART0_PARITY NONE
#endif
#if !defined(MSP430X_USART0_ORDER)
#define MSP430X_USART0_ORDER LSB
#endif
#if !defined(MSP430X_USART0_SIZE)
#define MSP430X_USART0_SIZE EIGHT
#endif
#if !defined(MSP430X_USART0_STOP)
#define MSP430X_USART0_STOP ONE
#endif
#if !defined(MSP430X_USART0_CLK_SRC)
#define MSP430X_USART0_CLK_SRC MSP430X_UCLK_SRC
#ifndef MSP430X_USART0_CLK_FREQ
#error "Requested external UART0 clock but no frequency given"
#endif
#define MSP430X_USART0_UCSSEL UCSSEL__UCLK
#elif MSP430X_USART0_CLK_SRC == MSP430X_ACLK_SRC
#define MSP430X_USART0_CLK_SRC MSP430X_ACLK_SRC
#define MSP430X_USART0_CLK_FREQ MSP430X_ACLK_FREQ
#define MSP430X_USART0_UCSSEL UCSSEL__ACLK
#elif MSP430X_USART0_CLK_SRC == MSP430X_SMCLK_SRC
#define MSP430X_USART0_CLK_SRC MSP430X_SMCLK_SRC
#define MSP430X_USART0_CLK_FREQ MSP430X_SMCLK_FREQ
#define MSP430X_USART0_UCSSEL UCSSEL__SMCLK
#else
#error "MSP430X_USART0_CLK_SRC invalid"
#endif
#endif
#if MSP430X_SERIAL_USE_USART1
#if !defined(MSP430X_USART1_PARITY)
#define MSP430X_USART1_PARITY NONE
#endif
#if !defined(MSP430X_USART1_ORDER)
#define MSP430X_USART1_ORDER LSB
#endif
#if !defined(MSP430X_USART1_SIZE)
#define MSP430X_USART1_SIZE EIGHT
#endif
#if !defined(MSP430X_USART1_STOP)
#define MSP430X_USART1_STOP ONE
#endif
#if !defined(MSP430X_USART1_CLK_SRC)
#define MSP430X_USART1_CLK_SRC MSP430X_UCLK_SRC
#ifndef MSP430X_USART1_CLK_FREQ
#error "Requested external UART0 clock but no frequency given"
#endif
#define MSP430X_USART1_UCSSEL UCSSEL__UCLK
#elif MSP430X_USART1_CLK_SRC == MSP430X_ACLK_SRC
#define MSP430X_USART1_CLK_SRC MSP430X_ACLK_SRC
#define MSP430X_USART1_CLK_FREQ MSP430X_ACLK_FREQ
#define MSP430X_USART1_UCSSEL UCSSEL__ACLK
#elif MSP430X_USART1_CLK_SRC == MSP430X_SMCLK_SRC
#define MSP430X_USART1_CLK_SRC MSP430X_SMCLK_SRC
#define MSP430X_USART1_CLK_FREQ MSP430X_SMCLK_FREQ
#define MSP430X_USART1_UCSSEL UCSSEL__SMCLK
#else
#error "MSP430X_USART1_CLK_SRC invalid"
#endif
#endif
#if MSP430X_SERIAL_USE_USART2
#if !defined(MSP430X_USART2_PARITY)
#define MSP430X_USART2_PARITY NONE
#endif
#if !defined(MSP430X_USART2_ORDER)
#define MSP430X_USART2_ORDER LSB
#endif
#if !defined(MSP430X_USART2_SIZE)
#define MSP430X_USART2_SIZE EIGHT
#endif
#if !defined(MSP430X_USART2_STOP)
#define MSP430X_USART2_STOP ONE
#endif
#if !defined(MSP430X_USART2_CLK_SRC)
#define MSP430X_USART2_CLK_SRC MSP430X_UCLK_SRC
#ifndef MSP430X_USART2_CLK_FREQ
#error "Requested external UART0 clock but no frequency given"
#endif
#define MSP430X_USART2_UCSSEL UCSSEL__UCLK
#elif MSP430X_USART2_CLK_SRC == MSP430X_ACLK_SRC
#define MSP430X_USART2_CLK_SRC MSP430X_ACLK_SRC
#define MSP430X_USART2_CLK_FREQ MSP430X_ACLK_FREQ
#define MSP430X_USART2_UCSSEL UCSSEL__ACLK
#elif MSP430X_USART2_CLK_SRC == MSP430X_SMCLK_SRC
#define MSP430X_USART2_CLK_SRC MSP430X_SMCLK_SRC
#define MSP430X_USART2_CLK_FREQ MSP430X_SMCLK_FREQ
#define MSP430X_USART2_UCSSEL UCSSEL__SMCLK
#else
#error "MSP430X_USART2_CLK_SRC invalid"
#endif
#endif
#if MSP430X_SERIAL_USE_USART3
#if !defined(MSP430X_USART3_PARITY)
#define MSP430X_USART3_PARITY NONE
#endif
#if !defined(MSP430X_USART3_ORDER)
#define MSP430X_USART3_ORDER LSB
#endif
#if !defined(MSP430X_USART3_SIZE)
#define MSP430X_USART3_SIZE EIGHT
#endif
#if !defined(MSP430X_USART3_STOP)
#define MSP430X_USART3_STOP ONE
#endif
#if !defined(MSP430X_USART3_CLK_SRC)
#define MSP430X_USART3_CLK_SRC MSP430X_UCLK_SRC
#ifndef MSP430X_USART3_CLK_FREQ
#error "Requested external UART0 clock but no frequency given"
#endif
#define MSP430X_USART3_UCSSEL UCSSEL__UCLK
#elif MSP430X_USART3_CLK_SRC == MSP430X_ACLK_SRC
#define MSP430X_USART3_CLK_SRC MSP430X_ACLK_SRC
#define MSP430X_USART3_CLK_FREQ MSP430X_ACLK_FREQ
#define MSP430X_USART3_UCSSEL UCSSEL__ACLK
#elif MSP430X_USART3_CLK_SRC == MSP430X_SMCLK_SRC
#define MSP430X_USART3_CLK_SRC MSP430X_SMCLK_SRC
#define MSP430X_USART3_CLK_FREQ MSP430X_SMCLK_FREQ
#define MSP430X_USART3_UCSSEL UCSSEL__SMCLK
#else
#error "MSP430X_USART3_CLK_SRC invalid"
#endif
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief MSP430X Serial Driver configuration structure.
* @details An insance of this structure must be passed to @p sdStart()
* in order to configure and start a serial driver operations.
* @note This structure content is architecture dependent, each driver
* implementation defines its own version and the custom static
* initializers.
*/
typedef struct {
/**
* @brief Bit rate.
*/
uint32_t sc_bitrate;
/* End of the mandatory fields.*/
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
input_queue_t iqueue; \
/* Output queue.*/ \
output_queue_t oqueue; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if (MSP430X_SERIAL_USE_USART0 == TRUE) && !defined(__DOXYGEN__)
extern SerialDriver SD0;
#endif
#if (MSP430X_SERIAL_USE_USART1 == TRUE) && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if (MSP430X_SERIAL_USE_USART2 == TRUE) && !defined(__DOXYGEN__)
extern SerialDriver SD2;
#endif
#if (MSP430X_SERIAL_USE_USART3 == TRUE) && !defined(__DOXYGEN__)
extern SerialDriver SD3;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void sd_lld_init(void);
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
void sd_lld_stop(SerialDriver *sdp);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_SERIAL == TRUE */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@ -0,0 +1,206 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/hal_st_lld.c
* @brief MSP430X ST subsystem low level driver source.
*
* @addtogroup ST
* @{
*/
#include "hal.h"
#include <msp430.h>
#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) || defined(__DOXYGEN__)
#define MSP430X_ST_DIV_CALC(x) ((MSP430X_ST_CLK_FREQ / OSAL_ST_FREQUENCY) == x)
#endif
#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined(__DOXYGEN__)
#if ((MSP430X_ST_CLK_FREQ / OSAL_ST_FREQUENCY / 64) > MSP_TIMER_COUNTER_MAX)
#error "Frequency too low for timer - please set OSAL_ST_FREQUENCY to a higher value"
#endif
#define MSP430X_ST_DIV_CALC(x) ((MSP430X_ST_CLK_FREQ / OSAL_ST_FREQUENCY / x) <= MSP_TIMER_COUNTER_MAX)
#endif
/* Find suitable prescaler setting */
#if MSP430X_ST_DIV_CALC(1)
#define MSP430X_ST_DIV 1
#define MSP430X_ST_DIV_BITS ID__1
#define MSP430X_ST_DIV_EX_BITS TAIDEX_0
#elif MSP430X_ST_DIV_CALC(2)
#define MSP430X_ST_DIV 2
#define MSP430X_ST_DIV_BITS ID__1
#define MSP430X_ST_DIV_EX_BITS TAIDEX_1
#elif MSP430X_ST_DIV_CALC(3)
#define MSP430X_ST_DIV 3
#define MSP430X_ST_DIV_BITS ID__1
#define MSP430X_ST_DIV_EX_BITS TAIDEX_2
#elif MSP430X_ST_DIV_CALC(4)
#define MSP430X_ST_DIV 4
#define MSP430X_ST_DIV_BITS ID__1
#define MSP430X_ST_DIV_EX_BITS TAIDEX_3
#elif MSP430X_ST_DIV_CALC(5)
#define MSP430X_ST_DIV 5
#define MSP430X_ST_DIV_BITS ID__1
#define MSP430X_ST_DIV_EX_BITS TAIDEX_4
#elif MSP430X_ST_DIV_CALC(6)
#define MSP430X_ST_DIV 6
#define MSP430X_ST_DIV_BITS ID__1
#define MSP430X_ST_DIV_EX_BITS TAIDEX_5
#elif MSP430X_ST_DIV_CALC(7)
#define MSP430X_ST_DIV 7
#define MSP430X_ST_DIV_BITS ID__1
#define MSP430X_ST_DIV_EX_BITS TAIDEX_6
#elif MSP430X_ST_DIV_CALC(8)
#define MSP430X_ST_DIV 8
#define MSP430X_ST_DIV_BITS ID__1
#define MSP430X_ST_DIV_EX_BITS TAIDEX_7
#elif MSP430X_ST_DIV_CALC(10)
#define MSP430X_ST_DIV 10
#define MSP430X_ST_DIV_BITS ID__2
#define MSP430X_ST_DIV_EX_BITS TAIDEX_4
#elif MSP430X_ST_DIV_CALC(12)
#define MSP430X_ST_DIV 12
#define MSP430X_ST_DIV_BITS ID__2
#define MSP430X_ST_DIV_EX_BITS TAIDEX_5
#elif MSP430X_ST_DIV_CALC(14)
#define MSP430X_ST_DIV 14
#define MSP430X_ST_DIV_BITS ID__2
#define MSP430X_ST_DIV_EX_BITS TAIDEX_6
#elif MSP430X_ST_DIV_CALC(16)
#define MSP430X_ST_DIV 16
#define MSP430X_ST_DIV_BITS ID__2
#define MSP430X_ST_DIV_EX_BITS TAIDEX_7
#elif MSP430X_ST_DIV_CALC(20)
#define MSP430X_ST_DIV 20
#define MSP430X_ST_DIV_BITS ID__4
#define MSP430X_ST_DIV_EX_BITS TAIDEX_4
#elif MSP430X_ST_DIV_CALC(24)
#define MSP430X_ST_DIV 24
#define MSP430X_ST_DIV_BITS ID__4
#define MSP430X_ST_DIV_EX_BITS TAIDEX_5
#elif MSP430X_ST_DIV_CALC(28)
#define MSP430X_ST_DIV 28
#define MSP430X_ST_DIV_BITS ID__4
#define MSP430X_ST_DIV_EX_BITS TAIDEX_6
#elif MSP430X_ST_DIV_CALC(32)
#define MSP430X_ST_DIV 32
#define MSP430X_ST_DIV_BITS ID__4
#define MSP430X_ST_DIV_EX_BITS TAIDEX_7
#elif MSP430X_ST_DIV_CALC(40)
#define MSP430X_ST_DIV 40
#define MSP430X_ST_DIV_BITS ID__8
#define MSP430X_ST_DIV_EX_BITS TAIDEX_4
#elif MSP430X_ST_DIV_CALC(48)
#define MSP430X_ST_DIV 48
#define MSP430X_ST_DIV_BITS ID__8
#define MSP430X_ST_DIV_EX_BITS TAIDEX_5
#elif MSP430X_ST_DIV_CALC(56)
#define MSP430X_ST_DIV 56
#define MSP430X_ST_DIV_BITS ID__8
#define MSP430X_ST_DIV_EX_BITS TAIDEX_6
#elif MSP430X_ST_DIV_CALC(64)
#define MSP430X_ST_DIV 64
#define MSP430X_ST_DIV_BITS ID__8
#define MSP430X_ST_DIV_EX_BITS TAIDEX_7
#else
#error "Error in calculating dividers - check OSAL_ST_FREQUENCY and frequency of input clock"
#endif
/* ugh never again*/
#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined(__DOXYGEN__)
#define MSP_TIMER_COUNTER (MSP430X_ST_CLK_FREQ / OSAL_ST_FREQUENCY / MSP430X_ST_DIV)
#define MSP430X_ST_CLK_FREQ_ (MSP_TIMER_COUNTER * MSP430X_ST_DIV * OSAL_ST_FREQUENCY)
#if (MSP430X_ST_CLK_FREQ != MSP430X_ST_CLK_FREQ_)
#warning "OSAL_ST_FREQUENCY cannot be generated exactly using timer"
#endif
#undef MSP430X_ST_CLK_FREQ_
#endif
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief Timer handler for both modes
*/
PORT_IRQ_HANDLER( MSP430X_ST_ISR ) {
OSAL_IRQ_PROLOGUE();
osalSysLockFromISR();
osalOsTimerHandlerI();
osalSysUnlockFromISR();
OSAL_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level ST driver initialization.
*
* @notapi
*/
void st_lld_init(void) {
#if (OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING) || defined (__DOXYGEN__)
/* Start disabled */
MSP430X_ST_CCR(MSP430X_ST_TIMER) = 0;
MSP430X_ST_CCTL(MSP430X_ST_TIMER) = 0;
MSP430X_ST_EX(MSP430X_ST_TIMER) = MSP430X_ST_DIV_EX_BITS;
MSP430X_ST_CTL(MSP430X_ST_TIMER) = (TACLR | MC_2 | MSP430X_ST_DIV_BITS | MSP430X_ST_TASSEL);
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING */
#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined (__DOXYGEN__)
/* Start enabled */
MSP430X_ST_CCR(MSP430X_ST_TIMER) = MSP_TIMER_COUNTER - 1;
MSP430X_ST_CCTL(MSP430X_ST_TIMER) = CCIE;
MSP430X_ST_EX(MSP430X_ST_TIMER) = MSP430X_ST_DIV_EX_BITS;
MSP430X_ST_CTL(MSP430X_ST_TIMER) = (TACLR | MC_1 | MSP430X_ST_DIV_BITS | MSP430X_ST_TASSEL);
#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */
}
#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
/** @} */

View File

@ -0,0 +1,216 @@
/*
ChibiOS - Copyright (C) 2016 Andrew Wygle aka awygle
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file MSP430X/hal_st_lld.h
* @brief MSP430X ST subsystem low level driver header.
* @details This header is designed to be include-able without having to
* include other files from the HAL.
*
* @addtogroup MSP430X
* @{
*/
#ifndef _ST_LLD_H_
#define _ST_LLD_H_
#include <msp430.h>
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Timer maximum value
*/
#define MSP_TIMER_COUNTER_MAX 65535
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief System timer clock source.
*
* @note Legal values are undefined, MSP430X_ACLK_SRC, and
* MSP430X_SMCLK_SRC.
* @note If undefined, must define MSP430X_ST_CLK_FREQ as frequency of
* external clock and configure PAL appropriately.
*/
#if !defined (MSP430X_ST_CLK_SRC)
#ifndef MSP430X_ST_CLK_FREQ
#warning "Requested external source for ST but no frequency given"
#warning "- assuming OSAL_ST_FREQUENCY"
#define MSP430X_ST_CLK_FREQ OSAL_ST_FREQUENCY
#endif
#define MSP430X_ST_TASSEL TASSEL__TACLK
#elif MSP430X_ST_CLK_SRC == MSP430X_ACLK_SRC
#define MSP430X_ST_CLK_FREQ MSP430X_ACLK_FREQ
#define MSP430X_ST_TASSEL TASSEL__ACLK
#elif MSP430X_ST_CLK_SRC == MSP430X_SMCLK_SRC
#define MSP430X_ST_CLK_FREQ MSP430X_SMCLK_FREQ
#define MSP430X_ST_TASSEL TASSEL__SMCLK
#endif
/* Timers */
/**
* @brief Timer type (by letter) to be used for ST.
* @note Legal values are A and B. D support not yet implemented.
* @note Defaults to A
*/
#if !defined(MSP430X_ST_TIMER_TYPE)
#define MSP430X_ST_TIMER_TYPE A
#endif
/**
* @brief Timer instance (by number) to be used for ST.
* @note Defaults to 0
*/
#if !defined (MSP430X_ST_TIMER_INDEX)
#define MSP430X_ST_TIMER_INDEX 0
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#define TIMER_HELPER2(x, y) x ## y
#define TIMER_HELPER(x, y) TIMER_HELPER2(x, y)
#define MSP430X_ST_TIMER TIMER_HELPER(MSP430X_ST_TIMER_TYPE, MSP430X_ST_TIMER_INDEX)
#define CCR_HELPER(x) T ## x ## CCR0
#define MSP430X_ST_CCR(x) CCR_HELPER(x)
#define CCTL_HELPER(x) T ## x ## CCTL0
#define MSP430X_ST_CCTL(x) CCTL_HELPER(x)
#define EX_HELPER(x) T ## x ## EX0
#define MSP430X_ST_EX(x) EX_HELPER(x)
#define CTL_HELPER(x) T ## x ## CTL
#define MSP430X_ST_CTL(x) CTL_HELPER(x)
#define R_HELPER(x) T ## x ## R
#define MSP430X_ST_R(x) R_HELPER(x)
#define ISR_HELPER2(x, y) TIMER ## y ## _ ## x ## 0_VECTOR
#define ISR_HELPER(x, y) ISR_HELPER2(x, y)
#define MSP430X_ST_ISR ISR_HELPER(MSP430X_ST_TIMER_TYPE, MSP430X_ST_TIMER_INDEX)
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void st_lld_init(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Driver inline functions. */
/*===========================================================================*/
/**
* @brief Returns the time counter value.
*
* @return The counter value.
*
* @notapi
*/
static inline systime_t st_lld_get_counter(void) {
return (systime_t)MSP430X_ST_R(MSP430X_ST_TIMER);
}
/**
* @brief Starts the alarm.
* @note Makes sure that no spurious alarms are triggered after
* this call.
*
* @param[in] abstime the time to be set for the first alarm
*
* @notapi
*/
static inline void st_lld_start_alarm(systime_t abstime) {
MSP430X_ST_CCR(MSP430X_ST_TIMER) = abstime;
/* Reset pending interrupt */
MSP430X_ST_CCTL(MSP430X_ST_TIMER) &= (~CCIFG);
/* Enable interrupt */
MSP430X_ST_CCTL(MSP430X_ST_TIMER) |= CCIE;
}
/**
* @brief Stops the alarm interrupt.
*
* @notapi
*/
static inline void st_lld_stop_alarm(void) {
MSP430X_ST_CCTL(MSP430X_ST_TIMER) &= (~CCIE);
}
/**
* @brief Sets the alarm time.
*
* @param[in] abstime the time to be set for the next alarm
*
* @notapi
*/
static inline void st_lld_set_alarm(systime_t abstime) {
MSP430X_ST_CCR(MSP430X_ST_TIMER) = abstime;
}
/**
* @brief Returns the current alarm time.
*
* @return The currently set alarm time.
*
* @notapi
*/
static inline systime_t st_lld_get_alarm(void) {
return MSP430X_ST_CCR(MSP430X_ST_TIMER);
}
/**
* @brief Determines if the alarm is active.
*
* @return The alarm status.
* @retval false if the alarm is not active.
* @retval true is the alarm is active
*
* @notapi
*/
static inline bool st_lld_is_alarm_active(void) {
return (bool)((MSP430X_ST_CCTL(MSP430X_ST_TIMER) & CCIE) != 0);
}
#endif /* _ST_LLD_H_ */
/** @} */

View File

@ -0,0 +1,8 @@
# List of all the MSP430X platform files.
PLATFORMSRC = ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_st_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_serial_lld.c \
${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X/hal_pal_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS_CONTRIB}/os/hal/ports/MSP430X