diff --git a/CMakeLists.txt b/CMakeLists.txt index f73e6dc..05903ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,12 @@ project(cadmium) set(CMAKE_CXX_STANDARD 17) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin) +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() +set(CMAKE_CXX_FLAGS_DEBUG "-g") +set(CMAKE_CXX_FLAGS_RELEASE "-O3") + add_library(cadmium INTERFACE) target_include_directories(cadmium INTERFACE include/ json/include) @@ -16,8 +22,26 @@ foreach(exampleSrc ${Examples}) target_link_libraries(${exampleName} cadmium) endforeach(exampleSrc) +if(APPLE) + # Apple Clang does not pack OpenMP. We must install it via HomeBrew and link it manually + if(CMAKE_C_COMPILER_ID MATCHES "Clang\$") + set(OpenMP_C_FLAGS "-Xpreprocessor -fopenmp") + set(OpenMP_C_LIB_NAMES "omp") + set(OpenMP_omp_LIBRARY omp) + endif() + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang\$") + set(OpenMP_CXX_FLAGS "-Xpreprocessor -fopenmp") + set(OpenMP_CXX_LIB_NAMES "omp") + set(OpenMP_omp_LIBRARY omp) + endif() +endif() find_package(OpenMP) if(OpenMP_CXX_FOUND) + if (APPLE) + # HomeBrew leaves a symlink to the installed version of OpenMP in these directories + include_directories("/usr/local/opt/libomp/include") + link_directories("/usr/local/opt/libomp/lib") + endif() FILE(GLOB Examples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} example/*/parallel_main_*.cpp) foreach(exampleSrc ${Examples}) get_filename_component(exampleName ${exampleSrc} NAME_WE) diff --git a/build.sh b/build.sh index c1b9d36..e5b8d68 100644 --- a/build.sh +++ b/build.sh @@ -1,8 +1,40 @@ +#! /bin/bash + +# Function to add the CADMIUM variable to the environment +add_cadmium_env() { + # Check if CADMIUM is already set in .bashrc + if ! grep -Fxq "export CADMIUM=$(pwd)" ~/.bashrc; then + echo "export CADMIUM=$(pwd)" >> ~/.bashrc + echo "The CADMIUM variable has been set to $(pwd) in ~/.bashrc." + else + echo "The CADMIUM variable is already set in ~/.bashrc." + fi + + # Source the updated .bashrc + source ~/.bashrc +} + echo Downloading all the dependencies... -git submodule update --init --recursive +sudo apt install build-essential make cmake git +git pull +git submodule update --init --recursive --progress mkdir build cd build || exit cmake .. make all cd .. echo Compilation done. All the examples are in the bin folder + +cd include +# Prompt the user for confirmation +echo "Do you want to add cadmium ($(pwd)) to the PATH? (yes/no)" +read -r response + +# Check the response and take action +if [[ "$response" =~ ^[Yy][Ee][Ss]$ || "$response" =~ ^[Yy]$ ]]; then + add_cadmium_env +elif [[ "$response" =~ ^[Nn][Oo]$ || "$response" =~ ^[Nn]$ ]]; then + echo "Operation canceled. The $(pwd) was not added to PATH." +else + echo "Invalid response. Please run the script again and respond with 'yes' or 'no'." +fi diff --git a/celldevs_examples.sh b/celldevs_examples.sh index fb6ecb3..dbf386b 100644 --- a/celldevs_examples.sh +++ b/celldevs_examples.sh @@ -1,11 +1,9 @@ echo Running asymmetric Cell-DEVS example... -cd example/celldevs_asymm_sir || exit -../../bin/main_asymm_sir config.json -cd ../.. -echo Simulation done. Results are available in example/celldevs_asymm_sir/log.csv +cd example/celldevs_sir || exit +../../bin/main_asymm_sir asymm_config.json +echo Simulation done. Results are available in example/celldevs_sir/log_asymm_sir.csv -echo Running classic Cell-DEVS example... -cd example/celldevs_grid_sir || exit -../../bin/main_grid_sir config.json +echo Running grid Cell-DEVS example... +../../bin/main_grid_sir grid_config.json cd ../.. -echo Simulation done. Results are available in example/celldevs_grid_sir/log.csv +echo Simulation done. Results are available in example/celldevs_sir/log_grid_sir.csv diff --git a/example/_blinky/_main_blinky.cpp b/example/_blinky/_main_blinky.cpp new file mode 100644 index 0000000..966ef41 --- /dev/null +++ b/example/_blinky/_main_blinky.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include "blinkySystem.hpp" + +using namespace cadmium::example::blinkySystem; + +int main(int argc, char *argv[]) { + // First, we parse the arguments + std::ifstream file; + + + auto model = std::make_shared("blinkySystem"); + auto rootCoordinator = cadmium::RootCoordinator(model); + auto logger = std::make_shared("log_blinkySystem.csv", ","); + rootCoordinator.setLogger(logger); + rootCoordinator.start(); + rootCoordinator.simulate(std::numeric_limits::infinity()); + rootCoordinator.stop(); + return 0; +} diff --git a/example/_rtModel/_main_rt_model.cpp b/example/_rtModel/_main_rt_model.cpp new file mode 100644 index 0000000..e8002b9 --- /dev/null +++ b/example/_rtModel/_main_rt_model.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include "covidSupervisorySystem.hpp" + +using namespace cadmium::example::covidSupervisorySystem; + +int main(int argc, char *argv[]) { + // First, we parse the arguments + std::ifstream file; + + + auto model = std::make_shared("covidSupervisorySystem"); + auto rootCoordinator = cadmium::RootCoordinator(model); + auto logger = std::make_shared("log_covidSupervisorySystem.csv", ","); + rootCoordinator.setLogger(logger); + rootCoordinator.start(); + rootCoordinator.simulate(std::numeric_limits::infinity()); + rootCoordinator.stop(); + return 0; +} diff --git a/example/_rtModel/include/c02SensorController.hpp b/example/_rtModel/include/c02SensorController.hpp new file mode 100644 index 0000000..e659cc2 --- /dev/null +++ b/example/_rtModel/include/c02SensorController.hpp @@ -0,0 +1,104 @@ +#ifndef _C02_SENSOR_HPP__ +#define _C02_SENSOR_HPP__ + +#include +#include + +namespace cadmium::example::covidSupervisorySystem { + //! Class for representing the Processor DEVS model state. + struct C02SensorControllerState { + double sigma; + double c02; + //! Processor state constructor. By default, the processor is idling. + C02SensorControllerState(): sigma(0), c02(1.00) {} + }; + + /** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ + std::ostream& operator<<(std::ostream &out, const C02SensorControllerState& state) { + out << "C02 Level:," << state.c02; + return out; + } + + //! Atomic DEVS model of a Job processor. + class C02SensorController : public Atomic { + private: + const float MIN_CO2_VOLTAGE = 0.5; //!< Time required by the Processor model to process one Job. + public: + Port c02In; //!< Input Port for receiving new Job objects. + Port c02Safe; //!< Output Port for sending processed Job objects. + + /** + * Constructor function. + * @param id ID of the new Processor model object. + */ + C02SensorController(const std::string& id): Atomic(id, C02SensorControllerState()) { + c02In = addInPort("c02In"); + c02Safe = addOutPort("c02Safe"); + } + + /** + * It updates the ProcessorState::clock, clears the ProcessorState::Job being processed, and passivates. + * @param state reference to the current state of the model. + */ + void internalTransition(C02SensorControllerState& state) const override { + state.sigma = std::numeric_limits::infinity(); + } + + /** + * Updates ProcessorState::clock and ProcessorState::sigma. + * If it is idling and gets a new Job via the Processor::inGenerated port, it starts processing it. + * @param state reference to the current model state. + * @param e time elapsed since the last state transition function was triggered. + * @param x reference to the model input port set. + */ + void externalTransition(C02SensorControllerState& state, double e) const override { + + if(!c02In->empty()){ + state.sigma = 0; + if(c02In->getBag().back()){ + state.c02 = 1; + }else{ + state.c02 = 0; + } + + return; + } + + state.sigma = std::numeric_limits::infinity(); + + + } + + /** + * It outputs the already processed ProcessorState::Job via the Processor::outProcessed port. + * @param state reference to the current model state. + * @param y reference to the atomic model output port set. + */ + void output(const C02SensorControllerState& state) const override { + + bool safe = false; + + if(state.c02 > MIN_CO2_VOLTAGE){ + safe = true; + } + c02Safe->addMessage(safe); + + } + + /** + * It returns the value of ProcessorState::sigma. + * @param state reference to the current model state. + * @return the sigma value. + */ + [[nodiscard]] double timeAdvance(const C02SensorControllerState& state) const override { + return state.sigma; + } + }; +} //namespace cadmium::example::covidSupervisorySystem + +#endif //_C02_SENSOR_HPP__ diff --git a/example/_rtModel/include/covidSupervisorySystem.hpp b/example/_rtModel/include/covidSupervisorySystem.hpp new file mode 100644 index 0000000..85383cb --- /dev/null +++ b/example/_rtModel/include/covidSupervisorySystem.hpp @@ -0,0 +1,43 @@ +#ifndef CADMIUM_EXAMPLE_COVID_SUPERVISORY_SYSTEM_HPP_ +#define CADMIUM_EXAMPLE_COVID_SUPERVISORY_SYSTEM_HPP_ + +#include +#include +#include "./digitalInput.hpp" +#include "./c02SensorController.hpp" +#include "./ledController.hpp" +#include "./occupencyController.hpp" + +namespace cadmium::example::covidSupervisorySystem { + //! Coupled DEVS model to show how the IEStream atomic model works. + struct covidSupervisorySystem : public Coupled { + + /** + * Constructor function for the iestream model. + * @param id ID of the iestream model. + * @param filePath path to the input file to be read. + */ + covidSupervisorySystem(const std::string& id) : Coupled(id) { + + auto digitalInput = addComponent("digitalInput"); + auto iestreamOccIn = addComponent>("iestreamOccIn", "../example/rtModel/occIn.txt"); + auto iestreamOccOut = addComponent>("iestreamOccOut", "../example/rtModel/occOut.txt"); + + + auto occupencyController = addComponent("occupencyController"); + auto ledController = addComponent("ledController"); + auto c02SensorController = addComponent("c02SensorController"); + + addCoupling(digitalInput->out, c02SensorController->c02In); + addCoupling(iestreamOccIn->out, occupencyController->personIn); + addCoupling(iestreamOccOut->out, occupencyController->personOut); + + + addCoupling(occupencyController->personSafe, ledController->occupancyIn); + addCoupling(c02SensorController->c02Safe, ledController->c02In); + + } + }; +} //namespace cadmium::example::covidSupervisorySystem + +#endif //CADMIUM_EXAMPLE_COVID_SUPERVISORY_SYSTEM_HPP_ \ No newline at end of file diff --git a/example/_rtModel/include/digitPin.hpp b/example/_rtModel/include/digitPin.hpp new file mode 100644 index 0000000..1810fb1 --- /dev/null +++ b/example/_rtModel/include/digitPin.hpp @@ -0,0 +1,72 @@ +/** +* Jon Menard +* ARSLab - Carleton University +* +* Digital Input: +* Model to interface with a digital Input pin for Embedded Cadmium. +*/ + + + +#ifndef RT_DIGITALPIN_HPP +#define RT_DIGITALPIN_HPP + + + +#include +#include + +#include +#include +#include +#include +#include +#include + + +using namespace std; +namespace cadmium { + + class DigitalPin { + mutable std::mutex input_mutex; + mutable bool keyPressed; + + public: + DigitalPin(){ + std::unique_lock mutex_lock(input_mutex, std::defer_lock); + mutex_lock.lock(); + keyPressed = false; + // _keyCode = keyCode; + mutex_lock.unlock(); + std::thread(&DigitalPin::listen, this).detach(); + }; + + bool checkPin(){ + bool pin; + std::unique_lock mutex_lock(input_mutex, std::defer_lock); + mutex_lock.lock(); + pin = keyPressed; + keyPressed = false; + + mutex_lock.unlock(); + + return pin; + } + + void listen(){ + std::unique_lock mutex_lock(input_mutex, std::defer_lock); + string str; + while(1){ + getline(cin, str); + if(str == ""){ + mutex_lock.lock(); + keyPressed = true; + mutex_lock.unlock(); + } + } + } + + }; +} // namespace cadmium + +#endif // RT_DIGITALPIN_HPP \ No newline at end of file diff --git a/example/_rtModel/include/digitalInput.hpp b/example/_rtModel/include/digitalInput.hpp new file mode 100644 index 0000000..a457274 --- /dev/null +++ b/example/_rtModel/include/digitalInput.hpp @@ -0,0 +1,114 @@ +/** +* Jon Menard +* ARSLab - Carleton University +* +* Digital Input: +* Model to interface with a digital Input pin for Embedded Cadmium. +*/ + +#ifndef RT_DIGITALINPUT_TEST_HPP +#define RT_DIGITALINPUT_TEST_HPP + +#include +#include +#include +#include "./digitPin.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// #ifdef RT_ARM_MBED + //This class will interface with a digital input pin. + //#include "../mbed.h" + +// using namespace cadmium; +// using namespace std; +namespace cadmium { + + struct DigitalInputState { + bool output; + bool last; + double sigma; + + /** + * Processor state constructor. By default, the processor is idling. + * + */ + explicit DigitalInputState(): output(true), last(false), sigma(0){ + } + + }; + + /** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ + + std::ostream& operator<<(std::ostream &out, const DigitalInputState& state) { + out << "Input Pin: " << (state.output ? 1 : 0); + return out; + } + + class DigitalInput : public Atomic { + public: + + Port out; + //Parameters to be overwriten when instantiating the atomic model + DigitalPin* digiPin; + double pollingRate; + // default constructor + DigitalInput(const std::string& id): Atomic(id, DigitalInputState()) { + out = addOutPort("out"); + digiPin = new DigitalPin(); + pollingRate = 0.01; + }; + + // internal transition + void internalTransition(DigitalInputState& state) const override { + state.last = state.output; + if(digiPin->checkPin()){ + state.output = !state.last; + } + state.sigma = pollingRate; + } + + // external transition + void externalTransition(DigitalInputState& state, double e) const override { + // MBED_ASSERT(false); + // throw std::logic_error("External transition called in a model with no input ports"); + } + + // output function + void output(const DigitalInputState& state) const override { + if(state.last != state.output) { + bool output = state.output; + out->addMessage(output); + if(output){ + std::cout << "Input: 1\n"; + }else{ + std::cout << "Input: 0 \n"; + } + } + } + + // time_advance function + [[nodiscard]] double timeAdvance(const DigitalInputState& state) const override { + return state.sigma; + } + + }; +} + +#endif // BOOST_SIMULATION_PDEVS_DIGITALINPUT_HPP \ No newline at end of file diff --git a/example/_rtModel/include/ledController.hpp b/example/_rtModel/include/ledController.hpp new file mode 100644 index 0000000..4a45f85 --- /dev/null +++ b/example/_rtModel/include/ledController.hpp @@ -0,0 +1,110 @@ +#ifndef _LED_CONTROLLER_HPP__ +#define _LED_CONTROLLER_HPP__ + +#include +#include + +namespace cadmium::example::covidSupervisorySystem { + //! Class for representing the Processor DEVS model state. + struct LEDControllerState { + bool occupancySafe; + bool c02Safe; + bool ledColor; + double sigma; + //! Processor state constructor. By default, the processor is idling. + LEDControllerState(): occupancySafe(true), c02Safe(true), ledColor(true), sigma(0) {} + }; + + /** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ + std::ostream& operator<<(std::ostream &out, const LEDControllerState& state) { + out << "LED Status:, " << state.ledColor; + return out; + } + + //! Atomic DEVS model of a Job processor. + class LEDController : public Atomic { + private: + + public: + Port c02In; + Port occupancyIn; + Port lEDOut; + + + /** + * Constructor function. + * @param id ID of the new Processor model object. + */ + LEDController(const std::string& id): Atomic(id, LEDControllerState()) { + c02In = addInPort("c02In"); + occupancyIn = addInPort("occupancyIn"); + lEDOut = addOutPort("lEDOut"); + } + + /** + * It updates the ProcessorState::clock, clears the ProcessorState::Job being processed, and passivates. + * @param state reference to the current state of the model. + */ + void internalTransition(LEDControllerState& state) const override { + state.sigma = std::numeric_limits::infinity(); + } + + /** + * Updates ProcessorState::clock and ProcessorState::sigma. + * If it is idling and gets a new Job via the Processor::inGenerated port, it starts processing it. + * @param state reference to the current model state. + * @param e time elapsed since the last state transition function was triggered. + * @param x reference to the model input port set. + */ + void externalTransition(LEDControllerState& state, double e) const override { + + if(!c02In->empty()){ + state.c02Safe = c02In->getBag().back(); + } + + if(!occupancyIn->empty()){ + state.occupancySafe = occupancyIn->getBag().back(); + } + + bool ledColor = state.ledColor; + + if(state.occupancySafe && state.c02Safe){ + state.ledColor = true; + }else{ + state.ledColor = false; + } + + if(ledColor != state.ledColor){ + state.sigma = 0; + return; + } + + state.sigma = std::numeric_limits::infinity(); + } + + /** + * It outputs the already processed ProcessorState::Job via the Processor::outProcessed port. + * @param state reference to the current model state. + * @param y reference to the atomic model output port set. + */ + void output(const LEDControllerState& state) const override { + lEDOut->addMessage(state.ledColor); + } + + /** + * It returns the value of ProcessorState::sigma. + * @param state reference to the current model state. + * @return the sigma value. + */ + [[nodiscard]] double timeAdvance(const LEDControllerState& state) const override { + return state.sigma; + } + }; +} //namespace cadmium::example::covidSupervisorySystem + +#endif //_LED_CONTROLLER_HPP__ diff --git a/example/_rtModel/include/occupencyController.hpp b/example/_rtModel/include/occupencyController.hpp new file mode 100644 index 0000000..79f42dd --- /dev/null +++ b/example/_rtModel/include/occupencyController.hpp @@ -0,0 +1,119 @@ +#ifndef _OCCUPENCY_CONTROLLER_HPP__ +#define _OCCUPENCY_CONTROLLER_HPP__ + +#include +#include + + +namespace cadmium::example::covidSupervisorySystem { + //! Class for representing the Processor DEVS model state. + struct OccupencyControllerState { + int personCount; + double sigma; + //! Processor state constructor. By default, the processor is idling. + OccupencyControllerState(): personCount(0), sigma(0) {} + }; + + /** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ + std::ostream& operator<<(std::ostream &out, const OccupencyControllerState& state) { + out << "Person Count:," << state.personCount; + return out; + } + + //! Atomic DEVS model of a Job processor. + class OccupencyController : public Atomic { + private: + const int MAX_OCCUPANCY = 3; + public: + Port personIn; + Port personOut; + Port personSafe; + + + /** + * Constructor function. + * @param id ID of the new Processor model object. + */ + OccupencyController(const std::string& id): Atomic(id, OccupencyControllerState()) { + personIn = addInPort("personIn"); + personOut = addInPort("personOut"); + personSafe = addOutPort("personSafe"); + } + + /** + * It updates the ProcessorState::clock, clears the ProcessorState::Job being processed, and passivates. + * @param state reference to the current state of the model. + */ + void internalTransition(OccupencyControllerState& state) const override { + state.sigma = std::numeric_limits::infinity(); + } + + /** + * Updates ProcessorState::clock and ProcessorState::sigma. + * If it is idling and gets a new Job via the Processor::inGenerated port, it starts processing it. + * @param state reference to the current model state. + * @param e time elapsed since the last state transition function was triggered. + * @param x reference to the model input port set. + */ + void externalTransition(OccupencyControllerState& state, double e) const override { + + int person_n = state.personCount; + + if(!personIn->empty()){ + for( const auto personEntered : personIn->getBag()){ + if(personEntered){ + state.personCount += 1; + } + } + } + + if(!personOut->empty()){ + for( const auto personLeft : personOut->getBag()){ + if(state.personCount > 0 && personLeft){ + state.personCount -= 1; + } + } + } + + + if(person_n != state.personCount){ + state.sigma = 0; + return; + } + + state.sigma = std::numeric_limits::infinity(); + } + + /** + * It outputs the already processed ProcessorState::Job via the Processor::outProcessed port. + * @param state reference to the current model state. + * @param y reference to the atomic model output port set. + */ + void output(const OccupencyControllerState& state) const override { + + bool safe = false; + + if(state.personCount < MAX_OCCUPANCY){ + safe = true; + } + + personSafe->addMessage(safe); + } + + /** + * It returns the value of ProcessorState::sigma. + * @param state reference to the current model state. + * @return the sigma value. + */ + [[nodiscard]] double timeAdvance(const OccupencyControllerState& state) const override { + return state.sigma; + } + }; +} //namespace cadmium::example::covidSupervisorySystem + +#endif //_OCCUPENCY_CONTROLLER_HPP__ diff --git a/example/_rtModel/occIn.txt b/example/_rtModel/occIn.txt new file mode 100644 index 0000000..7f31b4c --- /dev/null +++ b/example/_rtModel/occIn.txt @@ -0,0 +1,6 @@ +1 1 +2 1 +3 1 +10 1 +11 1 +12 1 \ No newline at end of file diff --git a/example/_rtModel/occOut.txt b/example/_rtModel/occOut.txt new file mode 100644 index 0000000..b990e3b --- /dev/null +++ b/example/_rtModel/occOut.txt @@ -0,0 +1,6 @@ +5 1 +6 1 +7 1 +15 1 +16 1 +17 1 \ No newline at end of file diff --git a/example/celldevs_benchmark/benchmark_config.json b/example/celldevs_benchmark/benchmark_config.json index abc5ab1..eb0c1cf 100644 --- a/example/celldevs_benchmark/benchmark_config.json +++ b/example/celldevs_benchmark/benchmark_config.json @@ -1,16 +1,21 @@ { "scenario": { - "shape": [50, 50], "origin": [-24, -24] + "shape": [50, 50], "origin": [0, 0] }, "cells": { "default": { "delay": "inertial", - "cell_type": "benchmark", + "model": "benchmark", "state": {"digit": 0}, "neighborhood": [ {"type": "von_neumann", "vicinity": 0.25, "range": 1}, {"type": "relative", "vicinity": 1, "neighbors": [[0, 0]]} ] } - } + }, + "viewer": [{ + "colors": [[0, 0, 0], [255, 0, 0]], + "breaks": [0, 0.5, 1], + "field": "digit" +}] } diff --git a/example/celldevs_benchmark/include/benchmark_grid_cell.hpp b/example/celldevs_benchmark/include/benchmark_grid_cell.hpp index a2a372c..03a2991 100644 --- a/example/celldevs_benchmark/include/benchmark_grid_cell.hpp +++ b/example/celldevs_benchmark/include/benchmark_grid_cell.hpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include "state.hpp" namespace cadmium::celldevs::example::benchmark { diff --git a/example/celldevs_benchmark/main_grid_benchmark.cpp b/example/celldevs_benchmark/main_grid_benchmark.cpp index eab8895..7e12856 100644 --- a/example/celldevs_benchmark/main_grid_benchmark.cpp +++ b/example/celldevs_benchmark/main_grid_benchmark.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include #include @@ -35,8 +35,7 @@ int main(int argc, char ** argv) { modelGenerated = std::chrono::high_resolution_clock::now(); auto rootCoordinator = cadmium::RootCoordinator(model); - auto logger = std::make_shared("grid_log.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("grid_benchmark_log.csv", ";"); rootCoordinator.start(); auto engineStarted = std::chrono::high_resolution_clock::now(); std::cout << "Engine creation time: " << std::chrono::duration_cast>>(engineStarted - modelGenerated).count() << " seconds" << std::endl; diff --git a/example/celldevs_sir/asymm_config.json b/example/celldevs_sir/asymm_config.json index 0bc052e..f55a160 100644 --- a/example/celldevs_sir/asymm_config.json +++ b/example/celldevs_sir/asymm_config.json @@ -2,7 +2,7 @@ "cells": { "default": { "delay": "inertial", - "cell_type": "SIR", + "model": "SIR", "state": {"p": 200, "s": 1, "i": 0, "r": 0}, "config": {"rec": 0.2, "susc": 0.8, "vir": 0.4} }, diff --git a/example/celldevs_sir/grid_config.json b/example/celldevs_sir/grid_config.json index a2ae8b2..1abbc80 100644 --- a/example/celldevs_sir/grid_config.json +++ b/example/celldevs_sir/grid_config.json @@ -5,7 +5,7 @@ "cells": { "default": { "delay": "inertial", - "cell_type": "SIR", + "model": "SIR", "state": {"p": 100, "s": 1, "i": 0, "r": 0}, "config": {"rec": 0.2, "susc": 0.8, "vir": 0.4}, "neighborhood": [ diff --git a/example/celldevs_sir/include/asymm_sir_cell.hpp b/example/celldevs_sir/include/asymm_sir_cell.hpp index a9a54b4..f3d18b2 100644 --- a/example/celldevs_sir/include/asymm_sir_cell.hpp +++ b/example/celldevs_sir/include/asymm_sir_cell.hpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include "state.hpp" namespace cadmium::celldevs::example::sir { diff --git a/example/celldevs_sir/include/grid_sir_cell.hpp b/example/celldevs_sir/include/grid_sir_cell.hpp index 9988d9a..3ecbb26 100644 --- a/example/celldevs_sir/include/grid_sir_cell.hpp +++ b/example/celldevs_sir/include/grid_sir_cell.hpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #include "state.hpp" namespace cadmium::celldevs::example::sir { diff --git a/example/celldevs_sir/main_asymm_sir.cpp b/example/celldevs_sir/main_asymm_sir.cpp index 564d94e..272ae11 100644 --- a/example/celldevs_sir/main_asymm_sir.cpp +++ b/example/celldevs_sir/main_asymm_sir.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include #include "asymm_sir_cell.hpp" @@ -25,13 +25,23 @@ int main(int argc, char ** argv) { } std::string configFilePath = argv[1]; double simTime = (argc > 2)? atof(argv[2]) : 500; + auto paramsProcessed = std::chrono::high_resolution_clock::now(); auto model = std::make_shared>("sir", addAsymmCell, configFilePath); model->buildModel(); + auto modelGenerated = std::chrono::high_resolution_clock::now(); + std::cout << "Model creation time: " << std::chrono::duration_cast>>( modelGenerated - paramsProcessed).count() << " seconds" << std::endl; + + modelGenerated = std::chrono::high_resolution_clock::now(); auto rootCoordinator = cadmium::RootCoordinator(model); - auto logger = std::make_shared("asymm_log.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("log_asymm_sir.csv", ";"); rootCoordinator.start(); - rootCoordinator.simulate(simTime); + auto engineStarted = std::chrono::high_resolution_clock::now(); + std::cout << "Engine creation time: " << std::chrono::duration_cast>>(engineStarted - modelGenerated).count() << " seconds" << std::endl; + + engineStarted = std::chrono::high_resolution_clock::now(); + rootCoordinator.simulate(simTime); + auto simulationDone = std::chrono::high_resolution_clock::now(); + std::cout << "Simulation time: " << std::chrono::duration_cast>>(simulationDone - engineStarted).count() << " seconds" << std::endl; rootCoordinator.stop(); } diff --git a/example/celldevs_sir/main_grid_sir.cpp b/example/celldevs_sir/main_grid_sir.cpp index 747269c..faa0538 100644 --- a/example/celldevs_sir/main_grid_sir.cpp +++ b/example/celldevs_sir/main_grid_sir.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include #include @@ -35,8 +35,7 @@ int main(int argc, char ** argv) { modelGenerated = std::chrono::high_resolution_clock::now(); auto rootCoordinator = cadmium::RootCoordinator(model); - auto logger = std::make_shared("grid_log.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("log_grid_sir.csv", ";"); rootCoordinator.start(); auto engineStarted = std::chrono::high_resolution_clock::now(); std::cout << "Engine creation time: " << std::chrono::duration_cast>>(engineStarted - modelGenerated).count() << " seconds" << std::endl; diff --git a/example/celldevs_sir/parallel_main_asymm_sir.cpp b/example/celldevs_sir/parallel_main_asymm_sir.cpp index d616eb4..22ecbd8 100644 --- a/example/celldevs_sir/parallel_main_asymm_sir.cpp +++ b/example/celldevs_sir/parallel_main_asymm_sir.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include #include "asymm_sir_cell.hpp" @@ -29,8 +29,7 @@ int main(int argc, char ** argv) { auto model = std::make_shared>("sir", addAsymmCell, configFilePath); model->buildModel(); auto rootCoordinator = cadmium::ParallelRootCoordinator(model); - auto logger = std::make_shared("asymm_log.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("log_parallel_asymm_sir.csv", ";"); rootCoordinator.start(); rootCoordinator.simulate(simTime); rootCoordinator.stop(); diff --git a/example/celldevs_sir/parallel_main_grid_sir.cpp b/example/celldevs_sir/parallel_main_grid_sir.cpp index 6571343..dfdd34b 100644 --- a/example/celldevs_sir/parallel_main_grid_sir.cpp +++ b/example/celldevs_sir/parallel_main_grid_sir.cpp @@ -1,6 +1,6 @@ -#include -#include -#include +#include +#include +#include #include #include #include @@ -35,8 +35,7 @@ int main(int argc, char ** argv) { modelGenerated = std::chrono::high_resolution_clock::now(); auto rootCoordinator = cadmium::ParallelRootCoordinator(model); - auto logger = std::make_shared("grid_log.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("grid_log.csv", ";"); rootCoordinator.start(); auto engineStarted = std::chrono::high_resolution_clock::now(); std::cout << "Engine creation time: " << std::chrono::duration_cast>>(engineStarted - modelGenerated).count() << " seconds" << std::endl; diff --git a/example/devstone/include/devstone.hpp b/example/devstone/include/devstone.hpp index d146012..5381c9b 100644 --- a/example/devstone/include/devstone.hpp +++ b/example/devstone/include/devstone.hpp @@ -1,8 +1,8 @@ #ifndef CADMIUM_EXAMPLE_DEVSTONE_HPP_ #define CADMIUM_EXAMPLE_DEVSTONE_HPP_ -#include -#include +#include +#include #include #include "devstone_coupled.hpp" diff --git a/example/devstone/include/devstone_atomic.hpp b/example/devstone/include/devstone_atomic.hpp index 1bea326..0e58970 100644 --- a/example/devstone/include/devstone_atomic.hpp +++ b/example/devstone/include/devstone_atomic.hpp @@ -1,7 +1,7 @@ #ifndef CADMIUM_EXAMPLE_DEVSTONE_ATOMIC_HPP_ #define CADMIUM_EXAMPLE_DEVSTONE_ATOMIC_HPP_ -#include +#include #include namespace cadmium::example::devstone { diff --git a/example/devstone/include/devstone_coupled.hpp b/example/devstone/include/devstone_coupled.hpp index 10f64f7..531a6de 100644 --- a/example/devstone/include/devstone_coupled.hpp +++ b/example/devstone/include/devstone_coupled.hpp @@ -1,8 +1,8 @@ #ifndef CADMIUM_EXAMPLE_DEVSTONE_COUPLED_HPP_ #define CADMIUM_EXAMPLE_DEVSTONE_COUPLED_HPP_ -#include -#include +#include +#include #include namespace cadmium::example::devstone { diff --git a/example/devstone/include/devstone_generator.hpp b/example/devstone/include/devstone_generator.hpp index f8ef5f5..e622eed 100644 --- a/example/devstone/include/devstone_generator.hpp +++ b/example/devstone/include/devstone_generator.hpp @@ -1,7 +1,7 @@ #ifndef CADMIUM_EXAMPLE_DEVSTONE_GENERATOR_HPP_ #define CADMIUM_EXAMPLE_DEVSTONE_GENERATOR_HPP_ -#include +#include #include namespace cadmium::example::devstone { diff --git a/example/devstone/parallel_main_devstone.cpp b/example/devstone/parallel_main_devstone.cpp index 3d5c744..45583f3 100644 --- a/example/devstone/parallel_main_devstone.cpp +++ b/example/devstone/parallel_main_devstone.cpp @@ -2,7 +2,7 @@ #include #include #include "include/devstone_coupled.hpp" -#include +#include using namespace cadmium::example::devstone; diff --git a/example/efp_gpt/include/ef.hpp b/example/efp_gpt/include/ef.hpp index e464f2a..1b38653 100644 --- a/example/efp_gpt/include/ef.hpp +++ b/example/efp_gpt/include/ef.hpp @@ -1,7 +1,7 @@ #ifndef CADMIUM_EXAMPLE_GPT_EF_HPP_ #define CADMIUM_EXAMPLE_GPT_EF_HPP_ -#include +#include #include "generator.hpp" #include "transducer.hpp" diff --git a/example/efp_gpt/include/efp.hpp b/example/efp_gpt/include/efp.hpp index 9cefef0..bc07a3f 100644 --- a/example/efp_gpt/include/efp.hpp +++ b/example/efp_gpt/include/efp.hpp @@ -1,7 +1,7 @@ #ifndef CADMIUM_EXAMPLE_EFP_EFP_HPP_ #define CADMIUM_EXAMPLE_EFP_EFP_HPP_ -#include +#include #include "ef.hpp" #include "processor.hpp" diff --git a/example/efp_gpt/include/generator.hpp b/example/efp_gpt/include/generator.hpp index d94876a..5aba858 100644 --- a/example/efp_gpt/include/generator.hpp +++ b/example/efp_gpt/include/generator.hpp @@ -1,7 +1,7 @@ #ifndef CADMIUM_EXAMPLE_GPT_GENERATOR_HPP_ #define CADMIUM_EXAMPLE_GPT_GENERATOR_HPP_ -#include +#include #include #include "job.hpp" diff --git a/example/efp_gpt/include/gpt.hpp b/example/efp_gpt/include/gpt.hpp index bafc128..62bb5bf 100644 --- a/example/efp_gpt/include/gpt.hpp +++ b/example/efp_gpt/include/gpt.hpp @@ -1,7 +1,7 @@ #ifndef CADMIUM_EXAMPLE_EFP_GPT_HPP_ #define CADMIUM_EXAMPLE_EFP_GPT_HPP_ -#include +#include #include "generator.hpp" #include "processor.hpp" #include "transducer.hpp" diff --git a/example/efp_gpt/include/processor.hpp b/example/efp_gpt/include/processor.hpp index b643801..ffb438e 100644 --- a/example/efp_gpt/include/processor.hpp +++ b/example/efp_gpt/include/processor.hpp @@ -1,7 +1,7 @@ #ifndef CADMIUM_EXAMPLE_GPT_PROCESSOR_HPP_ #define CADMIUM_EXAMPLE_GPT_PROCESSOR_HPP_ -#include +#include #include #include #include "job.hpp" diff --git a/example/efp_gpt/include/transducer.hpp b/example/efp_gpt/include/transducer.hpp index b997962..33fc14b 100644 --- a/example/efp_gpt/include/transducer.hpp +++ b/example/efp_gpt/include/transducer.hpp @@ -1,7 +1,7 @@ #ifndef CADMIUM_EXAMPLE_GPT_TRANSDUCER_HPP_ #define CADMIUM_EXAMPLE_GPT_TRANSDUCER_HPP_ -#include +#include #include #include "job.hpp" diff --git a/example/efp_gpt/main_efp.cpp b/example/efp_gpt/main_efp.cpp index 3c0dc59..de95283 100644 --- a/example/efp_gpt/main_efp.cpp +++ b/example/efp_gpt/main_efp.cpp @@ -1,8 +1,9 @@ -#include -#include +#include +#include #include #include #include +#include #include "efp.hpp" using namespace cadmium::example::gpt; @@ -17,7 +18,7 @@ int main(int argc, char *argv[]) { return -1; } int jobPeriod = std::stoi(argv[1]); - if (jobPeriod < 0) { + if (jobPeriod <= 0) { std::cerr << "ERROR: JOB_GENERATION_PERIOD is less than 0 (" << jobPeriod << ")" << std::endl; return -1; } @@ -52,8 +53,7 @@ int main(int argc, char *argv[]) { // Next, we create the coordinator and the logger auto rootCoordinator = cadmium::RootCoordinator(model); - auto logger = std::make_shared("log_efp.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("log_efp.csv", ";"); // And finally, we run the simulation rootCoordinator.start(); diff --git a/example/efp_gpt/main_gpt.cpp b/example/efp_gpt/main_gpt.cpp index 8d85563..fb779ba 100644 --- a/example/efp_gpt/main_gpt.cpp +++ b/example/efp_gpt/main_gpt.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include "gpt.hpp" @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { return -1; } int jobPeriod = std::stoi(argv[1]); - if (jobPeriod < 0) { + if (jobPeriod <= 0) { std::cerr << "ERROR: JOB_GENERATION_PERIOD is less than 0 (" << jobPeriod << ")" << std::endl; return -1; } @@ -33,8 +33,7 @@ int main(int argc, char *argv[]) { // Then, we create the model and start the simulation auto model = std::make_shared("gpt", jobPeriod, processingTime, obsTime); auto rootCoordinator = cadmium::RootCoordinator(model); - auto logger = std::make_shared("log_gpt.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("log_gpt.csv", ";"); rootCoordinator.start(); rootCoordinator.simulate(std::numeric_limits::infinity()); rootCoordinator.stop(); diff --git a/example/efp_gpt/main_rt_gpt.cpp b/example/efp_gpt/main_rt_gpt.cpp new file mode 100644 index 0000000..db02f04 --- /dev/null +++ b/example/efp_gpt/main_rt_gpt.cpp @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include "gpt.hpp" + +using namespace cadmium::example::gpt; + +int main(int argc, char *argv[]) { + // First, we parse the arguments + if (argc < 4) { + std::cerr << "ERROR: not enough arguments" << std::endl; + std::cerr << " Usage:" << std::endl; + std::cerr << " > main_gpt GENERATION_PERIOD PROCESSING_TIME OBSERVATION_TIME" << std::endl; + std::cerr << " (GENERATION_PERIOD, PROCESSING_TIME, and OBSERVATION_TIME must be greater than or equal to 0)" << std::endl; + return -1; + } + int jobPeriod = std::stoi(argv[1]); + if (jobPeriod < 0) { + std::cerr << "ERROR: JOB_GENERATION_PERIOD is less than 0 (" << jobPeriod << ")" << std::endl; + return -1; + } + int processingTime = std::stoi(argv[2]); + if (processingTime < 0) { + std::cerr << "ERROR: JOB_PROCESSING_TIME is less than 0 (" << processingTime << ")" << std::endl; + return -1; + } + double obsTime = std::stod(argv[3]); + if (obsTime < 0) { + std::cerr << "ERROR: OBSERVATION_TIME is less than 0 (" << obsTime << ")" << std::endl; + return -1; + } + + // Then, we create the model and start the simulation + auto model = std::make_shared("gpt", jobPeriod, processingTime, obsTime); + + // Let's create the RT clock. In this case, we will use a chrono clock with a maximum jitter of 10 milliseconds + // note that the max jitter is optional. If left blank, it won't check the delay jitter. + auto maxJitter = std::chrono::duration_cast(std::chrono::milliseconds(10)); + auto clock = cadmium::ChronoClock(maxJitter); + + // For creating RT coordinators, we must forward the model and the desired RT clock + auto rootCoordinator = cadmium::RealTimeRootCoordinator(model, clock); + // The rest works as with the other root coordinators. + rootCoordinator.setLogger("log_rt_gpt.csv", ";"); + rootCoordinator.start(); + rootCoordinator.simulate(std::numeric_limits::infinity()); + rootCoordinator.stop(); + return 0; +} diff --git a/example/efp_gpt/parallel_main_efp.cpp b/example/efp_gpt/parallel_main_efp.cpp index 3e9d207..2aac5e6 100644 --- a/example/efp_gpt/parallel_main_efp.cpp +++ b/example/efp_gpt/parallel_main_efp.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include "efp.hpp" @@ -31,8 +31,7 @@ int main(int argc, char *argv[]) { } auto model = std::make_shared("efp", jobPeriod, processingTime, obsTime); auto rootCoordinator = cadmium::ParallelRootCoordinator(model); - auto logger = std::make_shared("log_efp.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("log_parallel_efp.csv", ";"); rootCoordinator.start(); rootCoordinator.simulate(std::numeric_limits::infinity()); rootCoordinator.stop(); diff --git a/example/efp_gpt/parallel_main_gpt.cpp b/example/efp_gpt/parallel_main_gpt.cpp index e95f450..7cce899 100644 --- a/example/efp_gpt/parallel_main_gpt.cpp +++ b/example/efp_gpt/parallel_main_gpt.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include "gpt.hpp" @@ -33,8 +33,7 @@ int main(int argc, char *argv[]) { // Then, we create the model and start the simulation auto model = std::make_shared("gpt", jobPeriod, processingTime, obsTime); auto rootCoordinator = cadmium::ParallelRootCoordinator(model); - auto logger = std::make_shared("log_gpt.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("log_parallel_gpt.csv", ";"); rootCoordinator.start(); rootCoordinator.simulate(std::numeric_limits::infinity()); rootCoordinator.stop(); diff --git a/example/iestream/include/iestream_coupled.hpp b/example/iestream/include/iestream_coupled.hpp index ed5d307..387972b 100644 --- a/example/iestream/include/iestream_coupled.hpp +++ b/example/iestream/include/iestream_coupled.hpp @@ -1,23 +1,23 @@ #ifndef CADMIUM_EXAMPLE_IESTREAM_HPP_ #define CADMIUM_EXAMPLE_IESTREAM_HPP_ -#include +#include #include #include "message_t.hpp" namespace cadmium::example::iestream { - //! Coupled DEVS model to show how the IEStream atomic model works. - struct iestream_coupled : public Coupled { + //! Coupled DEVS model to show how the IEStream atomic model works. + struct iestream_coupled : public Coupled { - /** - * Constructor function for the iestream model. - * @param id ID of the iestream model. - * @param filePath path to the input file to be read. - */ - iestream_coupled(const std::string& id, const char* filePath): Coupled(id) { - auto iestream1 = addComponent>("iestream", filePath); - } - }; + /** + * Constructor function for the iestream model. + * @param id ID of the iestream model. + * @param filePath path to the input file to be read. + */ + iestream_coupled(const std::string& id, const char* filePath) : Coupled(id) { + auto iestream1 = addComponent>("iestream", filePath); + } + }; } //namespace cadmium::example::iestream #endif //CADMIUM_EXAMPLE_IESTREAM_HPP_ diff --git a/example/iestream/include/message_t.hpp b/example/iestream/include/message_t.hpp index 31fb666..f333bf9 100644 --- a/example/iestream/include/message_t.hpp +++ b/example/iestream/include/message_t.hpp @@ -4,32 +4,40 @@ #include namespace cadmium::example::iestream { - //! Messages. Generator objects create new messages for ABP model - struct Message_t { - int packet; //!> (std::istream& is, Message_t& m) { + //! Default constructor function. + Message_t() : packet(0), bit(0) {} + }; + + /** + * Insertion operator for Message_t objects. + * @param out output stream. + * @param m message to be represented in the output stream. + * @return output stream with the value of the message_t already inserted. + */ + std::ostream& operator<<(std::ostream& out, const Message_t& m) { + out << "{" << m.packet << "," << m.bit << "}"; + return out; + } + + /** + * Extraction operator for Message_t objects + * @param is input stream. + * @param m message to be filled. + * @return input stream after consuming the fields related to the message. + */ + std::istream& operator>>(std::istream& is, Message_t& m) { is >> m.packet >> m.bit; return is; } diff --git a/example/iestream/main_iestream.cpp b/example/iestream/main_iestream.cpp index 2f2f770..4391cc1 100644 --- a/example/iestream/main_iestream.cpp +++ b/example/iestream/main_iestream.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include "iestream_coupled.hpp" @@ -26,8 +26,7 @@ int main(int argc, char *argv[]) { auto model = std::make_shared("IEStreamCoupled", filePath); auto rootCoordinator = cadmium::RootCoordinator(model); - auto logger = std::make_shared("log_iestream.csv", ";"); - rootCoordinator.setLogger(logger); + rootCoordinator.setLogger("log_iestream.csv", ";"); rootCoordinator.start(); rootCoordinator.simulate(std::numeric_limits::infinity()); rootCoordinator.stop(); diff --git a/example/rt_mbed/.mbed b/example/rt_mbed/.mbed new file mode 100644 index 0000000..dd06db4 --- /dev/null +++ b/example/rt_mbed/.mbed @@ -0,0 +1,4 @@ +ARM_PATH=/usr/local/ARM_Compiler_5.06u6/ +TARGET=kl25z +TOOLCHAIN=GCC_ARM +ROOT=. diff --git a/example/rt_mbed/.mbedignore b/example/rt_mbed/.mbedignore new file mode 100644 index 0000000..841c5db --- /dev/null +++ b/example/rt_mbed/.mbedignore @@ -0,0 +1,6 @@ +mbed-os/rtos/* +mbed-os/features/* +mbed-os/events/* +mbed-os/components/* +mbed-os/usb/* +drivers/* diff --git a/example/rt_mbed/README.md b/example/rt_mbed/README.md new file mode 100644 index 0000000..1e14a50 --- /dev/null +++ b/example/rt_mbed/README.md @@ -0,0 +1,98 @@ +# Blinky model example + +This is the _Hello World!_ example for embedded systems. + +For a detailed explanation of this example check this repo: https://github.com/epecker/jupyter-cadmiumv2.git. + +## Simulation in real-time with a general purpose operating system + +To build this model to run in real-time in a PC with Linux: + +```bash +cd top_model +make all +``` + +Then, an executable will be placed in the folder `BUILD`. To run a simulation for 10~s just type: + +```bash +./Blinky +``` + +The results are then placed in the file `blinkyLog.csv`. + +You can clean the executable and other generated files (object ang log files) with: + +```bash +make clean +``` + +## Execution in real-time in an embedded board running Mbed-OS v5 + +### Install the toolchain + +To build an application with Mbed-OS we will use the **C**ommand **L**ine **I**nterface version 1 (Mbed CLI 1). This is a Python-based building tool. + +Mbed CLI1 can make use of different building toolchains, but we are going to use the **GNU ARM Embedded toolchains** (named `GCC_ARM` compiler in CLI). + +In what follows I'll assume we are using `gcc-arm-none-eabi-10.3-2021.10` for Linux (tested with Ubuntu 18.04 and 20.04). To download it, go to this [link](https://developer.arm.com/downloads/-/gnu-rm) and download the corresponding version for your OS. For Ubuntu: +```bash +$ wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2?rev=78196d3461ba4c9089a67b5f33edf82a&hash=D484B37FF37D6FC3597EBE2877FB666A41D5253B +``` + +Then, extract GCC ARM: +```bash +$ tar jxf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 +``` + +And finally move the GCC ARM Compiler to the `/opt/` folder (requires root privileges): +```bash +$ sudo mv gcc-arm-none-eabi-10.3-2021.10 /opt/ +``` + +### Installation and setup of Mbed CLI 1 + +A step-by-step guide to install the Mbed CLI 1 tool can be found [here](https://os.mbed.com/docs/mbed-os/v6.15/build-tools/install-and-set-up.html). Make sure that all the dependencies are satisfied, otherwise run the following: + +```bash +$ sudo apt install python3 python3-pip git +``` + +Then, to install the mbed-cli run: + +```bash +$ python3 -m pip install mbed-cli +``` + +Finally, to configure Mbed CLI 1 we use the command `mbed config` to make Mbed-OS know where to find the GCC ARM Compiler that we downloaded before. Given that we are using the GCC ARM Embedded Compiler, we have to set the `GCC_ARM_PATH`: +```bash +mbed config -G GCC_ARM_PATH /opt/gcc-arm-none-eabi-10.3-2021.10/bin +``` +where the `-G` means that this setting is global, i.e. it applies to all the applications compiled with Mbed CLI 1. + +### Donwload Mbed-OS v5 + +This model was tested with **Mbed-OS v5.13**. To download this version run: + +```bash +mbed deploy +``` + +This command makes use of the link in the file `mbed-os.lib`. + +## Build and run the simulation + +To build this model with Mbed CLI1 to run in a embedded platform and flash the executable just type: +```bash +make embedded +``` +Make sure that you have already plugged the board to the USB port, otherwise an error will came up. Once flashed, a serial terminal will start where the events and output values are printed. To close this terminal just type CTRL+C. + +In case you want to modify the compilation flags for the C/C++ compiler (arm-none-eabi-gcc / arm-none-eabi-g++) and/or set the path for additional libraries, edit the profile `cadmium_logging_off.json` in the parent folder. + +Finally, in order to clean the executable and other generated files just type: +```bash +make clean-embedded +``` + + diff --git a/example/rt_mbed/cadmium.json b/example/rt_mbed/cadmium.json new file mode 100644 index 0000000..573b241 --- /dev/null +++ b/example/rt_mbed/cadmium.json @@ -0,0 +1,18 @@ +{ + "GCC_ARM": { + "common": ["-c", "-Wno-all", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-Os", "-g1", "-DMBED_TRAP_ERRORS_ENABLED=1", + "-Wno-register", "-DBOOST_NO_PLATFORM_CONFIG", "-DRT_ARM_MBED", "-fexceptions","-DNO_LOGGING"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++17", "-Wvla", "-I", "../../../include", "-I", "../../boost_1_70_0", "-I", "../mbed-os", "-I", "../data_structures"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,-n"] + } +} diff --git a/example/rt_mbed/cadmium_logging_off.json b/example/rt_mbed/cadmium_logging_off.json new file mode 100644 index 0000000..57f49d7 --- /dev/null +++ b/example/rt_mbed/cadmium_logging_off.json @@ -0,0 +1,18 @@ +{ + "GCC_ARM": { + "common": ["-c", "-Wno-all", "-Wextra", "-Wall", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-Os", "-g1", "-DMBED_TRAP_ERRORS_ENABLED=1", + "-Wno-register", "-DBOOST_NO_PLATFORM_CONFIG", "-DRT_ARM_MBED", "-fexceptions","-DNO_LOGGING"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++17", "-Wvla", "-I", "../../../include", "-I", "../../boost_1_70_0", "-I", "../mbed-os", "-I", "../data_structures"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,-n"] + } +} diff --git a/example/rt_mbed/install.sh b/example/rt_mbed/install.sh new file mode 100644 index 0000000..2a3c101 --- /dev/null +++ b/example/rt_mbed/install.sh @@ -0,0 +1,98 @@ +#-------------------------- INSTALL RT_ARM_MBED DEPENDENCIES ---------------------------- + +GCC_FOLDER_NAME=gcc-arm-none-eabi-8-2018-q4-major +CADMIUM_DEPENDENCIES=0 + +PARENT_DIR="$(dirname "$PWD")" + + +# -> Options + +echo "Dependencies will install here: "$PARENT_DIR"/" + +echo "Do you wish to install Cadmium Dependencies as well? (Git and GCC 7 for Cadmium Desktop)" +select yn in "Yes" "No"; do + case $yn in + Yes ) echo "Cadmium Dependencies will be installed first."; CADMIUM_DEPENDENCIES=1; break;; + No ) echo "Cadmium Dependencies will not be installed."; break;; + esac +done + +echo "Continue with Install?" +select yn in "Yes" "No"; do + case $yn in + Yes ) break;; + No ) exit;; + esac +done + +# -> Begin Install + +#super user do to prompt for password so user can go get a coffee and not watch the install.. +sudo echo "### Install Dependencies ###" + +if [ $CADMIUM_DEPENDENCIES -eq 1 ] +then + + echo "--> Git" + sudo apt-get -y install git + + echo "-->GCC for Cadmium Desktop" + sudo apt-get -y install libboost-all-dev + sudo add-apt-repository -y ppa:jonathonf/gcc-7.1 + sudo apt-get update + sudo apt-get -y install gcc-7 g++-7 + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 --slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-7 --slave /usr bin/gcc-nm gcc-nm /usr/bin/gcc-nm-7 --slave /usr/bin/gcc-ranlib gcc-ranlib usr/bin/gcc-ranlib-7 + sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-7 60 --slave /usr/bin/g++-ar g++-ar /usr/bin/g++-ar-7 --slave /usr/bin/g++-nm g++-nm /usr/bin/g++-nm-7 --slave /usr/bin/g++-ranlib g++-ranlib usr/bin/g++-ranlib-7 g++ -v + +fi + +echo "--> Update Submodules" +git submodule update --init + + +echo "-->Python and PIP" +sudo apt-get -y install python2.7 python-pip + +echo "### Install python-tk for SVEC ###" +sudo apt-get install python-tk + +echo "### Download GCC ARM Compiler ###" +wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2?revision=d830f9dd-cd4f-406d-8672-cca9210dd220?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,8-2018-q4-major -O gcc-arm-none-eabi-8-2018-q4-major.tar.bz2 + +echo "### Extract GCC ARM Tarball ###" +tar jxf $GCC_FOLDER_NAME.tar.bz2 + +echo "### Install GCC ARM Compiler in /opt/gcc-arm-none-eabi-8-2018-q4-major ###" +sudo mv ./$GCC_FOLDER_NAME /opt/ + +echo "### Cleaning Up GCC ARM Download ###" +sudo rm $GCC_FOLDER_NAME.tar.bz2 +sudo rm -rf gcc-arm-none-eabi-8-2018-q4-major/ + +echo "### Install MBED-CLI ###" +sudo pip install mbed-cli + +echo "### Set MBED Compiler Path ###" +mbed config -G GCC_ARM_PATH /opt/$GCC_FOLDER_NAME/bin + +echo "### Install Mbed-CLI dependencies ###" +sudo pip install -r mbed-os/requirements.txt + +echo "### Install miniterm.py ###" +sudo pip install pyserial + +echo "### Download Boost 1.70.0 ###" +wget https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.bz2 -O boost_1_70_0.tar.bz2 + +echo "### Extract Boost ###" +tar jxf boost_1_70_0.tar.bz2 +mv boost_1_70_0 ../ + +echo "### Cleanup Boost Download ###" +sudo rm boost_1_70_0.tar.bz2 + +cd ../ #Move up a directory to clone git repositories + +echo "### Clone Cadmium (Forked Version for Alpha RT_ARM_MBED Release) ###" +git clone --recursive https://github.com/KyleBjornson/cadmium.git diff --git a/example/rt_mbed/mbed-os.lib b/example/rt_mbed/mbed-os.lib new file mode 100644 index 0000000..e46d47a --- /dev/null +++ b/example/rt_mbed/mbed-os.lib @@ -0,0 +1 @@ +https://github.com/ARMmbed/mbed-os/#1bf6b20df9d3cd5f29f001ffc6f0d0fcbbb96118 diff --git a/example/rt_mbed/mbed_app.json b/example/rt_mbed/mbed_app.json new file mode 100644 index 0000000..1d8213a --- /dev/null +++ b/example/rt_mbed/mbed_app.json @@ -0,0 +1,15 @@ +{ + "macros": [ + "NDEBUG=1" + ], + "target_overrides": { + "*": { + "target.printf_lib": "minimal-printf", + "platform.memory-tracing-enabled": "true", + "platform.stdio-baud-rate": 9600 + }, + "K64F": { + "platform.stdio-baud-rate": 9600 + } + } +} diff --git a/example/rt_mbed/mbed_settings.py b/example/rt_mbed/mbed_settings.py new file mode 100644 index 0000000..b10ad73 --- /dev/null +++ b/example/rt_mbed/mbed_settings.py @@ -0,0 +1,45 @@ +""" +mbed SDK +Copyright (c) 2016 ARM Limited + +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. +""" + +from os.path import join, abspath, dirname + +#ROOT = abspath(join(dirname(__file__), ".")) + +############################################################################## +# Build System Settings +############################################################################## +#BUILD_DIR = abspath(join(ROOT, "build")) + +# ARM +#ARM_PATH = "/usr/bin/" + +# GCC ARM +#GCC_ARM_PATH = "" + +# IAR +#IAR_PATH = "C:/Program Files (x86)/IAR Systems/Embedded Workbench 7.0/arm" + +# Goanna static analyser. Please overload it in private_settings.py +#GOANNA_PATH = "c:/Program Files (x86)/RedLizards/Goanna Central 3.2.3/bin" + +#BUILD_OPTIONS = [] + +# mbed.org username +#MBED_ORG_USER = "" + +# Print compiler warnings and errors as link format +#PRINT_COMPILER_OUTPUT_AS_LINK = False diff --git a/example/rt_mbed/top_model/README.md b/example/rt_mbed/top_model/README.md new file mode 100644 index 0000000..1838412 --- /dev/null +++ b/example/rt_mbed/top_model/README.md @@ -0,0 +1,9 @@ +To run the model in Linux in real time use: +```bash +make all +``` + +To run the model embedded in real time use. +```bash +make +``` diff --git a/example/rt_mbed/top_model/include/analogInput.hpp b/example/rt_mbed/top_model/include/analogInput.hpp new file mode 100644 index 0000000..d785cb8 --- /dev/null +++ b/example/rt_mbed/top_model/include/analogInput.hpp @@ -0,0 +1,103 @@ +/** +* Jon Menard +* ARSLab - Carleton University +* +* Analog Input: +* Model to interface with a Analog Input pin for Embedded Cadmium. +*/ + +#ifndef RT_ANALOGINPUT_HPP +#define RT_ANALOGINPUT_HPP + +#include +#include +#include "cadmium/modeling/devs/atomic.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../mbed.h" + +using namespace std; + +namespace cadmium { + + struct AnalogInputState { + double output; + double last; + double sigma; + + /** + * AnalogInputState constructor. + * + */ + explicit AnalogInputState(): output(0), last(0), sigma(0){ + } + + }; + + /** + * Insertion operator for AnalogIputState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + + std::ostream& operator<<(std::ostream &out, const AnalogInputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; + } + + class AnalogInput : public Atomic { + public: + + Port out; + //Parameters to be overwriten when instantiating the atomic model + AnalogIn* analogPin; + double pollingRate; + // default constructor + AnalogInput(const std::string& id, PinName pin): Atomic(id, AnalogInputState()) { + out = addOutPort("out"); + analogPin = new AnalogIn(pin); + pollingRate = 0.01; + state.output = (double) analogPin->read(); + state.last = state.output; + }; + + // internal transition + void internalTransition(AnalogInputState& state) const override { + state.last = state.output; + state.output = (double) analogPin->read(); + state.sigma = pollingRate; + } + + // external transition + void externalTransition(AnalogInputState& state, double e) const override { + // MBED_ASSERT(false); + // throw std::logic_error("External transition called in a model with no input ports"); + } + + // output function + void output(const AnalogInputState& state) const override { + if(state.last != state.output) { + out->addMessage(state.output); + } + } + + // time_advance function + [[nodiscard]] double timeAdvance(const AnalogInputState& state) const override { + return state.sigma; + } + }; +} + +#endif // RT_ANALOGINPUT_HPP diff --git a/example/rt_mbed/top_model/include/analogOutput.hpp b/example/rt_mbed/top_model/include/analogOutput.hpp new file mode 100644 index 0000000..41ea474 --- /dev/null +++ b/example/rt_mbed/top_model/include/analogOutput.hpp @@ -0,0 +1,99 @@ +/** +* Jon Menard +* ARSLab - Carleton University +* +* Analog Input: +* Model to interface with a Analog Output pin for Embedded Cadmium. +*/ + +#ifndef RT_ANALOGOUTPUT_HPP +#define RT_ANALOGOUTPUT_HPP + +#include +#include +#include "cadmium/modeling/devs/atomic.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../mbed.h" + +using namespace std; + +namespace cadmium { + + struct AnalogOutputState { + double output; + double sigma; + + /** + * AnalogOutputState constructor. + * + */ + explicit AnalogOutputState(): output(0), sigma(0){ + } + + }; + + /** + * Insertion operator for AnalogOutputState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + std::ostream& operator<<(std::ostream &out, const AnalogOutputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; + } + + class AnalogOutput : public Atomic { + public: + + Port in; + //Parameters to be overwriten when instantiating the atomic model + AnalogOut* analogPin; + + // default constructor + AnalogOutput(const std::string& id, PinName pin): Atomic(id, AnalogOutputState()) { + in = addInPort("in"); + analogPin = new mbed::AnalogOut(pin); + }; + + // internal transition + void internalTransition(AnalogOutputState& state) const override { + } + + // external transition + void externalTransition(AnalogOutputState& state, double e) const override { + if(!in->empty()){ + for( const auto x : in->getBag()){ + state.output = x; + } + + analogPin->write(state.output); + } + } + + + // output function + void output(const AnalogOutputState& state) const override { + }; + + // time_advance function + [[nodiscard]] double timeAdvance(const AnalogOutputState& state) const override { + return std::numeric_limits::infinity(); + } + + }; +} + +#endif // RT_ANALOGOUTPUT_HPP diff --git a/example/rt_mbed/top_model/include/blinky.hpp b/example/rt_mbed/top_model/include/blinky.hpp new file mode 100644 index 0000000..c62000c --- /dev/null +++ b/example/rt_mbed/top_model/include/blinky.hpp @@ -0,0 +1,101 @@ +#ifndef _BLINKY_HPP__ +#define _BLINKY_HPP__ + +#include +#ifndef NO_LOGGING + #include +#endif + +namespace cadmium::blinkySystem { + //! Class for representing the Blinky DEVS model state.struct BlinkyState { + struct BlinkyState { + double sigma; + bool lightOn; + bool fastToggle; + //! Blinky state constructor. + BlinkyState(): sigma(0), lightOn(false), fastToggle(false) {} + }; +// #ifndef NO_LOGGING + /** + * Insertion operator for BlinkyState objects. It displays the value of sigma and lightOn. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma and lightOn already inserted. + */ + std::ostream& operator<<(std::ostream &out, const BlinkyState& state) { + out << "Status:, " << state.lightOn << ", sigma: " << state.sigma; + return out; + } +// #endif + //! Atomic DEVS model of Blinky. + class Blinky : public Atomic { + private: + + public: + Port out; + Port in; + double slowToggleTime; + double fastToggleTime; + + /** + * Constructor function. + * @param id ID of the new Blinky model object. + */ + Blinky(const std::string& id): Atomic(id, BlinkyState()) { + out = addOutPort("out"); + in = addInPort("in"); + slowToggleTime = 3.0; + fastToggleTime = 0.75; + state.sigma = fastToggleTime; + } + + /** + * It updates the BlinkyState::lightOn. + * @param state reference to the current state of the model. + */ + void internalTransition(BlinkyState& state) const override { + state.lightOn = !state.lightOn; + } + + /** + * Updates BlinkyState::fastToggle and BlinkyState::sigma. + * @param state reference to the current model state. + * @param e time elapsed since the last state transition function was triggered. + * @param x reference to the model input port set. + */ + void externalTransition(BlinkyState& state, double e) const override { + + if(!in->empty()){ + for( const auto x : in->getBag()){ + if (x==0) + state.fastToggle = !state.fastToggle; + } + + if(state.fastToggle) + state.sigma = fastToggleTime; + else + state.sigma = slowToggleTime; + } + } + + /** + * It outputs the already processed BlinkyState::lightOn via the out port. + * @param state reference to the current model state. + * @param y reference to the atomic model output port set. + */ + void output(const BlinkyState& state) const override { + out->addMessage(state.lightOn); + } + + /** + * It returns the value of BlinkyState::sigma. + * @param state reference to the current model state. + * @return the sigma value. + */ + [[nodiscard]] double timeAdvance(const BlinkyState& state) const override { + return state.sigma; + } + }; +} //namespace cadmium::blinkySystem + +#endif //_BLINKY_HPP__ diff --git a/example/rt_mbed/top_model/include/blinkySystem.hpp b/example/rt_mbed/top_model/include/blinkySystem.hpp new file mode 100644 index 0000000..0d801b1 --- /dev/null +++ b/example/rt_mbed/top_model/include/blinkySystem.hpp @@ -0,0 +1,43 @@ +#ifndef CADMIUM_EXAMPLE_BLINKY_HPP_ +#define CADMIUM_EXAMPLE_BLINKY_HPP_ + +#include + +#ifdef RT_ARM_MBED + #include + #include "../mbed.h" + #include "PinNames.h" +#else + #include "generator.hpp" +#endif + +#include "blinky.hpp" +#include "digitalInputExt.hpp" + +namespace cadmium::blinkySystem { + + struct blinkySystem : public Coupled { + + /** + * Constructor function for the blinkySystem model. + * @param id ID of the blinkySystem model. + */ + blinkySystem(const std::string& id) : Coupled(id) { + auto blinky = addComponent("blinky"); +#ifdef RT_ARM_MBED + // NUCLEO F401RE + auto digitalOutput = addComponent("digitalOuput", LED1); + auto digitalInput = addComponent("digitalInput", PC_13); + addCoupling(digitalInput->out, blinky->in); + addCoupling(blinky->out, digitalOutput->in); +#else + auto generator = addComponent("generator"); + auto digitalInput = addComponent("digitalInput"); + addCoupling(generator->out, digitalInput->in); + addCoupling(digitalInput->out, blinky->in); +#endif + } + }; +} //namespace cadmium::blinkySystem + +#endif //CADMIUM_EXAMPLE_BLINKY_HPP_ diff --git a/example/rt_mbed/top_model/include/digitalInput.hpp b/example/rt_mbed/top_model/include/digitalInput.hpp new file mode 100644 index 0000000..a38b68c --- /dev/null +++ b/example/rt_mbed/top_model/include/digitalInput.hpp @@ -0,0 +1,103 @@ +/** +* Jon Menard +* ARSLab - Carleton University +* +* Digital Input: +* Model to interface with a digital Input pin for Embedded Cadmium. +*/ + +#ifndef RT_DIGITALINPUT_TEST_HPP +#define RT_DIGITALINPUT_TEST_HPP + +#include +#include +#include "cadmium/modeling/devs/atomic.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../mbed.h" + +using namespace std; + +namespace cadmium { + + struct DigitalInputState { + bool output; + bool last; + double sigma; + + /** + * DigitalInputState constructor. + * + */ + explicit DigitalInputState(): output(true), last(false), sigma(0){} + }; + + /** + * Insertion operator for DigitalInputState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + + std::ostream& operator<<(std::ostream &out, const DigitalInputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; + } + + class DigitalInput : public Atomic { + public: + + Port out; + //Parameters to be overwriten when instantiating the atomic model + DigitalIn* digiPin; + double pollingRate; + // default constructor + DigitalInput(const std::string& id, PinName pin): Atomic(id, DigitalInputState()) { + out = addOutPort("out"); + digiPin = new DigitalIn(pin); + pollingRate = 0.10; + state.output = digiPin->read(); + state.last = state.output; + }; + + // internal transition + void internalTransition(DigitalInputState& state) const override { + state.last = state.output; + state.output = digiPin->read() == 1; + state.sigma = pollingRate; + } + + // external transition + void externalTransition(DigitalInputState& state, double e) const override { + // MBED_ASSERT(false); + // throw std::logic_error("External transition called in a model with no input ports"); + } + + // output function + void output(const DigitalInputState& state) const override { + if(state.last != state.output) { + bool output = state.output; + out->addMessage(output); + } + } + + // time_advance function + [[nodiscard]] double timeAdvance(const DigitalInputState& state) const override { + return state.sigma; + } + + }; +} + +#endif // BOOST_SIMULATION_PDEVS_DIGITALINPUT_HPP diff --git a/example/rt_mbed/top_model/include/digitalInputExt.hpp b/example/rt_mbed/top_model/include/digitalInputExt.hpp new file mode 100644 index 0000000..f90aa2c --- /dev/null +++ b/example/rt_mbed/top_model/include/digitalInputExt.hpp @@ -0,0 +1,141 @@ +/** +* Ezequiel Pecker-Marcosig +* SEDLab - Universidad de Buenos Aires +* +* Jon Menard +* ARSLab - Carleton University +* +* Digital Input: +* Model to interface with a digital Input pin for Embedded Cadmium. +*/ + +#ifndef RT_DIGITALINPUTEXT_TEST_HPP +#define RT_DIGITALINPUTEXT_TEST_HPP + +#include +#include + +#include +#include +#include +#include +#ifndef NO_LOGGING + #include + #include + #include +#endif +#include +#include +#include +#include + +#ifdef RT_ARM_MBED + #include "../mbed.h" +#endif + +using namespace std; + +namespace cadmium { + + struct DigitalInputExtState { + bool output; + bool last; + double sigma; + + /** + * DigitalInputExtState constructor. + * + */ + explicit DigitalInputExtState(): output(true), last(false), sigma(0){} + }; +// #ifndef NO_LOGGING + /** + * Insertion operator for DigitalInputExtState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + std::ostream& operator<<(std::ostream &out, const DigitalInputExtState& state) { + out << "Input: " << (state.output ? 1 : 0); + return out; + } +// #endif + + class DigitalInputExt : public Atomic { + public: + + Port out; +#ifndef RT_ARM_MBED + Port in; + //Parameters to be overwriten when instantiating the atomic model +#else + DigitalIn* digiPin; + double pollingRate; +#endif + +#ifndef RT_ARM_MBED + // default constructor + DigitalInputExt(const std::string& id): Atomic(id, DigitalInputExtState()) { + out = addOutPort("out"); + in = addInPort("in"); + state.output = 0; + state.last = state.output; + }; +#else + // default constructor + DigitalInputExt(const std::string& id, PinName pin): Atomic(id, DigitalInputExtState()) { + out = addOutPort("out"); + digiPin = new DigitalIn(pin); + pollingRate = 0.10; + state.output = digiPin->read(); + state.last = state.output; + }; +#endif + + // internal transition + void internalTransition(DigitalInputExtState& state) const override { + +#ifdef RT_ARM_MBED + state.last = state.output; + state.output = digiPin->read() == 1; // 0: button pressed, 1: button released + state.sigma = pollingRate; +#else + state.sigma = std::numeric_limits::infinity(); +#endif + } + + // external transition + void externalTransition(DigitalInputExtState& state, double e) const override { +#ifndef RT_ARM_MBED + if(!in->empty()){ + for( const auto x : in->getBag()){ + if (x==0) + state.output = x; // x == 0 -> button pressed + } + } + state.sigma = 0; // automatically generates an internal transition +#endif + } + + // output function + void output(const DigitalInputExtState& state) const override { +#ifdef RT_ARM_MBED + if(state.last != state.output) { + bool output = state.output; + out->addMessage(output); + } +#else + bool output = state.output; + out->addMessage(output); +#endif + } + + // time_advance function + [[nodiscard]] double timeAdvance(const DigitalInputExtState& state) const override { + return state.sigma; + } + + }; +} + +#endif // RT_DIGITALINPUTEXT_TEST_HPP diff --git a/example/rt_mbed/top_model/include/digitalOutput.hpp b/example/rt_mbed/top_model/include/digitalOutput.hpp new file mode 100644 index 0000000..82f8309 --- /dev/null +++ b/example/rt_mbed/top_model/include/digitalOutput.hpp @@ -0,0 +1,102 @@ +/** +* Jon Menard +* ARSLab - Carleton University +* +* Digital Output: +* Model to interface with a digital Output pin for Embedded Cadmium. +*/ + +#ifndef RT_DIGITALOUTPUT_TEST_HPP +#define RT_DIGITALOUTPUT_TEST_HPP + +#include +#include "cadmium/modeling/devs/atomic.hpp" + +#include +#include +#include +#include +#ifndef NO_LOGGING + #include + #include + #include +#endif +#include +#include +#include +#include + +#ifdef RT_ARM_MBED + #include "../mbed.h" +#endif + +using namespace std; + +namespace cadmium { + + struct DigitalOutputState { + bool output; + double sigma; + + /** + * DigitalOutput state constructor. + * + */ + explicit DigitalOutputState(): output(true), sigma(0){ + } + + }; +// #ifndef NO_LOGGING + /** + * Insertion operator for DigitalOutputState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + std::ostream& operator<<(std::ostream &out, const DigitalOutputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; + } +// #endif + class DigitalOutput : public Atomic { + public: + + Port in; + //Parameters to be overwriten when instantiating the atomic model + DigitalOut* digiPin; + + // default constructor + DigitalOutput(const std::string& id, PinName pin): Atomic(id, DigitalOutputState()) { + in = addInPort("in"); + digiPin = new DigitalOut(pin); + }; + + // internal transition + void internalTransition(DigitalOutputState& state) const override { + } + + // external transition + void externalTransition(DigitalOutputState& state, double e) const override { + if(!in->empty()){ + for( const auto x : in->getBag()){ + state.output = x; + } + + digiPin->write(state.output ? 1 : 0); + } + } + + + // output function + void output(const DigitalOutputState& state) const override { + }; + + // time_advance function + [[nodiscard]] double timeAdvance(const DigitalOutputState& state) const override { + return std::numeric_limits::infinity(); + } + + }; +} + +#endif // RT_DIGITALOUTPUT_TEST_HPP diff --git a/example/rt_mbed/top_model/include/generator.hpp b/example/rt_mbed/top_model/include/generator.hpp new file mode 100644 index 0000000..ceb9078 --- /dev/null +++ b/example/rt_mbed/top_model/include/generator.hpp @@ -0,0 +1,89 @@ +#ifndef _GENERATOR_HPP__ +#define _GENERATOR_HPP__ + +#include +#include +#include + +namespace cadmium::blinkySystem { + //! Class for representing the Generator DEVS model state.struct GeneratorState { + struct GeneratorState { + double sigma; + bool val; + //! Generator state constructor. + GeneratorState(): sigma(0), val(0) {} + }; + /** + * Insertion operator for GeneratorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ + std::ostream& operator<<(std::ostream &out, const GeneratorState& state) { + out << "Status:, " << state.val; // state to string + return out; + } + + //! Atomic DEVS model of a Generator. + class Generator : public Atomic { + private: + + public: + Port out; + float a, b; + + /** + * Constructor function. + * @param id ID of the new Generator model object. + */ + Generator(const std::string& id): Atomic(id, GeneratorState()) { + out = addOutPort("out"); + a = 10; b = 20; + state.val = 0; + srand((unsigned) time(NULL)); + state.sigma = a + (float)rand()/RAND_MAX * (b-a); // sigma takes random values between 1 and 20 +// printf("[generator] init function\n"); + } + + /** + * It updates the GeneratorState::sigma. + * @param state reference to the current state of the model. + */ + void internalTransition(GeneratorState& state) const override { + state.sigma = a + (float)rand()/RAND_MAX * (b-a); // sigma takes random values between 1 and 20 +// printf("[generator] internal transition function\n"); + } + + /** + * Updates GeneratorState::state. + * @param state reference to the current model state. + * @param e time elapsed since the last state transition function was triggered. + * @param x reference to the model input port set. + */ + void externalTransition(GeneratorState& state, double e) const override { + state.sigma = std::numeric_limits::infinity(); +// printf("[generator] external transition function\n"); + } + + /** + * It outputs a 0 value to the out port. + * @param state reference to the current model state. + * @param y reference to the atomic model output port set. + */ + void output(const GeneratorState& state) const override { + out->addMessage(state.val); +// printf("[generator] output function\n"); + } + + /** + * It returns the value of GeneratorState::sigma. + * @param state reference to the current model state. + * @return the sigma value. + */ + [[nodiscard]] double timeAdvance(const GeneratorState& state) const override { + return state.sigma; + } + }; +} //namespace cadmium::blinkySystem + +#endif //_GENERATOR_HPP__ diff --git a/example/rt_mbed/top_model/include/interruptInput.hpp b/example/rt_mbed/top_model/include/interruptInput.hpp new file mode 100644 index 0000000..bc80a5d --- /dev/null +++ b/example/rt_mbed/top_model/include/interruptInput.hpp @@ -0,0 +1,123 @@ +/** +* Jon Menard +* ARSLab - Carleton University +* +* Interrupt Input: +* Model to interface with a Interrupt Input pin for Embedded Cadmium. +*/ + +#ifndef RT_INTERRUPT_INPUT_TEST_HPP +#define RT_INTERRUPT_INPUT_TEST_HPP + +#include +#include +#include "cadmium/modeling/devs/atomic.hpp" +#include "cadmium/simulation/_rt/real_time/linux/asynchronous_events.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../mbed.h" + +using namespace std; + +namespace cadmium { + + void AsyncEvent::notify() { + interrupted = true; + for (unsigned int i = 0; i < views.size(); i++) + views[i]->update(); + } + + struct InterruptInputState { + bool output; + bool last; + double sigma; + + /** + * InterruptInputState constructor. + * + */ + explicit InterruptInputState(): output(true), last(false), sigma(0){} + }; + + /** + * Insertion operator for InterruptInputState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + std::ostream& operator<<(std::ostream &out, const InterruptInputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; + } + + class InterruptInput : public Atomic, public AsyncEvent { + public: + + Port out; + Port triggerExternal; + //Parameters to be overwriten when instantiating the atomic model + InterruptIn* interruptPin; + + // default constructor + InterruptInput(const std::string& id, PinName pin): Atomic(id, InterruptInputState()), AsyncEvent(){ + out = addOutPort("out"); + triggerExternal = addInPort("triggerExternal"); + setPort(triggerExternal); + interruptPin = new InterruptIn(pin); + interruptPin->rise(callback(this, &cadmium::AsyncEvent::notify)); + interruptPin->fall(callback(this, &cadmium::AsyncEvent::notify)); + state.output = interruptPin->read(); + state.last = state.output; + }; + + + // internal transition + void internalTransition(InterruptInputState& state) const override { + state.sigma = std::numeric_limits::infinity(); + } + + // external transition + void externalTransition(InterruptInputState& state, double e) const override { + // if(!triggerExternal->empty()){ + + state.sigma = 0; + state.last = state.output; + state.output = (interruptPin->read() == 1); + + // } + + // MBED_ASSERT(false); + // throw std::logic_error("External transition called in a model with no input ports"); + } + + // output function + void output(const InterruptInputState& state) const override { + // if(state.last != state.output) + out->addMessage(state.output); + } + + // time_advance function + [[nodiscard]] double timeAdvance(const InterruptInputState& state) const override { + return state.sigma; + } + + void confluentTransition(InterruptInputState& s, double e) const { + this->externalTransition(s, e); + this->internalTransition(s); + } + + }; +} + +#endif // RT_INTERRUPT_INPUT_TEST_HPP diff --git a/example/rt_mbed/top_model/include/pwmOutput.hpp b/example/rt_mbed/top_model/include/pwmOutput.hpp new file mode 100644 index 0000000..83d9e9b --- /dev/null +++ b/example/rt_mbed/top_model/include/pwmOutput.hpp @@ -0,0 +1,100 @@ +/** +* Jon Menard +* ARSLab - Carleton University +* +* PWM Input: +* Model to interface with a PWM Output pin for Embedded Cadmium. +*/ + +#ifndef RT_PWMOUTPUT_HPP +#define RT_PWMOUTPUT_HPP + +#include +#include +#include "cadmium/modeling/devs/atomic.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../mbed.h" + +using namespace std; + +namespace cadmium { + + struct PWMOutputState { + double output; + double sigma; + + /** + * PWMOutputState constructor. + * + */ + explicit PWMOutputState(): output(0), sigma(0){} + }; + + /** + * Insertion operator for PWMOutputState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + + std::ostream& operator<<(std::ostream &out, const PWMOutputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; + } + + class PWMOutput : public Atomic { + public: + + Port in; + //Parameters to be overwriten when instantiating the atomic model + PwmOut* pwnPin; + + // default constructor + PWMOutput(const std::string& id, PinName pin): Atomic(id, PWMOutputState()) { + in = addInPort("in"); + pwmPin = new mbed::PwmOut(pin); + pwmPin->period_ms(10); + pwmPin->pulsewidth_ms(0); + }; + + // internal transition + void internalTransition(PWMOutputState& state) const override { + } + + // external transition + void externalTransition(PWMOutputState& state, double e) const override { + if(!in->empty()){ + for( const auto x : in->getBag()){ + state.output = x; + } + + pwnPin->write(state.output); + } + } + + + // output function + void output(const PWMOutputState& state) const override { + }; + + // time_advance function + [[nodiscard]] double timeAdvance(const PWMOutputState& state) const override { + return std::numeric_limits::infinity(); + } + + }; +} + +#endif // RT_PWMOUTPUT_HPP diff --git a/example/rt_mbed/top_model/main_rt_model.cpp b/example/rt_mbed/top_model/main_rt_model.cpp new file mode 100644 index 0000000..04c99b8 --- /dev/null +++ b/example/rt_mbed/top_model/main_rt_model.cpp @@ -0,0 +1,52 @@ +#include +#include +#include "blinkySystem.hpp" + +#ifdef RT_ARM_MBED + #include + #include "../mbed.h" + #ifndef NO_LOGGING + #include + #endif +#else + #include + #ifndef NO_LOGGING + #include + #endif +#endif + +using namespace cadmium::blinkySystem; + +int main(int argc, char *argv[]) { + + auto model = std::make_shared("blinkySystem"); +#ifdef RT_ARM_MBED + // Let's create the RT clock. In this case, we will use an mbed clock with a maximum jitter of 10 milliseconds + // note that the max jitter is optional. If left blank, it won't check the delay jitter. + long maxJitter = 10000; // 10000 us + auto clock = cadmium::MBEDClock(maxJitter); // choose the appropriate clock + // For creating RT coordinators, we must forward the model and the desired RT clock + auto rootCoordinator = cadmium::RealTimeRootCoordinator(model, clock); + // Let's define a logger to log all the atomics' transitions throug stdout which is mapped to the serial port (mbed-os) + #ifndef NO_LOGGING + rootCoordinator.setLogger(";"); + #endif +#else + // Let's create the RT clock. In this case, we will use a chrono clock with a maximum jitter of 10 milliseconds + // note that the max jitter is optional. If left blank, it won't check the delay jitter. + auto maxJitter = std::chrono::duration_cast(std::chrono::milliseconds(10)); + auto clock = cadmium::ChronoClock(maxJitter); + // For creating RT coordinators, we must forward the model and the desired RT clock + auto rootCoordinator = cadmium::RealTimeRootCoordinator(model, clock); + // Let's define a logger to log all the atomics' transitions in a csv file + #ifndef NO_LOGGING + // rootCoordinator.setLogger("blinkyLog.csv",";"); + #endif +#endif + + rootCoordinator.start(); +// rootCoordinator.simulate(std::numeric_limits::infinity()); + rootCoordinator.simulate(10.0); // run simulation for 10s + rootCoordinator.stop(); + return 0; +} diff --git a/example/rt_mbed/top_model/makefile b/example/rt_mbed/top_model/makefile new file mode 100644 index 0000000..23c45b6 --- /dev/null +++ b/example/rt_mbed/top_model/makefile @@ -0,0 +1,18 @@ +embedded: + # mbed compile --target NUCLEO_F401RE --toolchain GCC_ARM --profile ../cadmium.json --flash --sterm + mbed compile --target NUCLEO_F446RE --toolchain GCC_ARM --profile ../cadmium.json --flash --sterm + +clean-embedded: + rm -rf ../BUILD/ + +all: main.o + g++ -g -o Blinky main.o + +main.o: main_rt_model.cpp include/ + g++ -g -c -std=c++17 -I ../../../include -I include main_rt_model.cpp -o main.o + +clean: + rm -f *.o + rm -f *.csv + rm -f Blinky + diff --git a/example/rt_mbed/top_model/plotLogEmbed.py b/example/rt_mbed/top_model/plotLogEmbed.py new file mode 100644 index 0000000..dbe0eb0 --- /dev/null +++ b/example/rt_mbed/top_model/plotLogEmbed.py @@ -0,0 +1,43 @@ +import matplotlib.pyplot as plt +import serial + +# serial port parameters +PORT = '/dev/ttyACM0' +BAUDRATE = 9600 + +tblk_list = [] +outblk_list = [] +tdin_list = [] +outdin_list = [] + +with serial.Serial(PORT, BAUDRATE, timeout=1) as ser: + for i in range(0,100): + line = ser.readline() + # debug + # print(line) + if len(line.decode("utf-8").split(";")) != 5: + continue + t,atomic_id,atomic_name,port_name,val = line.decode("utf-8").split(";") + if (atomic_name=="blinky" and port_name=="out"): + print(line) + tblk_list.append(float(t)) + outblk_list.append(int(val.split(" ")[-1])) + elif (atomic_name=="digitalInput" and port_name=="out" and int(val)==0): + print(line) + tdin_list.append(float(t)) + outdin_list.append(int(val)) + +tblk = tblk_list +outblk = outblk_list +tdin = tdin_list +outdin = outdin_list + +plt.figure(figsize=(15,5)) +plt.step(tblk,outblk,label='output') +plt.plot(tdin,outdin,'r*',label='input') +plt.title('Blinky Output') +plt.xlabel('time (s)') +plt.ylabel('value') +plt.legend() +plt.grid(True) +plt.show() diff --git a/example/rt_mbed/top_model/plotLogSimu.py b/example/rt_mbed/top_model/plotLogSimu.py new file mode 100644 index 0000000..74cc229 --- /dev/null +++ b/example/rt_mbed/top_model/plotLogSimu.py @@ -0,0 +1,46 @@ +import matplotlib.pyplot as plt +from pathlib import Path + +CADMIUMV2_HOME = Path.home().joinpath('SED/demo-cadmiumv2') +CADMIUMV2_DIR = CADMIUMV2_HOME.joinpath('cadmium_v2') +CADMIUMV2_BLINKY_EXAMPLE = CADMIUMV2_HOME.joinpath('Blinky-improved') +CADMIUMV2_BLINKY_EXAMPLE_TOP = CADMIUMV2_BLINKY_EXAMPLE.joinpath('top_model') +LOGFILE = str(CADMIUMV2_BLINKY_EXAMPLE_TOP)+'/blinkyLog.csv' + +tblk_list = [] +outblk_list = [] +tgen_list = [] +outgen_list = [] + +# TODO: replace the following with pandas +with open(LOGFILE,'r') as f: + for line in f.readlines(): + # debug + # print(line) + t,atomic_id,atomic_name,port_name,val = line.split(";") + if (atomic_name=="blinky" and port_name=="out"): + tblk_list.append(float(t)) + outblk_list.append(int(val.split(" ")[-1])) + elif (atomic_name=="generator" and port_name=="out"): + tgen_list.append(float(t)) + outgen_list.append(int(val.split(" ")[-1])) + +f.close() + +T1 = 500 +T2 = 600 +tblk = [x for x in tblk_list if xT1] +outblk = outblk_list[:len(tblk)] +tgen = [x for x in tgen_list if xT1] +outgen = outgen_list[:len(tgen)] + + +plt.figure(figsize=(15,5)) +plt.step(tblk,outblk,label='output') +plt.plot(tgen,outgen,'r*',label='input') +plt.title('Blinky Output') +plt.xlabel('time (s)') +plt.ylabel('value') +plt.grid(True) +plt.legend() +plt.show() diff --git a/example/rt_mbed/top_model/printLogEmbed.py b/example/rt_mbed/top_model/printLogEmbed.py new file mode 100644 index 0000000..7092d2b --- /dev/null +++ b/example/rt_mbed/top_model/printLogEmbed.py @@ -0,0 +1,16 @@ +import matplotlib.pyplot as plt +import serial + +# serial port parameters +PORT = '/dev/ttyACM0' +BAUDRATE = 9600 + +tblk_list = [] +outblk_list = [] +tdin_list = [] +outdin_list = [] + +with serial.Serial(PORT, BAUDRATE, timeout=1) as ser: + for i in range(0,20): + line = ser.readline() + print(line.decode("utf-8").split(";")) diff --git a/example/rt_msp432/Example_1_Blinky.zip b/example/rt_msp432/Example_1_Blinky.zip new file mode 100644 index 0000000..e73239b Binary files /dev/null and b/example/rt_msp432/Example_1_Blinky.zip differ diff --git a/example/rt_msp432/Example_1_Blinky_Diagram.png b/example/rt_msp432/Example_1_Blinky_Diagram.png new file mode 100644 index 0000000..44a8f84 Binary files /dev/null and b/example/rt_msp432/Example_1_Blinky_Diagram.png differ diff --git a/example/rt_msp432/IO_Models/accelerometerInput.hpp b/example/rt_msp432/IO_Models/accelerometerInput.hpp new file mode 100644 index 0000000..e4ed15e --- /dev/null +++ b/example/rt_msp432/IO_Models/accelerometerInput.hpp @@ -0,0 +1,201 @@ +/** + * James Grieder & Srijan Gupta + * ARSLab - Carleton University + * + * A DEVS model for the Accelerometer (on the Educational Boosterpack MK II) + * when used with an MSP432P401R board. + * + * The accelerometer is polled every 0.2 seconds, and will output the X, Y, + * and Z axes of the accelerometer readings as 3 separate integer values. + */ + +#ifndef RT_ACCELEROMETERINPUT_HPP +#define RT_ACCELEROMETERINPUT_HPP + +//***************************************************************************** +// ADC14 Registers +//***************************************************************************** +/* ADC Control Registers */ +#define ADC14CTL0 (HWREG32(0x40012000)) +#define ADC14CTL1 (HWREG32(0x40012004)) +/* ADC Conversion Memory Control Registers */ +#define ADC14MCTL2 (HWREG32(0x40012020)) +#define ADC14MCTL3 (HWREG32(0x40012024)) +#define ADC14MCTL4 (HWREG32(0x40012028)) +/* ADC Conversion Memory Registers */ +#define ADC14MEM2 (HWREG32(0x400120A0)) +#define ADC14MEM3 (HWREG32(0x400120A4)) +#define ADC14MEM4 (HWREG32(0x400120A8)) +/* Interrupt Enable Registers */ +#define ADC14IER0 (HWREG32(0x4001213C)) +#define ADC14IER1 (HWREG32(0x40012140)) +/* Interrupt Flag Registers */ +#define ADC14IFGR0 (HWREG32(0x40012144)) + +#include "modeling/devs/atomic.hpp" +#include + +#include + +#ifdef RT_ARM_MBED +#endif + + +#ifndef NO_LOGGING +#include +#include +#include +#endif + + +// ------------BSP_Accelerometer_Input------------ +// Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu +// Read and return the immediate status of the +// accelerometer. The accelerometer X-, Y-, and +// Z-measurements are returned as 10-bit numbers, +// even if the ADC on the LaunchPad is more precise. +// Input: x is pointer to store X-measurement (0 to 1023) +// y is pointer to store Y-measurement (0 to 1023) +// z is pointer to store Z-measurement (0 to 1023) +// Output: none +// Assumes: BSP_Accelerometer_Init() has been called +void BSP_Accelerometer_Input(uint16_t *x, uint16_t *y, uint16_t *z){ + ADC14CTL0 &= ~0x00000002; // 1) ADC14ENC = 0 to allow programming + while(ADC14CTL0&0x00010000){}; // 2) wait for BUSY to be zero + ADC14CTL1 = (ADC14CTL1&~0x001F0000) | // clear STARTADDx bit field + (2 << 16); // 3) configure for STARTADDx = 2 + ADC14CTL0 |= 0x00000002; // 4) enable conversions + while(ADC14CTL0&0x00010000){}; // 5) wait for BUSY to be zero + ADC14CTL0 |= 0x00000001; // 6) start single conversion + while((ADC14IFGR0&0x10) == 0){}; // 7) wait for ADC14IFG4 + *x = ADC14MEM2>>4; // 8) P6.1/A14 result 0 to 1023 + *y = ADC14MEM3>>4; // P4.0/A13 result 0 to 1023 + *z = ADC14MEM4>>4; // P4.2/A11 result 0 to 1023 +} + + + +using namespace std; + +namespace cadmium { + +struct AccelerometerInputState { + uint16_t outputX; + uint16_t outputY; + uint16_t outputZ; + + uint16_t lastX; + uint16_t lastY; + uint16_t lastZ; + + double sigma; + + /** + * Processor state constructor. By default, the processor is idling. + * + */ + explicit AccelerometerInputState(): outputX(0), outputY(0), outputZ(0), lastX(0), lastY(0), lastZ(0), sigma(0){ + } + +}; + +#ifndef NO_LOGGING +/** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ +std::ostream& operator<<(std::ostream &out, const AccelerometerInputState& state) { + out << "x-axis: " << (state.output ? 1 : 0); + return out; +} +#endif + +class AccelerometerInput : public Atomic { +public: + + Port outX; + Port outY; + Port outZ; + + //Parameters to be overwritten when instantiating the atomic model + double pollingRate; + + // default constructor + AccelerometerInput(const std::string& id): Atomic(id, AccelerometerInputState()) { + + outX = addOutPort("outX"); + outY = addOutPort("outY"); + outZ = addOutPort("outZ"); + + pollingRate = 0.2; + + // Initialize ADC + // Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu + ADC14CTL0 &= ~0x00000002; // 2) ADC14ENC = 0 to allow programming + while(ADC14CTL0&0x00010000){}; // 3) wait for BUSY to be zero + ADC14CTL0 = 0x04223390; // 4) single, SMCLK, on, disabled, /1, 32 SHM + ADC14CTL1 = 0x00000030; // 5) ADC14MEM0, 14-bit, ref on, regular power + // 6) different for each initialization function + ADC14IER0 = 0; + ADC14IER1 = 0; // 7) no interrupts + + // Initialize Accelerometer Pins + // Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu + ADC14MCTL2 = 0x0000000E; // 6a) 0 to 3.3V, channel 14 + ADC14MCTL3 = 0x0000000D; // 6b) 0 to 3.3V, channel 13 + ADC14MCTL4 = 0x0000008B; // 6c) 0 to 3.3V, channel 11 + P6SEL0 |= 0x02; + P6SEL1 |= 0x02; // 8a) analog mode on P6.1/A14 + P4SEL0 |= 0x05; + P4SEL1 |= 0x05; // 8bc) analog mode on P4.2/A11 and P4.0/A13 + ADC14CTL0 |= 0x00000002; // 9) enable + + + // Get an initial reading + BSP_Accelerometer_Input(&state.outputX, &state.outputY, &state.outputZ); + + state.lastX = state.outputX; + state.lastY = state.outputY; + state.lastZ = state.outputZ; + }; + + // internal transition + void internalTransition(AccelerometerInputState& state) const override { + state.lastX = state.outputX; + state.lastY = state.outputY; + state.lastZ = state.outputZ; + + // Read pin + BSP_Accelerometer_Input(&state.outputX, &state.outputY, &state.outputZ); + + state.sigma = pollingRate; + } + + // external transition + void externalTransition(AccelerometerInputState& state, double e) const override { + throw CadmiumSimulationException("External transition called in a model with no input ports"); + } + + // output function + void output(const AccelerometerInputState& state) const override { + if(state.lastX != state.outputX) { + outX->addMessage((int)state.outputX); + } + if(state.lastY != state.outputY) { + outY->addMessage((int)state.outputY); + } + if(state.lastZ != state.outputZ) { + outZ->addMessage((int)state.outputZ); + } + } + + // time_advance function + [[nodiscard]] double timeAdvance(const AccelerometerInputState& state) const override { + return state.sigma; + } +}; +} + +#endif // RT_ACCELEROMETERINPUT_HPP diff --git a/example/rt_msp432/IO_Models/digitalInput.hpp b/example/rt_msp432/IO_Models/digitalInput.hpp new file mode 100644 index 0000000..0b61abd --- /dev/null +++ b/example/rt_msp432/IO_Models/digitalInput.hpp @@ -0,0 +1,98 @@ +/** + * Srijan Gupta & James Grieder + * ARSLab - Carleton University + * + * A DEVS model for digital input pins on the MSP432P401R board. This model can be + * used for switch inputs on the MSP432P401R, and switch and gator hole inputs on + * the Educational Boosterpack MK II. + * + * The specified pins are polled every 0.1 seconds, and will output the pin status + * as a boolean. + */ + +#ifndef __DIGITAL_INPUT_HPP__ +#define __DIGITAL_INPUT_HPP__ + +#include +#include +#include +#ifndef NO_LOGGING + #include +#endif + +namespace cadmium { + struct DigitalInputState { + bool output; + bool last; + double sigma; + + /** + * DigitalInputState constructor. + */ + explicit DigitalInputState(): output(true), last(false), sigma(0){} + }; + +#ifndef NO_LOGGING + /** + * Insertion operator for DigitalInputState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + std::ostream& operator<<(std::ostream &out, const DigitalInputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; + } +#endif + class DigitalInput : public Atomic { + public: + + Port out; + + //Parameters to be overwritten when instantiating the atomic model + uint_fast8_t port; + uint_fast16_t pins; + + // default constructor + DigitalInput(const std::string& id, uint_fast8_t selectedPort, uint_fast16_t selectedPins): Atomic(id, DigitalInputState()) { + out = addOutPort("out"); + port = selectedPort; + pins = selectedPins; + + if (port == GPIO_PORT_P2 && pins == GPIO_PIN3) { + ROM_GPIO_setAsInputPin(port, pins); + } else { + ROM_GPIO_setAsInputPinWithPullUpResistor(port,pins); + } + + state.output = ROM_GPIO_getInputPinValue(port,pins); + state.last = state.output; + state.sigma = 0.1; + }; + + // internal transition + void internalTransition(DigitalInputState& state) const override { + state.last = state.output; + state.output = ROM_GPIO_getInputPinValue(port,pins); + } + + // external transition + void externalTransition(DigitalInputState& state, double e) const override { + throw CadmiumSimulationException("External transition called in a model with no input ports"); + } + + // output function + void output(const DigitalInputState& state) const override { + if(state.last != state.output) { + out->addMessage(state.output); + } + } + + // time_advance function + [[nodiscard]] double timeAdvance(const DigitalInputState& state) const override { + return state.sigma; + } + }; +} // namespace cadmium + +#endif // __DIGITAL_INPUT_HPP__ diff --git a/example/rt_msp432/IO_Models/digitalOutput.hpp b/example/rt_msp432/IO_Models/digitalOutput.hpp new file mode 100644 index 0000000..dd42a7c --- /dev/null +++ b/example/rt_msp432/IO_Models/digitalOutput.hpp @@ -0,0 +1,86 @@ +/** + * Srijan Gupta & James Grieder + * ARSLab - Carleton University + * + * A DEVS model for digital output pins on the MSP432P401R board. This model can be + * used for the red LED and RGB on the MSP432P401R, or the RGB on the Educational + * Boosterpack MK II. + * + * Upon receiving a boolean value in the external transition function, the output + * pin will be set to high or low. + */ + +#ifndef __DIGITAL_OUTPUT_HPP__ +#define __DIGITAL_OUTPUT_HPP__ + +#include +#ifndef NO_LOGGING + #include +#endif +#include +#include + +namespace cadmium { + struct DigitalOutputState { + bool output; + /** + * DigitalOutput state constructor. + * + */ + explicit DigitalOutputState(): output(false){} + }; +#ifndef NO_LOGGING + /** + * Insertion operator for DigitalOutputState objects. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream. + */ + std::ostream& operator<<(std::ostream &out, const DigitalOutputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; + } +#endif + class DigitalOutput : public Atomic { + public: + + Port in; + //Parameters to be overwriten when instantiating the atomic model + uint_fast8_t port; + uint_fast16_t pins; + + // default constructor + DigitalOutput(const std::string& id, uint_fast8_t selectedPort,uint_fast16_t selectedPins): Atomic(id, DigitalOutputState()) { + in = addInPort("in"); + port = selectedPort; + pins = selectedPins; + ROM_GPIO_setAsOutputPin(port,pins); + }; + + // internal transition + void internalTransition(DigitalOutputState& state) const override { + } + + // external transition + void externalTransition(DigitalOutputState& state, double e) const override { + if(!in->empty()){ + for(const auto x : in->getBag()){ + state.output = x; + } + state.output ? ROM_GPIO_setOutputHighOnPin(port,pins) : ROM_GPIO_setOutputLowOnPin(port,pins); + } + } + + // output function + void output(const DigitalOutputState& state) const override { + } + + // time_advance function + [[nodiscard]] double timeAdvance(const DigitalOutputState& state) const override { + return std::numeric_limits::infinity(); + } + + }; +} // namespace cadmium + +#endif // __DIGITAL_OUTPUT_HPP__ diff --git a/example/rt_msp432/IO_Models/joystickInput.hpp b/example/rt_msp432/IO_Models/joystickInput.hpp new file mode 100644 index 0000000..b8f2546 --- /dev/null +++ b/example/rt_msp432/IO_Models/joystickInput.hpp @@ -0,0 +1,206 @@ +/** + * James Grieder & Srijan Gupta + * ARSLab - Carleton University + * + * A DEVS model for the Joystick on the Educational Boosterpack MK II + * when used with an MSP432P401R board. This includes the Horizontal and Vertical + * Axes of the Joystick, and the SELECT button. + * + * The accelerometer is polled every 0.1 seconds, and will output the X, and Y, + * axes of the joystick reading as 2 separate integer values. The SELECT button + * is polled at the same time, and the model outputs the value as a boolean. + */ + +#ifndef RT_JOYSTICKINPUT_HPP +#define RT_JOYSTICKINPUT_HPP + +//***************************************************************************** +// ADC14 Registers +//***************************************************************************** +/* ADC Control Registers */ +#define ADC14CTL0 (HWREG32(0x40012000)) +#define ADC14CTL1 (HWREG32(0x40012004)) +/* ADC Conversion Memory Control Registers */ +#define ADC14MCTL0 (HWREG32(0x40012018)) +#define ADC14MCTL1 (HWREG32(0x4001201C)) +/* ADC Conversion Memory Registers */ +#define ADC14MEM0 (HWREG32(0x40012098)) +#define ADC14MEM1 (HWREG32(0x4001209C)) +/* Interrupt Enable Registers */ +#define ADC14IER0 (HWREG32(0x4001213C)) +#define ADC14IER1 (HWREG32(0x40012140)) +/* Interrupt Flag Registers */ +#define ADC14IFGR0 (HWREG32(0x40012144)) + +#include "modeling/devs/atomic.hpp" +#include + +#include + +#ifdef RT_ARM_MBED +#endif + + +#ifndef NO_LOGGING +#include +#include +#include +#endif + + +// ------------BSP_Joystick_Input------------ +// Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu +// Read and return the immediate status of the +// joystick. Button de-bouncing for the Select +// button is not considered. The joystick X- and +// Y-positions are returned as 10-bit numbers, +// even if the ADC on the LaunchPad is more precise. +// Input: x is pointer to store X-position (0 to 1023) +// y is pointer to store Y-position (0 to 1023) +// select is pointer to store Select status (0 if pressed) +// Output: none +// Assumes: BSP_Joystick_Init() has been called +#define SELECT (*((volatile uint8_t *)(0x42000000+32*0x4C21+4*1))) +void BSP_Joystick_Input(uint16_t *x, uint16_t *y, uint8_t *select){ + ADC14CTL0 &= ~0x00000002; // 1) ADC14ENC = 0 to allow programming + while(ADC14CTL0&0x00010000){}; // 2) wait for BUSY to be zero + ADC14CTL1 = (ADC14CTL1&~0x001F0000) | // clear STARTADDx bit field + (0 << 16); // 3) configure for STARTADDx = 0 + ADC14CTL0 |= 0x00000002; // 4) enable conversions + while(ADC14CTL0&0x00010000){}; // 5) wait for BUSY to be zero + ADC14CTL0 |= 0x00000001; // 6) start single conversion + while((ADC14IFGR0&0x02) == 0){}; // 7) wait for ADC14IFG1 + *x = (int)ADC14MEM0>>4; // 8) P6.0/A15 result 0 to 1023 + *y = (int)ADC14MEM1>>4; // P4.4/A9 result 0 to 1023 + *select = (int)SELECT; // return 0(pressed) or 0x01(not pressed) +} + + + +using namespace std; + +namespace cadmium { + +struct JoystickInputState { + uint16_t outputX; + uint16_t outputY; + uint8_t outputSelect; + + uint16_t lastX; + uint16_t lastY; + uint8_t lastSelect; + + double sigma; + + /** + * Processor state constructor. By default, the processor is idling. + * + */ + explicit JoystickInputState(): outputX(0), outputY(0), outputSelect(0), lastX(0), lastY(0), lastSelect(0), sigma(0){ + } + +}; + +#ifndef NO_LOGGING +/** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ +std::ostream& operator<<(std::ostream &out, const JoystickInputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; +} +#endif + +class JoystickInput : public Atomic { +public: + + Port outX; + Port outY; + Port outSelect; + + //Parameters to be overwritten when instantiating the atomic model + double pollingRate; + + // default constructor + JoystickInput(const std::string& id): Atomic(id, JoystickInputState()) { + + outX = addOutPort("outX"); + outY = addOutPort("outY"); + outSelect = addOutPort("outSelect"); + + pollingRate = 0.2; + + // Initialize ADC + // Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu + ADC14CTL0 &= ~0x00000002; // 2) ADC14ENC = 0 to allow programming + while(ADC14CTL0&0x00010000){}; // 3) wait for BUSY to be zero + ADC14CTL0 = 0x04223390; // 4) single, SMCLK, on, disabled, /1, 32 SHM + ADC14CTL1 = 0x00000030; // 5) ADC14MEM0, 14-bit, ref on, regular power + // 6) different for each initialization function + ADC14IER0 = 0; + ADC14IER1 = 0; // 7) no interrupts + + // Initialize Joystick Pins + // Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu + ADC14MCTL0 = 0x0000000F; // 6a) 0 to 3.3V, channel 15 + ADC14MCTL1 = 0x00000089; // 6b) 0 to 3.3V, channel 9 + P6SEL0 |= 0x01; + P6SEL1 |= 0x01; // 8a) analog mode on P6.0/A15 + P4SEL0 |= 0x10; + P4SEL1 |= 0x10; // 8b) analog mode on P4.4/A9 + ADC14CTL0 |= 0x00000002; // 9) enable + P4SEL0 &= ~0x02; + P4SEL1 &= ~0x02; // configure P4.1 as GPIO + P4DIR &= ~0x02; // make P4.1 in + P4REN &= ~0x02; // disable pull resistor on P4.1 + + + // Get an initial reading + BSP_Joystick_Input(&state.outputX, &state.outputY, &state.outputSelect); + + state.lastX = state.outputX; + state.lastY = state.outputY; + state.lastSelect = state.outputSelect; + }; + + // internal transition + void internalTransition(JoystickInputState& state) const override { + state.lastX = state.outputX; + state.lastY = state.outputY; + state.lastSelect = state.outputSelect; + + // Read pin + BSP_Joystick_Input(&state.outputX, &state.outputY, &state.outputSelect); + + state.sigma = pollingRate; + } + + // external transition + void externalTransition(JoystickInputState& state, double e) const override { + throw CadmiumSimulationException("External transition called in a model with no input ports"); + } + + // output function + void output(const JoystickInputState& state) const override { + if(state.lastX != state.outputX) { + outX->addMessage((int)state.outputX); + } + if(state.lastY != state.outputY) { + outY->addMessage((int)state.outputY); + } + if(state.lastSelect != state.outputSelect) { + outSelect->addMessage((bool)state.outputSelect); + } + } + + // time_advance function + [[nodiscard]] double timeAdvance(const JoystickInputState& state) const override { + return state.sigma; + } +}; +} + +#endif // RT_JOYSTICKINPUT_HPP diff --git a/example/rt_msp432/IO_Models/lcdOutput.hpp b/example/rt_msp432/IO_Models/lcdOutput.hpp new file mode 100644 index 0000000..57226d3 --- /dev/null +++ b/example/rt_msp432/IO_Models/lcdOutput.hpp @@ -0,0 +1,1612 @@ +/** + * James Grieder & Hazel Griffith + * ARSLab - Carleton University + * + * A DEVS model for the LCD display screen on the Educational Boosterpack MK II + * when used with an MSP432P401R board. + * + * Upon receiving a string value in the external transition function, the input + * string is parsed into a separate function name and a list of parameters. The + * correct function is then invoked. + * + * See the associated LCD documentation, and the external transition function for + * supported function calls. + */ + +#ifndef __MSP_LCDOUTPUT_HPP__ +#define __MSP_LCDOUTPUT_HPP__ + +#include "modeling/devs/atomic.hpp" +#include +#include +#include + +#ifndef NO_LOGGING +#include +#include +#include +#endif + + +//color constants red grn blu +#define LCD_BLACK 0x0000 // 0, 0, 0 +#define LCD_BLUE 0x001F // 0, 0, 255 +#define LCD_DARKBLUE 0x34BF // 50, 150, 255 +#define LCD_RED 0xF800 // 255, 0, 0 +#define LCD_GREEN 0x07E0 // 0, 255, 0 +#define LCD_LIGHTGREEN 0x07EF // 0, 255, 120 +#define LCD_ORANGE 0xFD60 // 255, 175, 0 +#define LCD_CYAN 0x07FF // 0, 255, 255 +#define LCD_MAGENTA 0xF81F // 255, 0, 255 +#define LCD_YELLOW 0xFFE0 // 255, 255, 0 +#define LCD_WHITE 0xFFFF // 255, 255, 255 + + +// delay function +// which delays about 6*ulCount cycles +// ulCount=8000 => 1ms = 8000*6cycle/loop/48,000 +// Code Composer Studio Code +void parrotdelay(unsigned long ulCount){ + __asm ( "pdloop: subs r0, #1\n" + " bne pdloop\n"); +} + + +// ------------BSP_Delay1ms------------ +// Simple delay function which delays about n +// milliseconds. +// Inputs: n number of 1 msec to wait +// Outputs: none +void BSP_Delay1ms(uint32_t n){ + while(n){ + parrotdelay(8000); // 1 msec, tuned at 48 MHz, originally part of LCD module + n--; + } +} + + +/* ********************** */ +/* LCD Section */ +/* ********************** */ +// This section is based on ST7735.c, which itself is based +// on example code originally from Adafruit. Some sections +// such as the font table and initialization functions were +// copied verbatim from Adafruit's example and are subject +// to the following disclosure. +/*************************************************** + This is a library for the Adafruit 1.8" SPI display. + This library works with the Adafruit 1.8" TFT Breakout w/SD card + ----> http://www.adafruit.com/products/358 + as well as Adafruit raw 1.8" TFT displayun + ----> http://www.adafruit.com/products/618 + + Check out the links above for our tutorials and wiring diagrams + These displays use SPI to communicate, 4 or 5 pins are required to + interface (RST is optional) + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + MIT license, all text above must be included in any redistribution + ****************************************************/ +// some flags for ST7735_InitR() +enum initRFlags{ + none, + INITR_GREENTAB, + INITR_REDTAB, + INITR_BLACKTAB +}; + +#define ST7735_TFTWIDTH 128 +#define ST7735_TFTHEIGHT 128 + + +// Color definitions +#define ST7735_BLACK 0x0000 +#define ST7735_BLUE 0x001F +#define ST7735_RED 0xF800 +#define ST7735_GREEN 0x07E0 +#define ST7735_CYAN 0x07FF +#define ST7735_MAGENTA 0xF81F +#define ST7735_YELLOW 0xFFE0 +#define ST7735_WHITE 0xFFFF + + +// 12 rows (0 to 11) and 21 characters (0 to 20) +// Requires (11 + size*size*6*8) bytes of transmission for each character +uint32_t StX=0; // position along the horizonal axis 0 to 20 +uint32_t StY=0; // position along the vertical axis 0 to 11 +uint16_t StTextColor = ST7735_YELLOW; + +#define ST7735_NOP 0x00 +#define ST7735_SWRESET 0x01 +#define ST7735_RDDID 0x04 +#define ST7735_RDDST 0x09 + +#define ST7735_SLPIN 0x10 +#define ST7735_SLPOUT 0x11 +#define ST7735_PTLON 0x12 +#define ST7735_NORON 0x13 + +#define ST7735_INVOFF 0x20 +#define ST7735_INVON 0x21 +#define ST7735_DISPOFF 0x28 +#define ST7735_DISPON 0x29 +#define ST7735_CASET 0x2A +#define ST7735_RASET 0x2B +#define ST7735_RAMWR 0x2C +#define ST7735_RAMRD 0x2E + +#define ST7735_PTLAR 0x30 +#define ST7735_COLMOD 0x3A +#define ST7735_MADCTL 0x36 + +#define ST7735_FRMCTR1 0xB1 +#define ST7735_FRMCTR2 0xB2 +#define ST7735_FRMCTR3 0xB3 +#define ST7735_INVCTR 0xB4 +#define ST7735_DISSET5 0xB6 + +#define ST7735_PWCTR1 0xC0 +#define ST7735_PWCTR2 0xC1 +#define ST7735_PWCTR3 0xC2 +#define ST7735_PWCTR4 0xC3 +#define ST7735_PWCTR5 0xC4 +#define ST7735_VMCTR1 0xC5 + +#define ST7735_RDID1 0xDA +#define ST7735_RDID2 0xDB +#define ST7735_RDID3 0xDC +#define ST7735_RDID4 0xDD + +#define ST7735_PWCTR6 0xFC + +#define ST7735_GMCTRP1 0xE0 +#define ST7735_GMCTRN1 0xE1 + +#define TFT_CS (*((volatile uint8_t *)(0x42000000+32*0x4C42+4*0))) /* Port 5 Output, bit 0 is TFT CS */ +#define DC (*((volatile uint8_t *)(0x42000000+32*0x4C22+4*7))) /* Port 3 Output, bit 7 is DC */ +#define RESET (*((volatile uint8_t *)(0x42000000+32*0x4C42+4*7))) /* Port 5 Output, bit 7 is RESET*/ + +// standard ascii 5x7 font +// originally from glcdfont.c from Adafruit project +static const uint8_t Font[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, + 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, + 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, + 0x18, 0x3C, 0x7E, 0x3C, 0x18, + 0x1C, 0x57, 0x7D, 0x57, 0x1C, + 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, + 0x00, 0x18, 0x3C, 0x18, 0x00, + 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, + 0x00, 0x18, 0x24, 0x18, 0x00, + 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, + 0x30, 0x48, 0x3A, 0x06, 0x0E, + 0x26, 0x29, 0x79, 0x29, 0x26, + 0x40, 0x7F, 0x05, 0x05, 0x07, + 0x40, 0x7F, 0x05, 0x25, 0x3F, + 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, + 0x7F, 0x3E, 0x1C, 0x1C, 0x08, + 0x08, 0x1C, 0x1C, 0x3E, 0x7F, + 0x14, 0x22, 0x7F, 0x22, 0x14, + 0x5F, 0x5F, 0x00, 0x5F, 0x5F, + 0x06, 0x09, 0x7F, 0x01, 0x7F, + 0x00, 0x66, 0x89, 0x95, 0x6A, + 0x60, 0x60, 0x60, 0x60, 0x60, + 0x94, 0xA2, 0xFF, 0xA2, 0x94, + 0x08, 0x04, 0x7E, 0x04, 0x08, + 0x10, 0x20, 0x7E, 0x20, 0x10, + 0x08, 0x08, 0x2A, 0x1C, 0x08, + 0x08, 0x1C, 0x2A, 0x08, 0x08, + 0x1E, 0x10, 0x10, 0x10, 0x10, + 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, + 0x30, 0x38, 0x3E, 0x38, 0x30, + 0x06, 0x0E, 0x3E, 0x0E, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x5F, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x07, 0x00, + 0x14, 0x7F, 0x14, 0x7F, 0x14, + 0x24, 0x2A, 0x7F, 0x2A, 0x12, + 0x23, 0x13, 0x08, 0x64, 0x62, + 0x36, 0x49, 0x56, 0x20, 0x50, + 0x00, 0x08, 0x07, 0x03, 0x00, + 0x00, 0x1C, 0x22, 0x41, 0x00, + 0x00, 0x41, 0x22, 0x1C, 0x00, + 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, + 0x08, 0x08, 0x3E, 0x08, 0x08, + 0x00, 0x80, 0x70, 0x30, 0x00, + 0x08, 0x08, 0x08, 0x08, 0x08, + 0x00, 0x00, 0x60, 0x60, 0x00, + 0x20, 0x10, 0x08, 0x04, 0x02, + 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 + 0x00, 0x42, 0x7F, 0x40, 0x00, // 1 + 0x72, 0x49, 0x49, 0x49, 0x46, // 2 + 0x21, 0x41, 0x49, 0x4D, 0x33, // 3 + 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 + 0x27, 0x45, 0x45, 0x45, 0x39, // 5 + 0x3C, 0x4A, 0x49, 0x49, 0x31, // 6 + 0x41, 0x21, 0x11, 0x09, 0x07, // 7 + 0x36, 0x49, 0x49, 0x49, 0x36, // 8 + 0x46, 0x49, 0x49, 0x29, 0x1E, // 9 + 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x40, 0x34, 0x00, 0x00, + 0x00, 0x08, 0x14, 0x22, 0x41, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x00, 0x41, 0x22, 0x14, 0x08, + 0x02, 0x01, 0x59, 0x09, 0x06, + 0x3E, 0x41, 0x5D, 0x59, 0x4E, + 0x7C, 0x12, 0x11, 0x12, 0x7C, // A + 0x7F, 0x49, 0x49, 0x49, 0x36, // B + 0x3E, 0x41, 0x41, 0x41, 0x22, // C + 0x7F, 0x41, 0x41, 0x41, 0x3E, // D + 0x7F, 0x49, 0x49, 0x49, 0x41, // E + 0x7F, 0x09, 0x09, 0x09, 0x01, // F + 0x3E, 0x41, 0x41, 0x51, 0x73, // G + 0x7F, 0x08, 0x08, 0x08, 0x7F, // H + 0x00, 0x41, 0x7F, 0x41, 0x00, // I + 0x20, 0x40, 0x41, 0x3F, 0x01, // J + 0x7F, 0x08, 0x14, 0x22, 0x41, // K + 0x7F, 0x40, 0x40, 0x40, 0x40, // L + 0x7F, 0x02, 0x1C, 0x02, 0x7F, // M + 0x7F, 0x04, 0x08, 0x10, 0x7F, // N + 0x3E, 0x41, 0x41, 0x41, 0x3E, // O + 0x7F, 0x09, 0x09, 0x09, 0x06, // P + 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q + 0x7F, 0x09, 0x19, 0x29, 0x46, // R + 0x26, 0x49, 0x49, 0x49, 0x32, // S + 0x03, 0x01, 0x7F, 0x01, 0x03, // T + 0x3F, 0x40, 0x40, 0x40, 0x3F, // U + 0x1F, 0x20, 0x40, 0x20, 0x1F, // V + 0x3F, 0x40, 0x38, 0x40, 0x3F, // W + 0x63, 0x14, 0x08, 0x14, 0x63, // X + 0x03, 0x04, 0x78, 0x04, 0x03, // Y + 0x61, 0x59, 0x49, 0x4D, 0x43, // Z + 0x00, 0x7F, 0x41, 0x41, 0x41, + 0x02, 0x04, 0x08, 0x10, 0x20, + 0x00, 0x41, 0x41, 0x41, 0x7F, + 0x04, 0x02, 0x01, 0x02, 0x04, + 0x40, 0x40, 0x40, 0x40, 0x40, + 0x00, 0x03, 0x07, 0x08, 0x00, + 0x20, 0x54, 0x54, 0x78, 0x40, // a + 0x7F, 0x28, 0x44, 0x44, 0x38, // b + 0x38, 0x44, 0x44, 0x44, 0x28, // c + 0x38, 0x44, 0x44, 0x28, 0x7F, // d + 0x38, 0x54, 0x54, 0x54, 0x18, // e + 0x00, 0x08, 0x7E, 0x09, 0x02, // f + 0x18, 0xA4, 0xA4, 0x9C, 0x78, // g + 0x7F, 0x08, 0x04, 0x04, 0x78, // h + 0x00, 0x44, 0x7D, 0x40, 0x00, // i + 0x20, 0x40, 0x40, 0x3D, 0x00, // j + 0x7F, 0x10, 0x28, 0x44, 0x00, // k + 0x00, 0x41, 0x7F, 0x40, 0x00, // l + 0x7C, 0x04, 0x78, 0x04, 0x78, // m + 0x7C, 0x08, 0x04, 0x04, 0x78, // n + 0x38, 0x44, 0x44, 0x44, 0x38, // o + 0xFC, 0x18, 0x24, 0x24, 0x18, // p + 0x18, 0x24, 0x24, 0x18, 0xFC, // q + 0x7C, 0x08, 0x04, 0x04, 0x08, // r + 0x48, 0x54, 0x54, 0x54, 0x24, // s + 0x04, 0x04, 0x3F, 0x44, 0x24, // t + 0x3C, 0x40, 0x40, 0x20, 0x7C, // u + 0x1C, 0x20, 0x40, 0x20, 0x1C, // v + 0x3C, 0x40, 0x30, 0x40, 0x3C, // w + 0x44, 0x28, 0x10, 0x28, 0x44, // x + 0x4C, 0x90, 0x90, 0x90, 0x7C, // y + 0x44, 0x64, 0x54, 0x4C, 0x44, // z + 0x00, 0x08, 0x36, 0x41, 0x00, + 0x00, 0x00, 0x77, 0x00, 0x00, + 0x00, 0x41, 0x36, 0x08, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x02, + 0x3C, 0x26, 0x23, 0x26, 0x3C, + 0x1E, 0xA1, 0xA1, 0x61, 0x12, + 0x3A, 0x40, 0x40, 0x20, 0x7A, + 0x38, 0x54, 0x54, 0x55, 0x59, + 0x21, 0x55, 0x55, 0x79, 0x41, + 0x21, 0x54, 0x54, 0x78, 0x41, + 0x21, 0x55, 0x54, 0x78, 0x40, + 0x20, 0x54, 0x55, 0x79, 0x40, + 0x0C, 0x1E, 0x52, 0x72, 0x12, + 0x39, 0x55, 0x55, 0x55, 0x59, + 0x39, 0x54, 0x54, 0x54, 0x59, + 0x39, 0x55, 0x54, 0x54, 0x58, + 0x00, 0x00, 0x45, 0x7C, 0x41, + 0x00, 0x02, 0x45, 0x7D, 0x42, + 0x00, 0x01, 0x45, 0x7C, 0x40, + 0xF0, 0x29, 0x24, 0x29, 0xF0, + 0xF0, 0x28, 0x25, 0x28, 0xF0, + 0x7C, 0x54, 0x55, 0x45, 0x00, + 0x20, 0x54, 0x54, 0x7C, 0x54, + 0x7C, 0x0A, 0x09, 0x7F, 0x49, + 0x32, 0x49, 0x49, 0x49, 0x32, + 0x32, 0x48, 0x48, 0x48, 0x32, + 0x32, 0x4A, 0x48, 0x48, 0x30, + 0x3A, 0x41, 0x41, 0x21, 0x7A, + 0x3A, 0x42, 0x40, 0x20, 0x78, + 0x00, 0x9D, 0xA0, 0xA0, 0x7D, + 0x39, 0x44, 0x44, 0x44, 0x39, + 0x3D, 0x40, 0x40, 0x40, 0x3D, + 0x3C, 0x24, 0xFF, 0x24, 0x24, + 0x48, 0x7E, 0x49, 0x43, 0x66, + 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, + 0xFF, 0x09, 0x29, 0xF6, 0x20, + 0xC0, 0x88, 0x7E, 0x09, 0x03, + 0x20, 0x54, 0x54, 0x79, 0x41, + 0x00, 0x00, 0x44, 0x7D, 0x41, + 0x30, 0x48, 0x48, 0x4A, 0x32, + 0x38, 0x40, 0x40, 0x22, 0x7A, + 0x00, 0x7A, 0x0A, 0x0A, 0x72, + 0x7D, 0x0D, 0x19, 0x31, 0x7D, + 0x26, 0x29, 0x29, 0x2F, 0x28, + 0x26, 0x29, 0x29, 0x29, 0x26, + 0x30, 0x48, 0x4D, 0x40, 0x20, + 0x38, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x38, + 0x2F, 0x10, 0xC8, 0xAC, 0xBA, + 0x2F, 0x10, 0x28, 0x34, 0xFA, + 0x00, 0x00, 0x7B, 0x00, 0x00, + 0x08, 0x14, 0x2A, 0x14, 0x22, + 0x22, 0x14, 0x2A, 0x14, 0x08, + 0xAA, 0x00, 0x55, 0x00, 0xAA, + 0xAA, 0x55, 0xAA, 0x55, 0xAA, + 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x10, 0x10, 0x10, 0xFF, 0x00, + 0x14, 0x14, 0x14, 0xFF, 0x00, + 0x10, 0x10, 0xFF, 0x00, 0xFF, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x14, 0x14, 0x14, 0xFC, 0x00, + 0x14, 0x14, 0xF7, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x14, 0x14, 0xF4, 0x04, 0xFC, + 0x14, 0x14, 0x17, 0x10, 0x1F, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0x1F, 0x00, + 0x10, 0x10, 0x10, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0x1F, 0x10, + 0x10, 0x10, 0x10, 0xF0, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0xFF, 0x10, + 0x00, 0x00, 0x00, 0xFF, 0x14, + 0x00, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0x00, 0x1F, 0x10, 0x17, + 0x00, 0x00, 0xFC, 0x04, 0xF4, + 0x14, 0x14, 0x17, 0x10, 0x17, + 0x14, 0x14, 0xF4, 0x04, 0xF4, + 0x00, 0x00, 0xFF, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x14, 0x14, + 0x14, 0x14, 0xF7, 0x00, 0xF7, + 0x14, 0x14, 0x14, 0x17, 0x14, + 0x10, 0x10, 0x1F, 0x10, 0x1F, + 0x14, 0x14, 0x14, 0xF4, 0x14, + 0x10, 0x10, 0xF0, 0x10, 0xF0, + 0x00, 0x00, 0x1F, 0x10, 0x1F, + 0x00, 0x00, 0x00, 0x1F, 0x14, + 0x00, 0x00, 0x00, 0xFC, 0x14, + 0x00, 0x00, 0xF0, 0x10, 0xF0, + 0x10, 0x10, 0xFF, 0x10, 0xFF, + 0x14, 0x14, 0x14, 0xFF, 0x14, + 0x10, 0x10, 0x10, 0x1F, 0x00, + 0x00, 0x00, 0x00, 0xF0, 0x10, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x38, 0x44, 0x44, 0x38, 0x44, + 0x7C, 0x2A, 0x2A, 0x3E, 0x14, + 0x7E, 0x02, 0x02, 0x06, 0x06, + 0x02, 0x7E, 0x02, 0x7E, 0x02, + 0x63, 0x55, 0x49, 0x41, 0x63, + 0x38, 0x44, 0x44, 0x3C, 0x04, + 0x40, 0x7E, 0x20, 0x1E, 0x20, + 0x06, 0x02, 0x7E, 0x02, 0x02, + 0x99, 0xA5, 0xE7, 0xA5, 0x99, + 0x1C, 0x2A, 0x49, 0x2A, 0x1C, + 0x4C, 0x72, 0x01, 0x72, 0x4C, + 0x30, 0x4A, 0x4D, 0x4D, 0x30, + 0x30, 0x48, 0x78, 0x48, 0x30, + 0xBC, 0x62, 0x5A, 0x46, 0x3D, + 0x3E, 0x49, 0x49, 0x49, 0x00, + 0x7E, 0x01, 0x01, 0x01, 0x7E, + 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, + 0x44, 0x44, 0x5F, 0x44, 0x44, + 0x40, 0x51, 0x4A, 0x44, 0x40, + 0x40, 0x44, 0x4A, 0x51, 0x40, + 0x00, 0x00, 0xFF, 0x01, 0x03, + 0xE0, 0x80, 0xFF, 0x00, 0x00, + 0x08, 0x08, 0x6B, 0x6B, 0x08, + 0x36, 0x12, 0x36, 0x24, 0x36, + 0x06, 0x0F, 0x09, 0x0F, 0x06, + 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x00, + 0x30, 0x40, 0xFF, 0x01, 0x01, + 0x00, 0x1F, 0x01, 0x01, 0x1E, + 0x00, 0x19, 0x1D, 0x17, 0x12, + 0x00, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, +}; + + +static uint8_t ColStart, RowStart; // some displays need this changed +//static uint8_t Rotation; // 0 to 3 +//static enum initRFlags TabColor; +static int16_t _width = ST7735_TFTWIDTH; // this could probably be a constant, except it is used in Adafruit_GFX and depends on image rotation +static int16_t _height = ST7735_TFTHEIGHT; + + +// The Data/Command pin must be valid when the eighth bit is +// sent. The eUSCI module has no hardware input or output +// FIFOs, so this implementation is much simpler than it was +// for the Tiva LaunchPads. +// All operations wait until all data has been sent, +// configure the Data/Command pin, queue the message, and +// return the reply once it comes in. + +// This is a helper function that sends an 8-bit command to the LCD. +// Inputs: c 8-bit code to transmit +// Outputs: 8-bit reply +// Assumes: UCB0 and ports have already been initialized and enabled +uint8_t static writecommand(uint8_t c) { + while((UCB0IFG&0x0002)==0x0000){}; // wait until UCB0TXBUF empty + DC = 0x00; + TFT_CS = 0x00; + UCB0TXBUF = c; // command out + while((UCB0IFG&0x0001)==0x0000){}; // wait until UCB0RXBUF full + TFT_CS = 0x01; + return UCB0RXBUF; // return the response +} + + +// This is a helper function that sends a piece of 8-bit data to the LCD. +// Inputs: c 8-bit data to transmit +// Outputs: 8-bit reply +// Assumes: UCB0 and ports have already been initialized and enabled +uint8_t static writedata(uint8_t c) { + while((UCB0IFG&0x0002)==0x0000){}; // wait until UCB0TXBUF empty + DC = 0x01; + TFT_CS = 0x00; + UCB0TXBUF = c; // data out + while((UCB0IFG&0x0001)==0x0000){}; // wait until UCB0RXBUF full + TFT_CS = 0x01; + return UCB0RXBUF; // return the response +} + + +// Rather than a bazillion writecommand() and writedata() calls, screen +// initialization commands and arguments are organized in these tables +// stored in ROM. The table may look bulky, but that's mostly the +// formatting -- storage-wise this is hundreds of bytes more compact +// than the equivalent code. Companion function follows. +#define DELAY 0x80 +/*static const uint8_t + Bcmd[] = { // Initialization commands for 7735B screens + 18, // 18 commands in list: + ST7735_SWRESET, DELAY, // 1: Software reset, no args, w/delay + 50, // 50 ms delay + ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, no args, w/delay + 255, // 255 = 500 ms delay + ST7735_COLMOD , 1+DELAY, // 3: Set color mode, 1 arg + delay: + 0x05, // 16-bit color + 10, // 10 ms delay + ST7735_FRMCTR1, 3+DELAY, // 4: Frame rate control, 3 args + delay: + 0x00, // fastest refresh + 0x06, // 6 lines front porch + 0x03, // 3 lines back porch + 10, // 10 ms delay + ST7735_MADCTL , 1 , // 5: Memory access ctrl (directions), 1 arg: + 0x08, // Row addr/col addr, bottom to top refresh + ST7735_DISSET5, 2 , // 6: Display settings #5, 2 args, no delay: + 0x15, // 1 clk cycle nonoverlap, 2 cycle gate + // rise, 3 cycle osc equalize + 0x02, // Fix on VTL + ST7735_INVCTR , 1 , // 7: Display inversion control, 1 arg: + 0x0, // Line inversion + ST7735_PWCTR1 , 2+DELAY, // 8: Power control, 2 args + delay: + 0x02, // GVDD = 4.7V + 0x70, // 1.0uA + 10, // 10 ms delay + ST7735_PWCTR2 , 1 , // 9: Power control, 1 arg, no delay: + 0x05, // VGH = 14.7V, VGL = -7.35V + ST7735_PWCTR3 , 2 , // 10: Power control, 2 args, no delay: + 0x01, // Opamp current small + 0x02, // Boost frequency + ST7735_VMCTR1 , 2+DELAY, // 11: Power control, 2 args + delay: + 0x3C, // VCOMH = 4V + 0x38, // VCOML = -1.1V + 10, // 10 ms delay + ST7735_PWCTR6 , 2 , // 12: Power control, 2 args, no delay: + 0x11, 0x15, + ST7735_GMCTRP1,16 , // 13: Magical unicorn dust, 16 args, no delay: + 0x09, 0x16, 0x09, 0x20, // (seriously though, not sure what + 0x21, 0x1B, 0x13, 0x19, // these config values represent) + 0x17, 0x15, 0x1E, 0x2B, + 0x04, 0x05, 0x02, 0x0E, + ST7735_GMCTRN1,16+DELAY, // 14: Sparkles and rainbows, 16 args + delay: + 0x0B, 0x14, 0x08, 0x1E, // (ditto) + 0x22, 0x1D, 0x18, 0x1E, + 0x1B, 0x1A, 0x24, 0x2B, + 0x06, 0x06, 0x02, 0x0F, + 10, // 10 ms delay + ST7735_CASET , 4 , // 15: Column addr set, 4 args, no delay: + 0x00, 0x02, // XSTART = 2 + 0x00, 0x81, // XEND = 129 + ST7735_RASET , 4 , // 16: Row addr set, 4 args, no delay: + 0x00, 0x02, // XSTART = 1 + 0x00, 0x81, // XEND = 160 + ST7735_NORON , DELAY, // 17: Normal display on, no args, w/delay + 10, // 10 ms delay + ST7735_DISPON , DELAY, // 18: Main screen turn on, no args, w/delay + 255 }; // 255 = 500 ms delay*/ +static const uint8_t +Rcmd1[] = { // Init for 7735R, part 1 (red or green tab) + 15, // 15 commands in list: + ST7735_SWRESET, DELAY, // 1: Software reset, 0 args, w/delay + 150, // 150 ms delay + ST7735_SLPOUT , DELAY, // 2: Out of sleep mode, 0 args, w/delay + 255, // 500 ms delay + ST7735_FRMCTR1, 3 , // 3: Frame rate ctrl - normal mode, 3 args: + 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) + ST7735_FRMCTR2, 3 , // 4: Frame rate control - idle mode, 3 args: + 0x01, 0x2C, 0x2D, // Rate = fosc/(1x2+40) * (LINE+2C+2D) + ST7735_FRMCTR3, 6 , // 5: Frame rate ctrl - partial mode, 6 args: + 0x01, 0x2C, 0x2D, // Dot inversion mode + 0x01, 0x2C, 0x2D, // Line inversion mode + ST7735_INVCTR , 1 , // 6: Display inversion ctrl, 1 arg, no delay: + 0x07, // No inversion + ST7735_PWCTR1 , 3 , // 7: Power control, 3 args, no delay: + 0xA2, + 0x02, // -4.6V + 0x84, // AUTO mode + ST7735_PWCTR2 , 1 , // 8: Power control, 1 arg, no delay: + 0xC5, // VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD + ST7735_PWCTR3 , 2 , // 9: Power control, 2 args, no delay: + 0x0A, // Opamp current small + 0x00, // Boost frequency + ST7735_PWCTR4 , 2 , // 10: Power control, 2 args, no delay: + 0x8A, // BCLK/2, Opamp current small & Medium low + 0x2A, + ST7735_PWCTR5 , 2 , // 11: Power control, 2 args, no delay: + 0x8A, 0xEE, + ST7735_VMCTR1 , 1 , // 12: Power control, 1 arg, no delay: + 0x0E, + ST7735_INVOFF , 0 , // 13: Don't invert display, no args, no delay + ST7735_MADCTL , 1 , // 14: Memory access control (directions), 1 arg: + 0xC8, // row addr/col addr, bottom to top refresh + ST7735_COLMOD , 1 , // 15: set color mode, 1 arg, no delay: + 0x05 }; // 16-bit color +static const uint8_t +Rcmd2green[] = { // Init for 7735R, part 2 (green tab only) + 2, // 2 commands in list: + ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: + 0x00, 0x02, // XSTART = 0 + 0x00, 0x7F+0x02, // XEND = 127 + ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: + 0x00, 0x01, // XSTART = 0 + 0x00, 0x7F+0x01 }; // XEND = 127 +static const uint8_t +Rcmd2red[] = { // Init for 7735R, part 2 (red tab only) + 2, // 2 commands in list: + ST7735_CASET , 4 , // 1: Column addr set, 4 args, no delay: + 0x00, 0x00, // XSTART = 0 + 0x00, 0x7F, // XEND = 127 + ST7735_RASET , 4 , // 2: Row addr set, 4 args, no delay: + 0x00, 0x00, // XSTART = 0 + 0x00, 0x7F }; // XEND = 127 +static const uint8_t +Rcmd3[] = { // Init for 7735R, part 3 (red or green tab) + 4, // 4 commands in list: + ST7735_GMCTRP1, 16 , // 1: Magical unicorn dust, 16 args, no delay: + 0x02, 0x1c, 0x07, 0x12, + 0x37, 0x32, 0x29, 0x2d, + 0x29, 0x25, 0x2B, 0x39, + 0x00, 0x01, 0x03, 0x10, + ST7735_GMCTRN1, 16 , // 2: Sparkles and rainbows, 16 args, no delay: + 0x03, 0x1d, 0x07, 0x06, + 0x2E, 0x2C, 0x29, 0x2D, + 0x2E, 0x2E, 0x37, 0x3F, + 0x00, 0x00, 0x02, 0x10, + ST7735_NORON , DELAY, // 3: Normal display on, no args, w/delay + 10, // 10 ms delay + ST7735_DISPON , DELAY, // 4: Main screen turn on, no args w/delay + 100 }; // 100 ms delay + + +// Companion code to the above tables. Reads and issues +// a series of LCD commands stored in ROM byte array. +void static commandList(const uint8_t *addr) { + + uint8_t numCommands, numArgs; + uint16_t ms; + + numCommands = *(addr++); // Number of commands to follow + while(numCommands--) { // For each command... + writecommand(*(addr++)); // Read, issue command + numArgs = *(addr++); // Number of args to follow + ms = numArgs & DELAY; // If hibit set, delay follows args + numArgs &= ~DELAY; // Mask out delay bit + while(numArgs--) { // For each argument... + writedata(*(addr++)); // Read, issue argument + } + + if(ms) { + ms = *(addr++); // Read post-command delay time (ms) + if(ms == 255) ms = 500; // If 255, delay for 500 ms + BSP_Delay1ms(ms); + } + } +} + + +// Initialization code common to both 'B' and 'R' type displays +void static commonInit(const uint8_t *cmdList) { + ColStart = RowStart = 0; // May be overridden in init func + + // toggle RST low to reset; CS low so it'll listen to us + // UCB0STE is not available, so use GPIO on P5.0 + P3SEL0 &= ~0x80; + P3SEL1 &= ~0x80; // configure J4.31/P3.7 (D/C) as GPIO + P3DIR |= 0x80; // make J4.31/P3.7 (D/C) out + P5SEL0 &= ~0x81; + P5SEL1 &= ~0x81; // configure J2.17/P5.7 (Reset) and J2.13/P5.0 (TFT_CS) as GPIO + P5DIR |= 0x81; // make J2.17/P5.7 (Reset) and J2.13/P5.0 (TFT_CS) out + TFT_CS = 0x00; + RESET = 0x01; + BSP_Delay1ms(500); + RESET = 0x00; + BSP_Delay1ms(500); + RESET = 0x01; + BSP_Delay1ms(500); + TFT_CS = 0x01; + + // initialize eUSCI + UCB0CTLW0 = 0x0001; // hold the eUSCI module in reset mode + // configure UCB0CTLW0 for: + // bit15 UCCKPH = 1; data shifts in on first edge, out on following edge + // bit14 UCCKPL = 0; clock is low when inactive + // bit13 UCMSB = 1; MSB first + // bit12 UC7BIT = 0; 8-bit data + // bit11 UCMST = 1; master mode + // bits10-9 UCMODEx = 2; UCSTE active low + // bit8 UCSYNC = 1; synchronous mode + // bits7-6 UCSSELx = 2; eUSCI clock SMCLK + // bits5-2 reserved + // bit1 UCSTEM = 1; UCSTE pin enables slave + // bit0 UCSWRST = 1; reset enabled + UCB0CTLW0 = 0xAD83; + // set the baud rate for the eUSCI which gets its clock from SMCLK + // Clock_Init48MHz() from ClockSystem.c sets SMCLK = HFXTCLK/4 = 12 MHz + // if the SMCLK is set to 12 MHz, divide by 3 for 4 MHz baud clock + UCB0BRW = 3; + // modulation is not used in SPI mode, so clear UCB0MCTLW + // UCB0MCTLW = 0; // not actually a register in eUSCIB + P1SEL0 |= 0x60; + P1SEL1 &= ~0x60; // configure P1.6 and P1.5 as primary module function + UCB0CTLW0 &= ~0x0001; // enable eUSCI module + UCB0IE &= ~0x0003; // disable interrupts + + if(cmdList) commandList(cmdList); +} + + +/*//------------ST7735_InitB------------ +// Initialization for ST7735B screens. +// Input: none +// Output: none +void static ST7735_InitB(void) { + commonInit(Bcmd); + BSP_LCD_SetCursor(0,0); + StTextColor = ST7735_YELLOW; + BSP_LCD_FillScreen(0); // set screen to black +}*/ + + +// Set the region of the screen RAM to be modified +// Pixel colors are sent left to right, top to bottom +// (same as Font table is encoded; different from regular bitmap) +// Requires 11 bytes of transmission +void static setAddrWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) { + + writecommand(ST7735_CASET); // Column addr set + writedata(0x00); + writedata(x0+ColStart); // XSTART + writedata(0x00); + writedata(x1+ColStart); // XEND + + writecommand(ST7735_RASET); // Row addr set + writedata(0x00); + writedata(y0+RowStart); // YSTART + writedata(0x00); + writedata(y1+RowStart); // YEND + + writecommand(ST7735_RAMWR); // write to RAM +} + + +//------------BSP_LCD_FillRect------------ +// Draw a filled rectangle at the given coordinates with the given width, height, and color. +// Requires (11 + 2*w*h) bytes of transmission (assuming image fully on screen) +// Input: x horizontal position of the top left corner of the rectangle, columns from the left edge +// y vertical position of the top left corner of the rectangle, rows from the top edge +// w horizontal width of the rectangle +// h vertical height of the rectangle +// color 16-bit color, which can be produced by BSP_LCD_Color565() +// Output: none +void BSP_LCD_FillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { + uint8_t hi = color >> 8, lo = color; + + // rudimentary clipping (drawChar w/big text requires this) + if((x >= _width) || (y >= _height)) return; + if((x + w - 1) >= _width) w = _width - x; + if((y + h - 1) >= _height) h = _height - y; + + setAddrWindow(x, y, x+w-1, y+h-1); + + for(y=h; y>0; y--) { + for(x=w; x>0; x--) { + writedata(hi); + writedata(lo); + } + } +} + + +//------------BSP_LCD_FillScreen------------ +// Fill the screen with the given color. +// Requires 33,293 bytes of transmission +// Input: color 16-bit color, which can be produced by BSP_LCD_Color565() +// Output: none +void BSP_LCD_FillScreen(uint16_t color) { + BSP_LCD_FillRect(0, 0, _width, _height, color); // original + // screen is actually 129 by 129 pixels, x 0 to 128, y goes from 0 to 128 +} + + +//********BSP_LCD_SetCursor***************** +// Move the cursor to the desired X- and Y-position. The +// next character of the next unsigned decimal will be +// printed here. X=0 is the leftmost column. Y=0 is the top +// row. +// inputs: newX new X-position of the cursor (0<=newX<=20) +// newY new Y-position of the cursor (0<=newY<=12) +// outputs: none +void BSP_LCD_SetCursor(uint32_t newX, uint32_t newY){ + if((newX > 20) || (newY > 12)){ // bad input + return; // do nothing + } + StX = newX; + StY = newY; +} + + +//------------ST7735_InitR------------ +// Initialization for ST7735R screens (green or red tabs). +// Input: option one of the enumerated options depending on tabs +// Output: none +void static ST7735_InitR(enum initRFlags option) { + commonInit(Rcmd1); + if(option == INITR_GREENTAB) { + commandList(Rcmd2green); + ColStart = 2; + RowStart = 3; + } else { + // colstart, rowstart left at default '0' values + commandList(Rcmd2red); + } + commandList(Rcmd3); + + // if black, change MADCTL color filter + if (option == INITR_BLACKTAB) { + writecommand(ST7735_MADCTL); + writedata(0xC0); + } + // TabColor = option; + BSP_LCD_SetCursor(0,0); + StTextColor = ST7735_YELLOW; + BSP_LCD_FillScreen(0); // set screen to black +} + + +// ------------BSP_LCD_Init------------ +// Initialize the SPI and GPIO, which correspond with +// BoosterPack pins J1.7 (SPI CLK), J2.13 (SPI CS), J2.15 +// (SPI MOSI), J2.17 (LCD ~RST), and J4.31 (LCD DC). +// Input: none +// Output: none +void BSP_LCD_Init(void){ + ST7735_InitR(INITR_GREENTAB); +} + + +// Send two bytes of data, most significant byte first +// Requires 2 bytes of transmission +void static pushColor(uint16_t color) { + writedata((uint8_t)(color >> 8)); + writedata((uint8_t)color); +} + + +//------------BSP_LCD_DrawPixel------------ +// Color the pixel at the given coordinates with the given color. +// Requires 13 bytes of transmission +// Input: x horizontal position of the pixel, columns from the left edge +// must be less than 128 +// 0 is on the left, 126 is near the right +// y vertical position of the pixel, rows from the top edge +// must be less than 128 +// 126 is near the wires, 0 is the side opposite the wires +// color 16-bit color, which can be produced by BSP_LCD_Color565() +// Output: none +void BSP_LCD_DrawPixel(int16_t x, int16_t y, uint16_t color) { + + if((x < 0) || (x >= _width) || (y < 0) || (y >= _height)) return; + + // setAddrWindow(x,y,x+1,y+1); // original code, bug??? + setAddrWindow(x,y,x,y); + + pushColor(color); +} + + +//------------BSP_LCD_DrawFastVLine------------ +// Draw a vertical line at the given coordinates with the given height and color. +// A vertical line is parallel to the longer side of the rectangular display +// Requires (11 + 2*h) bytes of transmission (assuming image fully on screen) +// Input: x horizontal position of the start of the line, columns from the left edge +// y vertical position of the start of the line, rows from the top edge +// h vertical height of the line +// color 16-bit color, which can be produced by BSP_LCD_Color565() +// Output: none +void BSP_LCD_DrawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { + uint8_t hi = color >> 8, lo = color; + + // Rudimentary clipping + if((x >= _width) || (y >= _height)) return; + if((y+h-1) >= _height) h = _height-y; + setAddrWindow(x, y, x, y+h-1); + + while (h--) { + writedata(hi); + writedata(lo); + } +} + + +//------------BSP_LCD_DrawFastHLine------------ +// Draw a horizontal line at the given coordinates with the given width and color. +// A horizontal line is parallel to the shorter side of the rectangular display +// Requires (11 + 2*w) bytes of transmission (assuming image fully on screen) +// Input: x horizontal position of the start of the line, columns from the left edge +// y vertical position of the start of the line, rows from the top edge +// w horizontal width of the line +// color 16-bit color, which can be produced by BSP_LCD_Color565() +// Output: none +void BSP_LCD_DrawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { + uint8_t hi = color >> 8, lo = color; + + // Rudimentary clipping + if((x >= _width) || (y >= _height)) return; + if((x+w-1) >= _width) w = _width-x; + setAddrWindow(x, y, x+w-1, y); + + while (w--) { + writedata(hi); + writedata(lo); + } +} + + +//------------BSP_LCD_Color565------------ +// Pass 8-bit (each) R,G,B and get back 16-bit packed color. +// Input: r red value +// g green value +// b blue value +// Output: 16-bit color +uint16_t BSP_LCD_Color565(uint8_t r, uint8_t g, uint8_t b) { + return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); +} + + +//------------BSP_LCD_SwapColor------------ +// Swaps the red and blue values of the given 16-bit packed color; +// green is unchanged. +// Input: x 16-bit color in format B, G, R +// Output: 16-bit color in format R, G, B +uint16_t BSP_LCD_SwapColor(uint16_t x) { + return (x << 11) | (x & 0x07E0) | (x >> 11); +} + + +//------------BSP_LCD_DrawBitmap------------ +// Displays a 16-bit color BMP image. A bitmap file that is created +// by a PC image processing program has a header and may be padded +// with dummy columns so the data have four byte alignment. This +// function assumes that all of that has been stripped out, and the +// array image[] has one 16-bit halfword for each pixel to be +// displayed on the screen (encoded in reverse order, which is +// standard for bitmap files). An array can be created in this +// format from a 24-bit-per-pixel .bmp file using the associated +// converter program. +// (x,y) is the screen location of the lower left corner of BMP image +// Requires (11 + 2*w*h) bytes of transmission (assuming image fully on screen) +// Input: x horizontal position of the bottom left corner of the image, columns from the left edge +// y vertical position of the bottom left corner of the image, rows from the top edge +// image pointer to a 16-bit color BMP image +// w number of pixels wide +// h number of pixels tall +// Output: none +// Must be less than or equal to 128 pixels wide by 128 pixels high +void BSP_LCD_DrawBitmap(int16_t x, int16_t y, const uint16_t *image, int16_t w, int16_t h){ + int16_t skipC = 0; // non-zero if columns need to be skipped due to clipping + int16_t originalWidth = w; // save this value; even if not all columns fit on the screen, the image is still this width in ROM + int i = w*(h - 1); + + if((x >= _width) || ((y - h + 1) >= _height) || ((x + w) <= 0) || (y < 0)){ + return; // image is totally off the screen, do nothing + } + if((w > _width) || (h > _height)){ // image is too wide for the screen, do nothing + //***This isn't necessarily a fatal error, but it makes the + //following logic much more complicated, since you can have + //an image that exceeds multiple boundaries and needs to be + //clipped on more than one side. + return; + } + if((x + w - 1) >= _width){ // image exceeds right of screen + skipC = (x + w) - _width; // skip cut off columns + w = _width - x; + } + if((y - h + 1) < 0){ // image exceeds top of screen + i = i - (h - y - 1)*originalWidth; // skip the last cut off rows + h = y + 1; + } + if(x < 0){ // image exceeds left of screen + w = w + x; + skipC = -1*x; // skip cut off columns + i = i - x; // skip the first cut off columns + x = 0; + } + if(y >= _height){ // image exceeds bottom of screen + h = h - (y - _height + 1); + y = _height - 1; + } + + setAddrWindow(x, y-h+1, x+w-1, y); + + for(y=0; y> 8)); + // send the bottom 8 bits + writedata((uint8_t)image[i]); + i = i + 1; // go to the next pixel + } + i = i + skipC; + i = i - 2*originalWidth; + } +} + + +//------------BSP_LCD_DrawCharS------------ +// Simple character draw function. This is the same function from +// Adafruit_GFX.c but adapted for this processor. However, each call +// to BSP_LCD_DrawPixel() calls setAddrWindow(), which needs to send +// many extra data and commands. If the background color is the same +// as the text color, no background will be printed, and text can be +// drawn right over existing images without covering them with a box. +// Requires (11 + 2*size*size)*6*8 bytes of transmission (image fully on screen; textcolor != bgColor) +// Input: x horizontal position of the top left corner of the character, columns from the left edge +// y vertical position of the top left corner of the character, rows from the top edge +// c character to be printed +// textColor 16-bit color of the character +// bgColor 16-bit color of the background +// size number of pixels per character pixel (e.g. size==2 prints each pixel of font as 2x2 square) +// Output: none +void BSP_LCD_DrawCharS(int16_t x, int16_t y, char c, int16_t textColor, int16_t bgColor, uint8_t size){ + uint8_t line; // vertical column of pixels of character in font + int32_t i, j; + if((x >= _width) || // Clip right + (y >= _height) || // Clip bottom + ((x + 6 * size - 1) < 0) || // Clip left + ((y + 8 * size - 1) < 0)) // Clip top + return; + + for (i=0; i<6; i++ ) { + if (i == 5) + line = 0x0; + else + line = Font[(c*5)+i]; + for (j = 0; j<8; j++) { + if (line & 0x1) { + if (size == 1) // default size + BSP_LCD_DrawPixel(x+i, y+j, textColor); + else { // big size + BSP_LCD_FillRect(x+(i*size), y+(j*size), size, size, textColor); + } + } else if (bgColor != textColor) { + if (size == 1) // default size + BSP_LCD_DrawPixel(x+i, y+j, bgColor); + else { // big size + BSP_LCD_FillRect(x+i*size, y+j*size, size, size, bgColor); + } + } + line >>= 1; + } + } +} + + +//------------BSP_LCD_DrawChar------------ +// Advanced character draw function. This is similar to the function +// from Adafruit_GFX.c but adapted for this processor. However, this +// function only uses one call to setAddrWindow(), which allows it to +// run at least twice as fast. +// Requires (11 + size*size*6*8) bytes of transmission (assuming image fully on screen) +// Input: x horizontal position of the top left corner of the character, columns from the left edge +// y vertical position of the top left corner of the character, rows from the top edge +// c character to be printed +// textColor 16-bit color of the character +// bgColor 16-bit color of the background +// size number of pixels per character pixel (e.g. size==2 prints each pixel of font as 2x2 square) +// Output: none +void BSP_LCD_DrawChar(int16_t x, int16_t y, char c, int16_t textColor, int16_t bgColor, uint8_t size){ + uint8_t line; // horizontal row of pixels of character + int32_t col, row, i, j;// loop indices + if(((x + 6*size - 1) >= _width) || // Clip right + ((y + 8*size - 1) >= _height) || // Clip bottom + ((x + 6*size - 1) < 0) || // Clip left + ((y + 8*size - 1) < 0)){ // Clip top + return; + } + + setAddrWindow(x, y, x+6*size-1, y+8*size-1); + + line = 0x01; // print the top row first + // print the rows, starting at the top + for(row=0; row<8; row=row+1){ + for(i=0; i12) return 0; + while(*pt){ + BSP_LCD_DrawChar(x*6, y*10, *pt, textColor, ST7735_BLACK, 1); + pt++; + x = x+1; + if(x>20) return count; // number of characters printed + count++; + } + return count; // number of characters printed +} + + +//-----------------------fillmessage----------------------- +// Output a 32-bit number in unsigned decimal format +// Input: 32-bit number to be transferred +// Output: none +// Variable format 1-10 digits with no space before or after +char Message[12]; +uint32_t Messageindex; + +void static fillmessage(uint32_t n){ + // This function uses recursion to convert decimal number + // of unspecified length as an ASCII string + if(n >= 10){ + fillmessage(n/10); + n = n%10; + } + Message[Messageindex] = (n+'0'); /* n is between 0 and 9 */ + if(Messageindex<11)Messageindex++; +} +void static fillmessage4(uint32_t n){ + if(n>9999)n=9999; + if(n>=1000){ // 1000 to 9999 + Messageindex = 0; + } else if(n>=100){ // 100 to 999 + Message[0] = ' '; + Messageindex = 1; + }else if(n>=10){ // + Message[0] = ' '; /* n is between 10 and 99 */ + Message[1] = ' '; + Messageindex = 2; + }else{ + Message[0] = ' '; /* n is between 0 and 9 */ + Message[1] = ' '; + Message[2] = ' '; + Messageindex = 3; + } + fillmessage(n); +} +void static fillmessage5(uint32_t n){ + if(n>99999)n=99999; + if(n>=10000){ // 10000 to 99999 + Messageindex = 0; + } else if(n>=1000){ // 1000 to 9999 + Message[0] = ' '; + Messageindex = 1; + }else if(n>=100){ // 100 to 999 + Message[0] = ' '; + Message[1] = ' '; + Messageindex = 2; + }else if(n>=10){ // + Message[0] = ' '; /* n is between 10 and 99 */ + Message[1] = ' '; + Message[2] = ' '; + Messageindex = 3; + }else{ + Message[0] = ' '; /* n is between 0 and 9 */ + Message[1] = ' '; + Message[2] = ' '; + Message[3] = ' '; + Messageindex = 4; + } + fillmessage(n); +} +void static fillmessage2_1(uint32_t n){ + if(n>999)n=999; + if(n>=100){ // 100 to 999 + Message[0] = (n/100+'0'); /* tens digit */ + n = n%100; //the rest + }else { // 0 to 99 + Message[0] = ' '; /* n is between 0.0 and 9.9 */ + } + Message[1] = (n/10+'0'); /* ones digit */ + n = n%10; //the rest + Message[2] = '.'; + Message[3] = (n+'0'); /* tenths digit */ + Message[4] = 0; +} + +void static fillmessage2_Hex(uint32_t n){ char digit; +if(n>255){ + Message[0] = '*'; + Message[1] = '*'; +}else{ + digit = n/16; + if(digit<10){ + digit = digit+'0'; + }else{ + digit = digit+'A'-10; + } + Message[0] = digit; /* 16's digit */ + digit = n%16; + if(digit<10){ + digit = digit+'0'; + }else{ + digit = digit+'A'-10; + } + Message[1] = digit; /* ones digit */ +} +Message[2] = ','; +Message[3] = 0; +} + + +//-----------------------BSP_LCD_OutUDec----------------------- +// Output a 32-bit number in unsigned decimal format +// Position determined by BSP_LCD_SetCursor command +// Input: n 32-bit number to be transferred +// textColor 16-bit color of the numbers +// Output: none +// Variable format 1-10 digits with no space before or after +void BSP_LCD_OutUDec(uint32_t n, int16_t textColor){ + StTextColor = textColor; + Messageindex = 0; + fillmessage(n); + Message[Messageindex] = 0; // terminate + BSP_LCD_DrawString(StX,StY,Message,textColor); + StX = StX+Messageindex; + if(StX>20){ + StX = 20; + BSP_LCD_DrawChar(StX*6,StY*10,'*',ST7735_RED,ST7735_BLACK, 1); + } +} + + +//-----------------------BSP_LCD_OutUDec4----------------------- +// Output a 32-bit number in unsigned 4-digit decimal format +// Position determined by BSP_LCD_SetCursor command +// Input: 32-bit number to be transferred +// textColor 16-bit color of the numbers +// Output: none +// Fixed format 4 digits with no space before or after +void BSP_LCD_OutUDec4(uint32_t n, int16_t textColor){ + Messageindex = 0; + fillmessage4(n); + Message[Messageindex] = 0; // terminate + BSP_LCD_DrawString(StX,StY,Message,textColor); + StX = StX+Messageindex; + if(StX>20){ + StX = 20; + BSP_LCD_DrawChar(StX*6,StY*10,'*',ST7735_RED,ST7735_BLACK, 1); + } +} + + +//-----------------------BSP_LCD_OutUDec5----------------------- +// Output a 32-bit number in unsigned 5-digit decimal format +// Position determined by BSP_LCD_SetCursor command +// Input: 32-bit number to be transferred +// textColor 16-bit color of the numbers +// Output: none +// Fixed format 5 digits with no space before or after +void BSP_LCD_OutUDec5(uint32_t n, int16_t textColor){ + Messageindex = 0; + fillmessage5(n); + Message[Messageindex] = 0; // terminate + BSP_LCD_DrawString(StX,StY,Message,textColor); + StX = StX+Messageindex; + if(StX>20){ + StX = 20; + BSP_LCD_DrawChar(StX*6,StY*10,'*',ST7735_RED,ST7735_BLACK, 1); + } +} + + +//-----------------------BSP_LCD_OutUFix2_1----------------------- +// Output a 32-bit number in unsigned 3-digit fixed point, 0.1 resolution +// numbers 0 to 999 printed as " 0.0" to "99.9" +// Position determined by BSP_LCD_SetCursor command +// Input: 32-bit number to be transferred +// textColor 16-bit color of the numbers +// Output: none +// Fixed format 4 characters with no space before or after +void BSP_LCD_OutUFix2_1(uint32_t n, int16_t textColor){ + fillmessage2_1(n); + BSP_LCD_DrawString(StX,StY,Message,textColor); + StX = StX+4; + if(StX>20){ + StX = 20; + BSP_LCD_DrawChar(StX*6,StY*10,'*',ST7735_RED,ST7735_BLACK, 1); + } +} + +//-----------------------BSP_LCD_OutUHex2----------------------- +// Output a 32-bit number in unsigned 2-digit hexadecimal format +// numbers 0 to 255 printed as "00," to "FF," +// Position determined by BSP_LCD_SetCursor command +// Input: 32-bit number to be transferred +// textColor 16-bit color of the numbers +// Output: none +// Fixed format 3 characters with comma after +void BSP_LCD_OutUHex2(uint32_t n, int16_t textColor){ + fillmessage2_Hex(n); + BSP_LCD_DrawString(StX,StY,Message,textColor); + StX = StX+3; + if(StX>20){ + StX = 20; + BSP_LCD_DrawChar(StX*6,StY*10,'*',ST7735_RED,ST7735_BLACK, 1); + } +} + + +int TimeIndex; // horizontal position of next point to plot on graph (0 to 99) +int32_t Ymax, Ymin, Yrange; // vertical axis max, min, and range (units not specified) +uint16_t PlotBGColor; // background color of the plot used whenever clearing plot area + +// ------------BSP_LCD_Drawaxes------------ +// Set up the axes, labels, and other variables to +// allow data to be plotted in a chart using the +// functions BSP_LCD_PlotPoint() and +// BSP_LCD_PlotIncrement(). +// Input: axisColor 16-bit color for axes, which can be produced by BSP_LCD_Color565() +// bgColor 16-bit color for plot background, which can be produced by BSP_LCD_Color565() +// xLabel pointer to a null terminated string for x-axis (~4 character space) +// yLabel1 pointer to a null terminated string for top of y-axis (~3-5 character space) +// label1Color 16-bit color for y-axis label1, which can be produced by BSP_LCD_Color565() +// yLabel2 pointer to a null terminated string for bottom of y-axis (~3 character space) +// if yLabel2 is empty string, no yLabel2 is printed, and yLabel1 is centered +// label2Color 16-bit color for y-axis label2, which can be produced by BSP_LCD_Color565() +// ymax maximum value to be printed +// ymin minimum value to be printed +// Output: none +// Assumes: BSP_LCD_Init() has been called +void BSP_LCD_Drawaxes(uint16_t axisColor, uint16_t bgColor, char *xLabel, + char *yLabel1, uint16_t label1Color, char *yLabel2, uint16_t label2Color, + int32_t ymax, int32_t ymin){ + int i; + // assume that ymax > ymin + Ymax = ymax; + Ymin = ymin; + Yrange = Ymax - Ymin; + TimeIndex = 0; + PlotBGColor = bgColor; + BSP_LCD_FillRect(0, 17, 111, 111, bgColor); + BSP_LCD_DrawFastHLine(10, 117, 101, axisColor); + BSP_LCD_DrawFastVLine(10, 17, 101, axisColor); + for(i=20; i<=110; i=i+10){ + BSP_LCD_DrawPixel(i, 118, axisColor); + } + for(i=17; i<117; i=i+10){ + BSP_LCD_DrawPixel(9, i, axisColor); + } + i = 50; + while((*xLabel) && (i < 100)){ + BSP_LCD_DrawChar(i, 120, *xLabel, axisColor, bgColor, 1); + i = i + 6; + xLabel++; + } + if(*yLabel2){ // two labels + i = 26; + while((*yLabel2) && (i < 50)){ + BSP_LCD_DrawChar(0, i, *yLabel2, label2Color, bgColor, 1); + i = i + 8; + yLabel2++; + } + i = 82; + }else{ // one label + i = 42; + } + while((*yLabel1) && (i < 120)){ + BSP_LCD_DrawChar(0, i, *yLabel1, label1Color, bgColor, 1); + i = i + 8; + yLabel1++; + } +} + + +// ------------BSP_LCD_PlotPoint------------ +// Plot a point on the chart. To plot several points in the +// same column, call this function repeatedly before calling +// BSP_LCD_PlotIncrement(). The units of the data are the +// same as the ymax and ymin values specified in the +// initialization function. +// Input: data1 value to be plotted (units not specified) +// color1 16-bit color for the point, which can be produced by BSP_LCD_Color565() +// Output: none +// Assumes: BSP_LCD_Init() and BSP_LCD_Drawaxes() have been called +void BSP_LCD_PlotPoint(int32_t data1, uint16_t color1){ + data1 = ((data1 - Ymin)*100)/Yrange; + if(data1 > 98){ + data1 = 98; + color1 = LCD_RED; + } + if(data1 < 0){ + data1 = 0; + color1 = LCD_RED; + } + BSP_LCD_DrawPixel(TimeIndex + 11, 116 - data1, color1); + BSP_LCD_DrawPixel(TimeIndex + 11, 115 - data1, color1); +} + + +// ------------BSP_LCD_PlotIncrement------------ +// Increment the plot between subsequent calls to +// BSP_LCD_PlotPoint(). Automatically wrap and clear the +// column to be printed to. +// Input: none +// Output: none +// Assumes: BSP_LCD_Init() and BSP_LCD_Drawaxes() have been called +void BSP_LCD_PlotIncrement(void){ + TimeIndex = TimeIndex + 1; + if(TimeIndex > 99){ + TimeIndex = 0; + } + BSP_LCD_DrawFastVLine(TimeIndex + 11, 17, 100, PlotBGColor); +} +/* ********************** */ +/* End of LCD Section */ +/* ********************** */ + + +/* ************************** */ +/* DEVS Model Begins Here */ +/* ************************** */ + + +//using namespace std; + +namespace cadmium { + +struct LCDOutputState { + + string token; + string function; + string parameters; + char* parametersList[9]; + + int i; + + double sigma; + string input; + string lastInput; + + + /** + * Processor state constructor. By default, the processor is idling. + */ + explicit LCDOutputState(): sigma(0){ + } + +}; + +#ifndef NO_LOGGING +/** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ + +std::ostream& operator<<(std::ostream &out, const LCDOutputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; +} +#endif + +class LCDOutput : public Atomic { +public: + + Port in; + + std::unordered_map colourMap; + std::unordered_map functionMap; + + // default constructor + LCDOutput(const std::string& id): Atomic(id, LCDOutputState()) { + + in = addInPort("in"); + + // set up a map of strings to their associated colour macros + colourMap = { + {"LCD_BLACK", 0x0000}, + {"LCD_BLUE", 0x001F}, + {"LCD_DARKBLUE", 0x34BF}, + {"LCD_RED", 0xF800}, + {"LCD_GREEN", 0x07E0}, + {"LCD_LIGHTGREEN", 0x07EF}, + {"LCD_ORANGE", 0xFD50}, + {"LCD_CYAN", 0x07FF}, + {"LCD_MAGENTA", 0xF81F}, + {"LCD_YELLOW", 0xFFE0}, + {"LCD_WHITE", 0xFFFF}, + {"0x0000", 0x0000}, + {"0x001F", 0x001F}, + {"0x34BF", 0x34BF}, + {"0xF800", 0xF800}, + {"0x07E0", 0x07E0}, + {"0x07EF", 0x07EF}, + {"0xFD50", 0xFD50}, + {"0x07FF", 0x07FF}, + {"0xF81F", 0xF81F}, + {"0xFFE0", 0xFFE0}, + {"0xFFFF", 0xFFFF} + }; + + // set up a map of strings, and assign them an integer + functionMap = { + {"FillRect", 0}, + {"FillScreen", 1}, + {"DrawPixel", 2}, + {"DrawFastVLine", 3}, + {"DrawFastHLine", 4}, + {"DrawString", 5} + }; + + // initialize LCD screen + + }; + + + // internal transition + void internalTransition(LCDOutputState& state) const override { + } + + // external transition + void externalTransition(LCDOutputState& state, double e) const override { + if(!in->empty()){ + for( const auto x : in->getBag()){ + + state.lastInput = state.input; + state.input = x; + + state.input.erase(0,8); // Remove "BSP_LCD_" from the beginning of the input string + state.input.pop_back(); // Remove ")" from the end of the input string + + if (state.input.compare(state.lastInput) != 0) { + + int temp1 = state.input.find_first_of("("); + + state.function = state.input.substr(0, temp1); // isolate the function name + state.parameters = state.input.substr(temp1 + 1, string::npos); // isolate the list of parameters + + + char *params = new char[state.parameters.length() + 1]; + strcpy(params, state.parameters.c_str()); + + char *token = strtok(params, ","); + + int i = 0; + while (token != 0) { // separate the parameters + state.parametersList[i] = token; + i++; + token = strtok(NULL, ","); + } + + + char *textPtr; + + switch(functionMap.at(state.function)) { + + case 0: + BSP_LCD_FillRect(atoi(state.parametersList[0]), atoi(state.parametersList[1]), atoi(state.parametersList[2]), atoi(state.parametersList[3]), colourMap.at(state.parametersList[4])); + break; + + case 1: + BSP_LCD_FillScreen(colourMap.at(state.parametersList[0])); + break; + + case 2: + BSP_LCD_DrawPixel(atoi(state.parametersList[0]), atoi(state.parametersList[1]), colourMap.at(state.parametersList[2])); + break; + + case 3: + BSP_LCD_DrawFastVLine(atoi(state.parametersList[0]), atoi(state.parametersList[1]), atoi(state.parametersList[2]), colourMap.at(state.parametersList[3])); + break; + + case 4: + BSP_LCD_DrawFastHLine(atoi(state.parametersList[0]), atoi(state.parametersList[1]), atoi(state.parametersList[2]), colourMap.at(state.parametersList[3])); + break; + + case 5: + textPtr = state.parametersList[2]; + BSP_LCD_DrawString(atoi(state.parametersList[0]), atoi(state.parametersList[1]), textPtr, colourMap.at(state.parametersList[3])); + break; + + default: + BSP_LCD_FillScreen(LCD_GREEN); + + } + } + } + } + } + + + // output function + void output(const LCDOutputState& state) const override { + }; + + // time_advance function + [[nodiscard]] double timeAdvance(const LCDOutputState& state) const override { + return std::numeric_limits::infinity(); + } + +}; +} + +#endif // __MSP_LCDOUTPUT_HPP__ diff --git a/example/rt_msp432/IO_Models/lightSensorInput.hpp b/example/rt_msp432/IO_Models/lightSensorInput.hpp new file mode 100644 index 0000000..dbf9d04 --- /dev/null +++ b/example/rt_msp432/IO_Models/lightSensorInput.hpp @@ -0,0 +1,455 @@ +/** + * James Grieder & Srijan Gupta + * ARSLab - Carleton University + * + * A DEVS model for the Light Sensor on the Educational Boosterpack MK II + * when used with an MSP432P401R board. + * + * The light sensor is polled every 0.8 seconds (based on the duration of + * a single reading), and will output the reading as an integer value + * measured in units of lux. + */ + +#ifndef RT_LIGHTSENSORINPUT_HPP +#define RT_LIGHTSENSORINPUT_HPP + +#include "modeling/devs/atomic.hpp" +#include + +#include + +#ifdef RT_ARM_MBED +#endif + + +#ifndef NO_LOGGING + #include + #include + #include +#endif + + + +// There are two I2C devices on the Educational BoosterPack MKII: +// OPT3001 Light Sensor +// TMP006 Temperature sensor +// Both initialization functions can use this general I2C +// initialization. +void static i2cinit(void){ + // initialize eUSCI + UCB1CTLW0 = 0x0001; // hold the eUSCI module in reset mode + // configure UCB1CTLW0 for: + // bit15 UCA10 = 0; own address is 7-bit address + // bit14 UCSLA10 = 0; address slave with 7-bit address + // bit13 UCMM = 0; single master environment + // bit12 reserved + // bit11 UCMST = 1; master mode + // bits10-9 UCMODEx = 3; I2C mode + // bit8 UCSYNC = 1; synchronous mode + // bits7-6 UCSSELx = 2; eUSCI clock SMCLK + // bit5 UCTXACK = X; transmit ACK condition in slave mode + // bit4 UCTR = X; transmitter/receiver + // bit3 UCTXNACK = X; transmit negative acknowledge in slave mode + // bit2 UCTXSTP = X; transmit stop condition in master mode + // bit1 UCTXSTT = X; transmit start condition in master mode + // bit0 UCSWRST = 1; reset enabled + UCB1CTLW0 = 0x0F81; + // configure UCB1CTLW1 for: + // bits15-9 reserved + // bit8 UCETXINT = X; early UCTXIFG0 in slave mode + // bits7-6 UCCLTO = 3; timeout clock low after 165,000 SYSCLK cycles + // bit5 UCSTPNACK = 0; send negative acknowledge before stop condition in master receiver mode + // bit4 UCSWACK = 0; slave address acknowledge controlled by hardware + // bits3-2 UCASTPx = 2; generate stop condition automatically after UCB0TBCNT bytes + // bits1-0 UCGLITx = 0 deglitch time of 50 ns + UCB1CTLW1 = 0x00C8; + UCB1TBCNT = 2; // generate stop condition after this many bytes + // set the baud rate for the eUSCI which gets its clock from SMCLK + // Clock_Init48MHz() from ClockSystem.c sets SMCLK = HFXTCLK/4 = 12 MHz + // if the SMCLK is set to 12 MHz, divide by 120 for 100 kHz baud clock + UCB1BRW = 120; + P6SEL0 |= 0x30; + P6SEL1 &= ~0x30; // configure P6.5 and P6.4 as primary module function + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1IE = 0x0000; // disable interrupts +} + +/*// receives one byte from specified slave +// Note for HMC6352 compass only: +// Used with 'r' and 'g' commands +// Note for TMP102 thermometer only: +// Used to read the top byte of the contents of the pointer register +// This will work but is probably not what you want to do. +uint8_t static I2C_Recv(int8_t slave){ + int8_t data1; + while(UCB1STATW&0x0010){}; // wait for I2C ready + UCB1CTLW0 |= 0x0001; // hold the eUSCI module in reset mode + UCB1TBCNT = 1; // generate stop condition after this many bytes + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1I2CSA = slave; // I2CCSA[6:0] is slave address + UCB1CTLW0 = ((UCB1CTLW0&~0x0014) // clear bit4 (UCTR) for receive mode + // clear bit2 (UCTXSTP) for no transmit stop condition + | 0x0002); // set bit1 (UCTXSTT) for transmit start condition + while((UCB1IFG&0x0001) == 0){ // wait for complete character received + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + i2cinit(); // reset to known state + return 0xFF; + } + } + data1 = UCB1RXBUF&0xFF; // get the reply + return data1; +}*/ + +// receives two bytes from specified slave +// Note for HMC6352 compass only: +// Used with 'A' commands +// Note for TMP102 thermometer only: +// Used to read the contents of the pointer register +uint16_t static I2C_Recv2(int8_t slave){ + uint8_t data1, data2; + while(UCB1STATW&0x0010){}; // wait for I2C ready + UCB1CTLW0 |= 0x0001; // hold the eUSCI module in reset mode + UCB1TBCNT = 2; // generate stop condition after this many bytes + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1I2CSA = slave; // I2CCSA[6:0] is slave address + UCB1CTLW0 = ((UCB1CTLW0&~0x0014) // clear bit4 (UCTR) for receive mode + // clear bit2 (UCTXSTP) for no transmit stop condition + | 0x0002); // set bit1 (UCTXSTT) for transmit start condition + while((UCB1IFG&0x0001) == 0){ // wait for complete character received + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + i2cinit(); // reset to known state + return 0xFFFF; + } + } + data1 = UCB1RXBUF&0xFF; // get the reply + while((UCB1IFG&0x0001) == 0){ // wait for complete character received + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + i2cinit(); // reset to known state + return 0xFFFF; + } + } + data2 = UCB1RXBUF&0xFF; // get the reply + return (data1<<8)+data2; +} + +// sends one byte to specified slave +// Note for HMC6352 compass only: +// Used with 'S', 'W', 'O', 'C', 'E', 'L', and 'A' commands +// For 'A' commands, I2C_Recv2() should also be called +// Note for TMP102 thermometer only: +// Used to change the pointer register +// Returns 0 if successful, nonzero if error +uint16_t static I2C_Send1(int8_t slave, uint8_t data1){ + uint16_t debugdump; // save status register here in case of error + while(UCB1STATW&0x0010){}; // wait for I2C ready + UCB1CTLW0 |= 0x0001; // hold the eUSCI module in reset mode + UCB1TBCNT = 1; // generate stop condition after this many bytes + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1I2CSA = slave; // I2CCSA[6:0] is slave address + UCB1CTLW0 = ((UCB1CTLW0&~0x0004) // clear bit2 (UCTXSTP) for no transmit stop condition + // set bit1 (UCTXSTT) for transmit start condition + | 0x0012); // set bit4 (UCTR) for transmit mode + while(UCB1CTLW0&0x0002){}; // wait for slave address sent + UCB1TXBUF = data1&0xFF; // TXBUF[7:0] is data + while(UCB1STATW&0x0010){ // wait for I2C idle + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB1IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + return 0; +} + +/*// sends two bytes to specified slave +// Note for HMC6352 compass only: +// Used with 'r' and 'g' commands +// For 'r' and 'g' commands, I2C_Recv() should also be called +// Note for TMP102 thermometer only: +// Used to change the top byte of the contents of the pointer register +// This will work but is probably not what you want to do. +// Returns 0 if successful, nonzero if error +uint16_t static I2C_Send2(int8_t slave, uint8_t data1, uint8_t data2){ + uint16_t debugdump; // save status register here in case of error + while(UCB1STATW&0x0010){}; // wait for I2C ready + UCB1CTLW0 |= 0x0001; // hold the eUSCI module in reset mode + UCB1TBCNT = 2; // generate stop condition after this many bytes + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1I2CSA = slave; // I2CCSA[6:0] is slave address + UCB1CTLW0 = ((UCB1CTLW0&~0x0004) // clear bit2 (UCTXSTP) for no transmit stop condition + // set bit1 (UCTXSTT) for transmit start condition + | 0x0012); // set bit4 (UCTR) for transmit mode + while(UCB1CTLW0&0x0002){}; // wait for slave address sent + UCB1TXBUF = data1&0xFF; // TXBUF[7:0] is data + while((UCB1IFG&0x0002) == 0){ // wait for first data sent + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB1IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + UCB1TXBUF = data2&0xFF; // TXBUF[7:0] is data + while(UCB1STATW&0x0010){ // wait for I2C idle + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB1IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + return 0; +}*/ + +// sends three bytes to specified slave +// Note for HMC6352 compass only: +// Used with 'w' and 'G' commands +// Note for TMP102 thermometer only: +// Used to change the contents of the pointer register +// Returns 0 if successful, nonzero if error +uint16_t static I2C_Send3(int8_t slave, uint8_t data1, uint8_t data2, uint8_t data3){ + uint16_t debugdump; // save status register here in case of error + while(UCB1STATW&0x0010){}; // wait for I2C ready + UCB1CTLW0 |= 0x0001; // hold the eUSCI module in reset mode + UCB1TBCNT = 3; // generate stop condition after this many bytes + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1I2CSA = slave; // I2CCSA[6:0] is slave address + UCB1CTLW0 = ((UCB1CTLW0&~0x0004) // clear bit2 (UCTXSTP) for no transmit stop condition + // set bit1 (UCTXSTT) for transmit start condition + | 0x0012); // set bit4 (UCTR) for transmit mode + while((UCB1IFG&0x0002) == 0){}; // wait for slave address sent + UCB1TXBUF = data1&0xFF; // TXBUF[7:0] is data + while((UCB1IFG&0x0002) == 0){ // wait for first data sent + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB0IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + UCB1TXBUF = data2&0xFF; // TXBUF[7:0] is data + while((UCB1IFG&0x0002) == 0){ // wait for second data sent + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB1IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + UCB1TXBUF = data3&0xFF; // TXBUF[7:0] is data + while(UCB1STATW&0x0010){ // wait for I2C idle + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB1IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + return 0; +} + +// ------------BSP_LightSensor_Init------------ +// Initialize a GPIO pin for input, which corresponds +// with BoosterPack pins J1.8 (Light Sensor interrupt). +// Initialize two I2C pins, which correspond with +// BoosterPack pins J1.9 (SCL) and J1.10 (SDA). +// Input: none +// Output: none +void BSP_LightSensor_Init(void){ + i2cinit(); + P4SEL0 &= ~0x40; + P4SEL1 &= ~0x40; // configure P4.6 as GPIO + P4DIR &= ~0x40; // make P4.6 in + P4REN &= ~0x40; // disable pull resistor on P4.6 +} + +// Send the appropriate codes to initiate a +// measurement with an OPT3001 light sensor at I2C +// slave address 'slaveAddress'. +// Assumes: BSP_LightSensor_Init() has been called +void static lightsensorstart(uint8_t slaveAddress){ + // configure Low Limit Register (0x02) for: + // INT pin active after each conversion completes + I2C_Send3(slaveAddress, 0x02, 0xC0, 0x00); + // configure Configuration Register (0x01) for: + // 15-12 RN range number 1100b = automatic full-scale setting mode + // 11 CT conversion time 1b = 800 ms + // 10-9 M mode of conversion 01b = single-shot + // 8 OVF overflow flag field 0b (read only) + // 7 CRF conversion ready field 0b (read only) + // 6 FH flag high field 0b (read only) + // 5 FL flag low field 0b (read only) + // 4 L latch 1b = latch interrupt if measurement exceeds programmed ranges + // 3 POL polarity 0b = INT pin reports active low + // 2 ME mask exponent 0b = do not mask exponent (more math later) + // 1-0 FC fault count 00b = 1 fault triggers interrupt + I2C_Send3(slaveAddress, 0x01, 0xCA, 0x10); + I2C_Recv2(slaveAddress); // read Configuration Register to reset conversion ready +} + +// Send the appropriate codes to end a measurement +// with an OPT3001 light sensor at I2C slave address +// 'slaveAddress'. Return results (units 100*lux). +// Assumes: BSP_LightSensor_Init() has been called and measurement is ready +int32_t static lightsensorend(uint8_t slaveAddress){ + uint16_t raw, config; + I2C_Send1(slaveAddress, 0x00); // pointer register 0x00 = Result Register + raw = I2C_Recv2(slaveAddress); + // force the INT pin to clear by clearing and resetting the latch bit of the Configuration Register (0x01) + I2C_Send1(slaveAddress, 0x01); // pointer register 0x01 = Configuration Register + config = I2C_Recv2(slaveAddress);// current Configuration Register + I2C_Send3(slaveAddress, 0x01, (config&0xFF00)>>8, (config&0x00FF)&~0x0010); + I2C_Send3(slaveAddress, 0x01, (config&0xFF00)>>8, (config&0x00FF)|0x0010); + return (1<<(raw>>12))*(raw&0x0FFF); +} + +// ------------BSP_LightSensor_Input------------ +// Query the OPT3001 light sensor for a measurement. +// Wait until the measurement is ready, which may +// take 800 ms. +// Input: none +// Output: light intensity (units 100*lux) +// Assumes: BSP_LightSensor_Init() has been called +#define LIGHTINT (*((volatile uint8_t *)(0x42000000+32*0x4C21+4*6))) /* Port 4.6 Input */ +int LightBusy = 0; // 0 = idle; 1 = measuring +uint32_t BSP_LightSensor_Input(void){ + uint32_t light; + LightBusy = 1; + lightsensorstart(0x44); + while(LIGHTINT == 0x01){}; // wait for conversion to complete + light = lightsensorend(0x44); + LightBusy = 0; + return light; +} + +// ------------BSP_LightSensor_Start------------ +// Start a measurement using the OPT3001. +// If a measurement is currently in progress, return +// immediately. +// Input: none +// Output: none +// Assumes: BSP_LightSensor_Init() has been called +void BSP_LightSensor_Start(void){ + if(LightBusy == 0){ + // no measurement is in progress, so start one + LightBusy = 1; + lightsensorstart(0x44); + } +} + +// ------------BSP_LightSensor_End------------ +// Query the OPT3001 light sensor for a measurement. +// If no measurement is currently in progress, start +// one and return zero immediately. If the measurement +// is not yet complete, return zero immediately. If +// the measurement is complete, store the result in the +// pointer provided and return one. +// Input: light is pointer to store light intensity (units 100*lux) +// Output: one if measurement is ready and pointer is valid +// zero if measurement is not ready and pointer unchanged +// Assumes: BSP_LightSensor_Init() has been called +int BSP_LightSensor_End(uint32_t *light){ + uint32_t lightLocal; + if(LightBusy == 0){ + // no measurement is in progress, so start one + LightBusy = 1; + lightsensorstart(0x44); + return 0; // measurement needs more time to complete + } else{ + // measurement is in progress + if(LIGHTINT == 0x01){ + return 0; // measurement needs more time to complete + } else{ + lightLocal = lightsensorend(0x44); + *light = lightLocal; + LightBusy = 0; + return 1; // measurement is complete; pointer valid + } + } +} + + + +using namespace std; + +namespace cadmium { + +struct LightSensorInputState { + + uint32_t output; + uint32_t last; + double sigma; + + /** + * Processor state constructor. By default, the processor is idling. + * + */ + explicit LightSensorInputState(): output(0), last(0), sigma(0){ + } + +}; + +#ifndef NO_LOGGING +/** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ +std::ostream& operator<<(std::ostream &out, const LightSensorInputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; +} +#endif + + + +class LightSensorInput : public Atomic { +public: + + Port out; + + //Parameters to be overwritten when instantiating the atomic model + double pollingRate; + + // default constructor + LightSensorInput(const std::string& id): Atomic(id, LightSensorInputState()) { + + out = addOutPort("out"); + + pollingRate = 0.8; + + // Initialize + BSP_LightSensor_Init(); + + // Get an initial reading + state.output = BSP_LightSensor_Input() / 100; // Division by 100 converts the value to lux + + state.last = state.output; + }; + + // internal transition + void internalTransition(LightSensorInputState& state) const override { + state.last = state.output; + + // Read pin + state.output = BSP_LightSensor_Input() / 100; // Division by 100 converts the value to lux + + state.sigma = pollingRate; + } + + // external transition + void externalTransition(LightSensorInputState& state, double e) const override { + throw CadmiumSimulationException("External transition called in a model with no input ports"); + } + + // output function + void output(const LightSensorInputState& state) const override { + if(state.last != state.output) { + out->addMessage((int)state.output); + } + } + + // time_advance function + [[nodiscard]] double timeAdvance(const LightSensorInputState& state) const override { + return state.sigma; + } +}; +} + +#endif // RT_LIGHTSENSORINPUT_HPP diff --git a/example/rt_msp432/IO_Models/microphoneInput.hpp b/example/rt_msp432/IO_Models/microphoneInput.hpp new file mode 100644 index 0000000..4c87b2d --- /dev/null +++ b/example/rt_msp432/IO_Models/microphoneInput.hpp @@ -0,0 +1,170 @@ +/** + * James Grieder & Srijan Gupta + * ARSLab - Carleton University + * + * A DEVS model for the Microphone on the Educational Boosterpack MK II + * when used with an MSP432P401R board. + * + * The microphone is polled every 0.1 seconds, and will output the reading + * as an integer value between 0 and 1023. + */ + +#ifndef RT_MICROPHONEINPUT_HPP +#define RT_MICROPHONEINPUT_HPP + +//***************************************************************************** +// ADC14 Registers +//***************************************************************************** +/* ADC Control Registers */ +#define ADC14CTL0 (HWREG32(0x40012000)) +#define ADC14CTL1 (HWREG32(0x40012004)) +/* ADC Conversion Memory Control Registers */ +#define ADC14MCTL5 (HWREG32(0x4001202C)) +/* ADC Conversion Memory Registers */ +#define ADC14MEM5 (HWREG32(0x400120AC)) +/* Interrupt Enable Registers */ +#define ADC14IER0 (HWREG32(0x4001213C)) +#define ADC14IER1 (HWREG32(0x40012140)) +/* Interrupt Flag Registers */ +#define ADC14IFGR0 (HWREG32(0x40012144)) + +#include "modeling/devs/atomic.hpp" +#include + +#include + +#ifdef RT_ARM_MBED +#endif + + +#ifndef NO_LOGGING +#include +#include +#include +#endif + + +// ------------BSP_Microphone_Input------------ +// Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu +// Read and return the immediate status of the +// microphone. The sound measurement is returned +// as a 10-bit number, even if the ADC on the +// LaunchPad is more precise. +// Input: mic is pointer to store sound measurement (0 to 1023) +// Output: none +// Assumes: BSP_Microphone_Init() has been called +void BSP_Microphone_Input(uint16_t *mic){ + ADC14CTL0 &= ~0x00000002; // 1) ADC14ENC = 0 to allow programming + while(ADC14CTL0&0x00010000){}; // 2) wait for BUSY to be zero + ADC14CTL1 = (ADC14CTL1&~0x001F0000) | // clear STARTADDx bit field + (5 << 16); // 3) configure for STARTADDx = 5 + ADC14CTL0 |= 0x00000002; // 4) enable conversions + while(ADC14CTL0&0x00010000){}; // 5) wait for BUSY to be zero + ADC14CTL0 |= 0x00000001; // 6) start single conversion + while((ADC14IFGR0&0x20) == 0){}; // 7) wait for ADC14IFG5 + *mic = ADC14MEM5>>4; // 8) P4.3/A10 result 0 to 1023 +} + + + +using namespace std; + +namespace cadmium { + +struct MicrophoneInputState { + + uint16_t output; + uint16_t last; + double sigma; + + /** + * Processor state constructor. By default, the processor is idling. + * + */ + explicit MicrophoneInputState(): output(0), last(0), sigma(0){ + } + +}; + +#ifndef NO_LOGGING +/** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ +std::ostream& operator<<(std::ostream &out, const MicrophoneInputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; +} +#endif + +class MicrophoneInput : public Atomic { +public: + + Port out; + + //Parameters to be overwritten when instantiating the atomic model + double pollingRate; + + // default constructor + MicrophoneInput(const std::string& id): Atomic(id, MicrophoneInputState()) { + + out = addOutPort("out"); + + pollingRate = 0.3; + + // Initialize ADC + // Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu + ADC14CTL0 &= ~0x00000002; // 2) ADC14ENC = 0 to allow programming + while(ADC14CTL0&0x00010000){}; // 3) wait for BUSY to be zero + ADC14CTL0 = 0x04223390; // 4) single, SMCLK, on, disabled, /1, 32 SHM + ADC14CTL1 = 0x00000030; // 5) ADC14MEM0, 14-bit, ref on, regular power + // 6) different for each initialization function + ADC14IER0 = 0; + ADC14IER1 = 0; // 7) no interrupts + + // Initialize Microphone Pin + // Copyright 2016 by Jonathan W. Valvano, valvano@mail.utexas.edu + ADC14MCTL5 = 0x0000008A; // 6) 0 to 3.3V, channel 10 + P4SEL0 |= 0x08; + P4SEL1 |= 0x08; // 8) analog mode on P4.3/A10 + ADC14CTL0 |= 0x00000002; // 9) enable + + + // Get an initial reading + BSP_Microphone_Input(&state.output); + + state.last = state.output; + }; + + // internal transition + void internalTransition(MicrophoneInputState& state) const override { + state.last = state.output; + + // Read pin + BSP_Microphone_Input(&state.output); + + state.sigma = pollingRate; + } + + // external transition + void externalTransition(MicrophoneInputState& state, double e) const override { + throw CadmiumSimulationException("External transition called in a model with no input ports"); + } + + // output function + void output(const MicrophoneInputState& state) const override { + if(state.last != state.output) { + out->addMessage((int)state.output); + } + } + + // time_advance function + [[nodiscard]] double timeAdvance(const MicrophoneInputState& state) const override { + return state.sigma; + } +}; +} + +#endif // RT_MICROPHONEINPUT_HPP diff --git a/example/rt_msp432/IO_Models/pwmOutput.hpp b/example/rt_msp432/IO_Models/pwmOutput.hpp new file mode 100644 index 0000000..9117770 --- /dev/null +++ b/example/rt_msp432/IO_Models/pwmOutput.hpp @@ -0,0 +1,192 @@ +/** + * James Grieder & Srijan Gupta + * ARSLab - Carleton University + * + * A DEVS model for pulse-width modulation outputs (pwm) on the Educational + * Boosterpack MK II when used with an MSP432P401R board. This model can be + * used for the individual RGB LEDs, and the buzzer output. + * + * Upon receiving an integer value in the external transition function, the duty + * cycle of the associated pwm output pin is updated. The duty cycle must be + * between 0 and 1023, inclusively. + */ + +#ifndef __MSP_PWMOUTPUT_HPP__ +#define __MSP_PWMOUTPUT_HPP__ + +#include "modeling/devs/atomic.hpp" +#include +#include +#include + +#ifndef NO_LOGGING + #include + #include + #include +#endif + +using namespace std; + +namespace cadmium { + +struct PWMOutputState { + int output; + double sigma; + + /** + * Processor state constructor. By default, the processor is idling. + */ + explicit PWMOutputState(): output(0), sigma(0){ + } + +}; + +#ifndef NO_LOGGING +/** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ + +std::ostream& operator<<(std::ostream &out, const PWMOutputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; +} +#endif + +class PWMOutput : public Atomic { +public: + + Port in; + //Parameters to be overwritten when instantiating the atomic model + uint_fast8_t port; + uint_fast16_t pin; + + + + // default constructor + PWMOutput(const std::string& id, uint_fast8_t selectedPort,uint_fast16_t selectedPin): Atomic(id, PWMOutputState()) { + in = addInPort("in"); + port = selectedPort; + pin = selectedPin; + + uint16_t initialDutyCycle = 0; + + // Constants for PWM calculations + uint32_t SubsystemFrequency = 3000000; // 3MHz + uint16_t PWMCycles = SubsystemFrequency/2048; + + if (port == GPIO_PORT_P2) { + // Configure Timer0 for PWM + TA0CTL &= ~0x0030; // halt Timer + TA0CTL = 0x0200; // set clock source to SMCLK + + // Pin specific configs + if (pin == GPIO_PIN4) { // RGB Green + TA0CCTL1 = 0x00E0; // OUTMOD = reset/set + TA0CCR1 = (initialDutyCycle*PWMCycles)>>10; // defines when output signal is cleared + + } else if (pin == GPIO_PIN6) { // RGB Red + TA0CCTL3 = 0x00E0; // OUTMOD = reset/set + TA0CCR3 = (initialDutyCycle*PWMCycles)>>10; // defines when output signal is cleared + + } else if (pin == GPIO_PIN7) { // Buzzer + TA0CCTL4 = 0x00E0; // OUTMOD = reset/set + TA0CCR4 = (initialDutyCycle*PWMCycles)>>10; // defines when output signal is cleared + + } else { + throw CadmiumSimulationException("incorrect port/pin combination for pwmOutput"); + } + + // Configure Timer0 for PWM + TA0CCR0 = PWMCycles - 1; // defines when output signal is set + TA0EX0 &= ~0x0007; // configure for input clock divider /1 + TA0CTL |= 0x0014; // reset and start Timer A0 in up mode + + // Pin specific configs + P2SEL0 |= pin; + P2SEL1 &= ~pin; // configure P2.4 as timer out + P2DIR |= pin; // make P2.4 out + + + } else if (port == GPIO_PORT_P5) { + + if (pin == GPIO_PIN6) { + // Configure TimerA2 for PWM + TA2CTL &= ~0x0030; // halt Timer + TA2CTL = 0x0200; // set clock source to SMCLK + TA2CCTL1 = 0x00E0; // OUTMOD = reset/set + TA2CCR1 = (initialDutyCycle*1464)>>10; // defines when output signal is cleared + TA2CCR0 = PWMCycles - 1; // defines when output signal is set + TA2EX0 &= ~0x0007; // configure for input clock divider /1 + TA2CTL |= 0x0014; // start timer in UP mode + + // Pin specific configs + P5SEL0 |= pin; + P5SEL1 &= ~pin; // configure P5.6 as timer out + P5DIR |= pin; // make P5.6 out + } else { + throw CadmiumSimulationException("incorrect port/pin combination for pwmOutput"); + } + + } else { + throw CadmiumSimulationException("incorrect port/pin combination for pwmOutput"); + } + + }; + + // internal transition + void internalTransition(PWMOutputState& state) const override { + } + + // external transition + void externalTransition(PWMOutputState& state, double e) const override { + if(!in->empty()){ + for( const auto x : in->getBag()){ + state.output = x; + + if (x < 0) { + state.output = 0; + } else if (x > 1023) { + state.output = 1023; + } else { + state.output = x; + } + } + + if (port == GPIO_PORT_P2) { + if (pin == GPIO_PIN4) { // RGB Green + TA0CCR1 = ((uint16_t)(state.output*1464)>>10); + + } else if (pin == GPIO_PIN6) { // RGB Red + TA0CCR3 = ((uint16_t)(state.output*1464)>>10); + + } else if (pin == GPIO_PIN7) { // Buzzer + TA0CCR4 = ((uint16_t)(state.output*1464)>>10); + + } + + } else if (port == GPIO_PORT_P5) { + if (pin == GPIO_PIN6) { + TA2CCR1 = ((uint16_t)(state.output*1464)>>10); + + } + } + } + } + + + // output function + void output(const PWMOutputState& state) const override { + }; + + // time_advance function + [[nodiscard]] double timeAdvance(const PWMOutputState& state) const override { + return std::numeric_limits::infinity(); + } + +}; +} + +#endif // __MSP_PWMOUTPUT_HPP__ diff --git a/example/rt_msp432/IO_Models/temperatureSensorInput.hpp b/example/rt_msp432/IO_Models/temperatureSensorInput.hpp new file mode 100644 index 0000000..c0919e5 --- /dev/null +++ b/example/rt_msp432/IO_Models/temperatureSensorInput.hpp @@ -0,0 +1,385 @@ +/** + * James Grieder & Srijan Gupta + * ARSLab - Carleton University + * + * A DEVS model for the Temperature Sensor on the Educational Boosterpack MK II + * when used with an MSP432P401R board. + * + * The temperature sensor is polled every 4.0 seconds (based on the duration of + * a single reading), and will output the reading as an integer value + * measured in units of degrees Celsius, multiplied by a factor of 100,000. + */ + +#ifndef RT_TEMPERATURESENSORINPUT_HPP +#define RT_TEMPERATURESENSORINPUT_HPP + +#include "modeling/devs/atomic.hpp" +#include + +#include + + +#ifndef NO_LOGGING + #include + #include + #include +#endif + + + + +using namespace std; + +namespace cadmium { + +struct TemperatureSensorInputState { + + int32_t output; + int32_t last; + int32_t sensorV; + double sigma; + + /** + * Processor state constructor. By default, the processor is idling. + * + */ + explicit TemperatureSensorInputState(): output(0), last(0), sensorV(0), sigma(0){ + } + +}; + +#ifndef NO_LOGGING +/** + * Insertion operator for ProcessorState objects. It only displays the value of sigma. + * @param out output stream. + * @param s state to be represented in the output stream. + * @return output stream with sigma already inserted. + */ +std::ostream& operator<<(std::ostream &out, const TemperatureSensorInputState& state) { + out << "Pin: " << (state.output ? 1 : 0); + return out; +} +#endif + + + + +// There are two I2C devices on the Educational BoosterPack MKII: +// OPT3001 Light Sensor +// TMP006 Temperature sensor +// Both initialization functions can use this general I2C +// initialization. +void static i2cinit(void){ + // initialize eUSCI + UCB1CTLW0 = 0x0001; // hold the eUSCI module in reset mode + // configure UCB1CTLW0 for: + // bit15 UCA10 = 0; own address is 7-bit address + // bit14 UCSLA10 = 0; address slave with 7-bit address + // bit13 UCMM = 0; single master environment + // bit12 reserved + // bit11 UCMST = 1; master mode + // bits10-9 UCMODEx = 3; I2C mode + // bit8 UCSYNC = 1; synchronous mode + // bits7-6 UCSSELx = 2; eUSCI clock SMCLK + // bit5 UCTXACK = X; transmit ACK condition in slave mode + // bit4 UCTR = X; transmitter/receiver + // bit3 UCTXNACK = X; transmit negative acknowledge in slave mode + // bit2 UCTXSTP = X; transmit stop condition in master mode + // bit1 UCTXSTT = X; transmit start condition in master mode + // bit0 UCSWRST = 1; reset enabled + UCB1CTLW0 = 0x0F81; + // configure UCB1CTLW1 for: + // bits15-9 reserved + // bit8 UCETXINT = X; early UCTXIFG0 in slave mode + // bits7-6 UCCLTO = 3; timeout clock low after 165,000 SYSCLK cycles + // bit5 UCSTPNACK = 0; send negative acknowledge before stop condition in master receiver mode + // bit4 UCSWACK = 0; slave address acknowledge controlled by hardware + // bits3-2 UCASTPx = 2; generate stop condition automatically after UCB0TBCNT bytes + // bits1-0 UCGLITx = 0 deglitch time of 50 ns + UCB1CTLW1 = 0x00C8; + UCB1TBCNT = 2; // generate stop condition after this many bytes + // set the baud rate for the eUSCI which gets its clock from SMCLK + // Clock_Init48MHz() from ClockSystem.c sets SMCLK = HFXTCLK/4 = 12 MHz + // if the SMCLK is set to 12 MHz, divide by 120 for 100 kHz baud clock + UCB1BRW = 120; + P6SEL0 |= 0x30; + P6SEL1 &= ~0x30; // configure P6.5 and P6.4 as primary module function + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1IE = 0x0000; // disable interrupts +} + +// receives two bytes from specified slave +// Note for HMC6352 compass only: +// Used with 'A' commands +// Note for TMP102 thermometer only: +// Used to read the contents of the pointer register +uint16_t static I2C_Recv2(int8_t slave){ + uint8_t data1, data2; + while(UCB1STATW&0x0010){}; // wait for I2C ready + UCB1CTLW0 |= 0x0001; // hold the eUSCI module in reset mode + UCB1TBCNT = 2; // generate stop condition after this many bytes + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1I2CSA = slave; // I2CCSA[6:0] is slave address + UCB1CTLW0 = ((UCB1CTLW0&~0x0014) // clear bit4 (UCTR) for receive mode + // clear bit2 (UCTXSTP) for no transmit stop condition + | 0x0002); // set bit1 (UCTXSTT) for transmit start condition + while((UCB1IFG&0x0001) == 0){ // wait for complete character received + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + i2cinit(); // reset to known state + return 0xFFFF; + } + } + data1 = UCB1RXBUF&0xFF; // get the reply + while((UCB1IFG&0x0001) == 0){ // wait for complete character received + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + i2cinit(); // reset to known state + return 0xFFFF; + } + } + data2 = UCB1RXBUF&0xFF; // get the reply + return (data1<<8)+data2; +} + +// sends one byte to specified slave +// Note for HMC6352 compass only: +// Used with 'S', 'W', 'O', 'C', 'E', 'L', and 'A' commands +// For 'A' commands, I2C_Recv2() should also be called +// Note for TMP102 thermometer only: +// Used to change the pointer register +// Returns 0 if successful, nonzero if error +uint16_t static I2C_Send1(int8_t slave, uint8_t data1){ + uint16_t debugdump; // save status register here in case of error + while(UCB1STATW&0x0010){}; // wait for I2C ready + UCB1CTLW0 |= 0x0001; // hold the eUSCI module in reset mode + UCB1TBCNT = 1; // generate stop condition after this many bytes + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1I2CSA = slave; // I2CCSA[6:0] is slave address + UCB1CTLW0 = ((UCB1CTLW0&~0x0004) // clear bit2 (UCTXSTP) for no transmit stop condition + // set bit1 (UCTXSTT) for transmit start condition + | 0x0012); // set bit4 (UCTR) for transmit mode + while(UCB1CTLW0&0x0002){}; // wait for slave address sent + UCB1TXBUF = data1&0xFF; // TXBUF[7:0] is data + while(UCB1STATW&0x0010){ // wait for I2C idle + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB1IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + return 0; +} + +// sends three bytes to specified slave +// Note for HMC6352 compass only: +// Used with 'w' and 'G' commands +// Note for TMP102 thermometer only: +// Used to change the contents of the pointer register +// Returns 0 if successful, nonzero if error +uint16_t static I2C_Send3(int8_t slave, uint8_t data1, uint8_t data2, uint8_t data3){ + uint16_t debugdump; // save status register here in case of error + while(UCB1STATW&0x0010){}; // wait for I2C ready + UCB1CTLW0 |= 0x0001; // hold the eUSCI module in reset mode + UCB1TBCNT = 3; // generate stop condition after this many bytes + UCB1CTLW0 &= ~0x0001; // enable eUSCI module + UCB1I2CSA = slave; // I2CCSA[6:0] is slave address + UCB1CTLW0 = ((UCB1CTLW0&~0x0004) // clear bit2 (UCTXSTP) for no transmit stop condition + // set bit1 (UCTXSTT) for transmit start condition + | 0x0012); // set bit4 (UCTR) for transmit mode + while((UCB1IFG&0x0002) == 0){}; // wait for slave address sent + UCB1TXBUF = data1&0xFF; // TXBUF[7:0] is data + while((UCB1IFG&0x0002) == 0){ // wait for first data sent + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB0IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + UCB1TXBUF = data2&0xFF; // TXBUF[7:0] is data + while((UCB1IFG&0x0002) == 0){ // wait for second data sent + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB1IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + UCB1TXBUF = data3&0xFF; // TXBUF[7:0] is data + while(UCB1STATW&0x0010){ // wait for I2C idle + if(UCB1IFG&0x0030){ // bit5 set on not-acknowledge; bit4 set on arbitration lost + debugdump = UCB1IFG; // snapshot flag register for calling program + i2cinit(); // reset to known state + return debugdump; + } + } + return 0; +} + +// ------------BSP_TempSensor_Init------------ +// Initialize a GPIO pin for input, which corresponds +// with BoosterPack pins J2.11 (Temperature Sensor +// interrupt). Initialize two I2C pins, which +// correspond with BoosterPack pins J1.9 (SCL) and +// J1.10 (SDA). +// Input: none +// Output: none +void BSP_TempSensor_Init(void){ + i2cinit(); + P3SEL0 &= ~0x40; + P3SEL1 &= ~0x40; // configure P3.6 as GPIO + P3DIR &= ~0x40; // make P3.6 in + P3REN &= ~0x40; // disable pull resistor on P3.6 +} + +// Send the appropriate codes to initiate a +// measurement with a TMP006 temperature sensor at +// I2C slave address 'slaveAddress'. +// Assumes: BSP_TempSensor_Init() has been called +void static tempsensorstart(uint8_t slaveAddress){ + // configure Configuration Register (0x02) for: + // 15 RST software reset bit 0b = normal operation + // 14-12 MOD mode of operation 111b = sensor and die continuous conversion + // 11-9 CR ADC conversion rate 010b = 1 sample/sec + // 8 EN interrupt pin enable 1b = ~DRDY pin enabled (J2.11/P3.6) + // 7 ~DRDY data ready bit 0b (read only, automatic clear) + // 6-0 reserved 000000b (reserved) + I2C_Send3(slaveAddress, 0x02, 0x75, 0x00); +} + +// Send the appropriate codes to end a measurement +// with a TMP006 temperature sensor at I2C slave +// address 'slaveAddress'. Store the results at the +// provided pointers. +// Assumes: BSP_TempSensor_Init() has been called and measurement is ready +void static tempsensorend(uint8_t slaveAddress, int32_t *sensorV, int32_t *localT){ + int16_t raw; + I2C_Send1(slaveAddress, 0x00); // pointer register 0x00 = Sensor Voltage Register + raw = I2C_Recv2(slaveAddress); + *sensorV = raw*15625; // 156.25 nV per LSB + I2C_Send1(slaveAddress, 0x01); // pointer register 0x01 = Local Temperature Register + raw = I2C_Recv2(slaveAddress); + *localT = (raw>>2)*3125; // 0.03125 C per LSB +} + +// ------------BSP_TempSensor_Input------------ +// Query the TMP006 temperature sensor for a +// measurement. Wait until the measurement is ready, +// which may take 4 seconds. +// Input: sensorV is signed pointer to store sensor voltage (units 100*nV) +// localT is signed pointer to store local temperature (units 100,000*C) +// Output: none +// Assumes: BSP_TempSensor_Init() has been called +#define TEMPINT (*((volatile uint8_t *)(0x42000000+32*0x4C20+4*6))) /* Port 3.6 Input */ +int TempBusy = 0; // 0 = idle; 1 = measuring +void BSP_TempSensor_Input(int32_t *sensorV, int32_t *localT){ + int32_t volt, temp; + TempBusy = 1; + tempsensorstart(0x40); + while(TEMPINT == 0x01){}; // wait for conversion to complete + tempsensorend(0x40, &volt, &temp); + *sensorV = volt; + *localT = temp; + TempBusy = 0; +} + +// ------------BSP_TempSensor_Start------------ +// Start a measurement using the TMP006. +// If a measurement is currently in progress, return +// immediately. +// Input: none +// Output: none +// Assumes: BSP_TempSensor_Init() has been called +void BSP_TempSensor_Start(void){ + if(TempBusy == 0){ + // no measurement is in progress, so start one + TempBusy = 1; + tempsensorstart(0x40); + } +} + +// ------------BSP_TempSensor_End------------ +// Query the TMP006 temperature sensor for a +// measurement. If no measurement is currently in +// progress, start one and return zero immediately. +// If the measurement is not yet complete, return +// zero immediately. If the measurement is complete, +// store the result in the pointers provided and +// return one. +// Input: sensorV is signed pointer to store sensor voltage (units 100*nV) +// localT is signed pointer to store local temperature (units 100,000*C) +// Output: one if measurement is ready and pointers are valid +// zero if measurement is not ready and pointers unchanged +// Assumes: BSP_TempSensor_Init() has been called +int BSP_TempSensor_End(int32_t *sensorV, int32_t *localT){ + int32_t volt, temp; + if(TempBusy == 0){ + // no measurement is in progress, so start one + TempBusy = 1; + tempsensorstart(0x40); + return 0; // measurement needs more time to complete + } else{ + // measurement is in progress + if(TEMPINT == 0x01){ + return 0; // measurement needs more time to complete + } else{ + tempsensorend(0x40, &volt, &temp); + *sensorV = volt; + *localT = temp; + TempBusy = 0; + return 1; // measurement is complete; pointers valid + } + } +} + + + +class TemperatureSensorInput : public Atomic { +public: + + Port out; + + //Parameters to be overwritten when instantiating the atomic model + double pollingRate; + + // default constructor + TemperatureSensorInput(const std::string& id): Atomic(id, TemperatureSensorInputState()) { + + out = addOutPort("out"); + + pollingRate = 4.0; + + // Initialize + BSP_TempSensor_Init(); + + // Get an initial reading + BSP_TempSensor_Input(&state.sensorV, &state.output); + + state.last = state.output; + }; + + // internal transition + void internalTransition(TemperatureSensorInputState& state) const override { + state.last = state.output; + + // Read pin + BSP_TempSensor_Input(&state.sensorV, &state.output); + + state.sigma = pollingRate; + } + + // external transition + void externalTransition(TemperatureSensorInputState& state, double e) const override { + throw CadmiumSimulationException("External transition called in a model with no input ports"); + } + + // output function + void output(const TemperatureSensorInputState& state) const override { + out->addMessage((double)state.output); + } + + // time_advance function + [[nodiscard]] double timeAdvance(const TemperatureSensorInputState& state) const override { + return state.sigma; + } +}; +} + +#endif // RT_TEMPERATURESENSORINPUT_HPP diff --git a/example/rt_msp432/MSP432P4xx/adc14.c b/example/rt_msp432/MSP432P4xx/adc14.c new file mode 100644 index 0000000..3f72051 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/adc14.c @@ -0,0 +1,755 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include +#include + +/* DriverLib Includes */ +#include +#include +#include + +/* Statics */ +static volatile uint32_t* const _ctlRegs[32] = +{ &ADC14->MCTL[0], &ADC14->MCTL[1], &ADC14->MCTL[2], &ADC14->MCTL[3], + &ADC14->MCTL[4], &ADC14->MCTL[5], &ADC14->MCTL[6], &ADC14->MCTL[7], + &ADC14->MCTL[8], &ADC14->MCTL[9], &ADC14->MCTL[10], + &ADC14->MCTL[11], &ADC14->MCTL[12], &ADC14->MCTL[13], + &ADC14->MCTL[14], &ADC14->MCTL[15], &ADC14->MCTL[16], + &ADC14->MCTL[17], &ADC14->MCTL[18], &ADC14->MCTL[19], + &ADC14->MCTL[20], &ADC14->MCTL[21], &ADC14->MCTL[22], + &ADC14->MCTL[23], &ADC14->MCTL[24], &ADC14->MCTL[25], + &ADC14->MCTL[26], &ADC14->MCTL[27], &ADC14->MCTL[28], + &ADC14->MCTL[29], &ADC14->MCTL[30], &ADC14->MCTL[31] }; + +static uint_fast8_t _getIndexForMemRegister(uint32_t reg) +{ + switch (reg) + { + case ADC_MEM0: + return 0; + case ADC_MEM1: + return 1; + case ADC_MEM2: + return 2; + case ADC_MEM3: + return 3; + case ADC_MEM4: + return 4; + case ADC_MEM5: + return 5; + case ADC_MEM6: + return 6; + case ADC_MEM7: + return 7; + case ADC_MEM8: + return 8; + case ADC_MEM9: + return 9; + case ADC_MEM10: + return 10; + case ADC_MEM11: + return 11; + case ADC_MEM12: + return 12; + case ADC_MEM13: + return 13; + case ADC_MEM14: + return 14; + case ADC_MEM15: + return 15; + case ADC_MEM16: + return 16; + case ADC_MEM17: + return 17; + case ADC_MEM18: + return 18; + case ADC_MEM19: + return 19; + case ADC_MEM20: + return 20; + case ADC_MEM21: + return 21; + case ADC_MEM22: + return 22; + case ADC_MEM23: + return 23; + case ADC_MEM24: + return 24; + case ADC_MEM25: + return 25; + case ADC_MEM26: + return 26; + case ADC_MEM27: + return 27; + case ADC_MEM28: + return 28; + case ADC_MEM29: + return 29; + case ADC_MEM30: + return 30; + case ADC_MEM31: + return 31; + default: + ASSERT(false); + return ADC_INVALID_MEM; + + } +} + +//***************************************************************************** +// +//! +//! Returns a boolean value that tells if conversion is active/running or is +//! not acMSP432 ted. +//! +//! Originally a public function, but moved to static. External customers should +//! use the ADC14_isBusy function. +//! +//! \return true if conversion is active, false otherwise +// +//***************************************************************************** +static bool ADCIsConversionRunning(void) +{ + return BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_BUSY_OFS); +} + +void ADC14_enableModule(void) +{ + BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_ON_OFS) = 1; +} + +bool ADC14_disableModule(void) +{ + if (ADCIsConversionRunning()) + return false; + + BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_ON_OFS) = 0; + + return true; +} + +bool ADC14_enableSampleTimer(uint32_t multiSampleConvert) +{ + if (ADCIsConversionRunning()) + return false; + + BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_SHP_OFS) = 1; + + if (multiSampleConvert == ADC_MANUAL_ITERATION) + { + BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_MSC_OFS) = 0; + } else + { + BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_MSC_OFS) = 1; + } + + return true; +} + +bool ADC14_disableSampleTimer(void) +{ + if (ADCIsConversionRunning()) + return false; + + BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_SHP_OFS) = 0; + + return true; +} + +bool ADC14_initModule(uint32_t clockSource, uint32_t clockPredivider, + uint32_t clockDivider, uint32_t internalChannelMask) +{ + ASSERT( + clockSource == ADC_CLOCKSOURCE_ADCOSC + || clockSource == ADC_CLOCKSOURCE_SYSOSC + || clockSource == ADC_CLOCKSOURCE_ACLK + || clockSource == ADC_CLOCKSOURCE_MCLK + || clockSource == ADC_CLOCKSOURCE_SMCLK + || clockSource == ADC_CLOCKSOURCE_HSMCLK); + + ASSERT( + clockPredivider == ADC_PREDIVIDER_1 + || clockPredivider == ADC_PREDIVIDER_4 + || clockPredivider == ADC_PREDIVIDER_32 + || clockPredivider == ADC_PREDIVIDER_64); + + ASSERT( + clockDivider == ADC_DIVIDER_1 || clockDivider == ADC_DIVIDER_2 + || clockDivider == ADC_DIVIDER_3 + || clockDivider == ADC_DIVIDER_4 + || clockDivider == ADC_DIVIDER_5 + || clockDivider == ADC_DIVIDER_6 + || clockDivider == ADC_DIVIDER_7 + || clockDivider == ADC_DIVIDER_8); + + ASSERT( + !(internalChannelMask + & ~(ADC_MAPINTCH3 | ADC_MAPINTCH2 | ADC_MAPINTCH1 + | ADC_MAPINTCH0 | ADC_TEMPSENSEMAP | ADC_BATTMAP))); + + if (ADCIsConversionRunning()) + return false; + + ADC14->CTL0 = (ADC14->CTL0 + & ~(ADC14_CTL0_PDIV_MASK | ADC14_CTL0_DIV_MASK | ADC14_CTL0_SSEL_MASK)) + | clockDivider | clockPredivider | clockSource; + + ADC14->CTL1 = (ADC14->CTL1 + & ~(ADC_MAPINTCH3 | ADC_MAPINTCH2 | ADC_MAPINTCH1 | ADC_MAPINTCH0 + | ADC_TEMPSENSEMAP | ADC_BATTMAP)) | internalChannelMask; + + return true; +} + +void ADC14_setResolution(uint32_t resolution) +{ + ASSERT( + resolution == ADC_8BIT || resolution == ADC_10BIT + || resolution == ADC_12BIT || resolution == ADC_14BIT); + + ADC14->CTL1 = (ADC14->CTL1 & ~ADC14_CTL1_RES_MASK) | resolution; +} + +uint_fast32_t ADC14_getResolution(void) +{ + return ADC14->CTL1 & ADC14_CTL1_RES_MASK; +} + +bool ADC14_setSampleHoldTrigger(uint32_t source, bool invertSignal) +{ + + ASSERT( + source == ADC_TRIGGER_ADCSC || source == ADC_TRIGGER_SOURCE1 + || source == ADC_TRIGGER_SOURCE2 + || source == ADC_TRIGGER_SOURCE3 + || source == ADC_TRIGGER_SOURCE4 + || source == ADC_TRIGGER_SOURCE5 + || source == ADC_TRIGGER_SOURCE6 + || source == ADC_TRIGGER_SOURCE7); + + if (ADCIsConversionRunning()) + return false; + + if (invertSignal) + { + ADC14->CTL0 = (ADC14->CTL0 + & ~(ADC14_CTL0_ISSH | ADC14_CTL0_SHS_MASK)) | source + | ADC14_CTL0_ISSH; + } else + { + ADC14->CTL0 = (ADC14->CTL0 + & ~(ADC14_CTL0_ISSH | ADC14_CTL0_SHS_MASK)) | source; + } + + return true; +} + +bool ADC14_setSampleHoldTime(uint32_t firstPulseWidth, + uint32_t secondPulseWidth) +{ + ASSERT( + firstPulseWidth == ADC_PULSE_WIDTH_4 + || firstPulseWidth == ADC_PULSE_WIDTH_8 + || firstPulseWidth == ADC_PULSE_WIDTH_16 + || firstPulseWidth == ADC_PULSE_WIDTH_32 + || firstPulseWidth == ADC_PULSE_WIDTH_64 + || firstPulseWidth == ADC_PULSE_WIDTH_96 + || firstPulseWidth == ADC_PULSE_WIDTH_128 + || firstPulseWidth == ADC_PULSE_WIDTH_192); + + ASSERT( + secondPulseWidth == ADC_PULSE_WIDTH_4 + || secondPulseWidth == ADC_PULSE_WIDTH_8 + || secondPulseWidth == ADC_PULSE_WIDTH_16 + || secondPulseWidth == ADC_PULSE_WIDTH_32 + || secondPulseWidth == ADC_PULSE_WIDTH_64 + || secondPulseWidth == ADC_PULSE_WIDTH_96 + || secondPulseWidth == ADC_PULSE_WIDTH_128 + || secondPulseWidth == ADC_PULSE_WIDTH_192); + + if (ADCIsConversionRunning()) + return false; + + ADC14->CTL0 = (ADC14->CTL0 + & ~(ADC14_CTL0_SHT0_MASK | ADC14_CTL0_SHT1_MASK)) | secondPulseWidth + | (firstPulseWidth >> 4); + + return true; +} + +bool ADC14_configureMultiSequenceMode(uint32_t memoryStart, uint32_t memoryEnd, +bool repeatMode) +{ + uint32_t ii; + + ASSERT( + _getIndexForMemRegister(memoryStart) != ADC_INVALID_MEM + && _getIndexForMemRegister(memoryEnd) != ADC_INVALID_MEM); + + if (ADCIsConversionRunning()) + return false; + + /* Clearing out any lingering EOS */ + for (ii = 0; ii < 32; ii++) + { + BITBAND_PERI(*(_ctlRegs[ii]), ADC14_MCTLN_EOS_OFS) = 0; + } + + /* Setting Start/Stop locations */ + BITBAND_PERI( + (*(_ctlRegs[_getIndexForMemRegister(memoryEnd)])), + ADC14_MCTLN_EOS_OFS) = 1; + + ADC14->CTL1 = (ADC14->CTL1 & ~(ADC14_CTL1_CSTARTADD_MASK)) + | (_getIndexForMemRegister(memoryStart) << 16); + + /* Setting multiple sample mode */ + if (!repeatMode) + { + ADC14->CTL0 = (ADC14->CTL0 & ~(ADC14_CTL0_CONSEQ_MASK)) + | (ADC14_CTL0_CONSEQ_1); + } else + { + ADC14->CTL0 = (ADC14->CTL0 & ~(ADC14_CTL0_CONSEQ_MASK)) + | (ADC14_CTL0_CONSEQ_3); + } + + return true; +} + +bool ADC14_configureSingleSampleMode(uint32_t memoryDestination, +bool repeatMode) +{ + ASSERT(_getIndexForMemRegister(memoryDestination) != 32); + + if (ADCIsConversionRunning()) + return false; + + /* Setting the destination register */ + ADC14->CTL1 = (ADC14->CTL1 & ~(ADC14_CTL1_CSTARTADD_MASK)) + | (_getIndexForMemRegister(memoryDestination) << 16); + + /* Setting single sample mode */ + if (!repeatMode) + { + ADC14->CTL0 = (ADC14->CTL0 & ~(ADC14_CTL0_CONSEQ_MASK)) + | (ADC14_CTL0_CONSEQ_0); + } else + { + ADC14->CTL0 = (ADC14->CTL0 & ~(ADC14_CTL0_CONSEQ_MASK)) + | (ADC14_CTL0_CONSEQ_2); + } + + return true; +} + +bool ADC14_enableConversion(void) +{ + if (ADCIsConversionRunning() || !BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_ON_OFS)) + return false; + + ADC14->CTL0 |= (ADC14_CTL0_ENC); + + return true; +} + +bool ADC14_toggleConversionTrigger(void) +{ + if (!BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_ON_OFS)) + return false; + + if (BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_SC_OFS)) + { + BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_SC_OFS) = 0; + } else + { + BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_SC_OFS) = 1; + } + + return true; +} + +void ADC14_disableConversion(void) +{ + ADC14->CTL0 &= ~(ADC14_CTL0_SC | ADC14_CTL0_ENC); +} + +bool ADC14_isBusy(void) +{ + return BITBAND_PERI(ADC14->CTL0, ADC14_CTL0_BUSY_OFS); +} + +bool ADC14_configureConversionMemory(uint32_t memorySelect, uint32_t refSelect, + uint32_t channelSelect, bool differntialMode) +{ + uint32_t currentReg, ii; + uint32_t *curReg; + + /* Initialization */ + ii = 1; + currentReg = 0x01; + + if (ADCIsConversionRunning()) + return false; + + while (memorySelect != 0) + { + if (!(memorySelect & ii)) + { + ii = ii << 1; + continue; + } + + currentReg = memorySelect & ii; + memorySelect &= ~ii; + ii = ii << 1; + + curReg = (uint32_t*) _ctlRegs[_getIndexForMemRegister(currentReg)]; + + if (differntialMode) + { + (*curReg) = ((*curReg) + & ~(ADC14_MCTLN_VRSEL_MASK | ADC14_MCTLN_INCH_MASK + | ADC14_MCTLN_DIF)) + | (channelSelect | refSelect | ADC14_MCTLN_DIF); + } else + { + (*curReg) = ((*curReg) + & ~(ADC14_MCTLN_VRSEL_MASK | ADC14_MCTLN_INCH_MASK + | ADC14_MCTLN_DIF)) | (channelSelect | refSelect); + } + + } + + return true; +} + +bool ADC14_enableComparatorWindow(uint32_t memorySelect, uint32_t windowSelect) +{ + uint32_t currentReg, ii; + uint32_t *curRegPoint; + + /* Initialization */ + ii = 1; + currentReg = 0x01; + + if (ADCIsConversionRunning()) + return false; + + while (memorySelect != 0) + { + if (!(memorySelect & ii)) + { + ii = ii << 1; + continue; + } + + currentReg = memorySelect & ii; + memorySelect &= ~ii; + ii = ii << 1; + + curRegPoint = + (uint32_t*) _ctlRegs[_getIndexForMemRegister(currentReg)]; + + if (windowSelect == ADC_COMP_WINDOW0) + { + (*curRegPoint) = ((*curRegPoint) + & ~(ADC14_MCTLN_WINC | ADC14_MCTLN_WINCTH)) + | (ADC14_MCTLN_WINC); + } else if (windowSelect == ADC_COMP_WINDOW1) + { + (*curRegPoint) |= ADC14_MCTLN_WINC | ADC14_MCTLN_WINCTH; + } + + } + + return true; +} + +bool ADC14_disableComparatorWindow(uint32_t memorySelect) +{ + uint32_t currentReg, ii; + + /* Initialization */ + ii = 1; + currentReg = 0x01; + + if (ADCIsConversionRunning()) + return false; + + while (memorySelect != 0) + { + if (!(memorySelect & ii)) + { + ii = ii << 1; + continue; + } + + currentReg = memorySelect & ii; + memorySelect &= ~ii; + ii = ii << 1; + + (*(_ctlRegs[_getIndexForMemRegister(currentReg)])) &= + ~ADC14_MCTLN_WINC; + + } + + return true; +} + +bool ADC14_setComparatorWindowValue(uint32_t window, int16_t low, int16_t high) +{ + if (ADCIsConversionRunning()) + return false; + + if(BITBAND_PERI(ADC14->CTL1, ADC14_CTL1_DF_OFS)) + { + low = ((low << 2) | (0x8000 & low)) & 0xFFFC; + high = ((high << 2) | (0x8000 & high)) & 0xFFFC; + } + + if (window == ADC_COMP_WINDOW0) + { + ADC14->HI0 = (high); + ADC14->LO0 = (low); + + } else if (window == ADC_COMP_WINDOW1) + { + ADC14->HI1 = (high); + ADC14->LO1 = (low); + + } else + { + ASSERT(false); + return false; + } + + return true; +} + +bool ADC14_setResultFormat(uint32_t resultFormat) +{ + if (ADCIsConversionRunning()) + return false; + + if (resultFormat == ADC_UNSIGNED_BINARY) + { + BITBAND_PERI(ADC14->CTL1, ADC14_CTL1_DF_OFS) = 0; + } else if (resultFormat == ADC_SIGNED_BINARY) + { + BITBAND_PERI(ADC14->CTL1, ADC14_CTL1_DF_OFS) = 1; + } else + { + ASSERT(false); + } + + return true; +} + +uint_fast16_t ADC14_getResult(uint32_t memorySelect) +{ + return *((uint16_t*) (_ctlRegs[_getIndexForMemRegister(memorySelect)] + + 0x20)); +} + +void ADC14_getMultiSequenceResult(uint16_t* res) +{ + uint32_t *startAddr, *curAddr; + uint32_t ii; + + startAddr = (uint32_t*) _ctlRegs[(ADC14->CTL1 & ADC14_CTL1_CSTARTADD_MASK) + >> 16]; + + curAddr = startAddr; + + for (ii = 0; ii < 32; ii++) + { + res[ii] = *((uint16_t*)(curAddr + 32)); + + if (BITBAND_PERI((*curAddr), ADC14_MCTLN_EOS_OFS)) + break; + + if (curAddr == _ctlRegs[31]) + curAddr = (uint32_t*) _ctlRegs[0]; + else + curAddr++; + } + +} + +void ADC14_getResultArray(uint32_t memoryStart, uint32_t memoryEnd, + uint16_t* res) +{ + uint32_t ii = 0; + uint32_t *firstPoint, *secondPoint; + + bool foundEnd = false; + + ASSERT( + _getIndexForMemRegister(memoryStart) != ADC_INVALID_MEM + && _getIndexForMemRegister(memoryEnd) != ADC_INVALID_MEM); + + firstPoint = (uint32_t*) _ctlRegs[_getIndexForMemRegister(memoryStart)]; + secondPoint = (uint32_t*) _ctlRegs[_getIndexForMemRegister(memoryEnd)]; + + while (!foundEnd) + { + if (firstPoint == secondPoint) + { + foundEnd = true; + } + + res[ii] = *(((uint16_t*) firstPoint) + 0x40); + + if (firstPoint == _ctlRegs[31]) + firstPoint = (uint32_t*) _ctlRegs[0]; + else + firstPoint += 0x04; + } +} + +bool ADC14_enableReferenceBurst(void) +{ + if (ADCIsConversionRunning()) + return false; + + BITBAND_PERI(ADC14->CTL1, ADC14_CTL1_REFBURST_OFS) = 1; + + return true; +} + +bool ADC14_disableReferenceBurst(void) +{ + if (ADCIsConversionRunning()) + return false; + + BITBAND_PERI(ADC14->CTL1, ADC14_CTL1_REFBURST_OFS) = 0; + + return true; +} + +bool ADC14_setPowerMode(uint32_t adcPowerMode) +{ + if (ADCIsConversionRunning()) + return false; + + switch (adcPowerMode) + { + case ADC_UNRESTRICTED_POWER_MODE: + ADC14->CTL1 = (ADC14->CTL1 & ~(ADC14_CTL1_PWRMD_MASK)) + | (ADC14_CTL1_PWRMD_0); + break; + case ADC_ULTRA_LOW_POWER_MODE: + ADC14->CTL1 = (ADC14->CTL1 & ~(ADC14_CTL1_PWRMD_MASK)) + | (ADC14_CTL1_PWRMD_2); + break; + default: + ASSERT(false); + return false; + } + + return true; +} + +void ADC14_enableInterrupt(uint_fast64_t mask) +{ + uint32_t stat = mask & 0xFFFFFFFF; + + ADC14->IER0 |= stat; + stat = (mask >> 32); + ADC14->IER1 |= (stat); +} + +void ADC14_disableInterrupt(uint_fast64_t mask) +{ + uint32_t stat = mask & 0xFFFFFFFF; + + ADC14->IER0 &= ~stat; + stat = (mask >> 32); + ADC14->IER1 &= ~(stat); +} + +uint_fast64_t ADC14_getInterruptStatus(void) +{ + uint_fast64_t status = ADC14->IFGR1; + return ((status << 32) | ADC14->IFGR0); +} + +uint_fast64_t ADC14_getEnabledInterruptStatus(void) +{ + uint_fast64_t stat = ADC14->IER1; + + return ADC14_getInterruptStatus() & ((stat << 32) | ADC14->IER0); + +} + +void ADC14_clearInterruptFlag(uint_fast64_t mask) +{ + uint32_t stat = mask & 0xFFFFFFFF; + + ADC14->CLRIFGR0 |= stat; + stat = (mask >> 32); + ADC14->CLRIFGR1 |= (stat); +} + +void ADC14_registerInterrupt(void (*intHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + Interrupt_registerInterrupt(INT_ADC14, intHandler); + + // + // Enable the ADC interrupt. + // + Interrupt_enableInterrupt(INT_ADC14); +} + +void ADC14_unregisterInterrupt(void) +{ + // + // Disable the interrupt. + // + Interrupt_disableInterrupt(INT_ADC14); + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(INT_ADC14); +} + diff --git a/example/rt_msp432/MSP432P4xx/adc14.h b/example/rt_msp432/MSP432P4xx/adc14.h new file mode 100644 index 0000000..68efc5e --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/adc14.h @@ -0,0 +1,1073 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef ADC14_H_ +#define ADC14_H_ + +//***************************************************************************** +// +//! +//! \addtogroup adc14_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +//***************************************************************************** +// +// Control specific variables +// +//***************************************************************************** + +//***************************************************************************** +// +//The following are values that can be passed to ADC14_initModule +// +//***************************************************************************** +#define ADC_CLOCKSOURCE_ADCOSC (ADC14_CTL0_SSEL_0) +#define ADC_CLOCKSOURCE_SYSOSC (ADC14_CTL0_SSEL_1) +#define ADC_CLOCKSOURCE_ACLK (ADC14_CTL0_SSEL_2) +#define ADC_CLOCKSOURCE_MCLK (ADC14_CTL0_SSEL_3) +#define ADC_CLOCKSOURCE_SMCLK (ADC14_CTL0_SSEL_4) +#define ADC_CLOCKSOURCE_HSMCLK (ADC14_CTL0_SSEL_5) + +#define ADC_PREDIVIDER_1 (ADC14_CTL0_PDIV_0) +#define ADC_PREDIVIDER_4 (ADC14_CTL0_PDIV_1) +#define ADC_PREDIVIDER_32 (ADC14_CTL0_PDIV_2) +#define ADC_PREDIVIDER_64 (ADC14_CTL0_PDIV_3) + +#define ADC_DIVIDER_1 (ADC14_CTL0_DIV_0) +#define ADC_DIVIDER_2 (ADC14_CTL0_DIV_1) +#define ADC_DIVIDER_3 (ADC14_CTL0_DIV_2) +#define ADC_DIVIDER_4 (ADC14_CTL0_DIV_3) +#define ADC_DIVIDER_5 (ADC14_CTL0_DIV_4) +#define ADC_DIVIDER_6 (ADC14_CTL0_DIV_5) +#define ADC_DIVIDER_7 (ADC14_CTL0_DIV_6) +#define ADC_DIVIDER_8 (ADC14_CTL0_DIV_7) + +#define ADC_MAPINTCH3 (ADC14_CTL1_CH3MAP) +#define ADC_MAPINTCH2 (ADC14_CTL1_CH2MAP) +#define ADC_MAPINTCH1 (ADC14_CTL1_CH1MAP) +#define ADC_MAPINTCH0 (ADC14_CTL1_CH0MAP) +#define ADC_TEMPSENSEMAP (ADC14_CTL1_TCMAP) +#define ADC_BATTMAP (ADC14_CTL1_BATMAP) +#define ADC_NOROUTE 0 + +#define ADC_8BIT ADC14_CTL1_RES_0 +#define ADC_10BIT ADC14_CTL1_RES_1 +#define ADC_12BIT ADC14_CTL1_RES_2 +#define ADC_14BIT ADC14_CTL1_RES_3 + +#define ADC_TRIGGER_ADCSC ADC14_CTL0_SHS_0 +#define ADC_TRIGGER_SOURCE1 ADC14_CTL0_SHS_1 +#define ADC_TRIGGER_SOURCE2 ADC14_CTL0_SHS_2 +#define ADC_TRIGGER_SOURCE3 ADC14_CTL0_SHS_3 +#define ADC_TRIGGER_SOURCE4 ADC14_CTL0_SHS_4 +#define ADC_TRIGGER_SOURCE5 ADC14_CTL0_SHS_5 +#define ADC_TRIGGER_SOURCE6 ADC14_CTL0_SHS_6 +#define ADC_TRIGGER_SOURCE7 ADC14_CTL0_SHS_7 + +#define ADC_PULSE_WIDTH_4 ADC14_CTL0_SHT1_0 +#define ADC_PULSE_WIDTH_8 ADC14_CTL0_SHT1_1 +#define ADC_PULSE_WIDTH_16 ADC14_CTL0_SHT1_2 +#define ADC_PULSE_WIDTH_32 ADC14_CTL0_SHT1_3 +#define ADC_PULSE_WIDTH_64 ADC14_CTL0_SHT1_4 +#define ADC_PULSE_WIDTH_96 ADC14_CTL0_SHT1_5 +#define ADC_PULSE_WIDTH_128 ADC14_CTL0_SHT1_6 +#define ADC_PULSE_WIDTH_192 ADC14_CTL0_SHT1_7 + +#define ADC_NONDIFFERENTIAL_INPUTS false +#define ADC_DIFFERENTIAL_INPUTS true + +#define ADC_MEM0 0x00000001 +#define ADC_MEM1 0x00000002 +#define ADC_MEM2 0x00000004 +#define ADC_MEM3 0x00000008 +#define ADC_MEM4 0x00000010 +#define ADC_MEM5 0x00000020 +#define ADC_MEM6 0x00000040 +#define ADC_MEM7 0x00000080 +#define ADC_MEM8 0x00000100 +#define ADC_MEM9 0x00000200 +#define ADC_MEM10 0x00000400 +#define ADC_MEM11 0x00000800 +#define ADC_MEM12 0x00001000 +#define ADC_MEM13 0x00002000 +#define ADC_MEM14 0x00004000 +#define ADC_MEM15 0x00008000 +#define ADC_MEM16 0x00010000 +#define ADC_MEM17 0x00020000 +#define ADC_MEM18 0x00040000 +#define ADC_MEM19 0x00080000 +#define ADC_MEM20 0x00100000 +#define ADC_MEM21 0x00200000 +#define ADC_MEM22 0x00400000 +#define ADC_MEM23 0x00800000 +#define ADC_MEM24 0x01000000 +#define ADC_MEM25 0x02000000 +#define ADC_MEM26 0x04000000 +#define ADC_MEM27 0x08000000 +#define ADC_MEM28 0x10000000 +#define ADC_MEM29 0x20000000 +#define ADC_MEM30 0x40000000 +#define ADC_MEM31 0x80000000 + +#define ADC_VREFPOS_AVCC_VREFNEG_VSS (ADC14_MCTLN_VRSEL_0) +#define ADC_VREFPOS_INTBUF_VREFNEG_VSS (ADC14_MCTLN_VRSEL_1) +#define ADC_VREFPOS_EXTPOS_VREFNEG_EXTNEG (ADC14_MCTLN_VRSEL_14) +#define ADC_VREFPOS_EXTBUF_VREFNEG_EXTNEG (ADC14_MCTLN_VRSEL_15) + +#define ADC_INPUT_A0 (ADC14_MCTLN_INCH_0) +#define ADC_INPUT_A1 (ADC14_MCTLN_INCH_1) +#define ADC_INPUT_A2 (ADC14_MCTLN_INCH_2) +#define ADC_INPUT_A3 (ADC14_MCTLN_INCH_3) +#define ADC_INPUT_A4 (ADC14_MCTLN_INCH_4) +#define ADC_INPUT_A5 (ADC14_MCTLN_INCH_5) +#define ADC_INPUT_A6 (ADC14_MCTLN_INCH_6) +#define ADC_INPUT_A7 (ADC14_MCTLN_INCH_7) +#define ADC_INPUT_A8 (ADC14_MCTLN_INCH_8) +#define ADC_INPUT_A9 (ADC14_MCTLN_INCH_9) +#define ADC_INPUT_A10 (ADC14_MCTLN_INCH_10) +#define ADC_INPUT_A11 (ADC14_MCTLN_INCH_11) +#define ADC_INPUT_A12 (ADC14_MCTLN_INCH_12) +#define ADC_INPUT_A13 (ADC14_MCTLN_INCH_13) +#define ADC_INPUT_A14 (ADC14_MCTLN_INCH_14) +#define ADC_INPUT_A15 (ADC14_MCTLN_INCH_15) +#define ADC_INPUT_A16 (ADC14_MCTLN_INCH_16) +#define ADC_INPUT_A17 (ADC14_MCTLN_INCH_17) +#define ADC_INPUT_A18 (ADC14_MCTLN_INCH_18) +#define ADC_INPUT_A19 (ADC14_MCTLN_INCH_19) +#define ADC_INPUT_A20 (ADC14_MCTLN_INCH_20) +#define ADC_INPUT_A21 (ADC14_MCTLN_INCH_21) +#define ADC_INPUT_A22 (ADC14_MCTLN_INCH_22) +#define ADC_INPUT_A23 (ADC14_MCTLN_INCH_23) +#define ADC_INPUT_A24 (ADC14_MCTLN_INCH_24) +#define ADC_INPUT_A25 (ADC14_MCTLN_INCH_25) +#define ADC_INPUT_A26 (ADC14_MCTLN_INCH_26) +#define ADC_INPUT_A27 (ADC14_MCTLN_INCH_27) +#define ADC_INPUT_A28 (ADC14_MCTLN_INCH_28) +#define ADC_INPUT_A29 (ADC14_MCTLN_INCH_29) +#define ADC_INPUT_A30 (ADC14_MCTLN_INCH_30) +#define ADC_INPUT_A31 (ADC14_MCTLN_INCH_31) + +#define ADC_COMP_WINDOW0 0x00 +#define ADC_COMP_WINDOW1 0x01 + +#define ADC_SIGNED_BINARY 0x00 +#define ADC_UNSIGNED_BINARY 0x01 + +#define ADC_MANUAL_ITERATION 0x00 +#define ADC_AUTOMATIC_ITERATION ADC14_CTL0_MSC + +#define ADC_UNRESTRICTED_POWER_MODE ADC14_CTL1_PWRMD_0 +#define ADC_ULTRA_LOW_POWER_MODE ADC14_CTL1_PWRMD_2 + + +#define ADC_INT0 ADC14_IER0_IE0 +#define ADC_INT1 ADC14_IER0_IE1 +#define ADC_INT2 ADC14_IER0_IE2 +#define ADC_INT3 ADC14_IER0_IE3 +#define ADC_INT4 ADC14_IER0_IE4 +#define ADC_INT5 ADC14_IER0_IE5 +#define ADC_INT6 ADC14_IER0_IE6 +#define ADC_INT7 ADC14_IER0_IE7 +#define ADC_INT8 ADC14_IER0_IE8 +#define ADC_INT9 ADC14_IER0_IE9 +#define ADC_INT10 ADC14_IER0_IE10 +#define ADC_INT11 ADC14_IER0_IE11 +#define ADC_INT12 ADC14_IER0_IE12 +#define ADC_INT13 ADC14_IER0_IE13 +#define ADC_INT14 ADC14_IER0_IE14 +#define ADC_INT15 ADC14_IER0_IE15 +#define ADC_INT16 ADC14_IER0_IE16 +#define ADC_INT17 ADC14_IER0_IE17 +#define ADC_INT18 ADC14_IER0_IE18 +#define ADC_INT19 ADC14_IER0_IE19 +#define ADC_INT20 ADC14_IER0_IE20 +#define ADC_INT21 ADC14_IER0_IE21 +#define ADC_INT22 ADC14_IER0_IE22 +#define ADC_INT23 ADC14_IER0_IE23 +#define ADC_INT24 ADC14_IER0_IE24 +#define ADC_INT25 ADC14_IER0_IE25 +#define ADC_INT26 ADC14_IER0_IE26 +#define ADC_INT27 ADC14_IER0_IE27 +#define ADC_INT28 ADC14_IER0_IE28 +#define ADC_INT29 ADC14_IER0_IE29 +#define ADC_INT30 ADC14_IER0_IE30 +#define ADC_INT31 ADC14_IER0_IE31 +#define ADC_IN_INT 0x0000000200000000 +#define ADC_LO_INT 0x0000000400000000 +#define ADC_HI_INT 0x0000000800000000 +#define ADC_OV_INT 0x0000001000000000 +#define ADC_TOV_INT 0x0000002000000000 +#define ADC_RDY_INT 0x0000004000000000 + +#define ADC_INVALID_MEM 32 + +//***************************************************************************** +// +//Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! +//! Enables the ADC block. +//! +//! This will enable operation of the ADC block. +//! +//! \return none. +// +//***************************************************************************** +extern void ADC14_enableModule(void); + +//***************************************************************************** +// +//! +//! Disables the ADC block. +//! +//! This will disable operation of the ADC block. +//! +//! \return false if user is trying to disable during active conversion +// +//***************************************************************************** +extern bool ADC14_disableModule(void); + +//***************************************************************************** +// +//! +//! Initializes the ADC module and sets up the clock system divider/pre-divider. +//! This initialization function will also configure the internal/external +//! signal mapping. +//! +//! \note A call to this function while active ADC conversion is happening +//! is an invalid case and will result in a false value being returned. +//! +//! \param clockSource The clock source to use for the ADC module. +//! - \b ADC_CLOCKSOURCE_ADCOSC [DEFAULT] +//! - \b ADC_CLOCKSOURCE_SYSOSC +//! - \b ADC_CLOCKSOURCE_ACLK +//! - \b ADC_CLOCKSOURCE_MCLK +//! - \b ADC_CLOCKSOURCE_SMCLK +//! - \b ADC_CLOCKSOURCE_HSMCLK +//! +//! \param clockPredivider Divides the given clock source before feeding it +//! into the main clock divider. +//! Valid values are: +//! - \b ADC_PREDIVIDER_1 [DEFAULT] +//! - \b ADC_PREDIVIDER_4 +//! - \b ADC_PREDIVIDER_32 +//! - \b ADC_PREDIVIDER_64 +//! +//! \param clockDivider Divides the pre-divided clock source +//! Valid values are +//! - \b ADC_DIVIDER_1 [Default value] +//! - \b ADC_DIVIDER_2 +//! - \b ADC_DIVIDER_3 +//! - \b ADC_DIVIDER_4 +//! - \b ADC_DIVIDER_5 +//! - \b ADC_DIVIDER_6 +//! - \b ADC_DIVIDER_7 +//! - \b ADC_DIVIDER_8 +//! +//! \param internalChannelMask +//! Configures the internal/external pin mappings +//! for the ADC modules. This setting determines if the given ADC channel or +//! component is mapped to an external pin (default), or routed to an internal +//! component. This parameter is a bit mask where a logical high value will +//! switch the component to the internal routing. For a list of internal +//! routings, please refer to the device specific data sheet. +//! Valid values are a logical OR of the following values: +//! - \b ADC_MAPINTCH3 +//! - \b ADC_MAPINTCH2 +//! - \b ADC_MAPINTCH1 +//! - \b ADC_MAPINTCH0 +//! - \b ADC_TEMPSENSEMAP +//! - \b ADC_BATTMAP +//! - \n ADC_NOROUTE +//! If internalChannelMask is not desired, pass ADC_NOROUTE in lieu of this +//! parameter. +//! +//! \return false if the initialization fails due to an in progress conversion +//! +//! +// +//***************************************************************************** +extern bool ADC14_initModule(uint32_t clockSource, uint32_t clockPredivider, + uint32_t clockDivider, uint32_t internalChannelMask); + +//***************************************************************************** +// +//! +//! Sets the resolution of the ADC module. The default resolution is 12-bit, +//! however for power consumption concerns this can be limited to a lower +//! resolution +//! +//! \param resolution Resolution of the ADC module +//! - \b ADC_8BIT (10 clock cycle conversion time) +//! - \b ADC_10BIT (12 clock cycle conversion time) +//! - \b ADC_12BIT (14 clock cycle conversion time) +//! - \b ADC_14BIT (16 clock cycle conversion time)[DEFAULT] +//! +//! \return none +// +//***************************************************************************** +extern void ADC14_setResolution(uint32_t resolution); + +//***************************************************************************** +// +//! +//! Gets the resolution of the ADC module. +//! +//! \return Resolution of the ADC module +//! - \b ADC_8BIT (10 clock cycle conversion time) +//! - \b ADC_10BIT (12 clock cycle conversion time) +//! - \b ADC_12BIT (14 clock cycle conversion time) +//! - \b ADC_14BIT (16 clock cycle conversion time) +// +//***************************************************************************** +extern uint_fast32_t ADC14_getResolution(void); + +//***************************************************************************** +// +//! +//! Sets the source for the trigger of the ADC module. By default, this value +//! is configured to a software source (the ADCSC bit), however depending on +//! the specific device the trigger can be set to different sources (for +//! example, a timer output). These sources vary from part to part and the +//! user should refer to the device specific datasheet. +//! +//! \param source Trigger source for sampling. Possible values include: +//! - \b ADC_TRIGGER_ADCSC [DEFAULT] +//! - \b ADC_TRIGGER_SOURCE1 +//! - \b ADC_TRIGGER_SOURCE2 +//! - \b ADC_TRIGGER_SOURCE3 +//! - \b ADC_TRIGGER_SOURCE4 +//! - \b ADC_TRIGGER_SOURCE5 +//! - \b ADC_TRIGGER_SOURCE6 +//! - \b ADC_TRIGGER_SOURCE7 +//! \param invertSignal When set to true, will invert the trigger signal to a +//! falling edge. When false, will use a rising edge. +//! +//! \return false if setting fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_setSampleHoldTrigger(uint32_t source, bool invertSignal); + +//***************************************************************************** +// +//! +//! Sets the sample/hold time for the specified memory register range. The +//! duration of time required for a sample differs depending on the user's +//! hardware configuration. +//! +//! There are two values in the ADCC module. The first value controls +//! ADC memory locations ADC_MEMORY_0 through ADC_MEMORY_7 and +//! ADC_MEMORY_24 through ADC_MEMORY_31, while the second value +//! controls memory locations ADC_MEMORY_8 through ADC_MEMORY_23. +//! +//! \param firstPulseWidth Pulse width of the first pulse in ADCCLK cycles +//! Possible values must be one of the following: +//! - \b ADC_PULSE_WIDTH_4 [DEFAULT] +//! - \b ADC_PULSE_WIDTH_8 +//! - \b ADC_PULSE_WIDTH_16 +//! - \b ADC_PULSE_WIDTH_32 +//! - \b ADC_PULSE_WIDTH_64 +//! - \b ADC_PULSE_WIDTH_96 +//! - \b ADC_PULSE_WIDTH_128 +//! - \b ADC_PULSE_WIDTH_192 +//! \param secondPulseWidth Pulse width of the second pulse in ADCCLK +//! cycles. Possible values must be one of the following: +//! - \b ADC_PULSE_WIDTH_4 [DEFAULT] +//! - \b ADC_PULSE_WIDTH_8 +//! - \b ADC_PULSE_WIDTH_16 +//! - \b ADC_PULSE_WIDTH_32 +//! - \b ADC_PULSE_WIDTH_64 +//! - \b ADC_PULSE_WIDTH_96 +//! - \b ADC_PULSE_WIDTH_128 +//! - \b ADC_PULSE_WIDTH_192 +//! +//! \return false if setting fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_setSampleHoldTime(uint32_t firstPulseWidth, + uint32_t secondPulseWidth); + +//***************************************************************************** +// +//! +//! Configures the ADC module to use a multiple memory sample scheme. This +//! means that multiple samples will consecutively take place and be stored in +//! multiple memory locations. The first sample/conversion will be placed in +//! memoryStart, while the last sample will be stored in memoryEnd. +//! Each memory location should be configured individually using the +//! ADC14_configureConversionMemory function. +//! +//! The ADC module can be started in "repeat" mode which will cause the +//! ADC module to resume sampling once the initial sample/conversion set is +//! executed. For multi-sample mode, this means that the sampling of the +//! entire memory provided. +//! +//! \param memoryStart Memory location to store first sample/conversion +//! value. Possible values include: +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! \param memoryEnd Memory location to store last sample. +//! Possible values include: +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! \param repeatMode Specifies whether or not to repeat the conversion/sample +//! cycle after the first round of sample/conversions. Valid values +//! are true or false. +//! +//! \return false if setting fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_configureMultiSequenceMode(uint32_t memoryStart, + uint32_t memoryEnd, bool repeatMode); + +//***************************************************************************** +// +//! +//! Configures the ADC module to use a a single ADC memory location for +//! sampling/conversion. This is used when only one channel might be needed for +//! conversion, or where using a multiple sampling scheme is not important. +//! +//! The ADC module can be started in "repeat" mode which will cause the +//! ADC module to resume sampling once the initial sample/conversion set is +//! executed. In single sample mode, this will cause the ADC module to +//! continuously sample into the memory destination provided. + +//! \param memoryDestination Memory location to store sample/conversion +//! value. Possible values include: +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! +//! \param repeatMode Specifies whether or not to repeat the conversion/sample +//! cycle after the first round of sample/conversions +//! +//! \return false if setting fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_configureSingleSampleMode(uint32_t memoryDestination, + bool repeatMode); + +//***************************************************************************** +// +//! +//! Enables conversion of ADC data. Note that this only enables conversion. +//! To trigger the conversion, you will have to call the +//! ADC14_toggleConversionTrigger or use the source trigger configured in +//! ADC14_setSampleHoldTrigger. +//! +//! \return false if setting fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_enableConversion(void); + +//***************************************************************************** +// +//! +//! Halts conversion conversion of the ADC module. Note that the software bit +//! for triggering conversions will also be cleared with this function. +//! +//! If multi-sequence conversion mode was enabled, the position of the last +//! completed conversion can be retrieved using ADCLastConversionMemoryGet +//! +//! \return none +// +//***************************************************************************** +extern void ADC14_disableConversion(void); + +//***************************************************************************** +// +//! +//! Toggles the trigger for conversion of the ADC module by toggling the +//! trigger software bit. Note that this will cause the ADC to start +//! conversion regardless if the software bit was set as the trigger using +//! ADC14_setSampleHoldTrigger. +//! +//! \return false if setting fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_toggleConversionTrigger(void); + +//***************************************************************************** +// +//! +//! Returns a boolean value that tells if a conversion/sample is in progress +//! +//! \return true if conversion is active, false otherwise +// +//***************************************************************************** +extern bool ADC14_isBusy(void); + +//***************************************************************************** +// +//! +//! Configures an individual memory location for the ADC module. +//! +//! \param memorySelect is the individual ADC memory location to +//! configure. If multiple memory locations want to be configured with the +//! same configuration, this value can be logically ORed together with other +//! values. +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! \param refSelect is the voltage reference to use for the selected +//! memory spot. Possible values include: +//! - \b ADC_VREFPOS_AVCC_VREFNEG_VSS [DEFAULT] +//! - \b ADC_VREFPOS_INTBUF_VREFNEG_VSS +//! - \b ADC_VREFPOS_EXTPOS_VREFNEG_EXTNEG +//! - \b ADC_VREFPOS_EXTBUF_VREFNEG_EXTNEG +//! \param channelSelect selects the channel to be used for ADC sampling. +//! Note if differential mode is enabled, the value sampled will be +//! equal to the difference between the corresponding even/odd memory +//! locations. Possible values are: +//! - \b ADC_INPUT_A0 through \b ADC_INPUT_A31 +//! +//! \param differntialMode selects if the channel selected by the +//! channelSelect will be configured in differential mode. If this +//! parameter is given as true, the configured channel will be paired +//! with its neighbor in differential mode. for example, if channel A0 or A1 +//! is selected, the channel configured will be the difference between A0 +//! and A1. If A2 or A3 are selected, the channel configured will be the +//! difference between A2 and A3 (and so on). Users can enter true or false, +//! or one of the following values: +//! - ADC_NONDIFFERENTIAL_INPUTS +//! - ADC_DIFFERENTIAL_INPUTS +//! +//! +//! \return false if setting fails due to an in progress conversion +//! +// +//***************************************************************************** +extern bool ADC14_configureConversionMemory(uint32_t memorySelect, + uint32_t refSelect, uint32_t channelSelect, bool differntialMode); + +//***************************************************************************** +// +//! +//! Enables the specified mask of memory channels to use the specified +//! comparator window. THe ADCC module has two different comparator windows +//! that can be set with this function. +//! +//! \param memorySelect is the mask of memory locations to enable the +//! comparator window for. This can be a bitwise OR of the following +//! values: +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! \param windowSelect Memory location to store sample/conversion +//! value. Possible values include: +//! \b ADCOMP_WINDOW0 [DEFAULT] +//! \b ADCOMP_WINDOW1 +//! +//! \return false if setting fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_enableComparatorWindow(uint32_t memorySelect, + uint32_t windowSelect); + +//***************************************************************************** +// +//! +//! Disables the comparator window on the specified memory channels +//! +//! \param memorySelect is the mask of memory locations to disable the +//! comparator window for. This can be a bitwise OR of the following +//! values: +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! +//! \return false if setting fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_disableComparatorWindow(uint32_t memorySelect); + +//***************************************************************************** +// +//! +//! Sets the lower and upper limits of the specified window comparator. Note +//! that this function will truncate values based of the resolution/data +//! format configured. If the ADC is operating in 10-bit mode, and a 12-bit +//! value is passed into this function the most significant 2 bits will be +//! truncated. +//! +//! The parameters provided to this function for the upper and lower threshold +//! depend on the current resolution for the ADC. For example, if configured +//! in 12-bit mode, a 12-bit resolution is the maximum that can be provided +//! for the window. If in 2's complement mode, Bit 15 is used as the MSB. +//! +//! \param window Memory location to store sample/conversion +//! value. Possible values include: +//! \b ADC_COMP_WINDOW0 [DEFAULT] +//! \b ADC_COMP_WINDOW1 +//! \param low is the lower limit of the window comparator +//! \param high is the upper limit of the window comparator +//! +//! \return false if setting fails due to an in progress conversion +//! +// +//***************************************************************************** +extern bool ADC14_setComparatorWindowValue(uint32_t window, int16_t low, + int16_t high); + +//***************************************************************************** +// +//! +//! Switches between a binary unsigned data format and a signed 2's complement +//! data format. +//! +//! \param resultFormat Format for result to conversion results. +//! Possible values include: +//! \b ADC_UNSIGNED_BINARY [DEFAULT] +//! \b ADC_SIGNED_BINARY +//! +//! \return false if setting fails due to an in progress conversion +//! +// +//***************************************************************************** +extern bool ADC14_setResultFormat(uint32_t resultFormat); + +//***************************************************************************** +// +//! +//! Returns the conversion result for the specified memory channel in the format +//! assigned by the ADC14_setResultFormat (unsigned binary by default) function. +//! +//! \param memorySelect is the memory location to get the conversion result. +//! Valid values are: +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! \return conversion result of specified memory channel +//! +// +//***************************************************************************** +extern uint_fast16_t ADC14_getResult(uint32_t memorySelect); + +//***************************************************************************** +// +//! +//! Returns the conversion results of the currently configured multi-sequence +//! conversion. If a multi-sequence conversion has not happened, this value +//! is unreliable. Note that it is up to the user to verify the integrity of +//! and proper size of the array being passed. If there are 16 multi-sequence +//! results, and an array with only 4 elements allocated is passed, invalid +//! memory settings will occur +//! +//! \param res conversion result of the last multi-sequence sample +//! in an array of unsigned 16-bit integers +//! +//! \return None +//! +// +//***************************************************************************** +extern void ADC14_getMultiSequenceResult(uint16_t* res); + +//***************************************************************************** +// +//! +//! Returns the conversion results of the specified ADC memory locations. +//! Note that it is up to the user to verify the integrity of +//! and proper size of the array being passed. If there are 16 multi-sequence +//! results, and an array with only 4 elements allocated is passed, invalid +//! memory settings will occur. This function is inclusive. +//! +//! \param memoryStart is the memory location to get the conversion result. +//! Valid values are: +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! +//! \param memoryEnd is the memory location to get the conversion result. +//! Valid values are: +//! - \b ADC_MEM0 through \b ADC_MEM31 +//! \param res conversion result of the last multi-sequence sample +//! in an array of unsigned 16-bit integers +//! +//! \return None +//! +// +//***************************************************************************** +extern void ADC14_getResultArray(uint32_t memoryStart, uint32_t memoryEnd, + uint16_t* res); + +//***************************************************************************** +// +//! +//! Enables the "on-demand" activity of the voltage reference register. If this +//! setting is enabled, the internal voltage reference buffer will only be +//! updated during a sample or conversion cycle. This is used to optimize +//! power consumption. +//! +//! \return false if setting fails due to an in progress conversion +//! +// +//***************************************************************************** +extern bool ADC14_enableReferenceBurst(void); + +//***************************************************************************** +// +//! +//! Disables the "on-demand" activity of the voltage reference register. +//! +//! \return false if setting fails due to an in progress conversion +//! +// +//***************************************************************************** +extern bool ADC14_disableReferenceBurst(void); + +//***************************************************************************** +// +//! +//! Sets the power mode of the ADC module. A more aggressive power mode will +//! restrict the number of samples per second for sampling while optimizing +//! power consumption. Ideally, if power consumption is a concern, this value +//! should be set to the most restrictive setting that satisfies your sampling +//! requirement. +//! +//! \param adcPowerMode is the power mode to set. Valid values are: +//! - \b ADC_UNRESTRICTED_POWER_MODE (no restriction) +//! - \b ADC_LOW_POWER_MODE (500ksps restriction) +//! - \b ADC_ULTRA_LOW_POWER_MODE (200ksps restriction) +//! - \b ADC_EXTREME_LOW_POWER_MODE (50ksps restriction) +//! +//! \return false if setting fails due to an in progress conversion +//! +// +//***************************************************************************** +extern bool ADC14_setPowerMode(uint32_t powerMode); + +//***************************************************************************** +// +//! +//! Enables SAMPCON to be sourced from the sampling timer and to configures +//! multi sample and conversion mode. +//! \param multiSampleConvert - Switches between manual and automatic +//! iteration when using the sample timer. Valid values are: +//! - \b ADC_MANUAL_ITERATION The user will have to manually set the SHI signal +//! ( usually by ADC14_toggleConversionTrigger ) at the end +//! of each sample/conversion cycle. +//! - \b ADC_AUTOMATIC_ITERATION After one sample/convert is finished, the ADC +//! module will automatically continue on to the next sample +//! +//! \return false if the initialization fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_enableSampleTimer(uint32_t multiSampleConvert); + +//***************************************************************************** +// +//! +//! Disables SAMPCON from being sourced from the sample timer. +//! +//! \return false if the initialization fails due to an in progress conversion +// +//***************************************************************************** +extern bool ADC14_disableSampleTimer(void); + +//***************************************************************************** +// +//! +//! Enables the indicated ADCC interrupt sources. The ADC_INT0 +//! through ADC_INT31 parameters correspond to a completion event of the +//! corresponding memory location. For example, when the ADC_MEM0 location +//! finishes a conversion cycle, the ADC_INT0 interrupt will be set. +//! +//! \param mask is the bit mask of interrupts to enable. +//! Valid values are a bitwise OR of the following values: +//! - \b ADC_INT0 through ADC_INT31 +//! - \b ADC_IN_INT - Interrupt enable for a conversion in the result +//! register is either greater than the ADCLO or +//! lower than the ADCHI threshold. +//! - \b ADC_LO_INT - Interrupt enable for the falling short of the +//! lower limit interrupt of the window comparator for +//! the result register. +//! - \b ADC_HI_INT - Interrupt enable for the exceeding the upper +//! limit of the window comparator for the result +//! register. +//! - \b ADC_OV_INT - Interrupt enable for a conversion that is about +//! to save to a memory buffer that has not been read +//! out yet. +//! - \b ADC_TOV_INT -Interrupt enable for a conversion that is about +//! to start before the previous conversion has been +//! completed. +//! - \b ADC_RDY_INT -Interrupt enable for the local buffered reference +//! ready signal. +//! +//! +//! \return NONE +// +//***************************************************************************** +extern void ADC14_enableInterrupt(uint_fast64_t mask); + +//***************************************************************************** +// +//! +//! Disables the indicated ADCC interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. The ADC_INT0 through ADC_INT31 +//! parameters correspond to a completion event of the corresponding memory +//! location. For example, when the ADC_MEM0 location finishes a conversion +//! cycle, the ADC_INT0 interrupt will be set. +//! +//! \param mask is the bit mask of interrupts to disable. +//! Valid values are a bitwise OR of the following values: +//! - \b ADC_INT0 through ADC_INT31 +//! - \b ADC_IN_INT - Interrupt enable for a conversion in the result +//! register is either greater than the ADCLO or +//! lower than the ADCHI threshold. +//! - \b ADC_LO_INT - Interrupt enable for the falling short of the +//! lower limit interrupt of the window comparator for +//! the result register. +//! - \b ADC_HI_INT - Interrupt enable for the exceeding the upper +//! limit of the window comparator for the result +//! register. +//! - \b ADC_OV_INT - Interrupt enable for a conversion that is about +//! to save to a memory buffer that has not been read +//! out yet. +//! - \b ADC_TOV_INT -Interrupt enable for a conversion that is about +//! to start before the previous conversion has been +//! completed. +//! - \b ADC_RDY_INT -Interrupt enable for the local buffered reference +//! ready signal. +//! +//! +//! \return NONE +// +//***************************************************************************** +extern void ADC14_disableInterrupt(uint_fast64_t mask); + +//***************************************************************************** +// +//! +//! Returns the status of a the ADC interrupt register. The ADC_INT0 +//! through ADC_INT31 parameters correspond to a completion event of the +//! corresponding memory location. For example, when the ADC_MEM0 location +//! finishes a conversion cycle, the ADC_INT0 interrupt will be set. +//! +//! \return The interrupt status. Value is a bitwise OR of the following values: +//! - \b ADC_INT0 through ADC_INT31 +//! - \b ADC_IN_INT - Interrupt enable for a conversion in the result +//! register is either greater than the ADCLO or +//! lower than the ADCHI threshold. +//! - \b ADC_LO_INT - Interrupt enable for the falling short of the +//! lower limit interrupt of the window comparator for +//! the result register. +//! - \b ADC_HI_INT - Interrupt enable for the exceeding the upper +//! limit of the window comparator for the result +//! register. +//! - \b ADC_OV_INT - Interrupt enable for a conversion that is about +//! to save to a memory buffer that has not been read +//! out yet. +//! - \b ADC_TOV_INT -Interrupt enable for a conversion that is about +//! to start before the previous conversion has been +//! completed. +//! - \b ADC_RDY_INT -Interrupt enable for the local buffered reference +//! ready signal. +//! +//! +// +//***************************************************************************** +extern uint_fast64_t ADC14_getInterruptStatus(void); + +//***************************************************************************** +// +//! +//! Returns the status of a the ADC interrupt register masked with the +//! enabled interrupts. This function is useful to call in ISRs to get a list +//! of pending interrupts that are actually enabled and could have caused the +//! ISR. The ADC_INT0 through ADC_INT31 parameters correspond to a +//! completion event of the corresponding memory location. For example, +//! when the ADC_MEM0 location finishes a conversion cycle, the ADC_INT0 +// !interrupt will be set. +//! +//! \return The interrupt status. Value is a bitwise OR of the following values: +//! - \b ADC_INT0 through ADC_INT31 +//! - \b ADC_IN_INT - Interrupt enable for a conversion in the result +//! register is either greater than the ADCLO or +//! lower than the ADCHI threshold. +//! - \b ADC_LO_INT - Interrupt enable for the falling short of the +//! lower limit interrupt of the window comparator for +//! the result register. +//! - \b ADC_HI_INT - Interrupt enable for the exceeding the upper +//! limit of the window comparator for the result +//! register. +//! - \b ADC_OV_INT - Interrupt enable for a conversion that is about +//! to save to a memory buffer that has not been read +//! out yet. +//! - \b ADC_TOV_INT -Interrupt enable for a conversion that is about +//! to start before the previous conversion has been +//! completed. +//! - \b ADC_RDY_INT -Interrupt enable for the local buffered reference +//! ready signal. +//! +//! +// +//***************************************************************************** +extern uint_fast64_t ADC14_getEnabledInterruptStatus(void); + +//***************************************************************************** +// +//! +//! Clears the indicated ADCC interrupt sources. +//! +//! \param mask is the bit mask of interrupts to clear. The ADC_INT0 +//! through ADC_INT31 parameters correspond to a completion event of the +//! corresponding memory location. For example, when the ADC_MEM0 location +//! finishes a conversion cycle, the ADC_INT0 interrupt will be set. +//! Valid values are a bitwise OR of the following values: +//! - \b ADC_INT0 through ADC_INT31 +//! - \b ADC_IN_INT - Interrupt enable for a conversion in the result +//! register is either greater than the ADCLO or +//! lower than the ADCHI threshold. +//! - \b ADC_LO_INT - Interrupt enable for the falling short of the +//! lower limit interrupt of the window comparator for +//! the result register. +//! - \b ADC_HI_INT - Interrupt enable for the exceeding the upper +//! limit of the window comparator for the result +//! register. +//! - \b ADC_OV_INT - Interrupt enable for a conversion that is about +//! to save to a memory buffer that has not been read +//! out yet. +//! - \b ADC_TOV_INT -Interrupt enable for a conversion that is about +//! to start before the previous conversion has been +//! completed. +//! - \b ADC_RDY_INT -Interrupt enable for the local buffered reference +//! ready signal. +//! +//! +//! \return NONE +// +//***************************************************************************** +extern void ADC14_clearInterruptFlag(uint_fast64_t mask); + +//***************************************************************************** +// +//! +//! Registers an interrupt handler for the ADC interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the ADC +//! interrupt occurs. +//! +//! This function registers the handler to be called when an ADC +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific ADC14 interrupts must be enabled +//! via ADC14_enableInterrupt(). It is the interrupt handler's responsibility +//! to clear the interrupt source via ADC14_clearInterruptFlag(). +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void ADC14_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! +//! Unregisters the interrupt handler for the ADCC module. +//! +//! This function unregisters the handler to be called when an ADCC +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void ADC14_unregisterInterrupt(void); + +/* Defines for future devices that might have multiple instances */ +#define ADC14_enableModuleMultipleInstance(a) ADC14_enableModule() +#define ADC14_disableModuleMultipleInstance(a) ADC14_disableModule() +#define ADC14_initModuleMultipleInstance(a,b,c,d,e) ADC14_initModule(b,c,d,e) +#define ADC14_setResolutionMultipleInstance(a,b) ADC14_setResolution(b) +#define ADC14_getResolutionMultipleInstance(a) ADC14_getResolution() +#define ADC14_setSampleHoldTriggerMultipleInstance(a,b,c) ADC14_setSampleHoldTrigger(b,c) +#define ADC14_setSampleHoldTimeMultipleInstance(a,b,c) ADC14_setSampleHoldTime(b,c) +#define ADC14_configureMultiSequenceModeMultipleInstance(a,b,c,d) ADC14_configureMultiSequenceMode(b,c,d) +#define ADC14_configureSingleSampleModeMultipleInstance(a,b,c) ADC14_configureSingleSampleMode(b,c) +#define ADC14_enableConversionMultipleInstance(a,b) ADC14_enableConversion(b) +#define ADC14_disableConversionMultipleInstance(a) ADC14_disableConversion() +#define ADC14_toggleConversionTriggerMultipleInstance(a) ADC14_toggleConversionTrigger() +#define ADC14_isBusyMultipleInstance(a) ADC14_isBusy() +#define ADC14_configureConversionMemoryMultipleInstance(a,b,c,d,e) ADC14_configureConversionMemory(b,c,d,e) +#define ADC14_enableComparatorWindowMultipleInstance(a,b,c) ADC14_enableComparatorWindow(b,c) +#define ADC14_disableComparatorWindowMultipleInstance(a,b) ADC14_disableComparatorWindow(b) +#define ADC14_setComparatorWindowValueMultipleInstance(a,b,c,d) ADC14_setComparatorWindowValue(b,c,d) +#define ADC14_setResultFormatMultipleInstance(a,b) ADC14_setResultFormat(b) +#define ADC14_getResultMultipleInstance(a,b) ADC14_getResult(b) +#define ADC14_getMultiSequenceResultMultipleInstance(a,b) ADC14_getMultiSequenceResult(b) +#define ADC14_getResultArrayMultipleInstance(a,b,c,d) ADC14_getResultArray(b,c,d) +#define ADC14_enableReferenceBurstMultipleInstance(a) ADC14_enableReferenceBurst() +#define ADC14_disableReferenceBurstMultipleInstance(a) ADC14_disableReferenceBurst() +#define ADC14_setPowerModeMultipleInstance(a,b) ADC14_setPowerMode(b) +#define ADC14_enableSampleTimerMultipleInstance(a,b) ADC14_enableSampleTimer(b) +#define ADC14_disableSampleTimerMultipleInstance(a) ADC14_disableSampleTimer() +#define ADC14_enableInterruptMultipleInstance(a,b) ADC14_enableInterrupt(b) +#define ADC14_disableInterruptMultipleInstance(a,b) ADC14_disableInterrupt(b) +#define ADC14_getInterruptStatusMultipleInstance(a) ADC14_getInterruptStatus() +#define ADC14_getEnabledInterruptStatusMultipleInstance(a) ADC14_getEnabledInterruptStatus() +#define ADC14_clearInterruptFlagMultipleInstance(a,b) ADC14_clearInterruptFlag(b) +#define ADC14_registerInterruptMultipleInstance(a,b) ADC14_registerInterrupt(b) +#define ADC14_unregisterInterruptMultipleInstance(a) ADC14_unregisterInterrupt() + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif /* ADC14_H_ */ diff --git a/example/rt_msp432/MSP432P4xx/aes256.c b/example/rt_msp432/MSP432P4xx/aes256.c new file mode 100644 index 0000000..bf821a8 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/aes256.c @@ -0,0 +1,355 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include + +bool AES256_setCipherKey(uint32_t moduleInstance, const uint8_t * cipherKey, + uint_fast16_t keyLength) +{ + uint_fast8_t i; + uint16_t sCipherKey; + + AES256_CMSIS(moduleInstance)->CTL0 |= 0; + + switch (keyLength) + { + case AES256_KEYLENGTH_128BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__128BIT; + break; + + case AES256_KEYLENGTH_192BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__192BIT; + break; + + case AES256_KEYLENGTH_256BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__256BIT; + break; + default: + return false; + } + + keyLength = keyLength / 8; + + for (i = 0; i < keyLength; i = i + 2) + { + sCipherKey = (uint16_t) (cipherKey[i]); + sCipherKey = sCipherKey | ((uint16_t) (cipherKey[i + 1]) << 8); + AES256_CMSIS(moduleInstance)->KEY = sCipherKey; + } + + // Wait until key is written + while (!BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_KEYWR_OFS)) + ; + + return true; +} + +void AES256_encryptData(uint32_t moduleInstance, const uint8_t * data, + uint8_t * encryptedData) +{ + uint_fast8_t i; + uint16_t tempData = 0; + uint16_t tempVariable = 0; + + // Set module to encrypt mode + AES256_CMSIS(moduleInstance)->CTL0 &= ~AES256_CTL0_OP_MASK; + + // Write data to encrypt to module + for (i = 0; i < 16; i = i + 2) + { + tempVariable = (uint16_t) (data[i]); + tempVariable = tempVariable | ((uint16_t) (data[i + 1]) << 8); + AES256_CMSIS(moduleInstance)->DIN = tempVariable; + } + + // Key that is already written shall be used + // Encryption is initialized by setting AES256_STAT_KEYWR to 1 + BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_KEYWR_OFS) = 1; + + // Wait unit finished ~167 MCLK + while (BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_BUSY_OFS)) + ; + + // Write encrypted data back to variable + for (i = 0; i < 16; i = i + 2) + { + tempData = AES256_CMSIS(moduleInstance)->DOUT; + *(encryptedData + i) = (uint8_t) tempData; + *(encryptedData + i + 1) = (uint8_t) (tempData >> 8); + } +} + +void AES256_decryptData(uint32_t moduleInstance, const uint8_t * data, + uint8_t * decryptedData) +{ + uint_fast8_t i; + uint16_t tempData = 0; + uint16_t tempVariable = 0; + + // Set module to decrypt mode + AES256_CMSIS(moduleInstance)->CTL0 |= (AES256_CTL0_OP_3); + + // Write data to decrypt to module + for (i = 0; i < 16; i = i + 2) + { + tempVariable = (uint16_t) (data[i + 1] << 8); + tempVariable = tempVariable | ((uint16_t) (data[i])); + AES256_CMSIS(moduleInstance)->DIN = tempVariable; + } + + // Key that is already written shall be used + // Now decryption starts + BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_KEYWR_OFS) = 1; + + // Wait unit finished ~167 MCLK + while (BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_BUSY_OFS)) + ; + + // Write encrypted data back to variable + for (i = 0; i < 16; i = i + 2) + { + tempData = AES256_CMSIS(moduleInstance)->DOUT; + *(decryptedData + i) = (uint8_t) tempData; + *(decryptedData + i + 1) = (uint8_t) (tempData >> 8); + } +} + +bool AES256_setDecipherKey(uint32_t moduleInstance, const uint8_t * cipherKey, + uint_fast16_t keyLength) +{ + uint8_t i; + uint16_t tempVariable = 0; + + // Set module to decrypt mode + AES256_CMSIS(moduleInstance)->CTL0 = + (AES256_CMSIS(moduleInstance)->CTL0 & ~AES256_CTL0_OP_MASK) | AES256_CTL0_OP1; + + switch (keyLength) + { + case AES256_KEYLENGTH_128BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__128BIT; + break; + + case AES256_KEYLENGTH_192BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__192BIT; + break; + + case AES256_KEYLENGTH_256BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__256BIT; + break; + + default: + return false; + } + + keyLength = keyLength / 8; + + // Write cipher key to key register + for (i = 0; i < keyLength; i = i + 2) + { + tempVariable = (uint16_t) (cipherKey[i]); + tempVariable = tempVariable | ((uint16_t) (cipherKey[i + 1]) << 8); + AES256_CMSIS(moduleInstance)->KEY = tempVariable; + } + + // Wait until key is processed ~52 MCLK + while (BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_BUSY_OFS)) + ; + + return true; +} + +void AES256_clearInterruptFlag(uint32_t moduleInstance) +{ + BITBAND_PERI(AES256_CMSIS(moduleInstance)->CTL0,AES256_CTL0_RDYIFG_OFS) = 0; +} + +uint32_t AES256_getInterruptFlagStatus(uint32_t moduleInstance) +{ + return BITBAND_PERI(AES256_CMSIS(moduleInstance)->CTL0, AES256_CTL0_RDYIFG_OFS); +} + +void AES256_enableInterrupt(uint32_t moduleInstance) +{ + BITBAND_PERI(AES256_CMSIS(moduleInstance)->CTL0,AES256_CTL0_RDYIE_OFS) = 1; +} + +void AES256_disableInterrupt(uint32_t moduleInstance) +{ + BITBAND_PERI(AES256_CMSIS(moduleInstance)->CTL0,AES256_CTL0_RDYIE_OFS) = 0; +} + +void AES256_reset(uint32_t moduleInstance) +{ + BITBAND_PERI(AES256_CMSIS(moduleInstance)->CTL0,AES256_CTL0_SWRST_OFS) = 1; +} + +void AES256_startEncryptData(uint32_t moduleInstance, const uint8_t * data) +{ + uint8_t i; + uint16_t tempVariable = 0; + + // Set module to encrypt mode + AES256_CMSIS(moduleInstance)->CTL0 &= ~AES256_CTL0_OP_MASK; + + // Write data to encrypt to module + for (i = 0; i < 16; i = i + 2) + { + tempVariable = (uint16_t) (data[i]); + tempVariable = tempVariable | ((uint16_t) (data[i + 1]) << 8); + AES256_CMSIS(moduleInstance)->DIN = tempVariable; + } + + // Key that is already written shall be used + // Encryption is initialized by setting AES256_STAT_KEYWR to 1 + BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_KEYWR_OFS) = 1; +} + +void AES256_startDecryptData(uint32_t moduleInstance, const uint8_t * data) +{ + uint_fast8_t i; + uint16_t tempVariable = 0; + + // Set module to decrypt mode + AES256_CMSIS(moduleInstance)->CTL0 |= (AES256_CTL0_OP_3); + + // Write data to decrypt to module + for (i = 0; i < 16; i = i + 2) + { + tempVariable = (uint16_t) (data[i + 1] << 8); + tempVariable = tempVariable | ((uint16_t) (data[i])); + AES256_CMSIS(moduleInstance)->DIN = tempVariable; + } + + // Key that is already written shall be used + // Now decryption starts + BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_KEYWR_OFS) = 1; +} + +bool AES256_startSetDecipherKey(uint32_t moduleInstance, + const uint8_t * cipherKey, uint_fast16_t keyLength) +{ + uint_fast8_t i; + uint16_t tempVariable = 0; + + AES256_CMSIS(moduleInstance)->CTL0 = + (AES256_CMSIS(moduleInstance)->CTL0 & ~AES256_CTL0_OP_MASK) | AES256_CTL0_OP1; + + switch (keyLength) + { + case AES256_KEYLENGTH_128BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__128BIT; + break; + + case AES256_KEYLENGTH_192BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__192BIT; + break; + + case AES256_KEYLENGTH_256BIT: + AES256_CMSIS(moduleInstance)->CTL0 |= AES256_CTL0_KL__256BIT; + break; + + default: + return false; + } + + keyLength = keyLength / 8; + + // Write cipher key to key register + for (i = 0; i < keyLength; i = i + 2) + { + tempVariable = (uint16_t) (cipherKey[i]); + tempVariable = tempVariable | ((uint16_t) (cipherKey[i + 1]) << 8); + AES256_CMSIS(moduleInstance)->KEY = tempVariable; + } + + return true; +} + +bool AES256_getDataOut(uint32_t moduleInstance, uint8_t *outputData) +{ + uint8_t i; + uint16_t tempData = 0; + + // If module is busy, exit and return failure + if (BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_BUSY_OFS)) + return false; + + // Write encrypted data back to variable + for (i = 0; i < 16; i = i + 2) + { + tempData = AES256_CMSIS(moduleInstance)->DOUT; + *(outputData + i) = (uint8_t) tempData; + *(outputData + i + 1) = (uint8_t) (tempData >> 8); + } + + return true; +} + +bool AES256_isBusy(uint32_t moduleInstance) +{ + return BITBAND_PERI(AES256_CMSIS(moduleInstance)->STAT, AES256_STAT_BUSY_OFS); +} + +void AES256_clearErrorFlag(uint32_t moduleInstance) +{ + BITBAND_PERI(AES256_CMSIS(moduleInstance)->CTL0, AES256_CTL0_ERRFG_OFS) = 0; +} + +uint32_t AES256_getErrorFlagStatus(uint32_t moduleInstance) +{ + return BITBAND_PERI(AES256_CMSIS(moduleInstance)->CTL0, AES256_CTL0_ERRFG_OFS); +} + +void AES256_registerInterrupt(uint32_t moduleInstance, void (*intHandler)(void)) +{ + Interrupt_registerInterrupt(INT_AES256, intHandler); + Interrupt_enableInterrupt(INT_AES256); +} + +void AES256_unregisterInterrupt(uint32_t moduleInstance) +{ + Interrupt_disableInterrupt(INT_AES256); + Interrupt_unregisterInterrupt(INT_AES256); +} + +uint32_t AES256_getInterruptStatus(uint32_t moduleInstance) +{ + return AES256_getInterruptFlagStatus(moduleInstance); +} + diff --git a/example/rt_msp432/MSP432P4xx/aes256.h b/example/rt_msp432/MSP432P4xx/aes256.h new file mode 100644 index 0000000..925ebbf --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/aes256.h @@ -0,0 +1,451 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef AES256_H_ +#define AES256_H_ + +//***************************************************************************** +// +//! \addtogroup aes256_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +/* Module Defines and macro for easy access */ +#define AES256_CMSIS(x) ((AES256_Type *) x) + +//***************************************************************************** +// +// The following are deprecated values. Please refer to documentation for the +// correct values to use. +// +//***************************************************************************** +#define Key_128BIT 128 +#define Key_192BIT 192 +#define Key_256BIT 256 + +//***************************************************************************** +// +// The following are values that can be passed to the keyLength parameter for +// functions: AES256_setCipherKey(), AES256_setDecipherKey(), and +// AES256_startSetDecipherKey(). +// +//***************************************************************************** +#define AES256_KEYLENGTH_128BIT 128 +#define AES256_KEYLENGTH_192BIT 192 +#define AES256_KEYLENGTH_256BIT 256 + +//***************************************************************************** +// +// The following are values that can be passed toThe following are values that +// can be returned by the AES256_getErrorFlagStatus() function. +// +//***************************************************************************** +#define AES256_ERROR_OCCURRED AES256_CTL0_ERRFG +#define AES256_NO_ERROR 0x00 + +//***************************************************************************** +// +// The following are values that can be passed toThe following are values that +// can be returned by the AES256_isBusy() function. +// +//***************************************************************************** +#define AES256_BUSY AES256_STAT_BUSY +#define AES256_NOT_BUSY 0x00 + +//***************************************************************************** +// +// The following are values that can be passed toThe following are values that +// can be returned by the AES256_getInterruptFlagStatus() function. +// +//***************************************************************************** +#define AES256_READY_INTERRUPT 0x01 +#define AES256_NOTREADY_INTERRUPT 0x00 + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \brief Loads a 128, 192 or 256 bit cipher key to AES256 module. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! \param cipherKey is a pointer to an uint8_t array with a length of 16 bytes +//! that contains a 128 bit cipher key. +//! \param keyLength is the length of the key. +//! Valid values are: +//! - \b AES256_KEYLENGTH_128BIT +//! - \b AES256_KEYLENGTH_192BIT +//! - \b AES256_KEYLENGTH_256BIT +//! +//! \return true if set correctly, false otherwise +// +//***************************************************************************** +extern bool AES256_setCipherKey(uint32_t moduleInstance, + const uint8_t *cipherKey, uint_fast16_t keyLength); + +//***************************************************************************** +// +//! \brief Encrypts a block of data using the AES256 module. +//! +//! The cipher key that is used for encryption should be loaded in advance by +//! using function AES256_setCipherKey() +//! +//! \param moduleInstance is the base address of the AES256 module. +//! \param data is a pointer to an uint8_t array with a length of 16 bytes that +//! contains data to be encrypted. +//! \param encryptedData is a pointer to an uint8_t array with a length of 16 +//! bytes in that the encrypted data will be written. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_encryptData(uint32_t moduleInstance, const uint8_t *data, + uint8_t *encryptedData); + +//***************************************************************************** +// +//! \brief Decrypts a block of data using the AES256 module. +//! +//! This function requires a pregenerated decryption key. A key can be loaded +//! and pregenerated by using function AES256_setDecipherKey() or +//! AES256_startSetDecipherKey(). The decryption takes 167 MCLK. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! \param data is a pointer to an uint8_t array with a length of 16 bytes that +//! contains encrypted data to be decrypted. +//! \param decryptedData is a pointer to an uint8_t array with a length of 16 +//! bytes in that the decrypted data will be written. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_decryptData(uint32_t moduleInstance, const uint8_t *data, + uint8_t *decryptedData); + +//***************************************************************************** +// +//! \brief Sets the decipher key. +//! +//! The API AES256_startSetDecipherKey or AES256_setDecipherKey must be invoked +//! before invoking AES256_startDecryptData. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! \param cipherKey is a pointer to an uint8_t array with a length of 16 bytes +//! that contains a 128 bit cipher key. +//! \param keyLength is the length of the key. +//! Valid values are: +//! - \b AES256_KEYLENGTH_128BIT +//! - \b AES256_KEYLENGTH_192BIT +//! - \b AES256_KEYLENGTH_256BIT +//! +//! \return true if set, false otherwise +// +//***************************************************************************** +extern bool AES256_setDecipherKey(uint32_t moduleInstance, + const uint8_t *cipherKey, uint_fast16_t keyLength); + +//***************************************************************************** +// +//! \brief Clears the AES256 ready interrupt flag. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! +//! Modified bits are \b AESRDYIFG of \b AESACTL0 register. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_clearInterruptFlag(uint32_t moduleInstance); + +//***************************************************************************** +// +//! \brief Gets the AES256 ready interrupt flag status. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! +//! \return One of the following: +//! - \b AES256_READY_INTERRUPT +//! - \b AES256_NOTREADY_INTERRUPT +//! \n indicating the status of the AES256 ready status +// +//***************************************************************************** +extern uint32_t AES256_getInterruptFlagStatus(uint32_t moduleInstance); + +//***************************************************************************** +// +//! \brief Enables AES256 ready interrupt. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! +//! Modified bits are \b AESRDYIE of \b AESACTL0 register. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_enableInterrupt(uint32_t moduleInstance); + +//***************************************************************************** +// +//! \brief Disables AES256 ready interrupt. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! +//! Modified bits are \b AESRDYIE of \b AESACTL0 register. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_disableInterrupt(uint32_t moduleInstance); + +//***************************************************************************** +// +//! \brief Resets AES256 Module immediately. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! +//! Modified bits are \b AESSWRST of \b AESACTL0 register. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_reset(uint32_t moduleInstance); + +//***************************************************************************** +// +//! \brief Starts an encryption process on the AES256 module. +//! +//! The cipher key that is used for decryption should be loaded in advance by +//! using function AES256_setCipherKey(). This is a non-blocking equivalent pf +//! AES256_encryptData(). It is recommended to use the interrupt functionality +//! to check for procedure completion then use the AES256_getDataOut() API to +//! retrieve the encrypted data. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! \param data is a pointer to an uint8_t array with a length of 16 bytes that +//! contains data to be encrypted. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_startEncryptData(uint32_t moduleInstance, + const uint8_t *data); + +//***************************************************************************** +// +//! \brief Decypts a block of data using the AES256 module. +//! +//! This is the non-blocking equivalant of AES256_decryptData(). This function +//! requires a pregenerated decryption key. A key can be loaded and +//! pregenerated by using function AES256_setDecipherKey() or +//! AES256_startSetDecipherKey(). The decryption takes 167 MCLK. It is +//! recommended to use interrupt to check for procedure completion then use the +//! AES256_getDataOut() API to retrieve the decrypted data. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! \param data is a pointer to an uint8_t array with a length of 16 bytes that +//! contains encrypted data to be decrypted. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_startDecryptData(uint32_t moduleInstance, + const uint8_t *data); + +//***************************************************************************** +// +//! \brief Sets the decipher key +//! +//! The API AES256_startSetDecipherKey() or AES256_setDecipherKey() must be +//! invoked before invoking AES256_startDecryptData. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! \param cipherKey is a pointer to an uint8_t array with a length of 16 bytes +//! that contains a 128 bit cipher key. +//! \param keyLength is the length of the key. +//! Valid values are: +//! - \b AES256_KEYLENGTH_128BIT +//! - \b AES256_KEYLENGTH_192BIT +//! - \b AES256_KEYLENGTH_256BIT +//! +//! \return true if set correctly, false otherwise +// +//***************************************************************************** +extern bool AES256_startSetDecipherKey(uint32_t moduleInstance, + const uint8_t *cipherKey, uint_fast16_t keyLength); + +//***************************************************************************** +// +//! \brief Reads back the output data from AES256 module. +//! +//! This function is meant to use after an encryption or decryption process +//! that was started and finished by initiating an interrupt by use of +//! AES256_startEncryptData or AES256_startDecryptData functions. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! \param outputData is a pointer to an uint8_t array with a length of 16 +//! bytes in that the data will be written. +//! +//! \return true if data is valid, otherwise false +// +//***************************************************************************** +extern bool AES256_getDataOut(uint32_t moduleInstance, + uint8_t *outputData); + +//***************************************************************************** +// +//! \brief Gets the AES256 module busy status. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! +//! \return true if busy, false otherwise +// +//***************************************************************************** +extern bool AES256_isBusy(uint32_t moduleInstance); + +//***************************************************************************** +// +//! \brief Clears the AES256 error flag. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! +//! Modified bits are \b AESERRFG of \b AESACTL0 register. +//! +//! \return None +// +//***************************************************************************** +extern void AES256_clearErrorFlag(uint32_t moduleInstance); + +//***************************************************************************** +// +//! \brief Gets the AES256 error flag status. +//! +//! \param moduleInstance is the base address of the AES256 module. +//! +//! \return One of the following: +//! - \b AES256_ERROR_OCCURRED +//! - \b AES256_NO_ERROR +//! \n indicating the error flag status +// +//***************************************************************************** +extern uint32_t AES256_getErrorFlagStatus(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Registers an interrupt handler for the AES interrupt. +//! +//! \param moduleInstance Instance of the AES256 module +//! +//! \param intHandler is a pointer to the function to be called when the +//! AES interrupt occurs. +//! +//! This function registers the handler to be called when a AES +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific AES interrupts must be enabled +//! via AES256_enableInterrupt(). It is the interrupt handler's responsibility +//! to clear the interrupt source via AES256_clearInterrupt(). +//! +//! \return None. +// +//***************************************************************************** +extern void AES256_registerInterrupt(uint32_t moduleInstance, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the AES interrupt +//! +//! \param moduleInstance Instance of the AES256 module +//! +//! This function unregisters the handler to be called when AES +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void AES256_unregisterInterrupt(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Returns the current interrupt flag for the peripheral. +//! +//! \param moduleInstance Instance of the AES256 module +//! +//! \return The currently triggered interrupt flag for the module. +// +//***************************************************************************** +extern uint32_t AES256_getInterruptStatus(uint32_t moduleInstance); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif /* AES256_H_ */ + diff --git a/example/rt_msp432/MSP432P4xx/ccs/msp432p4xx_driverlib.lib b/example/rt_msp432/MSP432P4xx/ccs/msp432p4xx_driverlib.lib new file mode 100644 index 0000000..2f5bdca Binary files /dev/null and b/example/rt_msp432/MSP432P4xx/ccs/msp432p4xx_driverlib.lib differ diff --git a/example/rt_msp432/MSP432P4xx/comp_e.c b/example/rt_msp432/MSP432P4xx/comp_e.c new file mode 100644 index 0000000..c246ce2 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/comp_e.c @@ -0,0 +1,317 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include + +static uint16_t __getRegisterSettingForInput(uint32_t input) +{ + switch (input) + { + case COMP_E_INPUT0: + return COMP_E_CTL0_IPSEL_0; + case COMP_E_INPUT1: + return COMP_E_CTL0_IPSEL_1; + case COMP_E_INPUT2: + return COMP_E_CTL0_IPSEL_2; + case COMP_E_INPUT3: + return COMP_E_CTL0_IPSEL_3; + case COMP_E_INPUT4: + return COMP_E_CTL0_IPSEL_4; + case COMP_E_INPUT5: + return COMP_E_CTL0_IPSEL_5; + case COMP_E_INPUT6: + return COMP_E_CTL0_IPSEL_6; + case COMP_E_INPUT7: + return COMP_E_CTL0_IPSEL_7; + case COMP_E_INPUT8: + return COMP_E_CTL0_IPSEL_8; + case COMP_E_INPUT9: + return COMP_E_CTL0_IPSEL_9; + case COMP_E_INPUT10: + return COMP_E_CTL0_IPSEL_10; + case COMP_E_INPUT11: + return COMP_E_CTL0_IPSEL_11; + case COMP_E_INPUT12: + return COMP_E_CTL0_IPSEL_12; + case COMP_E_INPUT13: + return COMP_E_CTL0_IPSEL_13; + case COMP_E_INPUT14: + return COMP_E_CTL0_IPSEL_14; + case COMP_E_INPUT15: + return COMP_E_CTL0_IPSEL_15; + case COMP_E_VREF: + return COMP_E_VREF; + default: + ASSERT(false); + return 0x11; + } + +} + +bool COMP_E_initModule(uint32_t comparator, const COMP_E_Config *config) +{ + uint_fast8_t positiveTerminalInput = __getRegisterSettingForInput( + config->positiveTerminalInput); + uint_fast8_t negativeTerminalInput = __getRegisterSettingForInput( + config->negativeTerminalInput); + bool retVal = true; + + ASSERT(positiveTerminalInput < 0x10); ASSERT(negativeTerminalInput < 0x10); + ASSERT(positiveTerminalInput != negativeTerminalInput); + ASSERT( + config->outputFilterEnableAndDelayLevel + <= COMP_E_FILTEROUTPUT_DLYLVL4); + + /* Reset COMPE Control 1 & Interrupt Registers for initialization */ + COMP_E_CMSIS(comparator)->CTL0 = 0; + COMP_E_CMSIS(comparator)->INT = 0; + + // Set the Positive Terminal + if (COMP_E_VREF != positiveTerminalInput) + { + // Enable Positive Terminal Input Mux and Set to the appropriate input + COMP_E_CMSIS(comparator)->CTL0 |= COMP_E_CTL0_IPEN + + positiveTerminalInput; + + // Disable the input buffer + COMP_E_CMSIS(comparator)->CTL3 |= (1 << positiveTerminalInput); + } else + { + // Reset and Set COMPE Control 2 Register + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL2,COMP_E_CTL2_RSEL_OFS) = 0; + } + + // Set the Negative Terminal + if (COMP_E_VREF != negativeTerminalInput) + { + // Enable Negative Terminal Input Mux and Set to the appropriate input + COMP_E_CMSIS(comparator)->CTL0 |= COMP_E_CTL0_IMEN + + (negativeTerminalInput << 8); + + // Disable the input buffer + COMP_E_CMSIS(comparator)->CTL3 |= (1 << negativeTerminalInput); + } else + { + // Reset and Set COMPE Control 2 Register + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL2, COMP_E_CTL2_RSEL_OFS) = 1; + } + + // Reset and Set COMPE Control 1 Register + COMP_E_CMSIS(comparator)->CTL1 = config->powerMode + + config->outputFilterEnableAndDelayLevel + + config->invertedOutputPolarity; + + return retVal; +} + +void COMP_E_setReferenceVoltage(uint32_t comparator, + uint_fast16_t supplyVoltageReferenceBase, + uint_fast16_t lowerLimitSupplyVoltageFractionOf32, + uint_fast16_t upperLimitSupplyVoltageFractionOf32) +{ + ASSERT(supplyVoltageReferenceBase <= COMP_E_VREFBASE2_5V); + ASSERT(upperLimitSupplyVoltageFractionOf32 <= 32); + ASSERT(lowerLimitSupplyVoltageFractionOf32 <= 32); ASSERT( + upperLimitSupplyVoltageFractionOf32 + >= lowerLimitSupplyVoltageFractionOf32); + + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_MRVS_OFS) = 0; + COMP_E_CMSIS(comparator)->CTL2 &= COMP_E_CTL2_RSEL; + + // Set Voltage Source(Vcc | Vref, resistor ladder or not) + if (COMP_E_REFERENCE_AMPLIFIER_DISABLED == supplyVoltageReferenceBase) + { + COMP_E_CMSIS(comparator)->CTL2 |= COMP_E_CTL2_RS_1; + } else if (lowerLimitSupplyVoltageFractionOf32 == 32) + { + COMP_E_CMSIS(comparator)->CTL2 |= COMP_E_CTL2_RS_3; + } else + { + COMP_E_CMSIS(comparator)->CTL2 |= COMP_E_CTL2_RS_2; + } + + // Set COMPE Control 2 Register + COMP_E_CMSIS(comparator)->CTL2 |= supplyVoltageReferenceBase + + ((upperLimitSupplyVoltageFractionOf32 - 1) << 8) + + (lowerLimitSupplyVoltageFractionOf32 - 1); +} + +void COMP_E_setReferenceAccuracy(uint32_t comparator, + uint_fast16_t referenceAccuracy) +{ + ASSERT( + (referenceAccuracy == COMP_E_ACCURACY_STATIC) + || (referenceAccuracy == COMP_E_ACCURACY_CLOCKED)); + + if (referenceAccuracy) + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL2, COMP_E_CTL2_REFACC_OFS) = 1; + else + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL2, COMP_E_CTL2_REFACC_OFS) = 0; + +} + +void COMP_E_setPowerMode(uint32_t comparator, uint_fast16_t powerMode) +{ + COMP_E_CMSIS(comparator)->CTL1 = (COMP_E_CMSIS(comparator)->CTL1 + & ~(COMP_E_CTL1_PWRMD_MASK)) | powerMode; +} + +void COMP_E_enableModule(uint32_t comparator) +{ + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_ON_OFS) = 1; +} + +void COMP_E_disableModule(uint32_t comparator) +{ + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_ON_OFS) = 0; +} + +void COMP_E_shortInputs(uint32_t comparator) +{ + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_SHORT_OFS) = 1; +} + +void COMP_E_unshortInputs(uint32_t comparator) +{ + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_SHORT_OFS) = 0; +} + +void COMP_E_disableInputBuffer(uint32_t comparator, uint_fast16_t inputPort) +{ + ASSERT(inputPort <= COMP_E_INPUT15); + + COMP_E_CMSIS(comparator)->CTL3 |= (inputPort); +} + +void COMP_E_enableInputBuffer(uint32_t comparator, uint_fast16_t inputPort) +{ + ASSERT(inputPort <= COMP_E_INPUT15); + + COMP_E_CMSIS(comparator)->CTL3 &= ~(inputPort); +} + +void COMP_E_swapIO(uint32_t comparator) +{ + COMP_E_CMSIS(comparator)->CTL1 ^= COMP_E_CTL1_EX; // Toggle CEEX bit +} + +uint8_t COMP_E_outputValue(uint32_t comparator) +{ + return COMP_E_CMSIS(comparator)->CTL1 & COMP_E_CTL1_OUT; +} + +void COMP_E_enableInterrupt(uint32_t comparator, uint_fast16_t mask) +{ + // Set the Interrupt enable bit + COMP_E_CMSIS(comparator)->INT |= mask; +} + +uint_fast16_t COMP_E_getEnabledInterruptStatus(uint32_t comparator) +{ + return COMP_E_getInterruptStatus(comparator) & + COMP_E_CMSIS(comparator)->INT; +} + +void COMP_E_disableInterrupt(uint32_t comparator, uint_fast16_t mask) +{ + COMP_E_CMSIS(comparator)->INT &= ~(mask); +} + +void COMP_E_clearInterruptFlag(uint32_t comparator, uint_fast16_t mask) +{ + COMP_E_CMSIS(comparator)->INT &= ~(mask); +} + +uint_fast16_t COMP_E_getInterruptStatus(uint32_t comparator) +{ + return (COMP_E_CMSIS(comparator)->INT & (COMP_E_OUTPUT_INTERRUPT_FLAG | + COMP_E_INTERRUPT_FLAG_INVERTED_POLARITY | + COMP_E_INTERRUPT_FLAG_READY)); +} + +void COMP_E_setInterruptEdgeDirection(uint32_t comparator, + uint_fast8_t edgeDirection) +{ + ASSERT(edgeDirection <= COMP_E_RISINGEDGE); + + // Set the edge direction that will trigger an interrupt + if (COMP_E_RISINGEDGE == edgeDirection) + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_IES_OFS) = 1; + else if (COMP_E_FALLINGEDGE == edgeDirection) + BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_IES_OFS) = 0; +} + +void COMP_E_toggleInterruptEdgeDirection(uint32_t comparator) +{ + COMP_E_CMSIS(comparator)->CTL1 ^= COMP_E_CTL1_IES; +} + +void COMP_E_registerInterrupt(uint32_t comparator, void (*intHandler)(void)) +{ + switch (comparator) + { + case COMP_E0_BASE: + Interrupt_registerInterrupt(INT_COMP_E0, intHandler); + Interrupt_enableInterrupt(INT_COMP_E0); + break; + case COMP_E1_BASE: + Interrupt_registerInterrupt(INT_COMP_E1, intHandler); + Interrupt_enableInterrupt(INT_COMP_E1); + break; + default: + ASSERT(false); + } +} + +void COMP_E_unregisterInterrupt(uint32_t comparator) +{ + switch (comparator) + { + case COMP_E0_BASE: + Interrupt_disableInterrupt(INT_COMP_E0); + Interrupt_unregisterInterrupt(INT_COMP_E0); + break; + case COMP_E1_BASE: + Interrupt_disableInterrupt(INT_COMP_E1); + Interrupt_unregisterInterrupt(INT_COMP_E1); + break; + default: + ASSERT(false); + } +} + diff --git a/example/rt_msp432/MSP432P4xx/comp_e.h b/example/rt_msp432/MSP432P4xx/comp_e.h new file mode 100644 index 0000000..d8da59f --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/comp_e.h @@ -0,0 +1,733 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef COMP_E_H_ +#define COMP_E_H_ + +//***************************************************************************** +// +//! \addtogroup comp_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +/* Module defines for Comp */ +#define COMP_E_CMSIS(x) ((COMP_E_Type *) x) + +#define COMP_E_FILTEROUTPUT_OFF 0x00 +#define COMP_E_FILTEROUTPUT_DLYLVL1 (COMP_E_CTL1_F + COMP_E_CTL1_FDLY_0) +#define COMP_E_FILTEROUTPUT_DLYLVL2 (COMP_E_CTL1_F + COMP_E_CTL1_FDLY_1) +#define COMP_E_FILTEROUTPUT_DLYLVL3 (COMP_E_CTL1_F + COMP_E_CTL1_FDLY_2) +#define COMP_E_FILTEROUTPUT_DLYLVL4 (COMP_E_CTL1_F + COMP_E_CTL1_FDLY_3) + +#define COMP_E_INPUT0 (0x01) +#define COMP_E_INPUT1 (0x02) +#define COMP_E_INPUT2 (0x04) +#define COMP_E_INPUT3 (0x08) +#define COMP_E_INPUT4 (0x10) +#define COMP_E_INPUT5 (0x20) +#define COMP_E_INPUT6 (0x40) +#define COMP_E_INPUT7 (0x80) +#define COMP_E_INPUT8 (0x100) +#define COMP_E_INPUT9 (0x200) +#define COMP_E_INPUT10 (0x400) +#define COMP_E_INPUT11 (0x800) +#define COMP_E_INPUT12 (0x1000) +#define COMP_E_INPUT13 (0x2000) +#define COMP_E_INPUT14 (0x4000) +#define COMP_E_INPUT15 (0x8000) +#define COMP_E_VREF (0x9F) + +#define COMP_E_NORMALOUTPUTPOLARITY (!(COMP_E_CTL1_OUTPOL)) +#define COMP_E_INVERTEDOUTPUTPOLARITY (COMP_E_CTL1_OUTPOL) + +#define COMP_E_REFERENCE_AMPLIFIER_DISABLED (COMP_E_CTL2_CEREFL_0) +#define COMP_E_VREFBASE1_2V (COMP_E_CTL2_CEREFL_1) +#define COMP_E_VREFBASE2_0V (COMP_E_CTL2_CEREFL_2) +#define COMP_E_VREFBASE2_5V (COMP_E_CTL2_CEREFL_3) + +#define COMP_E_ACCURACY_STATIC (!COMP_E_CTL2_REFACC) +#define COMP_E_ACCURACY_CLOCKED (COMP_E_CTL2_REFACC) + +#define COMP_E_HIGH_SPEED_MODE (COMP_E_CTL1_PWRMD_0) +#define COMP_E_NORMAL_MODE (COMP_E_CTL1_PWRMD_1) +#define COMP_E_ULTRA_LOW_POWER_MODE (COMP_E_CTL1_PWRMD_2) + +#define COMP_E_OUTPUT_INTERRUPT (COMP_E_INT_IE) +#define COMP_E_INVERTED_POLARITY_INTERRUPT (COMP_E_INT_IIE) +#define COMP_E_READY_INTERRUPT (COMP_E_INT_RDYIE) + +#define COMP_E_OUTPUT_INTERRUPT_FLAG (COMP_E_INT_IFG) +#define COMP_E_INTERRUPT_FLAG_INVERTED_POLARITY (COMP_E_INT_IIFG) +#define COMP_E_INTERRUPT_FLAG_READY (COMP_E_INT_RDYIFG) + +#define COMP_E_FALLINGEDGE (!(COMP_E_CTL1_IES)) +#define COMP_E_RISINGEDGE (COMP_E_CTL1_IES) + +#define COMP_E_LOW (0x0) +#define COMP_E_HIGH (COMP_E_CTL1_OUT) + +//***************************************************************************** +// +//! ypedef COMP_E_Config +//! \brief Type definition for \link _COMP_E_Config \endlink structure +//! +//! \struct _COMP_E_Config +//! \brief Configuration structure for Comparator module. See +//! \link COMP_E_initModule \endlink for parameter documentation. +// +//***************************************************************************** +typedef struct _COMP_E_Config +{ + uint_fast16_t positiveTerminalInput; + uint_fast16_t negativeTerminalInput; + uint_fast8_t outputFilterEnableAndDelayLevel; + uint_fast8_t invertedOutputPolarity; + uint_fast16_t powerMode; +} COMP_E_Config; + +//***************************************************************************** +// +//! Initializes the Comparator Module. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param config Configuration structure for the Comparator module +//! +//!
+//! Configuration options for \link COMP_E_Config \endlink structure. +//!
+//! +//! \param positiveTerminalInput selects the input to the positive terminal. +//! Valid values are +//! - \b COMP_E_INPUT0 [Default] +//! - \b COMP_E_INPUT1 +//! - \b COMP_E_INPUT2 +//! - \b COMP_E_INPUT3 +//! - \b COMP_E_INPUT4 +//! - \b COMP_E_INPUT5 +//! - \b COMP_E_INPUT6 +//! - \b COMP_E_INPUT7 +//! - \b COMP_E_INPUT8 +//! - \b COMP_E_INPUT9 +//! - \b COMP_E_INPUT10 +//! - \b COMP_E_INPUT11 +//! - \b COMP_E_INPUT12 +//! - \b COMP_E_INPUT13 +//! - \b COMP_E_INPUT14 +//! - \b COMP_E_INPUT15 +//! - \b COMP_E_VREF +//! \n Modified bits are \b CEIPSEL and \b CEIPEN of \b CECTL0 register, +//! \b CERSEL of \b CECTL2 register, and CEPDx of \b CECTL3 register. +//! \param negativeTerminalInput selects the input to the negative terminal. +//! \n Valid values are: +//! - \b COMP_E_INPUT0 [Default] +//! - \b COMP_E_INPUT1 +//! - \b COMP_E_INPUT2 +//! - \b COMP_E_INPUT3 +//! - \b COMP_E_INPUT4 +//! - \b COMP_E_INPUT5 +//! - \b COMP_E_INPUT6 +//! - \b COMP_E_INPUT7 +//! - \b COMP_E_INPUT8 +//! - \b COMP_E_INPUT9 +//! - \b COMP_E_INPUT10 +//! - \b COMP_E_INPUT11 +//! - \b COMP_E_INPUT12 +//! - \b COMP_E_INPUT13 +//! - \b COMP_E_INPUT14 +//! - \b COMP_E_INPUT15 +//! - \b COMP_E_VREF +//! \n Modified bits are \b CEIMSEL and \b CEIMEN of \b CECTL0 register, +//! \b CERSEL of \b CECTL2 register, and CEPDx of \b CECTL3 register. +//! \param outputFilterEnableAndDelayLevel controls the output filter delay +//! state, which is either off or enabled with a specified delay level. +//! \n Valid values are +//! - \b COMP_E_FILTEROUTPUT_OFF [Default] +//! - \b COMP_E_FILTEROUTPUT_DLYLVL1 +//! - \b COMP_E_FILTEROUTPUT_DLYLVL2 +//! - \b COMP_E_FILTEROUTPUT_DLYLVL3 +//! - \b COMP_E_FILTEROUTPUT_DLYLVL4 +//! \n This parameter is device specific and delay levels should be found +//! in the device's datasheet. +//! \n Modified bits are \b CEF and \b CEFDLY of \b CECTL1 register. +//! \param invertedOutputPolarity controls if the output will be inverted or +//! not. Valid values are +//! - \b COMP_E_NORMALOUTPUTPOLARITY - indicates the output should be +//! normal. [Default] +//! - \b COMP_E_INVERTEDOUTPUTPOLARITY - the output should be inverted. +//! \n Modified bits are \b CEOUTPOL of \b CECTL1 register. +//! \param powerMode controls the power mode of the module +//! - \b COMP_E_HIGH_SPEED_MODE [default] +//! - \b COMP_E_NORMAL_MODE +//! - \b COMP_E_ULTRA_LOW_POWER_MODE +//! Upon successful initialization of the Comparator module, this function will +//! have reset all necessary register bits and set the given options in the +//! registers. To actually use the comparator module, the COMP_E_enableModule() +//! function must be explicitly called before use. +//! If a Reference Voltage is set to a terminal, the Voltage should be set +//! using the COMP_E_setReferenceVoltage() function. +//! +//! \return true or false of the initialization process. +// +//***************************************************************************** +extern bool COMP_E_initModule(uint32_t comparator, const COMP_E_Config *config); + +//***************************************************************************** +// +//! Generates a Reference Voltage to the terminal selected during +//! initialization. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param supplyVoltageReferenceBase decides the source and max amount of +//! Voltage that can be used as a reference. +//! Valid values are +//! - \b COMP_E_REFERENCE_AMPLIFIER_DISABLED +//! - \b COMP_E_VREFBASE1_2V +//! - \b COMP_E_VREFBASE2_0V +//! - \b COMP_E_VREFBASE2_5V +//! \param upperLimitSupplyVoltageFractionOf32 is the numerator of the +//! equation to generate the reference voltage for the upper limit +//! reference voltage. Valid values are between 0 and 32. +//! \param lowerLimitSupplyVoltageFractionOf32 is the numerator of the +//! equation to generate the reference voltage for the lower limit +//! reference voltage. Valid values are between 0 and 32. +//!
Modified bits are \b CEREF0 of \b CECTL2 register. +//! +//! Use this function to generate a voltage to serve as a reference to the +//! terminal selected at initialization. The voltage is determined by the +//! equation: Vbase * (Numerator / 32). If the upper and lower limit voltage +//! numerators are equal, then a static reference is defined, whereas they are +//! different then a hysteresis effect is generated. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_setReferenceVoltage(uint32_t comparator, + uint_fast16_t supplyVoltageReferenceBase, + uint_fast16_t lowerLimitSupplyVoltageFractionOf32, + uint_fast16_t upperLimitSupplyVoltageFractionOf32); + +//***************************************************************************** +// +//! Sets the reference accuracy +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param referenceAccuracy is the reference accuracy setting of the +//! comparator. Clocked is for low power/low accuracy. +//! Valid values are +//! - \b COMP_E_ACCURACY_STATIC +//! - \b COMP_E_ACCURACY_CLOCKED +//!
Modified bits are \b CEREFACC of \b CECTL2 register. +//! +//! The reference accuracy is set to the desired setting. Clocked is better for +//! low power operations but has a lower accuracy. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_setReferenceAccuracy(uint32_t comparator, + uint_fast16_t referenceAccuracy); + +//***************************************************************************** +// +//! Sets the power mode +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param powerMode decides the power mode +//! Valid values are +//! - \b COMP_E_HIGH_SPEED_MODE +//! - \b COMP_E_NORMAL_MODE +//! - \b COMP_E_ULTRA_LOW_POWER_MODE +//!
Modified bits are \b CEPWRMD of \b CECTL1 register. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_setPowerMode(uint32_t comparator, uint_fast16_t powerMode); + +//***************************************************************************** +// +//! Turns on the Comparator module. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! This function sets the bit that enables the operation of the +//! Comparator module. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_enableModule(uint32_t comparator); + +//***************************************************************************** +// +//! Turns off the Comparator module. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! This function clears the CEON bit disabling the operation of the Comparator +//! module, saving from excess power consumption. +//! +//! Modified bits are \b CEON of \b CECTL1 register. +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_disableModule(uint32_t comparator); + +//***************************************************************************** +// +//! Shorts the two input pins chosen during initialization. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! This function sets the bit that shorts the devices attached to the input +//! pins chosen from the initialization of the comparator. +//! +//! Modified bits are \b CESHORT of \b CECTL1 register. +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_shortInputs(uint32_t comparator); + +//***************************************************************************** +// +//! Disables the short of the two input pins chosen during initialization. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! This function clears the bit that shorts the devices attached to the input +//! pins chosen from the initialization of the comparator. +//! +//! Modified bits are \b CESHORT of \b CECTL1 register. +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_unshortInputs(uint32_t comparator); + +//***************************************************************************** +// +//! Disables the input buffer of the selected input port to effectively allow +//! for analog signals. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param inputPort is the port in which the input buffer will be disabled. +//! Valid values are a logical OR of the following: +//! - \b COMP_E_INPUT0 [Default] +//! - \b COMP_E_INPUT1 +//! - \b COMP_E_INPUT2 +//! - \b COMP_E_INPUT3 +//! - \b COMP_E_INPUT4 +//! - \b COMP_E_INPUT5 +//! - \b COMP_E_INPUT6 +//! - \b COMP_E_INPUT7 +//! - \b COMP_E_INPUT8 +//! - \b COMP_E_INPUT9 +//! - \b COMP_E_INPUT10 +//! - \b COMP_E_INPUT11 +//! - \b COMP_E_INPUT12 +//! - \b COMP_E_INPUT13 +//! - \b COMP_E_INPUT14 +//! - \b COMP_E_INPUT15 +//!
Modified bits are \b CEPDx of \b CECTL3 register. +//! +//! This function sets the bit to disable the buffer for the specified input +//! port to allow for analog signals from any of the comparator input pins. This +//! bit is automatically set when the input is initialized to be used with the +//! comparator module. This function should be used whenever an analog input is +//! connected to one of these pins to prevent parasitic voltage from causing +//! unexpected results. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_disableInputBuffer(uint32_t comparator, + uint_fast16_t inputPort); + +//***************************************************************************** +// +//! Enables the input buffer of the selected input port to allow for digital +//! signals. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param inputPort is the port in which the input buffer will be enabled. +//! Valid values are a logical OR of the following: +//! - \b COMP_E_INPUT0 [Default] +//! - \b COMP_E_INPUT1 +//! - \b COMP_E_INPUT2 +//! - \b COMP_E_INPUT3 +//! - \b COMP_E_INPUT4 +//! - \b COMP_E_INPUT5 +//! - \b COMP_E_INPUT6 +//! - \b COMP_E_INPUT7 +//! - \b COMP_E_INPUT8 +//! - \b COMP_E_INPUT9 +//! - \b COMP_E_INPUT10 +//! - \b COMP_E_INPUT11 +//! - \b COMP_E_INPUT12 +//! - \b COMP_E_INPUT13 +//! - \b COMP_E_INPUT14 +//! - \b COMP_E_INPUT15 +//!
Modified bits are \b CEPDx of \b CECTL3 register. +//! +//! This function clears the bit to enable the buffer for the specified input +//! port to allow for digital signals from any of the comparator input pins. +//! This should not be reset if there is an analog signal connected to the +//! specified input pin to prevent from unexpected results. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_enableInputBuffer(uint32_t comparator, + uint_fast16_t inputPort); + +//***************************************************************************** +// +//! Toggles the bit that swaps which terminals the inputs go to, while also +//! inverting the output of the comparator. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \ bCOMP_E0 +//! - \ bCOMP_E1 +//! +//! This function toggles the bit that controls which input goes to which +//! terminal. After initialization, this bit is set to 0, after toggling it once +//! the inputs are routed to the opposite terminal and the output is inverted. +//! +//! Modified bits are \b CEEX of \b CECTL1 register. +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_swapIO(uint32_t comparator); + +//***************************************************************************** +// +//! Returns the output value of the Comparator module. +//! +//! \param comparator is the instance of the Comparator module. Valid parameters +//! vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! Returns the output value of the Comparator module. +//! +//! \return COMP_E_HIGH or COMP_E_LOW as the output value of the Comparator +//! module. +// +//***************************************************************************** +extern uint8_t COMP_E_outputValue(uint32_t comparator); + +//***************************************************************************** +// +//! Enables selected Comparator interrupt sources. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param mask is the bit mask of the interrupt sources to be enabled. +//! Mask value is the logical OR of any of the following +//! - \b COMP_E_OUTPUT_INTERRUPT - Output interrupt +//! - \b COMP_E_INVERTED_POLARITY_INTERRUPT - Output interrupt inverted +//! polarity +//! - \b COMP_E_READY_INTERRUPT - Ready interrupt +//! +//! Enables the indicated Comparator interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. The default trigger for the non-inverted +//! interrupt is a rising edge of the output, this can be changed with the +//! interruptSetEdgeDirection() function. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_enableInterrupt(uint32_t comparator, uint_fast16_t mask); + +//***************************************************************************** +// +//! Disables selected Comparator interrupt sources. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param mask is the bit mask of the interrupt sources to be disabled. +//! Mask value is the logical OR of any of the following +//! - \b COMP_E_OUTPUT_INTERRUPT - Output interrupt +//! - \b COMP_E_INVERTED_POLARITY_INTERRUPT - Output interrupt inverted +//! polarity +//! - \b COMP_E_READY_INTERRUPT - Ready interrupt +//! +//! Disables the indicated Comparator interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_disableInterrupt(uint32_t comparator, uint_fast16_t mask); + +//***************************************************************************** +// +//! Clears Comparator interrupt flags. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param mask is a bit mask of the interrupt sources to be cleared. +//! Mask value is the logical OR of any of the following +//! - \b COMP_E_INTERRUPT_FLAG - Output interrupt flag +//! - \b COMP_E_INTERRUPT_FLAG_INVERTED_POLARITY - Output interrupt flag +//! inverted polarity +//! - \b COMP_E_INTERRUPT_FLAG_READY - Ready interrupt flag +//! +//! The Comparator interrupt source is cleared, so that it no longer asserts. +//! The highest interrupt flag is automatically cleared when an interrupt vector +//! generator is used. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_clearInterruptFlag(uint32_t comparator, uint_fast16_t mask); + +//***************************************************************************** +// +//! Gets the current Comparator interrupt status. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! This returns the interrupt status for the Comparator module based on which +//! flag is passed. +//! +//! \return The current interrupt flag status for the corresponding mask. +// +//***************************************************************************** +extern uint_fast16_t COMP_E_getInterruptStatus(uint32_t comparator); + +//***************************************************************************** +// +//! Enables selected Comparator interrupt sources masked with the enabled +//! interrupts. This function is useful to call in ISRs to get a list +//! of pending interrupts that are actually enabled and could have caused the +//! ISR. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! Enables the indicated Comparator interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. The default trigger for the non-inverted +//! interrupt is a rising edge of the output, this can be changed with the +//! COMP_E_setInterruptEdgeDirection() function. +//! +//! \return NONE +// +//***************************************************************************** +extern uint_fast16_t COMP_E_getEnabledInterruptStatus(uint32_t comparator); + +//***************************************************************************** +// +//! Explicitly sets the edge direction that would trigger an interrupt. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! \param edgeDirection determines which direction the edge would have to go +//! to generate an interrupt based on the non-inverted interrupt flag. +//! Valid values are +//! - \b COMP_E_FALLINGEDGE - sets the bit to generate an interrupt when +//! the output of the comparator falls from HIGH to LOW if the +//! normal interrupt bit is set(and LOW to HIGH if the inverted +//! interrupt enable bit is set). [Default] +//! - \b COMP_E_RISINGEDGE - sets the bit to generate an interrupt when the +//! output of the comparator rises from LOW to HIGH if the normal +//! interrupt bit is set(and HIGH to LOW if the inverted interrupt +//! enable bit is set). +//!
Modified bits are \b CEIES of \b CECTL1 register. +//! +//! This function will set which direction the output will have to go, whether +//! rising or falling, to generate an interrupt based on a non-inverted +//! interrupt. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_setInterruptEdgeDirection(uint32_t comparator, + uint_fast8_t edgeDirection); + +//***************************************************************************** +// +//! Toggles the edge direction that would trigger an interrupt. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! This function will toggle which direction the output will have to go, +//! whether rising or falling, to generate an interrupt based on a non-inverted +//! interrupt. If the direction was rising, it is now falling, if it was +//! falling, it is now rising. +//! +//! Modified bits are \b CEIES of \b CECTL1 register. +//! +//! \return NONE +// +//***************************************************************************** +extern void COMP_E_toggleInterruptEdgeDirection(uint32_t comparator); + +//***************************************************************************** +// +//! Registers an interrupt handler for the Comparator E interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the +//! Comparator interrupt occurs. +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! This function registers the handler to be called when a Comparator +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific Comparator interrupts must be enabled +//! via COMP_E_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via COMP_E_clearInterruptFlag(). +//! +//! \return None. +// +//***************************************************************************** +extern void COMP_E_registerInterrupt(uint32_t comparator, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the Comparator E interrupt +//! +//! \param comparator is the instance of the Comparator module. Valid +//! parameters vary from part to part, but can include: +//! - \b COMP_E0_BASE +//! - \b COMP_E1_BASE +//! +//! This function unregisters the handler to be called when Comparator E +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void COMP_E_unregisterInterrupt(uint32_t comparator); + +/* Backwards Compatibility Layer */ +#define COMP_E_enable(a) COMP_E_enableModule(a) +#define COMP_E_disable(a) COMP_E_disableModule(a) +#define COMP_E_IOSwap(a) COMP_E_swapIO(a) +#define COMP_E_interruptToggleEdgeDirection(a) COMP_E_toggleInterruptEdgeDirection(a) +#define COMP_E_clearInterrupt(a,b) COMP_E_clearInterruptFlag(a,b) + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + + +#endif /* COMP_E_H_ */ diff --git a/example/rt_msp432/MSP432P4xx/cpu.c b/example/rt_msp432/MSP432P4xx/cpu.c new file mode 100644 index 0000000..d92612d --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/cpu.c @@ -0,0 +1,430 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include + +//***************************************************************************** +// +// Wrapper function for the CPSID instruction. Returns the state of PRIMASK +// on entry. +// +//***************************************************************************** +#if defined(__GNUC__) +uint32_t __attribute__((naked)) CPU_cpsid(void) +{ + uint32_t ret; + + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsid i\n" + " bx lr\n" + : "=r" (ret)); + + // + // The return is handled in the inline assembly, but the compiler will + // still complain if there is not an explicit return here (despite the fact + // that this does not result in any code being produced because of the + // naked attribute). + // + return(ret); +} +#endif +#if defined(__ICCARM__) +uint32_t CPU_cpsid(void) +{ + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsid i\n"); + + // + // "Warning[Pe940]: missing return statement at end of non-void function" + // is suppressed here to avoid putting a "bx lr" in the inline assembly + // above and a superfluous return statement here. + // +#pragma diag_suppress=Pe940 +} +#pragma diag_default=Pe940 +#endif +#if defined(__CC_ARM) +__asm uint32_t CPU_cpsid(void) +{ + // + // Read PRIMASK and disable interrupts. + // + mrs r0, PRIMASK; + cpsid i; + bx lr +} +#endif +#if defined(__TI_ARM__) +uint32_t CPU_cpsid(void) +{ + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsid i\n" + " bx lr\n"); + + // + // The following keeps the compiler happy, because it wants to see a + // return value from this function. It will generate code to return + // a zero. However, the real return is the "bx lr" above, so the + // return(0) is never executed and the function returns with the value + // you expect in R0. + // + return(0); +} +#endif + +//***************************************************************************** +// +// Wrapper function returning the state of PRIMASK (indicating whether +// interrupts are enabled or disabled). +// +//***************************************************************************** +#if defined(__GNUC__) +uint32_t __attribute__((naked)) CPU_primask(void) +{ + uint32_t ret; + + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " bx lr\n" + : "=r" (ret)); + + // + // The return is handled in the inline assembly, but the compiler will + // still complain if there is not an explicit return here (despite the fact + // that this does not result in any code being produced because of the + // naked attribute). + // + return(ret); +} +#endif +#if defined(__ICCARM__) +uint32_t CPU_primask(void) +{ + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n"); + + // + // "Warning[Pe940]: missing return statement at end of non-void function" + // is suppressed here to avoid putting a "bx lr" in the inline assembly + // above and a superfluous return statement here. + // +#pragma diag_suppress=Pe940 +} +#pragma diag_default=Pe940 +#endif +#if defined(__CC_ARM) +__asm uint32_t CPU_primask(void) +{ + // + // Read PRIMASK and disable interrupts. + // + mrs r0, PRIMASK; + bx lr +} +#endif +#if defined(__TI_ARM__) +uint32_t CPU_primask(void) +{ + // + // Read PRIMASK and disable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " bx lr\n"); + + // + // The following keeps the compiler happy, because it wants to see a + // return value from this function. It will generate code to return + // a zero. However, the real return is the "bx lr" above, so the + // return(0) is never executed and the function returns with the value + // you expect in R0. + // + return(0); +} +#endif + +//***************************************************************************** +// +// Wrapper function for the CPSIE instruction. Returns the state of PRIMASK +// on entry. +// +//***************************************************************************** +#if defined(__GNUC__) +uint32_t __attribute__((naked)) CPU_cpsie(void) +{ + uint32_t ret; + + // + // Read PRIMASK and enable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsie i\n" + " bx lr\n" + : "=r" (ret)); + + // + // The return is handled in the inline assembly, but the compiler will + // still complain if there is not an explicit return here (despite the fact + // that this does not result in any code being produced because of the + // naked attribute). + // + return(ret); +} +#endif +#if defined(__ICCARM__) +uint32_t CPU_cpsie(void) +{ + // + // Read PRIMASK and enable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsie i\n"); + + // + // "Warning[Pe940]: missing return statement at end of non-void function" + // is suppressed here to avoid putting a "bx lr" in the inline assembly + // above and a superfluous return statement here. + // +#pragma diag_suppress=Pe940 +} +#pragma diag_default=Pe940 +#endif +#if defined(__CC_ARM) +__asm uint32_t CPU_cpsie(void) +{ + // + // Read PRIMASK and enable interrupts. + // + mrs r0, PRIMASK; + cpsie i; + bx lr +} +#endif +#if defined(__TI_ARM__) +uint32_t CPU_cpsie(void) +{ + // + // Read PRIMASK and enable interrupts. + // + __asm(" mrs r0, PRIMASK\n" + " cpsie i\n" + " bx lr\n"); + + // + // The following keeps the compiler happy, because it wants to see a + // return value from this function. It will generate code to return + // a zero. However, the real return is the "bx lr" above, so the + // return(0) is never executed and the function returns with the value + // you expect in R0. + // + return(0); +} +#endif + +//***************************************************************************** +// +// Wrapper function for the CPUWFI instruction. +// +//***************************************************************************** +#if defined(__GNUC__) +void __attribute__((naked)) CPU_wfi(void) +{ + // + // Wait for the next interrupt. + // + __asm(" wfi\n" + " bx lr\n"); +} +#endif +#if defined(__ICCARM__) +void CPU_wfi(void) +{ + // + // Wait for the next interrupt. + // + __asm(" wfi\n"); +} +#endif +#if defined(__CC_ARM) +__asm void CPU_wfi(void) +{ + // + // Wait for the next interrupt. + // + wfi; + bx lr +} +#endif +#if defined(__TI_ARM__) +void CPU_wfi(void) +{ + // + // Wait for the next interrupt. + // + __asm(" wfi\n"); +} +#endif + +//***************************************************************************** +// +// Wrapper function for writing the BASEPRI register. +// +//***************************************************************************** +#if defined(__GNUC__) +void __attribute__((naked)) CPU_basepriSet(uint32_t newBasepri) +{ + // + // Set the BASEPRI register + // + __asm(" msr BASEPRI, r0\n" + " bx lr\n"); +} +#endif +#if defined(__ICCARM__) +void CPU_basepriSet(uint32_t newBasepri) +{ + // + // Set the BASEPRI register + // + __asm(" msr BASEPRI, r0\n"); +} +#endif +#if defined(__CC_ARM) +__asm void CPU_basepriSet(uint32_t newBasepri) +{ + // + // Set the BASEPRI register + // + msr BASEPRI, r0; + bx lr +} +#endif +#if defined(__TI_ARM__) +void CPU_basepriSet(uint32_t newBasepri) +{ + // + // Set the BASEPRI register + // + __asm(" msr BASEPRI, r0\n"); +} +#endif + +//***************************************************************************** +// +// Wrapper function for reading the BASEPRI register. +// +//***************************************************************************** +#if defined(__GNUC__) +uint32_t __attribute__((naked)) CPU_basepriGet(void) +{ + uint32_t ret; + + // + // Read BASEPRI + // + __asm(" mrs r0, BASEPRI\n" + " bx lr\n" + : "=r" (ret)); + + // + // The return is handled in the inline assembly, but the compiler will + // still complain if there is not an explicit return here (despite the fact + // that this does not result in any code being produced because of the + // naked attribute). + // + return(ret); +} +#endif +#if defined(__ICCARM__) +uint32_t CPU_basepriGet(void) +{ + // + // Read BASEPRI + // + __asm(" mrs r0, BASEPRI\n"); + + // + // "Warning[Pe940]: missing return statement at end of non-void function" + // is suppressed here to avoid putting a "bx lr" in the inline assembly + // above and a superfluous return statement here. + // +#pragma diag_suppress=Pe940 +} +#pragma diag_default=Pe940 +#endif +#if defined(__CC_ARM) +__asm uint32_t CPU_basepriGet(void) +{ + // + // Read BASEPRI + // + mrs r0, BASEPRI; + bx lr +} +#endif +#if defined(__TI_ARM__) +uint32_t CPU_basepriGet(void) +{ + // + // Read BASEPRI + // + __asm(" mrs r0, BASEPRI\n" + " bx lr\n"); + + // + // The following keeps the compiler happy, because it wants to see a + // return value from this function. It will generate code to return + // a zero. However, the real return is the "bx lr" above, so the + // return(0) is never executed and the function returns with the value + // you expect in R0. + // + return(0); +} +#endif diff --git a/example/rt_msp432/MSP432P4xx/cpu.h b/example/rt_msp432/MSP432P4xx/cpu.h new file mode 100644 index 0000000..a09953b --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/cpu.h @@ -0,0 +1,76 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __CPU_H__ +#define __CPU_H__ + +#include + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +// Prototypes. +// +//***************************************************************************** +extern uint32_t CPU_cpsid(void); +extern uint32_t CPU_cpsie(void); +extern uint32_t CPU_primask(void); +extern void CPU_wfi(void); +extern uint32_t CPU_basepriGet(void); +extern void CPU_basepriSet(uint32_t newBasepri); + + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +#endif // __CPU_H__ + diff --git a/example/rt_msp432/MSP432P4xx/crc32.c b/example/rt_msp432/MSP432P4xx/crc32.c new file mode 100644 index 0000000..ba882d8 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/crc32.c @@ -0,0 +1,147 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include "crc32.h" +#include +#include +#include + +void CRC32_setSeed(uint32_t seed, uint_fast8_t crcType) +{ + ASSERT((CRC16_MODE == crcType) || (CRC32_MODE == crcType)); + + if (CRC16_MODE == crcType) + CRC32->INIRES16 = seed; + else + { + CRC32->INIRES32_HI = ((seed & 0xFFFF0000) >> 16); + CRC32->INIRES32_LO = (seed & 0xFFFF); + } +} + +void CRC32_set8BitData(uint8_t dataIn, uint_fast8_t crcType) +{ + ASSERT((CRC16_MODE == crcType) || (CRC32_MODE == crcType)); + + if (CRC16_MODE == crcType) + HWREG8(&(CRC32->DI16)) = dataIn; + else + HWREG8(&(CRC32->DI32)) = dataIn; +} + +void CRC32_set16BitData(uint16_t dataIn, uint_fast8_t crcType) +{ + ASSERT((CRC16_MODE == crcType) || (CRC32_MODE == crcType)); + + if (CRC16_MODE == crcType) + CRC32->DI16 = dataIn; + else + CRC32->DI32 = dataIn; +} + +void CRC32_set32BitData(uint32_t dataIn) +{ + //CRC32->DI32 = dataIn & 0xFFFF; + //CRC32->DI32 = (uint16_t) ((dataIn & 0xFFFF0000) >> 16); + + HWREG16(&(CRC32->DI32)) = dataIn & 0xFFFF; + HWREG16(&(CRC32->DI32)) = (uint16_t)( + (dataIn & 0xFFFF0000) >> 16); +} + +void CRC32_set8BitDataReversed(uint8_t dataIn, uint_fast8_t crcType) +{ + ASSERT((CRC16_MODE == crcType) || (CRC32_MODE == crcType)); + + if (CRC16_MODE == crcType) + HWREG8(&(CRC32->DIRB16)) = dataIn; + else + HWREG8(&(CRC32->DIRB32)) = dataIn; +} + +void CRC32_set16BitDataReversed(uint16_t dataIn, uint_fast8_t crcType) +{ + ASSERT((CRC16_MODE == crcType) || (CRC32_MODE == crcType)); + + if (CRC16_MODE == crcType) + CRC32->DIRB16 = dataIn; + else + CRC32->DIRB32 = dataIn; +} + +void CRC32_set32BitDataReversed(uint32_t dataIn) +{ + //CRC32->DIRB32 = dataIn & 0xFFFF; + //CRC32->DIRB32 = (uint16_t) ((dataIn & 0xFFFF0000) >> 16); + + HWREG16(&(CRC32->DIRB32)) = dataIn & 0xFFFF; + HWREG16(&(CRC32->DIRB32)) = (uint16_t)( + (dataIn & 0xFFFF0000) >> 16); + +} + +uint32_t CRC32_getResult(uint_fast8_t crcType) +{ + uint32_t result; + ASSERT((CRC16_MODE == crcType) || (CRC32_MODE == crcType)); + + if (CRC16_MODE == crcType) + return CRC32->INIRES16; + else + { + result = CRC32->INIRES32_HI; + result = (result << 16); + result |= CRC32->INIRES32_LO; + return (result); + } +} + +uint32_t CRC32_getResultReversed(uint_fast8_t crcType) +{ + uint32_t result; + ASSERT((CRC16_MODE == crcType) || (CRC32_MODE == crcType)); + + if (CRC16_MODE == crcType) + return CRC32->RESR16; + else + { + result = CRC32->RESR32_HI; + result = (result << 16); + result |= CRC32->RESR32_LO; + return (result); + } +} + diff --git a/example/rt_msp432/MSP432P4xx/crc32.h b/example/rt_msp432/MSP432P4xx/crc32.h new file mode 100644 index 0000000..c75214c --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/crc32.h @@ -0,0 +1,235 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef _CRC_32_H + +//***************************************************************************** +// +//! \addtogroup crc32_api +//! @{ +// +//***************************************************************************** + +#include + +#define CRC16_MODE 0x00 +#define CRC32_MODE 0x01 + +//***************************************************************************** +// +//! Sets the seed for the CRC. +//! +//! \param seed is the seed for the CRC to start generating a signature from. +//! Modified bits are \b CRC16INIRESL0 of \b CRC16INIRESL0 register. +//! \b CRC32INIRESL0 of \b CRC32INIRESL0 register +//! \param crcType selects between CRC32 and CRC16 +//! Valid values are \b CRC16_MODE and \b CRC32_MODE +//! +//! This function sets the seed for the CRC to begin generating a signature with +//! the given seed and all passed data. Using this function resets the CRC32 +//! signature. +//! +//! \return NONE +// +//***************************************************************************** +extern void CRC32_setSeed(uint32_t seed, uint_fast8_t crcType); + +//***************************************************************************** +// +//! Sets the 8 Bit data to add into the CRC module to generate a new signature. +//! +//! \param dataIn is the data to be added, through the CRC module, to the +//! signature. +//! Modified bits are \b CRC16DIB0 of \b CRC16DIB0 register. +//! \b CRC32DIB0 of \b CRC32DIB0 register. +//! \param crcType selects between CRC32 and CRC16 +//! Valid values are \b CRC16_MODE and \b CRC32_MODE +//! +//! This function sets the given data into the CRC module to generate the new +//! signature from the current signature and new data. Bit 0 is +//! treated as LSB. +//! +//! \return NONE +// +//***************************************************************************** +extern void CRC32_set8BitData(uint8_t dataIn, uint_fast8_t crcType); + +//***************************************************************************** +// +//! Sets the 16 Bit data to add into the CRC module to generate a new signature. +//! +//! \param dataIn is the data to be added, through the CRC module, to the +//! signature. +//! Modified bits are \b CRC16DIW0 of \b CRC16DIW0 register. +//! \b CRC32DIW0 of \b CRC32DIW0 register. +//! \param crcType selects between CRC32 and CRC16 +//! Valid values are \b CRC16_MODE and \b CRC32_MODE +//! +//! This function sets the given data into the CRC module to generate the new +//! signature from the current signature and new data. Bit 0 is +//! treated as LSB +//! +//! \return NONE +// +//***************************************************************************** +extern void CRC32_set16BitData(uint16_t dataIn, uint_fast8_t crcType); + +//***************************************************************************** +// +//! Sets the 32 Bit data to add into the CRC module to generate a new signature. +//! Available only for CRC32_MODE and not for CRC16_MODE +//! \param dataIn is the data to be added, through the CRC module, to the +//! signature. +//! Modified bits are \b CRC32DIL0 of \b CRC32DIL0 register. +//! +//! This function sets the given data into the CRC module to generate the new +//! signature from the current signature and new data. Bit 0 is +//! treated as LSB +//! +//! \return NONE +// +//***************************************************************************** +extern void CRC32_set32BitData(uint32_t dataIn); + +//***************************************************************************** +// +//! Translates the data by reversing the bits in each 8 bit data and then sets +//! this data to add into the CRC module to generate a new signature. +//! +//! \param dataIn is the data to be added, through the CRC module, to the +//! signature. +//! Modified bits are \b CRC16DIRBB0 of \b CRC16DIRBB0 register. +//! \b CRC32DIRBB0 of \b CRC32DIRBB0 register. +//! \param crcType selects between CRC32 and CRC16 +//! Valid values are \b CRC16_MODE and \b CRC32_MODE +//! +//! This function first reverses the bits in each byte of the data and then +//! generates the new signature from the current signature and new translated +//! data. Bit 0 is treated as MSB. +//! +//! \return NONE +// +//***************************************************************************** +extern void CRC32_set8BitDataReversed(uint8_t dataIn, uint_fast8_t crcType); + +//***************************************************************************** +// +//! Translates the data by reversing the bits in each 16 bit data and then +//! sets this data to add into the CRC module to generate a new signature. +//! +//! \param dataIn is the data to be added, through the CRC module, to the +//! signature. +//! Modified bits are \b CRC16DIRBW0 of \b CRC16DIRBW0 register. +//! \b CRC32DIRBW0 of \b CRC32DIRBW0 register. +//! \param crcType selects between CRC32 and CRC16 +//! Valid values are \b CRC16_MODE and \b CRC32_MODE +//! +//! This function first reverses the bits in each byte of the data and then +//! generates the new signature from the current signature and new translated +//! data. Bit 0 is treated as MSB. +//! +//! \return NONE +// +//***************************************************************************** +extern void CRC32_set16BitDataReversed(uint16_t dataIn, uint_fast8_t crcType); + +//***************************************************************************** +// +//! Translates the data by reversing the bits in each 32 Bit Data and then +//! sets this data to add into the CRC module to generate a new signature. +//! Available only for CRC32 mode and not for CRC16 mode +//! \param dataIn is the data to be added, through the CRC module, to the +//! signature. +//! Modified bits are \b CRC32DIRBL0 of \b CRC32DIRBL0 register. +//! +//! This function first reverses the bits in each byte of the data and then +//! generates the new signature from the current signature and new translated +//! data. Bit 0 is treated as MSB. +//! +//! \return NONE +// +//***************************************************************************** +extern void CRC32_set32BitDataReversed(uint32_t dataIn); + +//***************************************************************************** +// +//! Returns the value of CRC Signature Result. +//! +//! \param crcType selects between CRC32 and CRC16 +//! Valid values are \b CRC16_MODE and \b CRC32_MODE +//! +//! This function returns the value of the signature result generated by the CRC. +//! Bit 0 is treated as LSB. +//! \return uint32_t Result +// +//***************************************************************************** +extern uint32_t CRC32_getResult(uint_fast8_t crcType); + +//***************************************************************************** +// +//! Returns the bit-wise reversed format of the 32 bit Signature Result. +//! +//! \param crcType selects between CRC32 and CRC16 +//! Valid values are \b CRC16_MODE and \b CRC32_MODE +//! +//! This function returns the bit-wise reversed format of the Signature Result. +//! Bit 0 is treated as MSB. +//! +//! \return uint32_t Result +// +//***************************************************************************** +extern uint32_t CRC32_getResultReversed(uint_fast8_t crcType); + +/* Defines for future devices that might have multiple instances */ +#define CRC32_setSeedMultipleInstance(a,b,c) CRC32_setSeed(b,c) +#define CRC32_set8BitDataMultipleInstance(a,b,c) CRC32_set8BitData(b,c) +#define CRC32_set16BitDataMultipleInstance(a,b,c) CRC32_set16BitData(b,c) +#define CRC32_set32BitDataMultipleInstance(a,b) CRC32_set32BitData(b) +#define CRC32_set8BitDataReversedMultipleInstance(a,b,c) CRC32_set8BitDataReversed(b,c) +#define CRC32_set16BitDataReversedMultipleInstance(a,b,c) CRC32_set16BitDataReversed(b,c) +#define CRC32_set32BitDataReversedMultipleInstance(a,b) CRC32_set32BitDataReversed(b) +#define CRC32_getResultMultipleInstance(a,b) CRC32_getResult() +#define CRC32_getResultReversedMultipleInstance(a,b) CRC32_getResultReversed(b) + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + + +#endif diff --git a/example/rt_msp432/MSP432P4xx/cs.c b/example/rt_msp432/MSP432P4xx/cs.c new file mode 100644 index 0000000..44849d3 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/cs.c @@ -0,0 +1,993 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include + +/* DriverLib Includes */ +#include +#include +#include +#include + +/* Statics */ +static uint32_t hfxtFreq; +static uint32_t lfxtFreq; + +#ifdef DEBUG + +bool _CSIsClockDividerValid(uint8_t divider) +{ + return ((divider == CS_CLOCK_DIVIDER_1) || (divider == CS_CLOCK_DIVIDER_2) + || (divider == CS_CLOCK_DIVIDER_4) || (divider == CS_CLOCK_DIVIDER_8) + || (divider == CS_CLOCK_DIVIDER_16) || (divider == CS_CLOCK_DIVIDER_32) + || (divider == CS_CLOCK_DIVIDER_64) || (divider == CS_CLOCK_DIVIDER_128)); +} + +#endif + +static uint32_t _CSGetHFXTFrequency() +{ + if (hfxtFreq >= CS_1MHZ && hfxtFreq <= CS_4MHZ) + return CS_CTL2_HFXTFREQ_0; + else if (hfxtFreq > CS_4MHZ && hfxtFreq <= CS_8MHZ) + return CS_CTL2_HFXTFREQ_1; + else if (hfxtFreq > CS_8MHZ && hfxtFreq <= CS_16MHZ) + return CS_CTL2_HFXTFREQ_2; + else if (hfxtFreq > CS_16MHZ && hfxtFreq <= CS_24MHZ) + return CS_CTL2_HFXTFREQ_3; + else if (hfxtFreq > CS_24MHZ && hfxtFreq <= CS_32MHZ) + return CS_CTL2_HFXTFREQ_4; + else if (hfxtFreq > CS_32MHZ && hfxtFreq <= CS_40MHZ) + return CS_CTL2_HFXTFREQ_5; + else if (hfxtFreq > CS_40MHZ && hfxtFreq <= CS_48MHZ) + return CS_CTL2_HFXTFREQ_5; + else + { + ASSERT(false); + return 0; + } + +} + +static uint32_t _CSGetDividerValue(uint32_t wDivider) +{ + switch (wDivider) + { + case CS_CLOCK_DIVIDER_1: + return 1; + case CS_CLOCK_DIVIDER_2: + return 2; + case CS_CLOCK_DIVIDER_4: + return 4; + case CS_CLOCK_DIVIDER_8: + return 8; + case CS_CLOCK_DIVIDER_16: + return 16; + case CS_CLOCK_DIVIDER_32: + return 32; + case CS_CLOCK_DIVIDER_64: + return 64; + case CS_CLOCK_DIVIDER_128: + return 128; + default: + ASSERT(false); + return 1; + } +} + +static uint32_t _CSComputeCLKFrequency(uint32_t wClockSource, uint32_t wDivider) +{ + uint_fast8_t bDivider; + + bDivider = _CSGetDividerValue(wDivider); + + switch (wClockSource) + { + case CS_LFXTCLK_SELECT: + { + if (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + CS_clearInterruptFlag(CS_LFXT_FAULT); + + if (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + return (128000 / bDivider); + else + return (32768 / bDivider); + } + } + return lfxtFreq / bDivider; + } + case CS_HFXTCLK_SELECT: + { + if (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + CS_clearInterruptFlag(CS_HFXT_FAULT); + + if (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + return (128000 / bDivider); + else + return (32768 / bDivider); + } + } + return hfxtFreq / bDivider; + } + case CS_VLOCLK_SELECT: + return CS_VLOCLK_FREQUENCY / bDivider; + case CS_REFOCLK_SELECT: + { + if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + return (128000 / bDivider); + else + return (32768 / bDivider); + } + case CS_DCOCLK_SELECT: + return (CS_getDCOFrequency() / bDivider); + case CS_MODOSC_SELECT: + return CS_MODCLK_FREQUENCY / bDivider; + default: + ASSERT(false); + return 0; + } +} + +//****************************************************************************** +// Internal function for getting DCO nominal frequency +//****************************************************************************** +static uint32_t _CSGetDOCFrequency(void) +{ + uint32_t dcoFreq; + + switch (CS->CTL0 & CS_CTL0_DCORSEL_MASK) + { + case CS_CTL0_DCORSEL_0: + dcoFreq = 1500000; + break; + case CS_CTL0_DCORSEL_1: + dcoFreq = 3000000; + break; + case CS_CTL0_DCORSEL_2: + dcoFreq = 6000000; + break; + case CS_CTL0_DCORSEL_3: + dcoFreq = 12000000; + break; + case CS_CTL0_DCORSEL_4: + dcoFreq = 24000000; + break; + case CS_CTL0_DCORSEL_5: + dcoFreq = 48000000; + break; + default: + dcoFreq = 0; + } + + return (dcoFreq); +} + +void CS_setExternalClockSourceFrequency(uint32_t lfxt_XT_CLK_frequency, + uint32_t hfxt_XT_CLK_frequency) +{ + hfxtFreq = hfxt_XT_CLK_frequency; + lfxtFreq = lfxt_XT_CLK_frequency; +} + +void CS_initClockSignal(uint32_t selectedClockSignal, uint32_t clockSource, + uint32_t clockSourceDivider) +{ + ASSERT(_CSIsClockDividerValid(clockSourceDivider)); + + /* Unlocking the CS Module */ + CS->KEY = CS_KEY; + + switch (selectedClockSignal) + { + case CS_ACLK: + { + /* Making sure that the clock signal for ACLK isn't set to anything + * invalid + */ + ASSERT( + (selectedClockSignal != CS_DCOCLK_SELECT) + && (selectedClockSignal != CS_MODOSC_SELECT) + && (selectedClockSignal != CS_HFXTCLK_SELECT)); + + /* Waiting for the clock source ready bit to be valid before + * changing */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_ACLK_READY_OFS)) + ; + + /* Setting the divider and source */ + CS->CTL1 = ((clockSourceDivider >> CS_ACLK_DIV_BITPOS) + | (clockSource << CS_ACLK_SRC_BITPOS)) + | (CS->CTL1 & ~(CS_CTL1_SELA_MASK | CS_CTL1_DIVA_MASK)); + + /* Waiting for ACLK to be ready again */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_ACLK_READY_OFS)) + ; + + break; + } + case CS_MCLK: + { + + /* Waiting for the clock source ready bit to be valid before + * changing */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_MCLK_READY_OFS)) + ; + + CS->CTL1 = ((clockSourceDivider >> CS_MCLK_DIV_BITPOS) + | (clockSource << CS_MCLK_SRC_BITPOS)) + | (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)); + + /* Waiting for MCLK to be ready */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_MCLK_READY_OFS)) + ; + + break; + } + case CS_SMCLK: + { + /* Waiting for the clock source ready bit to be valid before + * changing */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_SMCLK_READY_OFS)) + ; + + CS->CTL1 = ((clockSourceDivider >> CS_SMCLK_DIV_BITPOS) + | (clockSource << CS_HSMCLK_SRC_BITPOS)) + | (CS->CTL1 & ~(CS_CTL1_DIVS_MASK | CS_CTL1_SELS_MASK)); + + /* Waiting for SMCLK to be ready */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_SMCLK_READY_OFS)) + ; + + break; + } + case CS_HSMCLK: + { + /* Waiting for the clock source ready bit to be valid before + * changing */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_HSMCLK_READY_OFS)) + ; + + CS->CTL1 = ((clockSourceDivider >> CS_HSMCLK_DIV_BITPOS) + | (clockSource << CS_HSMCLK_SRC_BITPOS)) + | (CS->CTL1 & ~(CS_CTL1_DIVHS_MASK | CS_CTL1_SELS_MASK)); + + /* Waiting for HSMCLK to be ready */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_HSMCLK_READY_OFS)) + ; + + break; + } + case CS_BCLK: + { + + /* Waiting for the clock source ready bit to be valid before + * changing */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_BCLK_READY_OFS)) + ; + + /* Setting the clock source and then returning + * (cannot divide CLK) + */ + if (clockSource == CS_LFXTCLK_SELECT) + BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS) = 0; + else if (clockSource == CS_REFOCLK_SELECT) + BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS) = 1; + else + ASSERT(false); + + /* Waiting for BCLK to be ready */ + while (!BITBAND_PERI(CS->STAT, CS_STAT_BCLK_READY_OFS)) + ; + + break; + } + default: + { + /* Should never get here */ + ASSERT(false); + } + } + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +bool CS_startHFXT(bool bypassMode) +{ + return CS_startHFXTWithTimeout(bypassMode, 0); +} + +bool CS_startHFXTWithTimeout(bool bypassMode, uint32_t timeout) +{ + uint32_t wHFFreqRange; + uint_fast8_t bNMIStatus; + bool boolTimeout; + + /* Unlocking the CS Module */ + CS->KEY = CS_KEY; + + /* Saving status and temporarily disabling NMIs for UCS faults */ + bNMIStatus = SysCtl_getNMISourceStatus() & SYSCTL_CS_SRC; + SysCtl_disableNMISource(SYSCTL_CS_SRC); + + /* Determining which frequency range to use */ + wHFFreqRange = _CSGetHFXTFrequency(); + boolTimeout = (timeout == 0) ? false : true; + + /* Setting to maximum drive strength */ + BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 1; + CS->CTL2 = (CS->CTL2 & (~CS_CTL2_HFXTFREQ_MASK)) | (wHFFreqRange); + + if (bypassMode) + { + BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTBYPASS_OFS) = 1; + } else + { + BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTBYPASS_OFS) = 0; + } + + /* Starting and Waiting for frequency stabilization */ + BITBAND_PERI(CS->CTL2, CS_CTL2_HFXT_EN_OFS) = 1; + while (BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + if (boolTimeout && ((--timeout) == 0)) + break; + + BITBAND_PERI(CS->CLRIFG,CS_CLRIFG_CLR_HFXTIFG_OFS) = 1; + } + + /* Setting the drive strength */ + if (!bypassMode) + { + if (wHFFreqRange != CS_CTL2_HFXTFREQ_0) + BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 1; + else + BITBAND_PERI(CS->CTL2, CS_CTL2_HFXTDRIVE_OFS) = 0; + } + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; + + /* Enabling the NMI state */ + SysCtl_enableNMISource(bNMIStatus); + + if(boolTimeout && timeout == 0) + return false; + + return true; +} + +bool CS_startLFXT(uint32_t xtDrive) +{ + return CS_startLFXTWithTimeout(xtDrive, 0); +} + +bool CS_startLFXTWithTimeout(uint32_t xtDrive, uint32_t timeout) +{ + uint8_t bNMIStatus; + bool boolBypassMode, boolTimeout; + + ASSERT(lfxtFreq != 0) + ASSERT( + (xtDrive == CS_LFXT_DRIVE0) || (xtDrive == CS_LFXT_DRIVE1) + || (xtDrive == CS_LFXT_DRIVE2) + || (xtDrive == CS_LFXT_DRIVE3) + || (xtDrive == CS_LFXT_BYPASS)); + + /* Unlocking the CS Module */ + CS->KEY = CS_KEY; + + /* Saving status and temporarily disabling NMIs for UCS faults */ + bNMIStatus = SysCtl_getNMISourceStatus() & SYSCTL_CS_SRC; + SysCtl_disableNMISource(SYSCTL_CS_SRC); + boolBypassMode = (xtDrive == CS_LFXT_BYPASS) ? true : false; + boolTimeout = (timeout == 0) ? false : true; + + /* Setting to maximum drive strength */ + if (boolBypassMode) + { + BITBAND_PERI(CS->CTL2, CS_CTL2_LFXTBYPASS_OFS) = 1; + } else + { + CS->CTL2 |= (CS_LFXT_DRIVE3); + BITBAND_PERI(CS->CTL2, CS_CTL2_LFXTBYPASS_OFS) = 0; + } + + /* Waiting for frequency stabilization */ + BITBAND_PERI(CS->CTL2, CS_CTL2_LFXT_EN_OFS) = 1; + + while (BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + if (boolTimeout && ((--timeout) == 0)) + break; + + BITBAND_PERI(CS->CLRIFG,CS_CLRIFG_CLR_LFXTIFG_OFS) = 1; + } + + /* Setting the drive strength */ + if (!boolBypassMode) + { + CS->CTL2 = ((CS->CTL2 & ~CS_LFXT_DRIVE3) | xtDrive); + } + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; + + /* Enabling the NMI state */ + SysCtl_enableNMISource(bNMIStatus); + + if(boolTimeout && timeout == 0) + return false; + + return true; +} + +void CS_enableClockRequest(uint32_t selectClock) +{ + ASSERT( + selectClock == CS_ACLK || selectClock == CS_HSMCLK + || selectClock == CS_SMCLK || selectClock == CS_MCLK); + + /* Unlocking the module */ + CS->KEY = CS_KEY; + + CS->CLKEN |= selectClock; + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_disableClockRequest(uint32_t selectClock) +{ + ASSERT( + selectClock == CS_ACLK || selectClock == CS_HSMCLK + || selectClock == CS_SMCLK || selectClock == CS_MCLK); + + /* Unlocking the module */ + CS->KEY = CS_KEY; + + CS->CLKEN &= ~selectClock; + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_setReferenceOscillatorFrequency(uint8_t referenceFrequency) +{ + ASSERT( + referenceFrequency == CS_REFO_32KHZ + || referenceFrequency == CS_REFO_128KHZ); + + /* Unlocking the module */ + CS->KEY = CS_KEY; + + BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS) = referenceFrequency; + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_enableDCOExternalResistor(void) +{ + /* Unlocking the module */ + CS->KEY = CS_KEY; + + BITBAND_PERI(CS->CTL0,CS_CTL0_DCORES_OFS) = 1; + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_setDCOExternalResistorCalibration(uint_fast8_t calData, + uint_fast8_t freqRange) +{ + uint_fast8_t rselVal; + + /* Unlocking the module */ + CS->KEY = CS_KEY; + + rselVal = (CS->CTL0 | CS_CTL0_DCORSEL_MASK)>>CS_CTL0_DCORSEL_OFS; + + CS->CTL0 &= ~CS_CTL0_DCORSEL_MASK; + + if( (freqRange == CS_OVER32MHZ) && ( TLV->HWREV > DEVICE_PG1_1)) + { + CS->DCOERCAL1 &= ~CS_DCOERCAL1_DCO_FCAL_RSEL5_MASK; + CS->DCOERCAL1 |= (calData); + } + else + { + CS->DCOERCAL0 &= ~CS_DCOERCAL0_DCO_FCAL_RSEL04_MASK; + CS->DCOERCAL0 |= (calData)<CTL0 |= (rselVal)<KEY, CS_KEY_KEY_OFS) = 1; + +} + +void CS_disableDCOExternalResistor(void) +{ + /* Unlocking the module */ + CS->KEY = CS_KEY; + + BITBAND_PERI(CS->CTL0,CS_CTL0_DCORES_OFS) = 0; + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_setDCOCenteredFrequency(uint32_t dcoFreq) +{ + ASSERT( + dcoFreq == CS_DCO_FREQUENCY_1_5 || dcoFreq == CS_DCO_FREQUENCY_3 + || dcoFreq == CS_DCO_FREQUENCY_6 + || dcoFreq == CS_DCO_FREQUENCY_12 + || dcoFreq == CS_DCO_FREQUENCY_24 + || dcoFreq == CS_DCO_FREQUENCY_48); + + /* Unlocking the CS Module */ + CS->KEY = CS_KEY; + + /* Resetting Tuning Parameters and Setting the frequency */ + CS->CTL0 = ((CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dcoFreq); + + /* Locking the CS Module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_tuneDCOFrequency(int16_t tuneParameter) +{ + CS->KEY = CS_KEY; + + uint16_t dcoTuneMask = 0x1FFF; + uint16_t dcoTuneSigned = 0x1000; + + if (TLV->HWREV > DEVICE_PG1_1) { + dcoTuneMask = 0x3FF; + dcoTuneSigned = 0x200; + } + + if (tuneParameter < 0) + { + CS->CTL0 = ((CS->CTL0 & ~dcoTuneMask) | (tuneParameter + & dcoTuneMask) | dcoTuneSigned); + } + else + { + CS->CTL0 = ((CS->CTL0 & ~dcoTuneMask) | (tuneParameter + & dcoTuneMask)); + } + + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +uint32_t CS_getDCOFrequency(void) +{ + float dcoConst; + int32_t calVal; + uint32_t centeredFreq; + int16_t dcoTune; + uint_fast8_t tlvLength; + SysCtl_CSCalTLV_Info *csInfo; + uint32_t retVal; + + centeredFreq = _CSGetDOCFrequency(); + + /* Parsing the TLV and getting the maximum erase pulses */ + SysCtl_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**)&csInfo); + + if(tlvLength == 0) + { + return centeredFreq; + } + + /* Checking to see if we need to do signed conversion */ + if ( TLV->HWREV > DEVICE_PG1_1) + { + dcoTune = CS->CTL0 & 0x3FF; + if (dcoTune & 0x200) + { + dcoTune = dcoTune | 0xFE00; + } + } + else + { + dcoTune = CS->CTL0 & 0x1FFF; + if (dcoTune & 0x1000) + { + dcoTune = dcoTune | 0xF000; + } + } + + if (dcoTune == 0) + return (uint32_t) centeredFreq; + + /* DCORSEL = 5 */ + if ((centeredFreq == 48000000) && ( TLV->HWREV > DEVICE_PG1_1)) + { + /* External Resistor */ + if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) + { + dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL5); + calVal = csInfo->rDCOER_FCAL_RSEL5; + } + /* Internal Resistor */ + else + { + dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL5); + calVal = csInfo->rDCOIR_FCAL_RSEL5; + } + } + /* DCORSEL = 4 */ + else + { + /* External Resistor */ + if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) + { + dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL04); + calVal = csInfo->rDCOER_FCAL_RSEL04; + } + /* Internal Resistor */ + else + { + dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL04); + calVal = csInfo->rDCOIR_FCAL_RSEL04; + } + } + + if( TLV->HWREV > DEVICE_PG1_1 ) + { + retVal = (uint32_t) (centeredFreq) + / (1 - ((dcoConst * dcoTune) + / ((1 + dcoConst * (768 - calVal))))); + } + else + { + retVal = (uint32_t) (centeredFreq) + / (1 - ((dcoConst * dcoTune) + / (8 * (1 + dcoConst * (768 - calVal))))); + } + return retVal; +} + +void CS_setDCOFrequency(uint32_t dcoFrequency) +{ + int32_t nomFreq, calVal, dcoSigned; + int16_t dcoTune; + float dcoConst; + bool rsel5 = false; + dcoSigned = (int32_t) dcoFrequency; + uint_fast8_t tlvLength; + SysCtl_CSCalTLV_Info *csInfo; + + if (dcoFrequency < 2000000) + { + nomFreq = CS_15MHZ; + CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_1_5); + } else if (dcoFrequency < 4000000) + { + nomFreq = CS_3MHZ; + CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_3); + } else if (dcoFrequency < 8000000) + { + nomFreq = CS_6MHZ; + CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_6); + } else if (dcoFrequency < 16000000) + { + nomFreq = CS_12MHZ; + CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12); + } else if (dcoFrequency < 32000000) + { + nomFreq = CS_24MHZ; + CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_24); + } else if (dcoFrequency < 640000001) + { + nomFreq = CS_48MHZ; + CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48); + rsel5 = true; + } else + { + ASSERT(false); + return; + } + + /* Parsing the TLV and getting the maximum erase pulses */ + SysCtl_getTLVInfo(TLV_TAG_CS, 0, &tlvLength, (uint32_t**)&csInfo); + + if(dcoFrequency == nomFreq || tlvLength == 0) + { + CS_tuneDCOFrequency(0); + return; + } + + if ((rsel5) && ( TLV->HWREV > DEVICE_PG1_1)) + { + /* External Resistor*/ + if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) + { + dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL5); + calVal = csInfo->rDCOER_FCAL_RSEL5; + } + /* Internal Resistor */ + else + { + dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL5); + calVal = csInfo->rDCOIR_FCAL_RSEL5; + } + } + /* DCORSEL = 4 */ + else + { + /* External Resistor */ + if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) + { + dcoConst = *((float *) &csInfo->rDCOER_CONSTK_RSEL04); + calVal = csInfo->rDCOER_FCAL_RSEL04; + } + /* Internal Resistor */ + else + { + dcoConst = *((float *) &csInfo->rDCOIR_CONSTK_RSEL04); + calVal = csInfo->rDCOIR_FCAL_RSEL04; + } + } + + if ( TLV->HWREV > DEVICE_PG1_1) + dcoTune = (int16_t) (((dcoSigned - nomFreq) + * (1.0f + dcoConst * (768.0f - calVal))) + / (dcoSigned * dcoConst)); + else + dcoTune = (int16_t) (((dcoSigned - nomFreq) + * (1.0f + dcoConst * (768.0f - calVal)) * 8.0f) + / (dcoSigned * dcoConst)); + + CS_tuneDCOFrequency(dcoTune); + +} + +uint32_t CS_getBCLK(void) +{ + if (BITBAND_PERI(CS->CTL1, CS_CTL1_SELB_OFS)) + return _CSComputeCLKFrequency(CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); + else + return _CSComputeCLKFrequency(CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1); +} + +uint32_t CS_getHSMCLK(void) +{ + uint32_t wSource, wDivider; + + wSource = (CS->CTL1 & CS_CTL1_SELS_MASK) >> CS_HSMCLK_SRC_BITPOS; + wDivider = ((CS->CTL1 & CS_CTL1_DIVHS_MASK) << CS_HSMCLK_DIV_BITPOS); + + return _CSComputeCLKFrequency(wSource, wDivider); +} + +uint32_t CS_getACLK(void) +{ + uint32_t wSource, wDivider; + + wSource = (CS->CTL1 & CS_CTL1_SELA_MASK) >> CS_ACLK_SRC_BITPOS; + wDivider = ((CS->CTL1 & CS_CTL1_DIVA_MASK) << CS_ACLK_DIV_BITPOS); + + return _CSComputeCLKFrequency(wSource, wDivider); +} + +uint32_t CS_getSMCLK(void) +{ + uint32_t wDivider, wSource; + + wSource = (CS->CTL1 & CS_CTL1_SELS_MASK) >> CS_HSMCLK_SRC_BITPOS; + wDivider = ((CS->CTL1 & CS_CTL1_DIVS_MASK)); + + return _CSComputeCLKFrequency(wSource, wDivider); + +} + +uint32_t CS_getMCLK(void) +{ + uint32_t wSource, wDivider; + + wSource = (CS->CTL1 & CS_CTL1_SELM_MASK) << CS_MCLK_SRC_BITPOS; + wDivider = ((CS->CTL1 & CS_CTL1_DIVM_MASK) << CS_MCLK_DIV_BITPOS); + + return _CSComputeCLKFrequency(wSource, wDivider); +} + +void CS_enableFaultCounter(uint_fast8_t counterSelect) +{ + ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER || + counterSelect == CS_HFXT_FAULT_COUNTER); + + /* Unlocking the module */ + CS->KEY = CS_KEY; + + if (counterSelect == CS_HFXT_FAULT_COUNTER) + { + BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTHF_EN_OFS) = 1; + } else + { + BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTLF_EN_OFS) = 1; + } + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_disableFaultCounter(uint_fast8_t counterSelect) +{ + ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER || + counterSelect == CS_HFXT_FAULT_COUNTER); + + /* Unlocking the module */ + CS->KEY = CS_KEY; + + if (counterSelect == CS_HFXT_FAULT_COUNTER) + { + BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTHF_EN_OFS) = 0; + } else + { + BITBAND_PERI(CS->CTL3, CS_CTL3_FCNTLF_EN_OFS) = 0; + } + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_resetFaultCounter(uint_fast8_t counterSelect) +{ + ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER || + counterSelect == CS_HFXT_FAULT_COUNTER); + + /* Unlocking the module */ + CS->KEY = CS_KEY; + + if (counterSelect == CS_HFXT_FAULT_COUNTER) + { + BITBAND_PERI(CS->CTL3, CS_CTL3_RFCNTHF_OFS) = 1; + } else + { + BITBAND_PERI(CS->CTL3, CS_CTL3_RFCNTLF_OFS) = 1; + } + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_startFaultCounter(uint_fast8_t counterSelect, uint_fast8_t countValue) +{ + ASSERT(counterSelect == CS_HFXT_FAULT_COUNTER || + counterSelect == CS_HFXT_FAULT_COUNTER); + + ASSERT(countValue == CS_FAULT_COUNTER_4096_CYCLES || + countValue == CS_FAULT_COUNTER_8192_CYCLES || + countValue == CS_FAULT_COUNTER_16384_CYCLES || + countValue == CS_FAULT_COUNTER_32768_CYCLES); + + /* Unlocking the module */ + CS->KEY = CS_KEY; + + if (counterSelect == CS_HFXT_FAULT_COUNTER) + { + CS->CTL3 = ((CS->CTL3 & ~CS_CTL3_FCNTHF_MASK) | (countValue << 4)); + } else + { + CS->CTL3 = ((CS->CTL3 & ~CS_CTL3_FCNTLF_MASK) | (countValue)); + } + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_enableInterrupt(uint32_t flags) +{ + /* Unlocking the module */ + CS->KEY = CS_KEY; + + CS->IE |= flags; + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_disableInterrupt(uint32_t flags) +{ + /* Unlocking the module */ + CS->KEY = CS_KEY; + + CS->IE &= ~flags; + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +uint32_t CS_getInterruptStatus(void) +{ + return CS->IFG; +} + +uint32_t CS_getEnabledInterruptStatus(void) +{ + return CS_getInterruptStatus() & CS->IE; +} + +void CS_clearInterruptFlag(uint32_t flags) +{ + /* Unlocking the module */ + CS->KEY = CS_KEY; + + CS->CLRIFG |= flags; + + /* Locking the module */ + BITBAND_PERI(CS->KEY, CS_KEY_KEY_OFS) = 1; +} + +void CS_registerInterrupt(void (*intHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + Interrupt_registerInterrupt(INT_CS, intHandler); + + // + // Enable the system control interrupt. + // + Interrupt_enableInterrupt(INT_CS); +} + +void CS_unregisterInterrupt(void) +{ + // + // Disable the interrupt. + // + Interrupt_disableInterrupt(INT_CS); + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(INT_CS); +} + diff --git a/example/rt_msp432/MSP432P4xx/cs.h b/example/rt_msp432/MSP432P4xx/cs.h new file mode 100644 index 0000000..b7217ba --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/cs.h @@ -0,0 +1,827 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __CS_H__ +#define __CS_H__ + +//***************************************************************************** +// +//! \addtogroup cs_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +//***************************************************************************** +// +// Control specific variables +// +//***************************************************************************** +#define CS_CLOCK_DIVIDER_1 CS_CTL1_DIVS_0 +#define CS_CLOCK_DIVIDER_2 CS_CTL1_DIVS_1 +#define CS_CLOCK_DIVIDER_4 CS_CTL1_DIVS_2 +#define CS_CLOCK_DIVIDER_8 CS_CTL1_DIVS_3 +#define CS_CLOCK_DIVIDER_16 CS_CTL1_DIVS_4 +#define CS_CLOCK_DIVIDER_32 CS_CTL1_DIVS_5 +#define CS_CLOCK_DIVIDER_64 CS_CTL1_DIVS_6 +#define CS_CLOCK_DIVIDER_128 CS_CTL1_DIVS_7 + +#define CS_LFXTCLK_SELECT CS_CTL1_SELM_0 +#define CS_HFXTCLK_SELECT CS_CTL1_SELM_5 +#define CS_VLOCLK_SELECT CS_CTL1_SELM_1 +#define CS_REFOCLK_SELECT CS_CTL1_SELM_2 +#define CS_DCOCLK_SELECT CS_CTL1_SELM_3 +#define CS_MODOSC_SELECT CS_CTL1_SELM_4 + +#define CS_KEY 0x695A + +/* Number of positions to shift for divider calculation */ +#define CS_ACLK_DIV_BITPOS 0x04 +#define CS_MCLK_DIV_BITPOS 0x0C +#define CS_SMCLK_DIV_BITPOS 0x00 +#define CS_HSMCLK_DIV_BITPOS 0x08 + +/* Number of positions to shift for source calculation */ +#define CS_ACLK_SRC_BITPOS 0x08 +#define CS_MCLK_SRC_BITPOS 0x00 +#define CS_SMCLK_SRC_BITPOS 0x04 +#define CS_HSMCLK_SRC_BITPOS 0x04 + +/* REFO Clock Values */ +#define CS_REFO_32KHZ 0x00 +#define CS_REFO_128KHZ 0x01 + +/* Frequency Values */ +#define CS_VLOCLK_FREQUENCY 10000 +#define CS_MODCLK_FREQUENCY 24000000 + +/* Interrupts */ +#define CS_LFXT_FAULT CS_IE_LFXTIE +#define CS_HFXT_FAULT CS_IE_HFXTIE +#define CS_DCO_OPEN_FAULT CS_IE_DCOR_OPNIE +#define CS_STARTCOUNT_LFXT_FAULT CS_IE_FCNTLFIE +#define CS_STARTCOUNT_HFXT_FAULT CS_IE_FCNTHFIE +#define CS_DCO_SHORT_FAULT CS_IFG_DCOR_SHTIFG + +//#define CS_HFXT_DRIVE0 CS_CTL2_HFXTDRIVE_0 +//#define CS_HFXT_DRIVE1 CS_CTL2_HFXTDRIVE_1 +#define CS_HFXT_DRIVE CS_CTL2_HFXTDRIVE +#define CS_HFXT_BYPASS CS_CTL2_HFXTBYPASS + +#define CS_LFXT_DRIVE0 CS_CTL2_LFXTDRIVE_0 +#define CS_LFXT_DRIVE1 CS_CTL2_LFXTDRIVE_1 +#define CS_LFXT_DRIVE2 CS_CTL2_LFXTDRIVE_2 +#define CS_LFXT_DRIVE3 CS_CTL2_LFXTDRIVE_3 +#define CS_LFXT_BYPASS CS_CTL2_LFXTBYPASS + +#define CS_ACLK CS_CLKEN_ACLK_EN +#define CS_MCLK CS_CLKEN_MCLK_EN +#define CS_SMCLK CS_CLKEN_SMCLK_EN +#define CS_HSMCLK CS_CLKEN_HSMCLK_EN +#define CS_BCLK CS_STAT_BCLK_READY + +#define CS_LFXTCLK 0x01 + +#define CS_1MHZ 1000000 +#define CS_15MHZ 1500000 +#define CS_3MHZ 3000000 +#define CS_4MHZ 4000000 +#define CS_6MHZ 6000000 +#define CS_8MHZ 8000000 +#define CS_12MHZ 12000000 +#define CS_16MHZ 16000000 +#define CS_24MHZ 24000000 +#define CS_32MHZ 32000000 +#define CS_40MHZ 40000000 +#define CS_48MHZ 48000000 + +#define CS_DCO_FREQUENCY_1_5 CS_CTL0_DCORSEL_0 +#define CS_DCO_FREQUENCY_3 CS_CTL0_DCORSEL_1 +#define CS_DCO_FREQUENCY_6 CS_CTL0_DCORSEL_2 +#define CS_DCO_FREQUENCY_12 CS_CTL0_DCORSEL_3 +#define CS_DCO_FREQUENCY_24 CS_CTL0_DCORSEL_4 +#define CS_DCO_FREQUENCY_48 CS_CTL0_DCORSEL_5 + +#define CS_HFXT_FAULT_COUNTER 0x01 +#define CS_LFXT_FAULT_COUNTER 0x02 + +#define CS_FAULT_COUNTER_4096_CYCLES CS_CTL3_FCNTLF_0 +#define CS_FAULT_COUNTER_8192_CYCLES CS_CTL3_FCNTLF_1 +#define CS_FAULT_COUNTER_16384_CYCLES CS_CTL3_FCNTLF_2 +#define CS_FAULT_COUNTER_32768_CYCLES CS_CTL3_FCNTLF_3 + +#define CS_OVER32MHZ 0x01 +#define CS_UNDER32MHZ 0x02 + +#define DEVICE_PG1_1 0x42 + +//****************************************************************************** +// +//! This function sets the external clock sources LFXT and HFXT crystal +//! oscillator frequency values. This function must be called if an external +//! crystal LFXT or HFXT is used and the user intends to call +//! CS_getSMCLK, CS_getMCLK, CS_getBCLK, CS_getHSMCLK, CS_getACLK and +//! any of the HFXT oscillator control functions +//! +//! \param lfxt_XT_CLK_frequency is the LFXT crystal frequencies in Hz +//! \param hfxt_XT_CLK_frequency is the HFXT crystal frequencies in Hz +//! +//! \return None +// +//****************************************************************************** +extern void CS_setExternalClockSourceFrequency(uint32_t lfxt_XT_CLK_frequency, + uint32_t hfxt_XT_CLK_frequency); + +//****************************************************************************** +// +//! This function initializes each of the clock signals. The user must ensure +//! that this function is called for each clock signal. If not, the default +//! state is assumed for the particular clock signal. Refer to DriverLib +//! documentation for CS module or Device Family User's Guide for details of +//! default clock signal states. +//! +//! Note that this function is blocking and will wait on the appropriate bit +//! to be set in the CSSTAT READY register to be set before setting the clock +//! source. +//! +//! Also note that when HSMCLK and SMCLK share the same clock signal. If you +//! change the clock signal for HSMCLK, the clock signal for SMCLK will change +//! also (and vice-versa). +//! +//! HFXTCLK is not available for BCLK or ACLK. +//! +//! \param selectedClockSignal Clock signal to initialize. +//! - \b CS_ACLK, +//! - \b CS_MCLK, +//! - \b CS_HSMCLK +//! - \b CS_SMCLK +//! - \b CS_BCLK [clockSourceDivider is ignored for this parameter] +//! \param clockSource Clock source for the selectedClockSignal signal. +//! - \b CS_LFXTCLK_SELECT, +//! - \b CS_HFXTCLK_SELECT, +//! - \b CS_VLOCLK_SELECT, [Not available for BCLK] +//! - \b CS_DCOCLK_SELECT, [Not available for ACLK, BCLK] +//! - \b CS_REFOCLK_SELECT, +//! - \b CS_MODOSC_SELECT [Not available for ACLK, BCLK] +//! \param clockSourceDivider - selected the clock divider to calculate +//! clock signal from clock source. This parameter is ignored when +//! setting BLCK. Valid values are: +//! - \b CS_CLOCK_DIVIDER_1, +//! - \b CS_CLOCK_DIVIDER_2, +//! - \b CS_CLOCK_DIVIDER_4, +//! - \b CS_CLOCK_DIVIDER_8, +//! - \b CS_CLOCK_DIVIDER_16, +//! - \b CS_CLOCK_DIVIDER_32, +//! - \b CS_CLOCK_DIVIDER_64, +//! - \b CS_CLOCK_DIVIDER_128 +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_initClockSignal(uint32_t selectedClockSignal, + uint32_t clockSource, uint32_t clockSourceDivider); + +//****************************************************************************** +// +//! Initializes the HFXT crystal oscillator, which supports crystal frequencies +//! between 0 MHz and 48 MHz, depending on the selected drive strength. Loops +//! until all oscillator fault flags are cleared, with no timeout. See the +//! device-specific data sheet for appropriate drive settings. NOTE: User must +//! call CS_setExternalClockSourceFrequency to set frequency of external clocks +//! before calling this function. +//! +//! \param bypassMode When this variable is set, the oscillator will start +//! in bypass mode and the signal can be generated by a digital square wave. +//! +//! \return true if started correctly, false otherwise +// +//****************************************************************************** +extern bool CS_startHFXT(bool bypassMode); + +//****************************************************************************** +// +//! Initializes the HFXT crystal oscillator, which supports crystal frequencies +//! between 0 MHz and 48 MHz, depending on the selected drive strength. Loops +//! until all oscillator fault flags are cleared, with no timeout. See the +//! device-specific data sheet for appropriate drive settings. NOTE: User must +//! call CS_setExternalClockSourceFrequency to set frequency of external clocks +//! before calling this function. This function has a timeout associated with +//! stabilizing the oscillator. +//! +//! \param bypassMode When this variable is set, the oscillator will start +//! in bypass mode and the signal can be generated by a digital square wave. +//! +//! \param timeout is the count value that gets decremented every time the loop +//! that clears oscillator fault flags gets executed. +//! +//! \return true if started correctly, false otherwise +// +//****************************************************************************** +extern bool CS_startHFXTWithTimeout(bool bypassMode, uint32_t timeout); + +//****************************************************************************** +// +//! Initializes the LFXT crystal oscillator, which supports crystal frequencies +//! up to 50kHz, depending on the selected drive strength. Loops +//! until all oscillator fault flags are cleared, with no timeout. See the +//! device-specific data sheet for appropriate drive settings. NOTE: User must +//! call CS_setExternalClockSourceFrequency to set frequency of external clocks +//! before calling this function. +//! +//! \param xtDrive is the target drive strength for the LFXT crystal +//! oscillator. +//! Valid values are: +//! - \b CS_LFXT_DRIVE0, +//! - \b CS_LFXT_DRIVE1, +//! - \b CS_LFXT_DRIVE2, +//! - \b CS_LFXT_DRIVE3, [Default Value] +//! - \b CS_LFXT_BYPASS +//! +//! \note When CS_LFXT_BYPASS is passed as a parameter the oscillator will start +//! in bypass mode and the signal can be generated by a digital square wave. +//! +//! \return true if started correctly, false otherwise +// +//****************************************************************************** +extern bool CS_startLFXT(uint32_t xtDrive); + +//****************************************************************************** +// +//! Initializes the LFXT crystal oscillator, which supports crystal frequencies +//! up to 50kHz, depending on the selected drive strength. Loops +//! until all oscillator fault flags are cleared. See the +//! device-specific data sheet for appropriate drive settings. NOTE: User must +//! call CS_setExternalClockSourceFrequency to set frequency of external clocks +//! before calling this function. This function has a timeout associated with +//! stabilizing the oscillator. +//! +//! \param xtDrive is the target drive strength for the LFXT crystal +//! oscillator. +//! Valid values are: +//! - \b CS_LFXT_DRIVE0, +//! - \b CS_LFXT_DRIVE1, +//! - \b CS_LFXT_DRIVE2, +//! - \b CS_LFXT_DRIVE3, [Default Value] +//! - \b CS_LFXT_BYPASS +//! +//! \note When CS_LFXT_BYPASS is passed as a parameter the oscillator will +//! start in bypass mode and the signal can be generated by a digital square +//! wave. +//! +//! \param timeout is the count value that gets decremented every time the loop +//! that clears oscillator fault flags gets executed. +//! +//! \return true if started correctly, false otherwise +// +//****************************************************************************** +extern bool CS_startLFXTWithTimeout(uint32_t xtDrive, uint32_t timeout); + +//****************************************************************************** +// +//! Selects between the frequency of the internal REFO clock source +//! +//! \param referenceFrequency selects between the valid frequencies: +//! - \b CS_REFO_32KHZ, +//! - \b CS_REFO_128KHZ, +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_setReferenceOscillatorFrequency(uint8_t referenceFrequency); + +//****************************************************************************** +// +//! Enables conditional module requests +//! +//! \param selectClock selects specific request enables. Valid values are +//! are a logical OR of the following values: +//! - \b CS_ACLK, +//! - \b CS_HSMCLK, +//! - \b CS_SMCLK, +//! - \b CS_MCLK +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_enableClockRequest(uint32_t selectClock); + +//****************************************************************************** +// +//! Disables conditional module requests +//! +//! \param selectClock selects specific request disables. Valid values are +//! are a logical OR of the following values: +//! - \b CS_ACLK, +//! - \b CS_HSMCLK, +//! - \b CS_SMCLK, +//! - \b CS_MCLK +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_disableClockRequest(uint32_t selectClock); + +//****************************************************************************** +// +//! Get the current ACLK frequency. +//! +//! If a oscillator fault is set, the frequency returned will be based on the +//! fail safe mechanism of CS module. The user of this API must ensure that +//! \link CS_setExternalClockSourceFrequency() \endlink API was invoked before +//! in case LFXT is being used. +//! +//! \return Current ACLK frequency in Hz +// +//****************************************************************************** +extern uint32_t CS_getACLK(void); + +//****************************************************************************** +// +//! Get the current SMCLK frequency. +//! +//! If a oscillator fault is set, the frequency returned will be based on the +//! fail safe mechanism of CS module. The user of this API must ensure that +//! CS_setExternalClockSourceFrequency API was invoked before in case LFXT or +//! HFXT is being used. +//! +//! \return Current SMCLK frequency in Hz +// +//****************************************************************************** +extern uint32_t CS_getSMCLK(void); + +//****************************************************************************** +// +//! Get the current MCLK frequency. +//! +//! If a oscillator fault is set, the frequency returned will be based on the +//! fail safe mechanism of CS module. The user of this API must ensure that +//! CS_setExternalClockSourceFrequency API was invoked before in case LFXT or +//! HFXT is being used. +//! +//! \return Current MCLK frequency in Hz +// +//****************************************************************************** +extern uint32_t CS_getMCLK(void); + +//****************************************************************************** +// +//! Get the current BCLK frequency. +//! +//! If a oscillator fault is set, the frequency returned will be based on the +//! fail safe mechanism of CS module. The user of this API must ensure that +//! \link CS_setExternalClockSourceFrequency \endlink API was invoked before in +//! case LFXT or HFXT is being used. +//! +//! \return Current BCLK frequency in Hz +// +//****************************************************************************** +extern uint32_t CS_getBCLK(void); + +//****************************************************************************** +// +//! Get the current HSMCLK frequency. +//! +//! If a oscillator fault is set, the frequency returned will be based on the +//! fail safe mechanism of CS module. The user of this API must ensure that +//! \link CS_setExternalClockSourceFrequency \endlink API was invoked before in +//! case LFXT or HFXT is being used. +//! +//! \return Current HSMCLK frequency in Hz +// +//****************************************************************************** +extern uint32_t CS_getHSMCLK(void); + +//****************************************************************************** +// +//! Sets the centered frequency of DCO operation. Each frequency represents +//! the centred frequency of a particular frequency range. Further tuning can +//! be achieved by using the CS_tuneDCOFrequency function. Note that setting +//! the nominal frequency will reset the tuning parameters. +//! +//! \param dcoFreq selects between the valid frequencies: +//! - \b CS_DCO_FREQUENCY_1_5, [1MHz to 2MHz] +//! - \b CS_DCO_FREQUENCY_3, [2MHz to 4MHz] +//! - \b CS_DCO_FREQUENCY_6, [4MHz to 8MHz] +//! - \b CS_DCO_FREQUENCY_12, [8MHz to 16MHz] +//! - \b CS_DCO_FREQUENCY_24, [16MHz to 32MHz] +//! - \b CS_DCO_FREQUENCY_48 [32MHz to 64MHz] +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_setDCOCenteredFrequency(uint32_t dcoFreq); + +//****************************************************************************** +// +//! Automatically sets/tunes the DCO to the given frequency. Any valid value +//! up to max frequency in the spec can be given to this function and the API +//! will do its best to determine the correct tuning parameter. +//! +//! \note The frequency ranges that can be custom tuned on early release MSP432 +//! devices is limited. For further details on supported tunable frequencies, +//! please refer to the device errata sheet or data sheet. +//! +//! \param dcoFrequency Frequency in Hz that the user wants to set the DCO to. +//! +//! \note This function uses floating point math to calculate the DCO tuning +//! parameter. If efficiency is a concern, the user should use the +//! \link FPU_enableModule \endlink function (if available) to enable +//! the floating point co-processor. +//! +//! \return None +// +//****************************************************************************** +extern void CS_setDCOFrequency(uint32_t dcoFrequency); + +//****************************************************************************** +// +//! Tunes the DCO to a specific frequency. Tuning of the DCO is based off of the +//! following equation in the user's guide: +//! +//! See the user's guide for more detailed information about DCO tuning. +//! +//! \note This function is not currently available on pre-release MSP432 devices. +//! On early release versions of MSP432, the DCO calibration information has not been +//! populated making the DCO only able to operate at the pre-calibrated centered +//! frequencies accessible by the \link CS_setDCOCenteredFrequency \endlink +//! function. While this function will be added on the final devices being released, +//! for early silicon please default to the pre-calibrated DCO center frequencies. +//! +//! \param tuneParameter Tuning parameter in 2's Compliment representation. +//! Can be negative or positive. +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_tuneDCOFrequency(int16_t tuneParameter); + +//****************************************************************************** +// +//! Enables the external resistor for DCO operation +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_enableDCOExternalResistor(void); + +//****************************************************************************** +// +//! Disables the external resistor for DCO operation +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_disableDCOExternalResistor(void); + +//****************************************************************************** +// +//! Sets the calibration value for the DCO when using the external resistor +//! mode. This value is used for tuning the DCO to custom frequencies. By +//! default, the value in the CS module is populated by the calibration +//! data of the suggested external resistor (see device datasheet). +//! +//! \param calData is the calibration data constant for the external resistor. +//! +//! \param freqRange is the range of the DCO to set the external calibration +//! for. Frequencies above 32MHZ have a different calibration value +//! than frequencies below 32MHZ. +//! +//! \return None +// +//****************************************************************************** +extern void CS_setDCOExternalResistorCalibration(uint_fast8_t uiCalData, + uint_fast8_t freqRange); + +//****************************************************************************** +// +//! Gets the current tuned DCO frequency. If no tuning has been done, this +//! returns the nominal DCO frequency of the current DCO range. Note that this +//! function will grab any constant/calibration data from the DDDS table +//! without any user interaction needed. +//! +//! \note This function uses floating point math to calculate the DCO tuning +//! parameter. If efficiency is a concern, the user should use the +//! \link FPU_enableModule \endlink function (if available) to enable +//! the floating point co-processor. +//! +//! \return Current DCO frequency in Hz +// +//****************************************************************************** +extern uint32_t CS_getDCOFrequency(void); + +//****************************************************************************** +// +//! Automatically sets/tunes the DCO to the given frequency. Any valid value +//! up to (and including) 64Mhz can be given to this function and the API +//! will do its best to determine the correct tuning parameter. +//! +//! +//! \note This function is not currently available on pre-release MSP432 devices. +//! On early release versions of MSP432, the DCO calibration information has not been +//! populated making the DCO only able to operate at the pre-calibrated centered +//! frequencies accessible by the \link CS_setDCOCenteredFrequency \endlink +//! function. While this function will be added on the final devices being released, +//! for early silicon please default to the pre-calibrated DCO center frequencies. +//! +//! \param dcoFrequency Frequency in Hz (1500000 - 64000000) that the user wants +//! to set the DCO to. +//! +//! \note This function uses floating point math to calculate the DCO tuning +//! parameter. If efficiency is a concern, the user should use the +//! \link FPU_enableModule \endlink function (if available) to enable +//! the floating point co-processor. +//! +//! \return None +// +//****************************************************************************** +extern void CS_setDCOFrequency(uint32_t dcoFrequency); + +//****************************************************************************** +// +//! Enables the fault counter for the CS module. This function can enable +//! either the HFXT fault counter or the LFXT fault counter. +//! +//! \param counterSelect selects the fault counter to enable +//! - \b CS_HFXT_FAULT_COUNTER +//! - \b CS_LFXT_FAULT_COUNTER +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_enableFaultCounter(uint_fast8_t counterSelect); + +//****************************************************************************** +// +//! Disables the fault counter for the CS module. This function can disable +//! either the HFXT fault counter or the LFXT fault counter. +//! +//! \param counterSelect selects the fault counter to disable +//! - \b CS_HFXT_FAULT_COUNTER +//! - \b CS_LFXT_FAULT_COUNTER +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_disableFaultCounter(uint_fast8_t counterSelect); + +//****************************************************************************** +// +//! Resets the fault counter for the CS module. This function can reset +//! either the HFXT fault counter or the LFXT fault counter. +//! +//! \param counterSelect selects the fault counter to reset +//! - \b CS_HFXT_FAULT_COUNTER +//! - \b CS_LFXT_FAULT_COUNTER +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_resetFaultCounter(uint_fast8_t counterSelect); + +//****************************************************************************** +// +//! Sets the count for the start value of the fault counter. This function can +//! be used to set either the HFXT count or the LFXT count. +//! +//! \param counterSelect selects the fault counter to reset +//! - \b CS_HFXT_FAULT_COUNTER +//! - \b CS_LFXT_FAULT_COUNTER +//! \param countValue selects the cycles to set the fault counter to +//! - \b CS_FAULT_COUNTER_4096_CYCLES +//! - \b CS_FAULT_COUNTER_8192_CYCLES +//! - \b CS_FAULT_COUNTER_16384_CYCLES +//! - \b CS_FAULT_COUNTER_32768_CYCLES +//! +//! \return NONE +// +//****************************************************************************** +extern void CS_startFaultCounter(uint_fast8_t counterSelect, + uint_fast8_t countValue); + +//***************************************************************************** +// +//! Enables individual clock control interrupt sources. +//! +//! \param flags is a bit mask of the interrupt sources to be enabled. Must +//! be a logical OR of: +//! - \b CS_LFXT_FAULT, +//! - \b CS_HFXT_FAULT, +//! - \b CS_DCOMIN_FAULT, +//! - \b CS_DCOMAX_FAULT, +//! - \b CS_DCO_OPEN_FAULT, +//! - \b CS_STARTCOUNT_LFXT_FAULT, +//! - \b CS_STARTCOUNT_HFXT_FAULT, +//! +//! This function enables the indicated clock system interrupt sources. Only +//! the sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +//! +//! \return None. +// +//***************************************************************************** +extern void CS_enableInterrupt(uint32_t flags); + +//***************************************************************************** +// +//! Disables individual clock system interrupt sources. +//! +//! \param flags is a bit mask of the interrupt sources to be disabled. Must +//! be a logical OR of: +//! - \b CS_LFXT_FAULT, +//! - \b CS_HFXT_FAULT, +//! - \b CS_DCOMIN_FAULT, +//! - \b CS_DCOMAX_FAULT, +//! - \b CS_DCO_OPEN_FAULT, +//! - \b CS_STARTCOUNT_LFXT_FAULT, +//! - \b CS_STARTCOUNT_HFXT_FAULT, +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +//! +//! \return None. +// +//***************************************************************************** +extern void CS_disableInterrupt(uint32_t flags); + +//***************************************************************************** +// +//! Gets the current interrupt status masked with the enabled interrupts. +//! This function is useful to call in ISRs to get a list of pending interrupts +//! that are actually enabled and could have caused the ISR. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! - \b CS_LFXT_FAULT, +//! - \b CS_HFXT_FAULT, +//! - \b CS_DCO_OPEN_FAULT, +//! - \b CS_DCO_SHORT_FAULT, +//! - \b CS_STARTCOUNT_LFXT_FAULT, +//! - \b CS_STARTCOUNT_HFXT_FAULT, +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +// +//***************************************************************************** +extern uint32_t CS_getEnabledInterruptStatus(void); + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \return The current interrupt status, enumerated as a bit field of: +//! - \b CS_LFXT_FAULT, +//! - \b CS_HFXT_FAULT, +//! - \b CS_DCO_OPEN_FAULT, +//! - \b CS_DCO_SHORT_FAULT, +//! - \b CS_STARTCOUNT_LFXT_FAULT, +//! - \b CS_STARTCOUNT_HFXT_FAULT, +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +// +//***************************************************************************** +extern uint32_t CS_getInterruptStatus(void); + +//***************************************************************************** +// +//! Clears clock system interrupt sources. +//! +//! \param flags is a bit mask of the interrupt sources to be cleared. Must +//! be a logical OR of: +//! - \b CS_LFXT_FAULT, +//! - \b CS_HFXT_FAULT, +//! - \b CS_DCO_OPEN_FAULT, +//! - \b CS_STARTCOUNT_LFXT_FAULT, +//! - \b CS_STARTCOUNT_HFXT_FAULT, +//! +//! The specified clock system interrupt sources are cleared, so that they no +//! longer assert. This function must be called in the interrupt handler to +//! keep it from being called again immediately upon exit. +//! +//! \note Because there is a write buffer in the Cortex-M processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +//! +//! \return None. +// +//***************************************************************************** +extern void CS_clearInterruptFlag(uint32_t flags); + +//***************************************************************************** +// +//! Registers an interrupt handler for the clock system interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the clock +//! system interrupt occurs. +//! +//! This function registers the handler to be called when a clock system +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific clock system interrupts must be enabled +//! via CS_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via CS_clearInterruptFlag(). +//! +//! Clock System can generate interrupts when +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void CS_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the clock system. +//! +//! This function unregisters the handler to be called when a clock system +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void CS_unregisterInterrupt(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif diff --git a/example/rt_msp432/MSP432P4xx/debug.h b/example/rt_msp432/MSP432P4xx/debug.h new file mode 100644 index 0000000..9f70988 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/debug.h @@ -0,0 +1,76 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +//***************************************************************************** +// +// Prototype for the function that is called when an invalid argument is passed +// to an API. This is only used when doing a DEBUG build. +// +//***************************************************************************** +extern void __error__(char *pcFilename, unsigned long line); + +//***************************************************************************** +// +// The ASSERT macro, which does the actual assertion checking. Typically, this +// will be for procedure arguments. +// +//***************************************************************************** +#ifdef DEBUG +#define ASSERT(expr) { \ + if(!(expr)) \ + { \ + __error__(__FILE__, __LINE__); \ + } \ + } +#else +#define ASSERT(expr) +#endif + +#ifdef DEBUG +#define assert(expr) { \ + if(!(expr)) \ + { \ + __error__(__FILE__, __LINE__); \ + } \ + } +#else +#define assert(expr) +#endif + +#endif // __DEBUG_H__ diff --git a/example/rt_msp432/MSP432P4xx/dma.c b/example/rt_msp432/MSP432P4xx/dma.c new file mode 100644 index 0000000..863f340 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/dma.c @@ -0,0 +1,850 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include + +#include +#include +#include + +void DMA_enableModule(void) +{ + // + // Set the master enable bit in the config register. + // + DMA_Control->CFG = DMA_CFG_MASTEN; +} + +void DMA_disableModule(void) +{ + // + // Clear the master enable bit in the config register. + // + DMA_Control->CFG = 0; +} + +uint32_t DMA_getErrorStatus(void) +{ + // + // Return the DMA error status. + // + return DMA_Control->ERRCLR; +} + +void DMA_clearErrorStatus(void) +{ + // + // Clear the DMA error interrupt. + // + DMA_Control->ERRCLR = 1; +} + +void DMA_enableChannel(uint32_t channelNum) +{ + // + // Check the arguments. + // + ASSERT((channelNum & 0xffff) < 8); + + // + // Set the bit for this channel in the enable set register. + // + DMA_Control->ENASET = 1 << (channelNum & 0x0F); +} + +void DMA_disableChannel(uint32_t channelNum) +{ + // + // Check the arguments. + // + ASSERT((channelNum & 0xffff) < 8); + + // + // Set the bit for this channel in the enable clear register. + // + DMA_Control->ENACLR = 1 << (channelNum & 0x0F); +} + +bool DMA_isChannelEnabled(uint32_t channelNum) +{ + // + // Check the arguments. + // + ASSERT((channelNum & 0xffff) < 8); + + // + // AND the specified channel bit with the enable register and return the + // result. + // + return ((DMA_Control->ENASET & (1 << (channelNum & 0x0F))) ? true : false); +} + +void DMA_setControlBase(void *controlTable) +{ + // + // Check the arguments. + // + ASSERT(((uint32_t) controlTable & ~0x3FF) == (uint32_t) controlTable); + ASSERT((uint32_t) controlTable >= 0x20000000); + + // + // Program the base address into the register. + // + DMA_Control->CTLBASE = (uint32_t) controlTable; +} + +void* DMA_getControlBase(void) +{ + // + // Read the current value of the control base register and return it to + // the caller. + // + return ((void *) DMA_Control->CTLBASE); +} + +void* DMA_getControlAlternateBase(void) +{ + // + // Read the current value of the control base register and return it to + // the caller. + // + return ((void *) DMA_Control->ATLBASE); +} + +void DMA_requestChannel(uint32_t channelNum) +{ + // + // Check the arguments. + // + ASSERT((channelNum & 0xffff) < 8); + + // + // Set the bit for this channel in the software DMA request register. + // + DMA_Control->SWREQ = 1 << (channelNum & 0x0F); +} + +void DMA_enableChannelAttribute(uint32_t channelNum, uint32_t attr) +{ + // + // Check the arguments. + // + ASSERT((channelNum & 0xffff) < 8); + ASSERT( + (attr + & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT + | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) + == 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the channelNum parameter, extract just the channel number + // from this parameter. + // + channelNum &= 0x0F; + + // + // Set the useburst bit for this channel if set in config. + // + if (attr & UDMA_ATTR_USEBURST) + { + DMA_Control->USEBURSTSET = 1 << channelNum; + } + + // + // Set the alternate control select bit for this channel, + // if set in config. + // + if (attr & UDMA_ATTR_ALTSELECT) + { + DMA_Control->ALTSET = 1 << channelNum; + } + + // + // Set the high priority bit for this channel, if set in config. + // + if (attr & UDMA_ATTR_HIGH_PRIORITY) + { + DMA_Control->PRIOSET = 1 << channelNum; + } + + // + // Set the request mask bit for this channel, if set in config. + // + if (attr & UDMA_ATTR_REQMASK) + { + DMA_Control->REQMASKSET = 1 << channelNum; + } +} + +void DMA_disableChannelAttribute(uint32_t channelNum, uint32_t attr) +{ + // + // Check the arguments. + // + ASSERT((channelNum & 0xffff) < 8); + ASSERT( + (attr + & ~(UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT + | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK)) + == 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the channelNum parameter, extract just the channel number + // from this parameter. + // + channelNum &= 0x0F; + + // + // Clear the useburst bit for this channel if set in config. + // + if (attr & UDMA_ATTR_USEBURST) + { + DMA_Control->USEBURSTCLR = 1 << channelNum; + } + + // + // Clear the alternate control select bit for this channel, if set in + // config. + // + if (attr & UDMA_ATTR_ALTSELECT) + { + DMA_Control->ALTCLR = 1 << channelNum; + } + + // + // Clear the high priority bit for this channel, if set in config. + // + if (attr & UDMA_ATTR_HIGH_PRIORITY) + { + DMA_Control->PRIOCLR = 1 << channelNum; + } + + // + // Clear the request mask bit for this channel, if set in config. + // + if (attr & UDMA_ATTR_REQMASK) + { + DMA_Control->REQMASKCLR = 1 << channelNum; + } +} + +uint32_t DMA_getChannelAttribute(uint32_t channelNum) +{ + uint32_t attr = 0; + + // + // Check the arguments. + // + ASSERT((channelNum & 0xffff) < 8); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the channelNum parameter, extract just the channel number + // from this parameter. + // + channelNum &= 0x0F; + + // + // Check to see if useburst bit is set for this channel. + // + if (DMA_Control->USEBURSTSET & (1 << channelNum)) + { + attr |= UDMA_ATTR_USEBURST; + } + + // + // Check to see if the alternate control bit is set for this channel. + // + if (DMA_Control->ALTSET & (1 << channelNum)) + { + attr |= UDMA_ATTR_ALTSELECT; + } + + // + // Check to see if the high priority bit is set for this channel. + // + if (DMA_Control->PRIOSET & (1 << channelNum)) + { + attr |= UDMA_ATTR_HIGH_PRIORITY; + } + + // + // Check to see if the request mask bit is set for this channel. + // + if (DMA_Control->REQMASKSET & (1 << channelNum)) + { + attr |= UDMA_ATTR_REQMASK; + } + + // + // Return the configuration flags. + // + return (attr); +} + +void DMA_setChannelControl(uint32_t channelStructIndex, uint32_t control) +{ + DMA_ControlTable *pCtl; + + // + // Check the arguments. + // + ASSERT((channelStructIndex & 0xffff) < 64); + ASSERT(DMA_Control->CTLBASE != 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the channelStructIndex parameter, extract just the channel + // index from this parameter. + // + channelStructIndex &= 0x3f; + + // + // Get the base address of the control table. + // + pCtl = (DMA_ControlTable *) DMA_Control->CTLBASE; + + // + // Get the current control word value and mask off the fields to be + // changed, then OR in the new settings. + // + pCtl[channelStructIndex].control = ((pCtl[channelStructIndex].control + & ~(UDMA_CHCTL_DSTINC_M | UDMA_CHCTL_DSTSIZE_M | UDMA_CHCTL_SRCINC_M + | UDMA_CHCTL_SRCSIZE_M | UDMA_CHCTL_ARBSIZE_M + | UDMA_CHCTL_NXTUSEBURST)) | control); +} + +void DMA_setChannelTransfer(uint32_t channelStructIndex, uint32_t mode, + void *srcAddr, void *dstAddr, uint32_t transferSize) +{ + DMA_ControlTable *controlTable; + uint32_t control; + uint32_t increment; + uint32_t bufferBytes; + + // + // Check the arguments. + // + ASSERT((channelStructIndex & 0xffff) < 64); + ASSERT(DMA->CTLBASE != 0); + ASSERT(mode <= UDMA_MODE_PER_SCATTER_GATHER); + ASSERT((transferSize != 0) && (transferSize <= 1024)); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the channelStructIndex parameter, extract just the channel + // index from this parameter. + // + channelStructIndex &= 0x3f; + + // + // Get the base address of the control table. + // + controlTable = (DMA_ControlTable *) DMA_Control->CTLBASE; + + // + // Get the current control word value and mask off the mode and size + // fields. + // + control = (controlTable[channelStructIndex].control + & ~(UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M)); + + // + // Adjust the mode if the alt control structure is selected. + // + if (channelStructIndex & UDMA_ALT_SELECT) + { + if ((mode == UDMA_MODE_MEM_SCATTER_GATHER) + || (mode == UDMA_MODE_PER_SCATTER_GATHER)) + { + mode |= UDMA_MODE_ALT_SELECT; + } + } + + // + // Set the transfer size and mode in the control word (but don't write the + // control word yet as it could kick off a transfer). + // + control |= mode | ((transferSize - 1) << 4); + + // + // Get the address increment value for the source, from the control word. + // + increment = (control & UDMA_CHCTL_SRCINC_M); + + // + // Compute the ending source address of the transfer. If the source + // increment is set to none, then the ending address is the same as the + // beginning. + // + if (increment != UDMA_SRC_INC_NONE) + { + increment = increment >> 26; + bufferBytes = transferSize << increment; + srcAddr = (void *) ((uint32_t) srcAddr + bufferBytes - 1); + } + + // + // Load the source ending address into the control block. + // + controlTable[channelStructIndex].srcEndAddr = srcAddr; + + // + // Get the address increment value for the destination, from the control + // word. + // + increment = control & UDMA_CHCTL_DSTINC_M; + + // + // Compute the ending destination address of the transfer. If the + // destination increment is set to none, then the ending address is the + // same as the beginning. + // + if (increment != UDMA_DST_INC_NONE) + { + // + // There is a special case if this is setting up a scatter-gather + // transfer. The destination pointer must point to the end of + // the alternate structure for this channel instead of calculating + // the end of the buffer in the normal way. + // + if ((mode == UDMA_MODE_MEM_SCATTER_GATHER) + || (mode == UDMA_MODE_PER_SCATTER_GATHER)) + { + dstAddr = (void *) &controlTable[channelStructIndex + | UDMA_ALT_SELECT].spare; + } + // + // Not a scatter-gather transfer, calculate end pointer normally. + // + else + { + increment = increment >> 30; + bufferBytes = transferSize << increment; + dstAddr = (void *) ((uint32_t) dstAddr + bufferBytes - 1); + } + } + + // + // Load the destination ending address into the control block. + // + controlTable[channelStructIndex].dstEndAddr = dstAddr; + + // + // Write the new control word value. + // + controlTable[channelStructIndex].control = control; +} + +void DMA_setChannelScatterGather(uint32_t channelNum, uint32_t taskCount, + void *taskList, uint32_t isPeriphSG) +{ + DMA_ControlTable *controlTable; + DMA_ControlTable *pTaskTable; + + // + // Check the parameters + // + ASSERT((channelNum & 0xffff) < 8); + ASSERT(DMA->CTLBASE != 0); + ASSERT(taskList != 0); + ASSERT(taskCount <= 1024); + ASSERT(taskCount != 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the channelNum parameter, extract just the channel number + // from this parameter. + // + channelNum &= 0x0F; + + // + // Get the base address of the control table. + // + controlTable = (DMA_ControlTable *) DMA_Control->CTLBASE; + + // + // Get a handy pointer to the task list + // + pTaskTable = (DMA_ControlTable *) taskList; + + // + // Compute the ending address for the source pointer. This address is the + // last element of the last task in the task table + // + controlTable[channelNum].srcEndAddr = &pTaskTable[taskCount - 1].spare; + + // + // Compute the ending address for the destination pointer. This address + // is the end of the alternate structure for this channel. + // + controlTable[channelNum].dstEndAddr = &controlTable[channelNum + | UDMA_ALT_SELECT].spare; + + // + // Compute the control word. Most configurable items are fixed for + // scatter-gather. Item and increment sizes are all 32-bit and arb + // size must be 4. The count is the number of items in the task list + // times 4 (4 words per task). + // + controlTable[channelNum].control = (UDMA_CHCTL_DSTINC_32 + | UDMA_CHCTL_DSTSIZE_32 | UDMA_CHCTL_SRCINC_32 + | UDMA_CHCTL_SRCSIZE_32 | UDMA_CHCTL_ARBSIZE_4 + | (((taskCount * 4) - 1) << UDMA_CHCTL_XFERSIZE_S) + | (isPeriphSG ? + UDMA_CHCTL_XFERMODE_PER_SG : + UDMA_CHCTL_XFERMODE_MEM_SG)); + + // + // Scatter-gather operations can leave the alt bit set. So if doing + // back to back scatter-gather transfers, the second attempt may not + // work correctly because the alt bit is set. Therefore, clear the + // alt bit here to ensure that it is always cleared before a new SG + // transfer is started. + // + DMA_Control->ALTCLR = 1 << channelNum; +} + +uint32_t DMA_getChannelSize(uint32_t channelStructIndex) +{ + DMA_ControlTable *controlTable; + uint32_t control; + + // + // Check the arguments. + // + ASSERT((channelStructIndex & 0xffff) < 16); + ASSERT(DMA->CTLBASE != 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the channelStructIndex parameter, extract just the channel + // index from this parameter. + // + channelStructIndex &= 0x3f; + + // + // Get the base address of the control table. + // + controlTable = (DMA_ControlTable *) DMA_Control->CTLBASE; + + // + // Get the current control word value and mask off all but the size field + // and the mode field. + // + control = (controlTable[channelStructIndex].control + & (UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M)); + + // + // If the size field and mode field are 0 then the transfer is finished + // and there are no more items to transfer + // + if (control == 0) + { + return (0); + } + + // + // Otherwise, if either the size field or more field is non-zero, then + // not all the items have been transferred. + // + else + { + // + // Shift the size field and add one, then return to user. + // + return ((control >> 4) + 1); + } +} + +uint32_t DMA_getChannelMode(uint32_t channelStructIndex) +{ + DMA_ControlTable *controlTable; + uint32_t control; + + // + // Check the arguments. + // + ASSERT((channelStructIndex & 0xffff) < 64); + ASSERT(DMA->CTLBASE != 0); + + // + // In case a channel selector macro (like UDMA_CH0_USB0EP1RX) was + // passed as the channelStructIndex parameter, extract just the channel + // index from this parameter. + // + channelStructIndex &= 0x3f; + + // + // Get the base address of the control table. + // + controlTable = (DMA_ControlTable *) DMA_Control->CTLBASE; + + // + // Get the current control word value and mask off all but the mode field. + // + control = + (controlTable[channelStructIndex].control & UDMA_CHCTL_XFERMODE_M); + + // + // Check if scatter/gather mode, and if so, mask off the alt bit. + // + if (((control & ~UDMA_MODE_ALT_SELECT) == UDMA_MODE_MEM_SCATTER_GATHER) + || ((control & ~UDMA_MODE_ALT_SELECT) + == UDMA_MODE_PER_SCATTER_GATHER)) + { + control &= ~UDMA_MODE_ALT_SELECT; + } + + // + // Return the mode to the caller. + // + return (control); +} + +void DMA_assignChannel(uint32_t mapping) +{ + switch (mapping) + { + case DMA_CH0_RESERVED0: + case DMA_CH0_EUSCIA0TX: + case DMA_CH0_EUSCIB0TX0: + case DMA_CH0_EUSCIB3TX1: + case DMA_CH0_EUSCIB2TX2: + case DMA_CH0_EUSCIB1TX3: + case DMA_CH0_TIMERA0CCR0: + case DMA_CH0_AESTRIGGER0: + DMA_Channel->CH_SRCCFG[0] = (mapping >> 24) & 0x1F; + break; + case DMA_CH1_RESERVED0: + case DMA_CH1_EUSCIA0RX: + case DMA_CH1_EUSCIB0RX0: + case DMA_CH1_EUSCIB3RX1: + case DMA_CH1_EUSCIB2RX2: + case DMA_CH1_EUSCIB1RX3: + case DMA_CH1_TIMERA0CCR2: + case DMA_CH1_AESTRIGGER1: + DMA_Channel->CH_SRCCFG[1] = (mapping >> 24) & 0x1F; + break; + case DMA_CH2_RESERVED0: + case DMA_CH2_EUSCIA1TX: + case DMA_CH2_EUSCIB1TX0: + case DMA_CH2_EUSCIB0TX1: + case DMA_CH2_EUSCIB3TX2: + case DMA_CH2_EUSCIB2TX3: + case DMA_CH2_TIMERA1CCR0: + case DMA_CH2_AESTRIGGER2: + DMA_Channel->CH_SRCCFG[2] = (mapping >> 24) & 0x1F; + break; + case DMA_CH3_RESERVED0: + case DMA_CH3_EUSCIA1RX: + case DMA_CH3_EUSCIB1RX0: + case DMA_CH3_EUSCIB0RX1: + case DMA_CH3_EUSCIB3RX2: + case DMA_CH3_EUSCIB2RX3: + case DMA_CH3_TIMERA1CCR2: + case DMA_CH3_RESERVED1: + DMA_Channel->CH_SRCCFG[3] = (mapping >> 24) & 0x1F; + break; + case DMA_CH4_RESERVED0: + case DMA_CH4_EUSCIA2TX: + case DMA_CH4_EUSCIB2TX0: + case DMA_CH4_EUSCIB1TX1: + case DMA_CH4_EUSCIB0TX2: + case DMA_CH4_EUSCIB3TX3: + case DMA_CH4_TIMERA2CCR0: + case DMA_CH4_RESERVED1: + DMA_Channel->CH_SRCCFG[4] = (mapping >> 24) & 0x1F; + break; + case DMA_CH5_RESERVED0: + case DMA_CH5_EUSCIA2RX: + case DMA_CH5_EUSCIB2RX0: + case DMA_CH5_EUSCIB1RX1: + case DMA_CH5_EUSCIB0RX2: + case DMA_CH5_EUSCIB3RX3: + case DMA_CH5_TIMERA2CCR2: + case DMA_CH5_RESERVED1: + DMA_Channel->CH_SRCCFG[5] = (mapping >> 24) & 0x1F; + break; + case DMA_CH6_RESERVED0: + case DMA_CH6_EUSCIA3TX: + case DMA_CH6_EUSCIB3TX0: + case DMA_CH6_EUSCIB2TX1: + case DMA_CH6_EUSCIB1TX2: + case DMA_CH6_EUSCIB0TX3: + case DMA_CH6_TIMERA3CCR0: + case DMA_CH6_EXTERNALPIN: + DMA_Channel->CH_SRCCFG[6] = (mapping >> 24) & 0x1F; + break; + case DMA_CH7_RESERVED0: + case DMA_CH7_EUSCIA3RX: + case DMA_CH7_EUSCIB3RX0: + case DMA_CH7_EUSCIB2RX1: + case DMA_CH7_EUSCIB1RX2: + case DMA_CH7_EUSCIB0RX3: + case DMA_CH7_TIMERA3CCR2: + case DMA_CH7_ADC14: + DMA_Channel->CH_SRCCFG[7] = (mapping >> 24) & 0x1F; + break; + default: + ASSERT(false); + } + +} + +void DMA_assignInterrupt(uint32_t interruptNumber, uint32_t channel) +{ + ASSERT( + interruptNumber == DMA_INT1 || interruptNumber == DMA_INT2 + || interruptNumber == DMA_INT3); + + if (interruptNumber == DMA_INT1) + { + DMA_Channel->INT1_SRCCFG = (DMA_Channel->INT1_SRCCFG + & ~DMA_INT1_SRCCFG_INT_SRC_MASK) | channel; + } else if (interruptNumber == DMA_INT2) + { + DMA_Channel->INT2_SRCCFG = (DMA_Channel->INT2_SRCCFG + & ~DMA_INT1_SRCCFG_INT_SRC_MASK) | channel; + } else if (interruptNumber == DMA_INT3) + { + DMA_Channel->INT3_SRCCFG = (DMA_Channel->INT3_SRCCFG + & ~DMA_INT1_SRCCFG_INT_SRC_MASK) | channel; + } + + /* Enabling the assigned interrupt */ + DMA_enableInterrupt(interruptNumber); +} + +void DMA_requestSoftwareTransfer(uint32_t channel) +{ + DMA_Channel->SW_CHTRIG |= (1 << channel); +} + +uint32_t DMA_getInterruptStatus(void) +{ + return DMA_Channel->INT0_SRCFLG; +} + +void DMA_clearInterruptFlag(uint32_t channel) +{ + DMA_Channel->INT0_CLRFLG |= (1 << channel); +} + +void DMA_enableInterrupt(uint32_t interruptNumber) +{ + ASSERT( + (interruptNumber == DMA_INT0) || (interruptNumber == DMA_INT1) + || (interruptNumber == DMA_INT2) + || (interruptNumber == DMA_INT3)); + + if (interruptNumber == DMA_INT1) + { + DMA_Channel->INT1_SRCCFG |= DMA_INT1_SRCCFG_EN; + } else if (interruptNumber == DMA_INT2) + { + DMA_Channel->INT2_SRCCFG |= DMA_INT2_SRCCFG_EN; + } else if (interruptNumber == DMA_INT3) + { + DMA_Channel->INT3_SRCCFG |= DMA_INT3_SRCCFG_EN; + } + +} + +void DMA_disableInterrupt(uint32_t interruptNumber) +{ + ASSERT( + (interruptNumber == DMA_INT0) || (interruptNumber == DMA_INT1) + || (interruptNumber == DMA_INT2) + || (interruptNumber == DMA_INT3)); + + if (interruptNumber == DMA_INT1) + { + DMA_Channel->INT1_SRCCFG &= ~DMA_INT1_SRCCFG_EN; + } else if (interruptNumber == DMA_INT2) + { + DMA_Channel->INT2_SRCCFG &= ~DMA_INT2_SRCCFG_EN; + } else if (interruptNumber == DMA_INT3) + { + DMA_Channel->INT3_SRCCFG &= ~DMA_INT3_SRCCFG_EN; + } +} + +void DMA_registerInterrupt(uint32_t interruptNumber, void (*intHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(intHandler); + ASSERT( + (interruptNumber == DMA_INT0) || (interruptNumber == DMA_INT1) + || (interruptNumber == DMA_INT2) + || (interruptNumber == DMA_INT3) + || (interruptNumber == DMA_INTERR)); + + // + // Register the interrupt handler. + // + Interrupt_registerInterrupt(interruptNumber, intHandler); + + // + // Enable the memory management fault. + // + Interrupt_enableInterrupt(interruptNumber); + +} + +void DMA_unregisterInterrupt(uint32_t interruptNumber) +{ + ASSERT( + (interruptNumber == DMA_INT0) || (interruptNumber == DMA_INT1) + || (interruptNumber == DMA_INT2) + || (interruptNumber == DMA_INT3) + || (interruptNumber == DMA_INTERR)); + + // + // Disable the interrupt. + // + Interrupt_disableInterrupt(interruptNumber); + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(interruptNumber); +} + diff --git a/example/rt_msp432/MSP432P4xx/dma.h b/example/rt_msp432/MSP432P4xx/dma.h new file mode 100644 index 0000000..97d9cd1 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/dma.h @@ -0,0 +1,1006 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __DMA_H__ +#define __DMA_H__ + +//***************************************************************************** +// +//! \addtogroup dma_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +//***************************************************************************** +// +// A structure that defines an entry in the channel control table. These +// fields are used by the DMA controller and normally it is not necessary for +// software to directly read or write fields in the table. +// +//***************************************************************************** +typedef struct _DMA_ControlTable +{ + // + // The ending source address of the data transfer. + // + volatile void *srcEndAddr; + + // + // The ending destination address of the data transfer. + // + volatile void *dstEndAddr; + + // + // The channel control mode. + // + volatile uint32_t control; + + // + // An unused location. + // + volatile uint32_t spare; +} DMA_ControlTable; + +//***************************************************************************** +// +//! A helper macro for building scatter-gather task table entries. +//! +//! This macro is intended to be used to help populate a table of DMA tasks +//! for a scatter-gather transfer. This macro will calculate the values for +//! the fields of a task structure entry based on the input parameters. +//! +//! There are specific requirements for the values of each parameter. No +//! checking is done so it is up to the caller to ensure that correct values +//! are used for the parameters. +//! +//! The \b transferCount parameter is the number of items that will be +//! transferred by this task. It must be in the range 1-1024. +//! +//! The \b itemSize parameter is the bit size of the transfer data. It must +//! be one of \b UDMA_SIZE_8, \b UDMA_SIZE_16, or \b UDMA_SIZE_32. +//! +//! The \e srcIncrement parameter is the increment size for the source data. +//! It must be one of \b UDMA_SRC_INC_8, \b UDMA_SRC_INC_16, +//! \b UDMA_SRC_INC_32, or \b UDMA_SRC_INC_NONE. +//! +//! The \b srcAddr parameter is a void pointer to the beginning of the source +//! data. +//! +//! The \b dstIncrement parameter is the increment size for the destination +//! data. It must be one of \b UDMA_DST_INC_8, \b UDMA_DST_INC_16, +//! \b UDMA_DST_INC_32, or \b UDMA_DST_INC_NONE. +//! +//! The \b dstAddr parameter is a void pointer to the beginning of the +//! location where the data will be transferred. +//! +//! The \b arbSize parameter is the arbitration size for the transfer, and +//! must be one of \b UDMA_ARB_1, \b UDMA_ARB_2, \b UDMA_ARB_4, and so on +//! up to \b UDMA_ARB_1024. This is used to select the arbitration size in +//! powers of 2, from 1 to 1024. +//! +//! The \e mode parameter is the mode to use for this transfer task. It +//! must be one of \b UDMA_MODE_BASIC, \b UDMA_MODE_AUTO, +//! \b UDMA_MODE_MEM_SCATTER_GATHER, or \b UDMA_MODE_PER_SCATTER_GATHER. Note +//! that normally all tasks will be one of the scatter-gather modes while the +//! last task is a task list will be AUTO or BASIC. +//! +//! This macro is intended to be used to initialize individual entries of +//! a structure of DMA_ControlTable type, like this: +//! +//! \code{.c} +//! DMA_ControlTable MyTaskList[] = +//! { +//! DMA_TaskStructEntry(Task1Count, UDMA_SIZE_8, +//! UDMA_SRC_INC_8, MySourceBuf, +//! UDMA_DST_INC_8, MyDestBuf, +//! UDMA_ARB_8, UDMA_MODE_MEM_SCATTER_GATHER), +//! DMA_TaskStructEntry(Task2Count, ... ), +//! } +//! \endcode +//! +//! \param transferCount is the count of items to transfer for this task. +//! \param itemSize is the bit size of the items to transfer for this task. +//! \param srcIncrement is the bit size increment for source data. +//! \param srcAddr is the starting address of the data to transfer. +//! \param dstIncrement is the bit size increment for destination data. +//! \param dstAddr is the starting address of the destination data. +//! \param arbSize is the arbitration size to use for the transfer task. +//! \param mode is the transfer mode for this task. +//! +//! \return Nothing; this is not a function. +// +//***************************************************************************** +#define DMA_TaskStructEntry(transferCount, \ + itemSize, \ + srcIncrement, \ + srcAddr, \ + dstIncrement, \ + dstAddr, \ + arbSize, \ + mode) \ + { \ + (((srcIncrement) == UDMA_SRC_INC_NONE) ? (void *)(srcAddr) : \ + ((void *)(&((uint8_t *)(srcAddr))[((transferCount) << \ + ((srcIncrement) >> 26)) - 1]))), \ + (((dstIncrement) == UDMA_DST_INC_NONE) ? (void *)(dstAddr) : \ + ((void *)(&((uint8_t *)(dstAddr))[((transferCount) << \ + ((dstIncrement) >> 30)) - 1]))), \ + (srcIncrement) | (dstIncrement) | (itemSize) | (arbSize) | \ + (((transferCount) - 1) << 4) | \ + ((((mode) == UDMA_MODE_MEM_SCATTER_GATHER) || \ + ((mode) == UDMA_MODE_PER_SCATTER_GATHER)) ? \ + (mode) | UDMA_MODE_ALT_SELECT : (mode)), 0 \ + } + +//***************************************************************************** +// +// Flags that can be passed to DMA_enableChannelAttribute(), +// DMA_disableChannelAttribute(), and returned from DMA_getChannelAttribute(). +// +//***************************************************************************** +#define UDMA_ATTR_USEBURST 0x00000001 +#define UDMA_ATTR_ALTSELECT 0x00000002 +#define UDMA_ATTR_HIGH_PRIORITY 0x00000004 +#define UDMA_ATTR_REQMASK 0x00000008 +#define UDMA_ATTR_ALL 0x0000000F + +//***************************************************************************** +// +// DMA control modes that can be passed to DMAModeSet() and returned +// DMAModeGet(). +// +//***************************************************************************** +#define UDMA_MODE_STOP 0x00000000 +#define UDMA_MODE_BASIC 0x00000001 +#define UDMA_MODE_AUTO 0x00000002 +#define UDMA_MODE_PINGPONG 0x00000003 +#define UDMA_MODE_MEM_SCATTER_GATHER \ + 0x00000004 +#define UDMA_MODE_PER_SCATTER_GATHER \ + 0x00000006 +#define UDMA_MODE_ALT_SELECT 0x00000001 + +//***************************************************************************** +// +// Channel configuration values that can be passed to DMAControlSet(). +// +//***************************************************************************** +#define UDMA_DST_INC_8 0x00000000 +#define UDMA_DST_INC_16 0x40000000 +#define UDMA_DST_INC_32 0x80000000 +#define UDMA_DST_INC_NONE 0xc0000000 +#define UDMA_SRC_INC_8 0x00000000 +#define UDMA_SRC_INC_16 0x04000000 +#define UDMA_SRC_INC_32 0x08000000 +#define UDMA_SRC_INC_NONE 0x0c000000 +#define UDMA_SIZE_8 0x00000000 +#define UDMA_SIZE_16 0x11000000 +#define UDMA_SIZE_32 0x22000000 +#define UDMA_DST_PROT_PRIV 0x00200000 +#define UDMA_SRC_PROT_PRIV 0x00040000 +#define UDMA_ARB_1 0x00000000 +#define UDMA_ARB_2 0x00004000 +#define UDMA_ARB_4 0x00008000 +#define UDMA_ARB_8 0x0000c000 +#define UDMA_ARB_16 0x00010000 +#define UDMA_ARB_32 0x00014000 +#define UDMA_ARB_64 0x00018000 +#define UDMA_ARB_128 0x0001c000 +#define UDMA_ARB_256 0x00020000 +#define UDMA_ARB_512 0x00024000 +#define UDMA_ARB_1024 0x00028000 +#define UDMA_NEXT_USEBURST 0x00000008 + +//***************************************************************************** +// +// Flags to be OR'd with the channel ID to indicate if the primary or alternate +// control structure should be used. +// +//***************************************************************************** +#define UDMA_PRI_SELECT 0x00000000 +#define UDMA_ALT_SELECT 0x00000008 + +//***************************************************************************** +// +// Values that can be passed to DMA_assignChannel() to select peripheral +// mapping for each channel. The channels named RESERVED may be assigned +// to a peripheral in future parts. +// +//***************************************************************************** +// +// Channel 0 +// +#define DMA_CH0_RESERVED0 0x00000000 +#define DMA_CH0_EUSCIA0TX 0x01000000 +#define DMA_CH0_EUSCIB0TX0 0x02000000 +#define DMA_CH0_EUSCIB3TX1 0x03000000 +#define DMA_CH0_EUSCIB2TX2 0x04000000 +#define DMA_CH0_EUSCIB1TX3 0x05000000 +#define DMA_CH0_TIMERA0CCR0 0x06000000 +#define DMA_CH0_AESTRIGGER0 0x07000000 + +// +// Channel 1 +// +#define DMA_CH1_RESERVED0 0x00000001 +#define DMA_CH1_EUSCIA0RX 0x01000001 +#define DMA_CH1_EUSCIB0RX0 0x02000001 +#define DMA_CH1_EUSCIB3RX1 0x03000001 +#define DMA_CH1_EUSCIB2RX2 0x04000001 +#define DMA_CH1_EUSCIB1RX3 0x05000001 +#define DMA_CH1_TIMERA0CCR2 0x06000001 +#define DMA_CH1_AESTRIGGER1 0x07000001 + +// +// Channel 2 +// +#define DMA_CH2_RESERVED0 0x00000002 +#define DMA_CH2_EUSCIA1TX 0x01000002 +#define DMA_CH2_EUSCIB1TX0 0x02000002 +#define DMA_CH2_EUSCIB0TX1 0x03000002 +#define DMA_CH2_EUSCIB3TX2 0x04000002 +#define DMA_CH2_EUSCIB2TX3 0x05000002 +#define DMA_CH2_TIMERA1CCR0 0x06000002 +#define DMA_CH2_AESTRIGGER2 0x07000002 + +// +// Channel 3 +// +#define DMA_CH3_RESERVED0 0x00000003 +#define DMA_CH3_EUSCIA1RX 0x01000003 +#define DMA_CH3_EUSCIB1RX0 0x02000003 +#define DMA_CH3_EUSCIB0RX1 0x03000003 +#define DMA_CH3_EUSCIB3RX2 0x04000003 +#define DMA_CH3_EUSCIB2RX3 0x05000003 +#define DMA_CH3_TIMERA1CCR2 0x06000003 +#define DMA_CH3_RESERVED1 0x07000003 + +// +// Channel 4 +// +#define DMA_CH4_RESERVED0 0x00000004 +#define DMA_CH4_EUSCIA2TX 0x01000004 +#define DMA_CH4_EUSCIB2TX0 0x02000004 +#define DMA_CH4_EUSCIB1TX1 0x03000004 +#define DMA_CH4_EUSCIB0TX2 0x04000004 +#define DMA_CH4_EUSCIB3TX3 0x05000004 +#define DMA_CH4_TIMERA2CCR0 0x06000004 +#define DMA_CH4_RESERVED1 0x07000004 + +// +// Channel 5 +// +#define DMA_CH5_RESERVED0 0x00000005 +#define DMA_CH5_EUSCIA2RX 0x01000005 +#define DMA_CH5_EUSCIB2RX0 0x02000005 +#define DMA_CH5_EUSCIB1RX1 0x03000005 +#define DMA_CH5_EUSCIB0RX2 0x04000005 +#define DMA_CH5_EUSCIB3RX3 0x05000005 +#define DMA_CH5_TIMERA2CCR2 0x06000005 +#define DMA_CH5_RESERVED1 0x07000005 + +// +// Channel 6 +// +#define DMA_CH6_RESERVED0 0x00000006 +#define DMA_CH6_EUSCIA3TX 0x01000006 +#define DMA_CH6_EUSCIB3TX0 0x02000006 +#define DMA_CH6_EUSCIB2TX1 0x03000006 +#define DMA_CH6_EUSCIB1TX2 0x04000006 +#define DMA_CH6_EUSCIB0TX3 0x05000006 +#define DMA_CH6_TIMERA3CCR0 0x06000006 +#define DMA_CH6_EXTERNALPIN 0x07000006 + +// +// Channel 7 +// +#define DMA_CH7_RESERVED0 0x00000007 +#define DMA_CH7_EUSCIA3RX 0x01000007 +#define DMA_CH7_EUSCIB3RX0 0x02000007 +#define DMA_CH7_EUSCIB2RX1 0x03000007 +#define DMA_CH7_EUSCIB1RX2 0x04000007 +#define DMA_CH7_EUSCIB0RX3 0x05000007 +#define DMA_CH7_TIMERA3CCR2 0x06000007 +#define DMA_CH7_ADC14 0x07000007 + +// +// Different interrupt handlers to pass into DMA_registerInterrupt and +// DMA_unregisterInterrupt and other Int functions +// +#define DMA_INT0 INT_DMA_INT0 +#define DMA_INT1 INT_DMA_INT1 +#define DMA_INT2 INT_DMA_INT2 +#define DMA_INT3 INT_DMA_INT3 +#define DMA_INTERR INT_DMA_ERR + +#define DMA_CHANNEL_0 0 +#define DMA_CHANNEL_1 1 +#define DMA_CHANNEL_2 2 +#define DMA_CHANNEL_3 3 +#define DMA_CHANNEL_4 4 +#define DMA_CHANNEL_5 5 +#define DMA_CHANNEL_6 6 +#define DMA_CHANNEL_7 7 + +//***************************************************************************** +// +// API Function prototypes +// +//***************************************************************************** + +//***************************************************************************** +// +//! Enables the DMA controller for use. +//! +//! This function enables the DMA controller. The DMA controller must be +//! enabled before it can be configured and used. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_enableModule(void); + +//***************************************************************************** +// +//! Disables the DMA controller for use. +//! +//! This function disables the DMA controller. Once disabled, the DMA +//! controller cannot operate until re-enabled with DMA_enableModule(). +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_disableModule(void); + +//***************************************************************************** +// +//! Gets the DMA error status. +//! +//! This function returns the DMA error status. It should be called from +//! within the DMA error interrupt handler to determine if a DMA error +//! occurred. +//! +//! \return Returns non-zero if a DMA error is pending. +// +//***************************************************************************** +extern uint32_t DMA_getErrorStatus(void); + +//***************************************************************************** +// +//! Clears the DMA error interrupt. +//! +//! This function clears a pending DMA error interrupt. This function should +//! be called from within the DMA error interrupt handler to clear the +//! interrupt. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_clearErrorStatus(void); + +//***************************************************************************** +// +//! Enables a DMA channel for operation. +//! +//! \param channelNum is the channel number to enable. +//! +//! When a DMA transfer is completed, the channel is automatically disabled by +//! the DMA controller. Therefore, this function should be called prior to +//! starting up any new transfer. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_enableChannel(uint32_t channelNum); + +//***************************************************************************** +// +//! Disables a DMA channel for operation. +//! +//! \param channelNum is the channel number to disable. +//! +//! This function disables a specific DMA channel. Once disabled, a channel +//! cannot respond to DMA transfer requests until re-enabled via +//! DMA_enableChannel(). +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_disableChannel(uint32_t channelNum); + +//***************************************************************************** +// +//! Checks if a DMA channel is enabled for operation. +//! +//! \param channelNum is the channel number to check. +//! +//! This function checks to see if a specific DMA channel is enabled. This +//! function can be used to check the status of a transfer, as the channel is +//! automatically disabled at the end of a transfer. +//! +//! \return Returns \b true if the channel is enabled, \b false if disabled. +// +//***************************************************************************** +extern bool DMA_isChannelEnabled(uint32_t channelNum); + +//***************************************************************************** +// +//! Sets the base address for the channel control table. +//! +//! \param controlTable is a pointer to the 1024-byte-aligned base address +//! of the DMA channel control table. +//! +//! This function configures the base address of the channel control table. +//! This table resides in system memory and holds control information for each +//! DMA channel. The table must be aligned on a 1024-byte boundary. The base +//! address must be configured before any of the channel functions can be used. +//! +//! The size of the channel control table depends on the number of DMA +//! channels and the transfer modes that are used. Refer to the introductory +//! text and the microcontroller datasheet for more information about the +//! channel control table. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_setControlBase(void *controlTable); + +//***************************************************************************** +// +//! Gets the base address for the channel control table. +//! +//! This function gets the base address of the channel control table. This +//! table resides in system memory and holds control information for each DMA +//! channel. +//! +//! \return Returns a pointer to the base address of the channel control table. +// +//***************************************************************************** +extern void* DMA_getControlBase(void); + +//***************************************************************************** +// +//! Gets the base address for the channel control table alternate structures. +//! +//! This function gets the base address of the second half of the channel +//! control table that holds the alternate control structures for each channel. +//! +//! \return Returns a pointer to the base address of the second half of the +//! channel control table. +// +//***************************************************************************** +extern void* DMA_getControlAlternateBase(void); + +//***************************************************************************** +// +//! Requests a DMA channel to start a transfer. +//! +//! \param channelNum is the channel number on which to request a DMA +//! transfer. +//! +//! This function allows software to request a DMA channel to begin a +//! transfer. This function could be used for performing a memory-to-memory +//! transfer, or if for some reason a transfer needs to be initiated by +//! software instead of the peripheral associated with that channel. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_requestChannel(uint32_t channelNum); + +//***************************************************************************** +// +//! Enables attributes of a DMA channel. +//! +//! \param channelNum is the channel to configure. +//! \param attr is a combination of attributes for the channel. +//! +//! This function is used to enable attributes of a DMA channel. +//! +//! The \e attr parameter is the logical OR of any of the following: +//! +//! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst +//! mode. +//! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure +//! for this channel (it is very unlikely that this flag should be used). +//! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority. +//! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the +//! peripheral for this channel. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_enableChannelAttribute(uint32_t channelNum, uint32_t attr); + +//***************************************************************************** +// +//! Disables attributes of a DMA channel. +//! +//! \param channelNum is the channel to configure. +//! \param attr is a combination of attributes for the channel. +//! +//! This function is used to disable attributes of a DMA channel. +//! +//! The \e attr parameter is the logical OR of any of the following: +//! +//! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst +//! mode. +//! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure +//! for this channel. +//! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority. +//! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the +//! peripheral for this channel. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_disableChannelAttribute(uint32_t channelNum, uint32_t attr); + +//***************************************************************************** +// +//! Gets the enabled attributes of a DMA channel. +//! +//! \param channelNum is the channel to configure. +//! +//! This function returns a combination of flags representing the attributes of +//! the DMA channel. +//! +//! \return Returns the logical OR of the attributes of the DMA channel, which +//! can be any of the following: +//! - \b UDMA_ATTR_USEBURST is used to restrict transfers to use only burst +//! mode. +//! - \b UDMA_ATTR_ALTSELECT is used to select the alternate control structure +//! for this channel. +//! - \b UDMA_ATTR_HIGH_PRIORITY is used to set this channel to high priority. +//! - \b UDMA_ATTR_REQMASK is used to mask the hardware request signal from the +//! peripheral for this channel. +// +//***************************************************************************** +extern uint32_t DMA_getChannelAttribute(uint32_t channelNum); + +//***************************************************************************** +// +//! Sets the control parameters for a DMA channel control structure. +//! +//! \param channelStructIndex is the logical OR of the DMA channel number +//! with \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT. +//! \param control is logical OR of several control values to set the control +//! parameters for the channel. +//! +//! This function is used to set control parameters for a DMA transfer. These +//! parameters are typically not changed often. +//! +//! The \e channelStructIndex parameter should be the logical OR of the +//! channel number with one of \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to +//! choose whether the primary or alternate data structure is used. +//! +//! The \e control parameter is the logical OR of five values: the data size, +//! the source address increment, the destination address increment, the +//! arbitration size, and the use burst flag. The choices available for each +//! of these values is described below. +//! +//! Choose the data size from one of \b UDMA_SIZE_8, \b UDMA_SIZE_16, or +//! \b UDMA_SIZE_32 to select a data size of 8, 16, or 32 bits. +//! +//! Choose the source address increment from one of \b UDMA_SRC_INC_8, +//! \b UDMA_SRC_INC_16, \b UDMA_SRC_INC_32, or \b UDMA_SRC_INC_NONE to select +//! an address increment of 8-bit bytes, 16-bit half-words, 32-bit words, or +//! to select non-incrementing. +//! +//! Choose the destination address increment from one of \b UDMA_DST_INC_8, +//! \b UDMA_DST_INC_16, \b UDMA_DST_INC_32, or \b UDMA_SRC_INC_8 to select +//! an address increment of 8-bit bytes, 16-bit half-words, 32-bit words, or +//! to select non-incrementing. +//! +//! The arbitration size determines how many items are transferred before +//! the DMA controller re-arbitrates for the bus. Choose the arbitration size +//! from one of \b UDMA_ARB_1, \b UDMA_ARB_2, \b UDMA_ARB_4, \b UDMA_ARB_8, +//! through \b UDMA_ARB_1024 to select the arbitration size from 1 to 1024 +//! items, in powers of 2. +//! +//! The value \b UDMA_NEXT_USEBURST is used to force the channel to only +//! respond to burst requests at the tail end of a scatter-gather transfer. +//! +//! \note The address increment cannot be smaller than the data size. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_setChannelControl(uint32_t channelStructIndex, + uint32_t control); + +//***************************************************************************** +// +//! Sets the transfer parameters for a DMA channel control structure. +//! +//! \param channelStructIndex is the logical OR of the DMA channel number +//! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT. +//! \param mode is the type of DMA transfer. +//! \param srcAddr is the source address for the transfer. +//! \param dstAddr is the destination address for the transfer. +//! \param transferSize is the number of data items to transfer. +//! +//! This function is used to configure the parameters for a DMA transfer. +//! These parameters are typically changed often. The function +//! DMA_setChannelControl() MUST be called at least once for this channel prior +//! to calling this function. +//! +//! The \e channelStructIndex parameter should be the logical OR of the +//! channel number with one of \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT to +//! choose whether the primary or alternate data structure is used. +//! +//! The \e mode parameter should be one of the following values: +//! +//! - \b UDMA_MODE_STOP stops the DMA transfer. The controller sets the mode +//! to this value at the end of a transfer. +//! - \b UDMA_MODE_BASIC to perform a basic transfer based on request. +//! - \b UDMA_MODE_AUTO to perform a transfer that always completes once +//! started even if the request is removed. +//! - \b UDMA_MODE_PINGPONG to set up a transfer that switches between the +//! primary and alternate control structures for the channel. This mode +//! allows use of ping-pong buffering for DMA transfers. +//! - \b UDMA_MODE_MEM_SCATTER_GATHER to set up a memory scatter-gather +//! transfer. +//! - \b UDMA_MODE_PER_SCATTER_GATHER to set up a peripheral scatter-gather +//! transfer. +//! +//! The \e srcAddr and \e dstAddr parameters are pointers to the first +//! location of the data to be transferred. These addresses should be aligned +//! according to the item size. The compiler takes care of this alignment if +//! the pointers are pointing to storage of the appropriate data type. +//! +//! The \e transferSize parameter is the number of data items, not the number +//! of bytes. +//! +//! The two scatter-gather modes, memory and peripheral, are actually different +//! depending on whether the primary or alternate control structure is +//! selected. This function looks for the \b UDMA_PRI_SELECT and +//! \b UDMA_ALT_SELECT flag along with the channel number and sets the +//! scatter-gather mode as appropriate for the primary or alternate control +//! structure. +//! +//! The channel must also be enabled using DMA_enableChannel() after calling +//! this function. The transfer does not begin until the channel has been +//! configured and enabled. Note that the channel is automatically disabled +//! after the transfer is completed, meaning that DMA_enableChannel() must be +//! called again after setting up the next transfer. +//! +//! \note Great care must be taken to not modify a channel control structure +//! that is in use or else the results are unpredictable, including the +//! possibility of undesired data transfers to or from memory or peripherals. +//! For BASIC and AUTO modes, it is safe to make changes when the channel is +//! disabled, or the DMA_getChannelMode() returns \b UDMA_MODE_STOP. For +//! PINGPONG or one of the SCATTER_GATHER modes, it is safe to modify the +//! primary or alternate control structure only when the other is being used. +//! The DMA_getChannelMode() function returns \b UDMA_MODE_STOP when a +//! channel control structure is inactive and safe to modify. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_setChannelTransfer(uint32_t channelStructIndex, uint32_t mode, + void *srcAddr, void *dstAddr, uint32_t transferSize); + +//***************************************************************************** +// +//! Configures a DMA channel for scatter-gather mode. +//! +//! \param channelNum is the DMA channel number. +//! \param taskCount is the number of scatter-gather tasks to execute. +//! \param taskList is a pointer to the beginning of the scatter-gather +//! task list. +//! \param isPeriphSG is a flag to indicate it is a peripheral scatter-gather +//! transfer (else it is memory scatter-gather transfer) +//! +//! This function is used to configure a channel for scatter-gather mode. +//! The caller must have already set up a task list and must pass a pointer to +//! the start of the task list as the \e taskList parameter. The +//! \e taskCount parameter is the count of tasks in the task list, not the +//! size of the task list. The flag \e bIsPeriphSG should be used to indicate +//! if scatter-gather should be configured for peripheral or memory +//! operation. +//! +//! \sa DMA_TaskStructEntry +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_setChannelScatterGather(uint32_t channelNum, uint32_t taskCount, + void *taskList, uint32_t isPeriphSG); + +//***************************************************************************** +// +//! Gets the current transfer size for a DMA channel control structure. +//! +//! \param channelStructIndex is the logical OR of the DMA channel number +//! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT. +//! +//! This function is used to get the DMA transfer size for a channel. The +//! transfer size is the number of items to transfer, where the size of an item +//! might be 8, 16, or 32 bits. If a partial transfer has already occurred, +//! then the number of remaining items is returned. If the transfer is +//! complete, then 0 is returned. +//! +//! \return Returns the number of items remaining to transfer. +// +//***************************************************************************** +extern uint32_t DMA_getChannelSize(uint32_t channelStructIndex); + +//***************************************************************************** +// +//! Gets the transfer mode for a DMA channel control structure. +//! +//! \param channelStructIndex is the logical OR of the DMA channel number +//! with either \b UDMA_PRI_SELECT or \b UDMA_ALT_SELECT. +//! +//! This function is used to get the transfer mode for the DMA channel and +//! to query the status of a transfer on a channel. When the transfer is +//! complete the mode is \b UDMA_MODE_STOP. +//! +//! \return Returns the transfer mode of the specified channel and control +//! structure, which is one of the following values: \b UDMA_MODE_STOP, +//! \b UDMA_MODE_BASIC, \b UDMA_MODE_AUTO, \b UDMA_MODE_PINGPONG, +//! \b UDMA_MODE_MEM_SCATTER_GATHER, or \b UDMA_MODE_PER_SCATTER_GATHER. +// +//***************************************************************************** +extern uint32_t DMA_getChannelMode(uint32_t channelStructIndex); + +//***************************************************************************** +// +//! Assigns a peripheral mapping for a DMA channel. +//! +//! \param mapping is a macro specifying the peripheral assignment for +//! a channel. +//! +//! This function assigns a peripheral mapping to a DMA channel. It is +//! used to select which peripheral is used for a DMA channel. The parameter +//! \e mapping should be one of the macros named \b UDMA_CHn_tttt from the +//! header file \e dma.h. For example, to assign DMA channel 0 to the +//! eUSCI AO RX channel, the parameter should be the macro +//! \b UDMA_CH1_EUSCIA0RX. +//! +//! Please consult the data sheet for a table showing all the +//! possible peripheral assignments for the DMA channels for a particular +//! device. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_assignChannel(uint32_t mapping); + +//***************************************************************************** +// +//! Initializes a software transfer of the corresponding DMA channel. This is +//! done if the user wants to force a DMA on the specified channel without the +//! hardware precondition. Specific channels can be configured using the +//! DMA_assignChannel function. +//! +//! \param channel is the channel to trigger the interrupt +//! +//! +//! \return None +// +//***************************************************************************** +extern void DMA_requestSoftwareTransfer(uint32_t channel); + +//***************************************************************************** +// +//! Assigns a specific DMA channel to the corresponding interrupt handler. For +//! MSP432 devices, there are three configurable interrupts, and one master +//! interrupt. This function will assign a specific DMA channel to the +//! provided configurable DMA interrupt. +//! +//! Note that once a channel is assigned to a configurable interrupt, it will be +//! masked in hardware from the master DMA interrupt (interruptNumber zero). This +//! function can also be used in conjunction with the DMAIntTrigger function +//! to provide the feature to software trigger specific channel interrupts. +//! +//! \param interruptNumber is the configurable interrupt to assign the given +//! channel. Valid values are: +//! - \b DMA_INT1 the first configurable DMA interrupt handler +//! - \b DMA_INT2 the second configurable DMA interrupt handler +//! - \b DMA_INT3 the third configurable DMA interrupt handler +//! +//! \param channel is the channel to assign the interrupt +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_assignInterrupt(uint32_t interruptNumber, uint32_t channel); + +//***************************************************************************** +// +//! Enables the specified interrupt for the DMA controller. Note for interrupts +//! one through three, specific channels have to be mapped to the interrupt +//! using the DMA_assignInterrupt function. +//! +//! \param interruptNumber identifies which DMA interrupt is to be enabled. +//! This interrupt should be one of the following: +//! +//! - \b DMA_INT0 the master DMA interrupt handler +//! - \b DMA_INT1 the first configurable DMA interrupt handler +//! - \b DMA_INT2 the second configurable DMA interrupt handler +//! - \b DMA_INT3 the third configurable DMA interrupt handler +//! - \b DMA_INTERR the third configurable DMA interrupt handler +//! +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_enableInterrupt(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Disables the specified interrupt for the DMA controller. +//! +//! \param interruptNumber identifies which DMA interrupt is to be disabled. +//! This interrupt should be one of the following: +//! +//! - \b DMA_INT0 the master DMA interrupt handler +//! - \b DMA_INT1 the first configurable DMA interrupt handler +//! - \b DMA_INT2 the second configurable DMA interrupt handler +//! - \b DMA_INT3 the third configurable DMA interrupt handler +//! - \b DMA_INTERR the third configurable DMA interrupt handler +//! +//! Note for interrupts that are associated with a specific DMA channel +//! (DMA_INT1 - DMA_INT3), this function will also enable that specific +//! channel for interrupts. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_disableInterrupt(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Gets the DMA controller channel interrupt status for interrupt zero. +//! +//! This function is used to get the interrupt status of the DMA controller. +//! The returned value is a 32-bit bit mask that indicates which channels are +//! requesting an interrupt. This function can be used from within an +//! interrupt handler to determine or confirm which DMA channel has requested +//! an interrupt. +//! +//! Note that this will only apply to interrupt zero for the DMA +//! controller as only one interrupt can be associated with interrupts one +//! through three. If an interrupt is assigned to an interrupt other +//! than interrupt zero, it will be masked by this function. +//! +//! \return Returns a 32-bit mask which indicates requesting DMA channels. +//! There is a bit for each channel and a 1 indicates that the channel +//! is requesting an interrupt. Multiple bits can be set. +// +//***************************************************************************** +extern uint32_t DMA_getInterruptStatus(void); + +//***************************************************************************** +// +//! Clears the DMA controller channel interrupt mask for interrupt zero. +//! +//! \param channel is the channel interrupt to clear. +//! +//! This function is used to clear the interrupt status of the DMA controller. +//! Note that only interrupts that weren't assigned to DMA interrupts one +//! through three using the DMA_assignInterrupt function will be affected by +//! thisfunctions. For other DMA interrupts, only one channel can be associated +//! and therefore clearing in unnecessary. +//! +//! \return None +// +//***************************************************************************** +extern void DMA_clearInterruptFlag(uint32_t intChannel); + +//***************************************************************************** +// +//! Registers an interrupt handler for the DMA controller. +//! +//! \param interruptNumber identifies which DMA interrupt is to be registered. +//! \param intHandler is a pointer to the function to be called when the +//! interrupt is called. +//! +//! This function registers and enables the handler to be called when the DMA +//! controller generates an interrupt. The \e interrupt parameter should be +//! one of the following: +//! +//! - \b DMA_INT0 the master DMA interrupt handler +//! - \b DMA_INT1 the first configurable DMA interrupt handler +//! - \b DMA_INT2 the second configurable DMA interrupt handler +//! - \b DMA_INT3 the third configurable DMA interrupt handler +//! - \b DMA_INTERR the third configurable DMA interrupt handler +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_registerInterrupt(uint32_t intChannel, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the DMA controller. +//! +//! \param interruptNumber identifies which DMA interrupt to unregister. +//! +//! This function disables and unregisters the handler to be called for the +//! specified DMA interrupt. The \e interrupt parameter should be one of +//! \b the parameters as documented for the function +//! DMA_registerInterrupt(). +//! +//! Note fore interrupts that are associated with a specific DMA channel +//! (DMA_INT1 - DMA_INT3), this function will also disable that specific +//! channel for interrupts. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void DMA_unregisterInterrupt(uint32_t intChannel); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __UDMA_H__ diff --git a/example/rt_msp432/MSP432P4xx/driverlib.h b/example/rt_msp432/MSP432P4xx/driverlib.h new file mode 100644 index 0000000..7279da6 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/driverlib.h @@ -0,0 +1,70 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __DRIVERLIB__H_ +#define __DRIVERLIB__H_ + +#include "adc14.h" +#include "aes256.h" +#include "comp_e.h" +#include "cpu.h" +#include "crc32.h" +#include "cs.h" +#include "dma.h" +#include "eusci.h" +#include "flash.h" +#include "fpu.h" +#include "gpio.h" +#include "i2c.h" +#include "interrupt.h" +#include "mpu.h" +#include "pcm.h" +#include "pmap.h" +#include "pss.h" +#include "ref_a.h" +#include "reset.h" +#include "rom.h" +#include "rom_map.h" +#include "rtc_c.h" +#include "spi.h" +#include "sysctl.h" +#include "systick.h" +#include "timer32.h" +#include "timer_a.h" +#include "uart.h" +#include "wdt_a.h" + +#endif diff --git a/example/rt_msp432/MSP432P4xx/eusci.h b/example/rt_msp432/MSP432P4xx/eusci.h new file mode 100644 index 0000000..4bcd139 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/eusci.h @@ -0,0 +1,45 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef EUSCI_H_ +#define EUSCI_H_ + +#include + +#define EUSCI_A_CMSIS(x) ((EUSCI_A_Type *) x) +#define EUSCI_B_CMSIS(x) ((EUSCI_B_Type *) x) + +#endif /* EUSCI_H_ */ diff --git a/example/rt_msp432/MSP432P4xx/ewarm/msp432p4xx_driverlib.a b/example/rt_msp432/MSP432P4xx/ewarm/msp432p4xx_driverlib.a new file mode 100644 index 0000000..3cfcdf2 Binary files /dev/null and b/example/rt_msp432/MSP432P4xx/ewarm/msp432p4xx_driverlib.a differ diff --git a/example/rt_msp432/MSP432P4xx/flash.c b/example/rt_msp432/MSP432P4xx/flash.c new file mode 100644 index 0000000..c1a0a7d --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/flash.c @@ -0,0 +1,1569 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include + +/* DriverLib Includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +static const uint32_t MAX_ERASE_NO_TLV = 50; +static const uint32_t MAX_PROGRAM_NO_TLV = 5; + +static volatile uint32_t* __getBurstProgramRegs[16] = +{ &FLCTL->PRGBRST_DATA0_0, &FLCTL->PRGBRST_DATA0_1, +&FLCTL->PRGBRST_DATA0_2, &FLCTL->PRGBRST_DATA0_3, +&FLCTL->PRGBRST_DATA1_0, &FLCTL->PRGBRST_DATA1_1, +&FLCTL->PRGBRST_DATA1_2, &FLCTL->PRGBRST_DATA1_3, +&FLCTL->PRGBRST_DATA2_0, &FLCTL->PRGBRST_DATA2_1, +&FLCTL->PRGBRST_DATA2_2, &FLCTL->PRGBRST_DATA2_3, +&FLCTL->PRGBRST_DATA3_0, &FLCTL->PRGBRST_DATA3_1, +&FLCTL->PRGBRST_DATA3_2, &FLCTL->PRGBRST_DATA3_3 }; + +static uint32_t getUserFlashSector(uint32_t addr) +{ + if (addr > 0x1ffff) + { + addr = addr - 0x20000; + } + + switch (addr) + { + case 0: + return FLASH_SECTOR0; + case 0x1000: + return FLASH_SECTOR1; + case 0x2000: + return FLASH_SECTOR2; + case 0x3000: + return FLASH_SECTOR3; + case 0x4000: + return FLASH_SECTOR4; + case 0x5000: + return FLASH_SECTOR5; + case 0x6000: + return FLASH_SECTOR6; + case 0x7000: + return FLASH_SECTOR7; + case 0x8000: + return FLASH_SECTOR8; + case 0x9000: + return FLASH_SECTOR9; + case 0xA000: + return FLASH_SECTOR10; + case 0xB000: + return FLASH_SECTOR11; + case 0xC000: + return FLASH_SECTOR12; + case 0xD000: + return FLASH_SECTOR13; + case 0xE000: + return FLASH_SECTOR14; + case 0xF000: + return FLASH_SECTOR15; + case 0x10000: + return FLASH_SECTOR16; + case 0x11000: + return FLASH_SECTOR17; + case 0x12000: + return FLASH_SECTOR18; + case 0x13000: + return FLASH_SECTOR19; + case 0x14000: + return FLASH_SECTOR20; + case 0x15000: + return FLASH_SECTOR21; + case 0x16000: + return FLASH_SECTOR22; + case 0x17000: + return FLASH_SECTOR23; + case 0x18000: + return FLASH_SECTOR24; + case 0x19000: + return FLASH_SECTOR25; + case 0x1A000: + return FLASH_SECTOR26; + case 0x1B000: + return FLASH_SECTOR27; + case 0x1C000: + return FLASH_SECTOR28; + case 0x1D000: + return FLASH_SECTOR29; + case 0x1E000: + return FLASH_SECTOR30; + case 0x1F000: + return FLASH_SECTOR31; + default: + ASSERT(false); + return 0; + } +} + +void FlashCtl_getMemoryInfo(uint32_t addr, uint32_t *sectorNum, + uint32_t *bankNum) +{ + uint32_t bankLimit; + + bankLimit = SysCtl_getFlashSize() / 2; + + if (addr > bankLimit) + { + *(sectorNum) = FLASH_BANK1; + addr = (addr - bankLimit); + } else + { + *(sectorNum) = FLASH_BANK0; + } + + *(bankNum) = (addr - __MAIN_MEMORY_START__) / 4096; +} + +static bool _FlashCtl_Program8(uint32_t src, uint32_t dest, uint32_t mTries) +{ + uint32_t ii; + uint8_t data; + + /* Enabling the correct verification settings */ + FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST); + FlashCtl_clearProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE); + + data = HWREG8(src); + + for (ii = 0; ii < mTries; ii++) + { + /* Clearing flags */ + FLCTL->CLRIFG |= (FLASH_PROGRAM_ERROR | FLASH_POSTVERIFY_FAILED + | FLASH_PREVERIFY_FAILED | FLASH_WRDPRGM_COMPLETE); + + HWREG8(dest) = data; + + while (!(FlashCtl_getInterruptStatus() & FLASH_WRDPRGM_COMPLETE)) + { + __no_operation(); + } + + /* Pre-Verify */ + if ((BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) + && BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPRE_OFS))) + { + data = __FlashCtl_remaskData8Pre(data, dest); + + if (data != 0xFF) + { + FlashCtl_clearProgramVerification(FLASH_REGPRE); + continue; + } + + } + + /* Post Verify */ + if ((BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPST_OFS))) + { + data = __FlashCtl_remaskData8Post(data, dest); + + /* Seeing if we actually need to do another pulse */ + if (data == 0xFF) + return true; + + FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST); + continue; + } + + /* If we got this far, return true */ + return true; + + } + + return false; + +} + +static bool _FlashCtl_Program32(uint32_t src, uint32_t dest, uint32_t mTries) +{ + uint32_t ii; + uint32_t data; + + /* Enabling the correct verification settings */ + FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST); + FlashCtl_clearProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE); + + data = HWREG32(src); + + for (ii = 0; ii < mTries; ii++) + { + /* Clearing flags */ + FLCTL->CLRIFG |= (FLASH_PROGRAM_ERROR | FLASH_POSTVERIFY_FAILED + | FLASH_PREVERIFY_FAILED | FLASH_WRDPRGM_COMPLETE); + + HWREG32(dest) = data; + + while (!(FlashCtl_getInterruptStatus() & FLASH_WRDPRGM_COMPLETE)) + { + __no_operation(); + } + + /* Pre-Verify */ + if ((BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) + && BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPRE_OFS))) + { + data = __FlashCtl_remaskData32Pre(data, dest); + + if (data != 0xFFFFFFFF) + { + + FlashCtl_clearProgramVerification(FLASH_REGPRE); + continue; + } + + } + + /* Post Verify */ + if ((BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPST_OFS))) + { + data = __FlashCtl_remaskData32Post(data, dest); + + /* Seeing if we actually need to do another pulse */ + if (data == 0xFFFFFFFF) + return true; + + FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST); + continue; + } + + /* If we got this far, return true */ + return true; + + } + + return false; + +} + +static bool _FlashCtl_ProgramBurst(uint32_t src, uint32_t dest, uint32_t length, + uint32_t mTries) +{ + uint32_t bCalc, otpOffset, ii, jj; + bool res; + + /* Setting verification */ + FlashCtl_clearProgramVerification(FLASH_REGPRE | FLASH_REGPOST); + FlashCtl_setProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE); + + /* Assume Failure */ + res = false; + + /* Waiting for idle status */ + while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK) + != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0) + { + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; + } + + /* Setting/clearing INFO flash flags as appropriate */ + if (dest > __MAIN_MEMORY_END__) + { + FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT + & ~FLCTL_PRGBRST_CTLSTAT_TYPE_MASK) | FLCTL_PRGBRST_CTLSTAT_TYPE_1; + otpOffset = __INFO_FLASH_TECH_START__; + } else + { + FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT + & ~FLCTL_PRGBRST_CTLSTAT_TYPE_MASK) | FLCTL_PRGBRST_CTLSTAT_TYPE_0; + otpOffset = __MAIN_MEMORY_START__; + } + + bCalc = 0; + FLCTL->PRGBRST_STARTADDR = (dest - otpOffset); + + /* Initially populating the burst registers */ + while (bCalc < 16 && length != 0) + { + HWREG32(__getBurstProgramRegs[bCalc]) = HWREG32(src); + bCalc++; + length -= 4; + src += 4; + } + + for (ii = 0; ii < mTries; ii++) + { + /* Clearing Flags */ + FLCTL->CLRIFG |= (FLASH_BRSTPRGM_COMPLETE | FLASH_POSTVERIFY_FAILED + | FLASH_PREVERIFY_FAILED); + + /* Waiting for idle status */ + while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK) + != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0) + { + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; + } + + /* Start the burst program */ + FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT + & ~(FLCTL_PRGBRST_CTLSTAT_LEN_MASK)) + | ((bCalc / 4) << FLASH_BURST_PRG_BIT) + | FLCTL_PRGBRST_CTLSTAT_START; + + /* Waiting for the burst to complete */ + while ((FLCTL->PRGBRST_CTLSTAT & + FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK) + != FLASH_PRGBRSTCTLSTAT_BURSTSTATUS_COMPLETE) + { + __no_operation(); + } + + /* Checking for errors and clearing/masking */ + + /* Address Error */ + if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_ADDR_ERR_OFS)) + { + goto BurstCleanUp; + } + + /* Pre-Verify Error */ + if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) && BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_PRE_ERR_OFS)) + { + __FlashCtl_remaskBurstDataPre(dest, bCalc * 4); + + for (jj = 0; jj < bCalc; jj++) + { + if (HWREG32(__getBurstProgramRegs[jj]) + != 0xFFFFFFFF) + { + FlashCtl_clearProgramVerification(FLASH_BURSTPRE); + break; + } + } + + if (jj != bCalc) + continue; + } + + /* Post-Verify Error */ + if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_PST_ERR_OFS)) + { + __FlashCtl_remaskBurstDataPost(dest, bCalc * 4); + + for (jj = 0; jj < bCalc; jj++) + { + if ((HWREG32(__getBurstProgramRegs[jj])) + != 0xFFFFFFFF) + { + FlashCtl_setProgramVerification( + FLASH_BURSTPOST | FLASH_BURSTPRE); + break; + } + } + + if (jj != bCalc) + continue; + + } + + /* If we got this far, the program happened */ + res = true; + goto BurstCleanUp; + } + + BurstCleanUp: + /* Waiting for idle status */ + while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK) + != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0) + { + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; + } + return res; +} + +void FlashCtl_enableReadBuffering(uint_fast8_t memoryBank, + uint_fast8_t accessMethod) +{ + if (memoryBank == FLASH_BANK0 && accessMethod == FLASH_DATA_READ) + BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFD_OFS) = 1; + else if (memoryBank == FLASH_BANK1 && accessMethod == FLASH_DATA_READ) + BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFD_OFS) = 1; + else if (memoryBank == FLASH_BANK0 + && accessMethod == FLASH_INSTRUCTION_FETCH) + BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFI_OFS) = 1; + else if (memoryBank == FLASH_BANK1 + && accessMethod == FLASH_INSTRUCTION_FETCH) + BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFI_OFS) = 1; + else + ASSERT(false); +} + +void FlashCtl_disableReadBuffering(uint_fast8_t memoryBank, + uint_fast8_t accessMethod) +{ + if (memoryBank == FLASH_BANK0 && accessMethod == FLASH_DATA_READ) + BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFD_OFS) = 0; + else if (memoryBank == FLASH_BANK1 && accessMethod == FLASH_DATA_READ) + BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFD_OFS) = 0; + else if (memoryBank == FLASH_BANK0 + && accessMethod == FLASH_INSTRUCTION_FETCH) + BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFI_OFS) = 0; + else if (memoryBank == FLASH_BANK1 + && accessMethod == FLASH_INSTRUCTION_FETCH) + BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFI_OFS) = 0; + else + ASSERT(false); +} + +bool FlashCtl_unprotectSector(uint_fast8_t memorySpace, uint32_t sectorMask) +{ + switch (memorySpace) + { + case FLASH_MAIN_MEMORY_SPACE_BANK0: + FLCTL->BANK0_MAIN_WEPROT &= ~sectorMask; + break; + case FLASH_MAIN_MEMORY_SPACE_BANK1: + FLCTL->BANK1_MAIN_WEPROT &= ~sectorMask; + break; + case FLASH_INFO_MEMORY_SPACE_BANK0: + ASSERT(sectorMask <= 0x04); + FLCTL->BANK0_INFO_WEPROT &= ~sectorMask; + break; + case FLASH_INFO_MEMORY_SPACE_BANK1: + ASSERT(sectorMask <= 0x04); + FLCTL->BANK1_INFO_WEPROT &= ~sectorMask; + break; + + default: + ASSERT(false); + + } + + return !FlashCtl_isSectorProtected(memorySpace, sectorMask); +} + +bool FlashCtl_protectSector(uint_fast8_t memorySpace, uint32_t sectorMask) +{ + switch (memorySpace) + { + case FLASH_MAIN_MEMORY_SPACE_BANK0: + FLCTL->BANK0_MAIN_WEPROT |= sectorMask; + break; + case FLASH_MAIN_MEMORY_SPACE_BANK1: + FLCTL->BANK1_MAIN_WEPROT |= sectorMask; + break; + case FLASH_INFO_MEMORY_SPACE_BANK0: + ASSERT(sectorMask <= 0x04); + FLCTL->BANK0_INFO_WEPROT |= sectorMask; + break; + case FLASH_INFO_MEMORY_SPACE_BANK1: + ASSERT(sectorMask <= 0x04); + FLCTL->BANK1_INFO_WEPROT |= sectorMask; + break; + + default: + ASSERT(false); + + } + + return FlashCtl_isSectorProtected(memorySpace, sectorMask); +} + +bool FlashCtl_isSectorProtected(uint_fast8_t memorySpace, uint32_t sector) +{ + switch (memorySpace) + { + case FLASH_MAIN_MEMORY_SPACE_BANK0: + return FLCTL->BANK0_MAIN_WEPROT & sector; + case FLASH_MAIN_MEMORY_SPACE_BANK1: + return FLCTL->BANK1_MAIN_WEPROT & sector; + case FLASH_INFO_MEMORY_SPACE_BANK0: + ASSERT(sector <= 0x04); + return FLCTL->BANK0_INFO_WEPROT & sector; + case FLASH_INFO_MEMORY_SPACE_BANK1: + ASSERT(sector <= 0x04); + return FLCTL->BANK1_INFO_WEPROT & sector; + default: + return false; + } +} + +bool FlashCtl_verifyMemory(void* verifyAddr, uint32_t length, + uint_fast8_t pattern) +{ + uint32_t memoryPattern, addr, otpOffset; + uint32_t b0WaitState, b1WaitState, intStatus; + uint32_t bankOneStart, startBank, endBank; + uint_fast8_t b0readMode, b1readMode; + uint_fast8_t memoryType; + bool res; + + ASSERT(pattern == FLASH_0_PATTERN || pattern == FLASH_1_PATTERN); + + /* Saving interrupt context and disabling interrupts for program + * operation + */ + intStatus = CPU_primask(); + Interrupt_disableMaster(); + + /* Casting and determining the memory that we need to use */ + addr = (uint32_t) verifyAddr; + memoryType = + (addr > __MAIN_MEMORY_END__) ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE; + + /* Assuming Failure */ + res = false; + + /* Finding out which bank we are in */ + if(addr > SysCtl_getFlashSize()) + { + bankOneStart = __INFO_FLASH_TECH_MIDDLE__; + } + else + { + bankOneStart = SysCtl_getFlashSize() / 2; + } + startBank = addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1; + endBank = (addr + length) < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1; + + /* Saving context and changing read modes */ + b0WaitState = FlashCtl_getWaitState(startBank); + b0readMode = FlashCtl_getReadMode(startBank); + + /* Setting the wait state to account for the mode */ + FlashCtl_setWaitState(startBank, (2 * b0WaitState) + 1); + + if(startBank != endBank) + { + b1WaitState = FlashCtl_getWaitState(endBank); + b1readMode = FlashCtl_getReadMode(endBank); + FlashCtl_setWaitState(endBank, (2 * b1WaitState) + 1); + } + + /* Changing to the relevant VERIFY mode */ + if (pattern == FLASH_1_PATTERN) + { + FlashCtl_setReadMode(startBank, FLASH_ERASE_VERIFY_READ_MODE); + + if(startBank != endBank) + { + FlashCtl_setReadMode(endBank, FLASH_ERASE_VERIFY_READ_MODE); + } + + memoryPattern = 0xFFFFFFFF; + } else + { + FlashCtl_setReadMode(startBank, FLASH_PROGRAM_VERIFY_READ_MODE); + + if(startBank != endBank) + { + FlashCtl_setReadMode(endBank, FLASH_PROGRAM_VERIFY_READ_MODE); + } + + memoryPattern = 0; + } + + /* Taking care of byte accesses */ + while ((addr & 0x03) && (length > 0)) + { + if (HWREG8(addr++) != ((uint8_t) memoryPattern)) + goto FlashVerifyCleanup; + length--; + } + + /* Making sure we are aligned by 128-bit address */ + while (((addr & 0x0F)) && (length > 3)) + { + if (HWREG32(addr) != memoryPattern) + goto FlashVerifyCleanup; + + addr = addr + 4; + length = length - 4; + } + + /* Burst Verify */ + if (length > 63) + { + /* Setting/clearing INFO flash flags as appropriate */ + if (addr > __MAIN_MEMORY_END__) + { + FLCTL->RDBRST_CTLSTAT = (FLCTL->RDBRST_CTLSTAT + & ~FLCTL_RDBRST_CTLSTAT_MEM_TYPE_MASK) + | FLCTL_RDBRST_CTLSTAT_MEM_TYPE_1; + otpOffset = __INFO_FLASH_TECH_START__; + } else + { + FLCTL->RDBRST_CTLSTAT = (FLCTL->RDBRST_CTLSTAT + & ~FLCTL_RDBRST_CTLSTAT_MEM_TYPE_MASK) + | FLCTL_RDBRST_CTLSTAT_MEM_TYPE_0; + otpOffset = __MAIN_MEMORY_START__; + } + + /* Clearing any lingering fault flags and preparing burst verify*/ + BITBAND_PERI(FLCTL->RDBRST_CTLSTAT, + FLCTL_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1; + FLCTL->RDBRST_FAILCNT = 0; + FLCTL->RDBRST_STARTADDR = addr - otpOffset; + FLCTL->RDBRST_LEN = (length & 0xFFFFFFF0); + addr += FLCTL->RDBRST_LEN; + length = length & 0xF; + + /* Starting Burst Verify */ + FLCTL->RDBRST_CTLSTAT = (FLCTL_RDBRST_CTLSTAT_STOP_FAIL | pattern + | memoryType | FLCTL_RDBRST_CTLSTAT_START); + + /* While the burst read hasn't finished */ + while ((FLCTL->RDBRST_CTLSTAT & FLCTL_RDBRST_CTLSTAT_BRST_STAT_MASK) + != FLCTL_RDBRST_CTLSTAT_BRST_STAT_3) + { + __no_operation(); + } + + /* Checking for a verification/access error/failure */ + if (BITBAND_PERI(FLCTL->RDBRST_CTLSTAT, + FLCTL_RDBRST_CTLSTAT_CMP_ERR_OFS) + || BITBAND_PERI(FLCTL->RDBRST_CTLSTAT, + FLCTL_RDBRST_CTLSTAT_ADDR_ERR_OFS) + || FLCTL->RDBRST_FAILCNT) + { + goto FlashVerifyCleanup; + } + } + + /* Remaining Words */ + while (length > 3) + { + if (HWREG32(addr) != memoryPattern) + goto FlashVerifyCleanup; + + addr = addr + 4; + length = length - 4; + } + + /* Remaining Bytes */ + while (length > 0) + { + if (HWREG8(addr++) != ((uint8_t) memoryPattern)) + goto FlashVerifyCleanup; + length--; + } + + /* If we got this far, that means it no failure happened */ + res = true; + + FlashVerifyCleanup: + + /* Clearing the Read Burst flag and returning */ + BITBAND_PERI(FLCTL->RDBRST_CTLSTAT, + FLCTL_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1; + + FlashCtl_setReadMode(startBank, b0readMode); + FlashCtl_setWaitState(startBank, b0WaitState); + + if(startBank != endBank) + { + FlashCtl_setReadMode(endBank, b1readMode); + FlashCtl_setWaitState(endBank, b1WaitState); + } + + if(intStatus == 0) + Interrupt_enableMaster(); + + return res; +} + +bool FlashCtl_setReadMode(uint32_t flashBank, uint32_t readMode) +{ + + if (FLCTL->POWER_STAT & FLCTL_POWER_STAT_RD_2T) + return false; + + if (flashBank == FLASH_BANK0) + { + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL + & ~FLCTL_BANK0_RDCTL_RD_MODE_MASK) | readMode; + while ((FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_RD_MODE_MASK) + != readMode) + ; + } else if (flashBank == FLASH_BANK1) + { + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL + & ~FLCTL_BANK1_RDCTL_RD_MODE_MASK) | readMode; + while ((FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_RD_MODE_MASK) + != readMode) + ; + } else + { + ASSERT(false); + return false; + } + + return true; +} + +uint32_t FlashCtl_getReadMode(uint32_t flashBank) +{ + if (flashBank == FLASH_BANK0) + { + return (FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_RD_MODE_MASK); + } else if (flashBank == FLASH_BANK1) + { + return (FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_RD_MODE_MASK); + } else + { + ASSERT(false); + return 0; + } +} + +void FlashCtl_initiateMassErase(void) +{ + /* Clearing old mass erase flags */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1; + + /* Performing the mass erase */ + FLCTL->ERASE_CTLSTAT |= (FLCTL_ERASE_CTLSTAT_MODE + | FLCTL_ERASE_CTLSTAT_START); +} + +bool FlashCtl_performMassErase(void) +{ + uint32_t userFlash, ii, sector, intStatus; + bool res; + + /* Saving interrupt context and disabling interrupts for program + * operation + */ + intStatus = CPU_primask(); + Interrupt_disableMaster(); + + /* Assume Failure */ + res = false; + + /* Clearing old mass erase flags */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1; + + /* Performing the mass erase */ + FLCTL->ERASE_CTLSTAT |= (FLCTL_ERASE_CTLSTAT_MODE + | FLCTL_ERASE_CTLSTAT_START); + + while ((FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK) + == FLCTL_ERASE_CTLSTAT_STATUS_1 + || (FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK) + == FLCTL_ERASE_CTLSTAT_STATUS_2) + { + __no_operation(); + } + + /* Return false if an address error */ + if (BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_ADDR_ERR_OFS)) + goto MassEraseCleanup; + + /* Changing to erase verify */ + userFlash = SysCtl_getFlashSize() / 2; + + for (ii = __MAIN_MEMORY_START__; ii < userFlash; ii += 4096) + { + sector = getUserFlashSector(ii); + + if (!((FLCTL->BANK0_MAIN_WEPROT) & sector)) + { + if (!FlashCtl_verifyMemory((void*) ii, 4096, FLASH_1_PATTERN)) + { + if (!FlashCtl_eraseSector(ii)) + goto MassEraseCleanup; + } + } + + if (!(FLCTL->BANK1_MAIN_WEPROT & sector)) + { + if (!FlashCtl_verifyMemory((void*) (ii + userFlash), 4096, + FLASH_1_PATTERN)) + { + if (!FlashCtl_eraseSector(ii + userFlash)) + goto MassEraseCleanup; + } + } + + if (sector < FLCTL_BANK0_MAIN_WEPROT_PROT2) + { + if (!(FLCTL->BANK0_INFO_WEPROT & sector)) + { + if (!FlashCtl_verifyMemory( + (void*) (ii + __INFO_FLASH_TECH_START__), 4096, + FLASH_1_PATTERN)) + { + if (!FlashCtl_eraseSector(ii + __INFO_FLASH_TECH_START__)) + goto MassEraseCleanup; + } + } + + if (!(FLCTL->BANK1_INFO_WEPROT & sector)) + { + if (!FlashCtl_verifyMemory((void*) (ii + (0x202000)), 4096, + FLASH_1_PATTERN)) + { + if (!FlashCtl_eraseSector(ii + (0x202000))) + goto MassEraseCleanup; + } + } + + } + } + + /* If we got this far, the mass erase happened */ + res = true; + + MassEraseCleanup: + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1; + + if(intStatus == 0) + Interrupt_enableMaster(); + + return res; +} + +bool FlashCtl_eraseSector(uint32_t addr) +{ + uint_fast8_t memoryType, ii; + uint32_t otpOffset = 0; + uint32_t intStatus; + uint_fast8_t mTries, tlvLength; + SysCtl_FlashTLV_Info *flInfo; + bool res; + + /* Saving interrupt context and disabling interrupts for program + * operation + */ + intStatus = CPU_primask(); + Interrupt_disableMaster(); + + /* Assuming Failure */ + res = false; + + memoryType = + addr > __MAIN_MEMORY_END__ ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE; + + /* Parsing the TLV and getting the maximum erase pulses */ + SysCtl_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo); + + if (tlvLength == 0 || flInfo->maxErasePulses == 0) + { + mTries = MAX_ERASE_NO_TLV; + } else + { + mTries = flInfo->maxErasePulses; + } + + /* We can only erase on 4KB boundaries */ + while (addr & 0xFFF) + { + addr--; + } + + /* Clearing the status */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1; + + if (memoryType == FLASH_INFO_SPACE) + { + otpOffset = __INFO_FLASH_TECH_START__; + FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT + & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_1; + + } else + { + otpOffset = __MAIN_MEMORY_START__; + FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT + & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_0; + } + + /* Clearing old flags and setting up the erase */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_MODE_OFS) = 0; + FLCTL->ERASE_SECTADDR = addr - otpOffset; + + for (ii = 0; ii < mTries; ii++) + { + /* Clearing the status */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = + 1; + + /* Starting the erase */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, + FLCTL_ERASE_CTLSTAT_START_OFS) = 1; + + while ((FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK) + == FLCTL_ERASE_CTLSTAT_STATUS_1 + || (FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK) + == FLCTL_ERASE_CTLSTAT_STATUS_2) + { + __no_operation(); + } + + /* Return false if an address error */ + if (BITBAND_PERI(FLCTL->ERASE_CTLSTAT, + FLCTL_ERASE_CTLSTAT_ADDR_ERR_OFS)) + { + goto SectorEraseCleanup; + } + /* Erase verifying */ + if (FlashCtl_verifyMemory((void*) addr, 4096, FLASH_1_PATTERN)) + { + res = true; + goto SectorEraseCleanup; + } + + } + +SectorEraseCleanup: + + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1; + + if(intStatus == 0) + Interrupt_enableMaster(); + + return res; +} + +void FlashCtl_initiateSectorErase(uint32_t addr) +{ + uint_fast8_t memoryType; + uint32_t otpOffset = 0; + + memoryType = + addr > __MAIN_MEMORY_END__ ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE; + + /* We can only erase on 4KB boundaries */ + while (addr & 0xFFF) + { + addr--; + } + + /* Clearing the status */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1; + + if (memoryType == FLASH_INFO_SPACE) + { + otpOffset = __INFO_FLASH_TECH_START__; + FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT + & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_1; + + } else + { + otpOffset = __MAIN_MEMORY_START__; + FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT + & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_0; + } + + /* Clearing old flags and setting up the erase */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_MODE_OFS) = 0; + FLCTL->ERASE_SECTADDR = addr - otpOffset; + + /* Starting the erase */ + BITBAND_PERI(FLCTL->ERASE_CTLSTAT, + FLCTL_ERASE_CTLSTAT_START_OFS) = 1; + +} + +bool FlashCtl_programMemory(void* src, void* dest, uint32_t length) +{ + uint32_t destAddr, srcAddr, burstLength, intStatus; + bool res; + uint_fast8_t mTries, tlvLength; + SysCtl_FlashTLV_Info *flInfo; + + /* Saving interrupt context and disabling interrupts for program + * operation + */ + intStatus = CPU_primask(); + Interrupt_disableMaster(); + + /* Parsing the TLV and getting the maximum erase pulses */ + SysCtl_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo); + + if (tlvLength == 0 || flInfo->maxProgramPulses == 0) + { + mTries = MAX_PROGRAM_NO_TLV; + } else + { + mTries = flInfo->maxProgramPulses; + } + + /* Casting to integers */ + srcAddr = (uint32_t) src; + destAddr = (uint32_t) dest; + + /* Enabling word programming */ + FlashCtl_enableWordProgramming(FLASH_IMMEDIATE_WRITE_MODE); + + /* Assume failure */ + res = false; + + /* Taking care of byte accesses */ + while ((destAddr & 0x03) && length > 0) + { + if (!_FlashCtl_Program8(srcAddr, destAddr, mTries)) + { + goto FlashProgramCleanUp; + } else + { + srcAddr++; + destAddr++; + length--; + } + } + + /* Taking care of word accesses */ + while ((destAddr & 0x0F) && (length > 3)) + { + if (!_FlashCtl_Program32(srcAddr, destAddr, mTries)) + { + goto FlashProgramCleanUp; + } else + { + srcAddr += 4; + destAddr += 4; + length -= 4; + } + } + + /* Taking care of burst programs */ + while (length > 16) + { + burstLength = length > 63 ? 64 : length & 0xFFFFFFF0; + + if (!_FlashCtl_ProgramBurst(srcAddr, destAddr, burstLength, mTries)) + { + goto FlashProgramCleanUp; + } else + { + srcAddr += burstLength; + destAddr += burstLength; + length -= burstLength; + } + } + + /* Remaining word accesses */ + while (length > 3) + { + if (!_FlashCtl_Program32(srcAddr, destAddr, mTries)) + { + goto FlashProgramCleanUp; + } else + { + srcAddr+=4; + destAddr+=4; + length-=4; + } + } + + /* Remaining byte accesses */ + while (length > 0) + { + if (!_FlashCtl_Program8(srcAddr, destAddr, mTries)) + { + goto FlashProgramCleanUp; + } else + { + srcAddr++; + destAddr++; + length--; + } + } + + /* If we got this far that means that we succeeded */ + res = true; + + FlashProgramCleanUp: + + if(intStatus == 0) + Interrupt_enableMaster(); + + FlashCtl_disableWordProgramming(); + return res; + +} +void FlashCtl_setProgramVerification(uint32_t verificationSetting) +{ + if ((verificationSetting & FLASH_BURSTPOST)) + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 1; + + if ((verificationSetting & FLASH_BURSTPRE)) + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 1; + + if ((verificationSetting & FLASH_REGPRE)) + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) = 1; + + if ((verificationSetting & FLASH_REGPOST)) + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PST_OFS) = 1; +} + +void FlashCtl_clearProgramVerification(uint32_t verificationSetting) +{ + if ((verificationSetting & FLASH_BURSTPOST)) + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 0; + + if ((verificationSetting & FLASH_BURSTPRE)) + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 0; + + if ((verificationSetting & FLASH_REGPRE)) + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) = 0; + + if ((verificationSetting & FLASH_REGPOST)) + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PST_OFS) = 0; + +} + +void FlashCtl_enableWordProgramming(uint32_t mode) +{ + if (mode == FLASH_IMMEDIATE_WRITE_MODE) + { + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 1; + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS) = 0; + + } else if (mode == FLASH_COLLATED_WRITE_MODE) + { + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 1; + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS) = 1; + } +} + +void FlashCtl_disableWordProgramming(void) +{ + BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 0; +} + +uint32_t FlashCtl_isWordProgrammingEnabled(void) +{ + if (!BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS)) + { + return 0; + } else if (BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS)) + return FLASH_COLLATED_WRITE_MODE; + else + return FLASH_IMMEDIATE_WRITE_MODE; +} + +void FlashCtl_setWaitState(uint32_t flashBank, uint32_t waitState) +{ + if (flashBank == FLASH_BANK0) + { + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL + & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | (waitState << FLCTL_BANK0_RDCTL_WAIT_OFS); + } else if (flashBank == FLASH_BANK1) + { + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL + & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | (waitState << FLCTL_BANK1_RDCTL_WAIT_OFS); + } else + { + ASSERT(false); + } +} + +uint32_t FlashCtl_getWaitState(uint32_t flashBank) +{ + if (flashBank == FLASH_BANK0) + { + return (FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_WAIT_MASK) >> FLCTL_BANK0_RDCTL_WAIT_OFS; + } else if (flashBank == FLASH_BANK1) + { + return (FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_WAIT_MASK) >> FLCTL_BANK1_RDCTL_WAIT_OFS; + } else + { + ASSERT(false); + return 0; + } +} + +void FlashCtl_enableInterrupt(uint32_t flags) +{ + FLCTL->IE |= flags; +} + +void FlashCtl_disableInterrupt(uint32_t flags) +{ + FLCTL->IE &= ~flags; +} + +uint32_t FlashCtl_getInterruptStatus(void) +{ + return FLCTL->IFG; +} + +uint32_t FlashCtl_getEnabledInterruptStatus(void) +{ + return FlashCtl_getInterruptStatus() & FLCTL->IE; +} + +void FlashCtl_clearInterruptFlag(uint32_t flags) +{ + FLCTL->CLRIFG |= flags; +} + +void FlashCtl_registerInterrupt(void (*intHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + Interrupt_registerInterrupt(INT_FLCTL, intHandler); + + // + // Enable the system control interrupt. + // + Interrupt_enableInterrupt(INT_FLCTL); +} + +void FlashCtl_unregisterInterrupt(void) +{ + // + // Disable the interrupt. + // + Interrupt_disableInterrupt(INT_FLCTL); + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(INT_FLCTL); +} + +uint8_t __FlashCtl_remaskData8Post(uint8_t data, uint32_t addr) +{ + uint32_t readMode, waitState, bankProgram, bankOneStart; + + /* Changing the waitstate and read mode of whichever bank we are in */ + /* Finding out which bank we are in */ + if(addr > SysCtl_getFlashSize()) + { + bankOneStart = __INFO_FLASH_TECH_MIDDLE__; + } + else + { + bankOneStart = SysCtl_getFlashSize() / 2; + } + + bankProgram = + addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1; + + /* Saving the current wait states and read mode */ + waitState = FlashCtl_getWaitState(bankProgram); + readMode = FlashCtl_getReadMode(bankProgram); + + /* Setting the wait state to account for the mode */ + FlashCtl_setWaitState(bankProgram, (2 * waitState) + 1); + + /* Changing to PROGRAM VERIFY mode */ + FlashCtl_setReadMode(bankProgram, FLASH_PROGRAM_VERIFY_READ_MODE); + + data = ~(~(data) & HWREG8(addr)); + + /* Setting the wait state to account for the mode */ + FlashCtl_setReadMode(bankProgram, readMode); + FlashCtl_setWaitState(bankProgram, waitState); + + return data; +} + +uint8_t __FlashCtl_remaskData8Pre(uint8_t data, uint32_t addr) +{ + uint32_t readMode, waitState, bankProgram, bankOneStart; + + /* Changing the waitstate and read mode of whichever bank we are in */ + /* Finding out which bank we are in */ + if(addr > SysCtl_getFlashSize()) + { + bankOneStart = __INFO_FLASH_TECH_MIDDLE__; + } + else + { + bankOneStart = SysCtl_getFlashSize() / 2; + } + + bankProgram = + addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1; + + /* Saving the current wait states and read mode */ + waitState = FlashCtl_getWaitState(bankProgram); + readMode = FlashCtl_getReadMode(bankProgram); + + /* Setting the wait state to account for the mode */ + FlashCtl_setWaitState(bankProgram, (2 * waitState) + 1); + + /* Changing to PROGRAM VERIFY mode */ + FlashCtl_setReadMode(bankProgram, FLASH_PROGRAM_VERIFY_READ_MODE); + + data |= ~(HWREG8(addr) | data); + + /* Setting the wait state to account for the mode */ + FlashCtl_setReadMode(bankProgram, readMode); + FlashCtl_setWaitState(bankProgram, waitState); + + return data; +} + +uint32_t __FlashCtl_remaskData32Post(uint32_t data, uint32_t addr) +{ + uint32_t bankProgramStart, bankProgramEnd, bank1Start; + uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode; + + /* Changing the waitstate and read mode of whichever bank we are in */ + /* Finding out which bank we are in */ + if(addr > SysCtl_getFlashSize()) + { + bank1Start = __INFO_FLASH_TECH_MIDDLE__; + } + else + { + bank1Start = SysCtl_getFlashSize() / 2; + } + + bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1; + bankProgramEnd = (addr + 4) < bank1Start ? FLASH_BANK0 : FLASH_BANK1; + + /* Saving the current wait states and read mode */ + b0WaitState = FlashCtl_getWaitState(bankProgramStart); + b0ReadMode = FlashCtl_getReadMode(bankProgramStart); + FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1); + FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE); + + if (bankProgramStart != bankProgramEnd) + { + b1WaitState = FlashCtl_getWaitState(bankProgramEnd); + b1ReadMode = FlashCtl_getReadMode(bankProgramEnd); + FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1); + FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE); + } + + data = ~(~(data) & HWREG32(addr)); + + /* Setting the wait state to account for the mode */ + FlashCtl_setReadMode(bankProgramStart, b0ReadMode); + FlashCtl_setWaitState(bankProgramStart, b0WaitState); + + if (bankProgramStart != bankProgramEnd) + { + FlashCtl_setReadMode(bankProgramEnd, b1ReadMode); + FlashCtl_setWaitState(bankProgramEnd, b1WaitState); + } + + return data; +} + +uint32_t __FlashCtl_remaskData32Pre(uint32_t data, uint32_t addr) +{ + uint32_t bankProgramStart, bankProgramEnd, bank1Start; + uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode; + + /* Changing the waitstate and read mode of whichever bank we are in */ + /* Finding out which bank we are in */ + if(addr > SysCtl_getFlashSize()) + { + bank1Start = __INFO_FLASH_TECH_MIDDLE__; + } + else + { + bank1Start = SysCtl_getFlashSize() / 2; + } + + bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1; + bankProgramEnd = (addr + 4) < bank1Start ? FLASH_BANK0 : FLASH_BANK1; + + /* Saving the current wait states and read mode */ + b0WaitState = FlashCtl_getWaitState(bankProgramStart); + b0ReadMode = FlashCtl_getReadMode(bankProgramStart); + FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1); + FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE); + + if (bankProgramStart != bankProgramEnd) + { + b1WaitState = FlashCtl_getWaitState(bankProgramEnd); + b1ReadMode = FlashCtl_getReadMode(bankProgramEnd); + FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1); + FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE); + } + + data |= ~(HWREG32(addr) | data); + + /* Setting the wait state to account for the mode */ + FlashCtl_setReadMode(bankProgramStart, b0ReadMode); + FlashCtl_setWaitState(bankProgramStart, b0WaitState); + + if (bankProgramStart != bankProgramEnd) + { + FlashCtl_setReadMode(bankProgramEnd, b1ReadMode); + FlashCtl_setWaitState(bankProgramEnd, b1WaitState); + } + + return data; +} + +void __FlashCtl_remaskBurstDataPre(uint32_t addr, uint32_t size) +{ + + uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii; + uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode; + + /* Waiting for idle status */ + while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK) + != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0) + { + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; + } + + /* Changing the waitstate and read mode of whichever bank we are in */ + /* Finding out which bank we are in */ + if(addr > SysCtl_getFlashSize()) + { + bank1Start = __INFO_FLASH_TECH_MIDDLE__; + } + else + { + bank1Start = SysCtl_getFlashSize() / 2; + } + + bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1; + bankProgramEnd = (addr + size) < bank1Start ? FLASH_BANK0 : FLASH_BANK1; + + /* Saving the current wait states and read mode */ + b0WaitState = FlashCtl_getWaitState(bankProgramStart); + b0ReadMode = FlashCtl_getReadMode(bankProgramStart); + FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1); + FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE); + + if (bankProgramStart != bankProgramEnd) + { + b1WaitState = FlashCtl_getWaitState(bankProgramEnd); + b1ReadMode = FlashCtl_getReadMode(bankProgramEnd); + FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1); + FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE); + } + + /* Going through each BURST program register and masking out for pre + * verifcation + */ + size = (size / 4); + for (ii = 0; ii < size; ii++) + { + HWREG32(__getBurstProgramRegs[ii]) |= + ~(HWREG32(__getBurstProgramRegs[ii]) + | HWREG32(addr)); + addr += 4; + } + + /* Setting the wait state to account for the mode */ + FlashCtl_setReadMode(bankProgramStart, b0ReadMode); + FlashCtl_setWaitState(bankProgramStart, b0WaitState); + + if (bankProgramStart != bankProgramEnd) + { + FlashCtl_setReadMode(bankProgramEnd, b1ReadMode); + FlashCtl_setWaitState(bankProgramEnd, b1WaitState); + } + +} +void __FlashCtl_remaskBurstDataPost(uint32_t addr, uint32_t size) +{ + uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii; + uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode; + + /* Waiting for idle status */ + while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK) + != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0) + { + BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT, + FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; + } + + /* Changing the waitstate and read mode of whichever bank we are in */ + /* Finding out which bank we are in */ + if(addr > SysCtl_getFlashSize()) + { + bank1Start = __INFO_FLASH_TECH_MIDDLE__; + } + else + { + bank1Start = SysCtl_getFlashSize() / 2; + } + + bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1; + bankProgramEnd = (addr + size) < bank1Start ? FLASH_BANK0 : FLASH_BANK1; + + /* Saving the current wait states and read mode */ + b0WaitState = FlashCtl_getWaitState(bankProgramStart); + b0ReadMode = FlashCtl_getReadMode(bankProgramStart); + FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1); + FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE); + + if (bankProgramStart != bankProgramEnd) + { + b1WaitState = FlashCtl_getWaitState(bankProgramEnd); + b1ReadMode = FlashCtl_getReadMode(bankProgramEnd); + FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1); + FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE); + } + + /* Going through each BURST program register and masking out for post + * verifcation if needed + */ + size = (size / 4); + for (ii = 0; ii < size; ii++) + { + HWREG32(__getBurstProgramRegs[ii]) = ~(~(HWREG32( + __getBurstProgramRegs[ii])) & HWREG32(addr)); + + addr += 4; + } + + /* Setting the wait state to account for the mode */ + FlashCtl_setReadMode(bankProgramStart, b0ReadMode); + FlashCtl_setWaitState(bankProgramStart, b0WaitState); + + if (bankProgramStart != bankProgramEnd) + { + FlashCtl_setReadMode(bankProgramEnd, b1ReadMode); + FlashCtl_setWaitState(bankProgramEnd, b1WaitState); + } +} diff --git a/example/rt_msp432/MSP432P4xx/flash.h b/example/rt_msp432/MSP432P4xx/flash.h new file mode 100644 index 0000000..a7073bc --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/flash.h @@ -0,0 +1,943 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __FLASH_H__ +#define __FLASH_H__ + +//***************************************************************************** +// +//! \addtogroup flash_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +//***************************************************************************** +// +// Control specific variables +// +//***************************************************************************** +#define FLASH_BURST_PRG_BIT 0x03 + +/* Interrupts */ +#define FLASH_PROGRAM_ERROR FLCTL_IFG_PRG_ERR +#define FLASH_BENCHMARK_INT FLCTL_IFG_BMRK +#define FLASH_ERASE_COMPLETE FLCTL_IFG_ERASE +#define FLASH_BRSTPRGM_COMPLETE FLCTL_IFG_PRGB +#define FLASH_WRDPRGM_COMPLETE FLCTL_IFG_PRG +#define FLASH_POSTVERIFY_FAILED FLCTL_IFG_AVPST +#define FLASH_PREVERIFY_FAILED FLCTL_IFG_AVPRE +#define FLASH_BRSTRDCMP_COMPLETE FLCTL_IFG_RDBRST + +#define FLASH_NORMAL_READ_MODE FLCTL_BANK0_RDCTL_RD_MODE_0 +#define FLASH_MARGIN0_READ_MODE FLCTL_BANK0_RDCTL_RD_MODE_1 +#define FLASH_MARGIN1_READ_MODE FLCTL_BANK0_RDCTL_RD_MODE_2 +#define FLASH_PROGRAM_VERIFY_READ_MODE FLCTL_BANK0_RDCTL_RD_MODE_3 +#define FLASH_ERASE_VERIFY_READ_MODE FLCTL_BANK0_RDCTL_RD_MODE_4 +#define FLASH_LEAKAGE_VERIFY_READ_MODE FLCTL_BANK0_RDCTL_RD_MODE_5 +#define FLASH_MARGIN0B_READ_MODE FLCTL_BANK0_RDCTL_RD_MODE_9 +#define FLASH_MARGIN1B_READ_MODE FLCTL_BANK0_RDCTL_RD_MODE_10 + +#define FLASH_PRGBRSTCTLSTAT_BURSTSTATUS_COMPLETE FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_7 + +#define FLASH_BANK0 0x00 +#define FLASH_BANK1 0x01 +#define FLASH_DATA_READ 0x00 +#define FLASH_INSTRUCTION_FETCH 0x01 + +#define FLASH_MAIN_MEMORY_SPACE_BANK0 0x01 +#define FLASH_MAIN_MEMORY_SPACE_BANK1 0x02 +#define FLASH_INFO_MEMORY_SPACE_BANK0 0x03 +#define FLASH_INFO_MEMORY_SPACE_BANK1 0x04 + +#define FLASH_MAIN_SPACE FLCTL_RDBRST_CTLSTAT_MEM_TYPE_0 +#define FLASH_INFO_SPACE FLCTL_RDBRST_CTLSTAT_MEM_TYPE_1 +#define FLASH_1_PATTERN FLCTL_RDBRST_CTLSTAT_DATA_CMP +#define FLASH_0_PATTERN 0x00 + +#define FLASH_SECTOR0 FLCTL_BANK0_MAIN_WEPROT_PROT0 +#define FLASH_SECTOR1 FLCTL_BANK0_MAIN_WEPROT_PROT1 +#define FLASH_SECTOR2 FLCTL_BANK0_MAIN_WEPROT_PROT2 +#define FLASH_SECTOR3 FLCTL_BANK0_MAIN_WEPROT_PROT3 +#define FLASH_SECTOR4 FLCTL_BANK0_MAIN_WEPROT_PROT4 +#define FLASH_SECTOR5 FLCTL_BANK0_MAIN_WEPROT_PROT5 +#define FLASH_SECTOR6 FLCTL_BANK0_MAIN_WEPROT_PROT6 +#define FLASH_SECTOR7 FLCTL_BANK0_MAIN_WEPROT_PROT7 +#define FLASH_SECTOR8 FLCTL_BANK0_MAIN_WEPROT_PROT8 +#define FLASH_SECTOR9 FLCTL_BANK0_MAIN_WEPROT_PROT9 +#define FLASH_SECTOR10 FLCTL_BANK0_MAIN_WEPROT_PROT10 +#define FLASH_SECTOR11 FLCTL_BANK0_MAIN_WEPROT_PROT11 +#define FLASH_SECTOR12 FLCTL_BANK0_MAIN_WEPROT_PROT12 +#define FLASH_SECTOR13 FLCTL_BANK0_MAIN_WEPROT_PROT13 +#define FLASH_SECTOR14 FLCTL_BANK0_MAIN_WEPROT_PROT14 +#define FLASH_SECTOR15 FLCTL_BANK0_MAIN_WEPROT_PROT15 +#define FLASH_SECTOR16 FLCTL_BANK0_MAIN_WEPROT_PROT16 +#define FLASH_SECTOR17 FLCTL_BANK0_MAIN_WEPROT_PROT17 +#define FLASH_SECTOR18 FLCTL_BANK0_MAIN_WEPROT_PROT18 +#define FLASH_SECTOR19 FLCTL_BANK0_MAIN_WEPROT_PROT19 +#define FLASH_SECTOR20 FLCTL_BANK0_MAIN_WEPROT_PROT20 +#define FLASH_SECTOR21 FLCTL_BANK0_MAIN_WEPROT_PROT21 +#define FLASH_SECTOR22 FLCTL_BANK0_MAIN_WEPROT_PROT22 +#define FLASH_SECTOR23 FLCTL_BANK0_MAIN_WEPROT_PROT23 +#define FLASH_SECTOR24 FLCTL_BANK0_MAIN_WEPROT_PROT24 +#define FLASH_SECTOR25 FLCTL_BANK0_MAIN_WEPROT_PROT25 +#define FLASH_SECTOR26 FLCTL_BANK0_MAIN_WEPROT_PROT26 +#define FLASH_SECTOR27 FLCTL_BANK0_MAIN_WEPROT_PROT27 +#define FLASH_SECTOR28 FLCTL_BANK0_MAIN_WEPROT_PROT28 +#define FLASH_SECTOR29 FLCTL_BANK0_MAIN_WEPROT_PROT29 +#define FLASH_SECTOR30 FLCTL_BANK0_MAIN_WEPROT_PROT30 +#define FLASH_SECTOR31 FLCTL_BANK0_MAIN_WEPROT_PROT31 + +#define FLASH_NOVER 0 +#define FLASH_BURSTPOST FLCTL_PRGBRST_CTLSTAT_AUTO_PST +#define FLASH_BURSTPRE FLCTL_PRGBRST_CTLSTAT_AUTO_PRE +#define FLASH_REGPRE FLCTL_PRG_CTLSTAT_VER_PRE +#define FLASH_REGPOST FLCTL_PRG_CTLSTAT_VER_PST +#define FLASH_FULLVER (FLCTL_PRGBRST_CTLSTAT_AUTO_PST | \ + FLCTL_PRGBRST_CTLSTAT_AUTO_PRE | FLCTL_PRG_CTLSTAT_VER_PRE \ + | FLCTL_PRG_CTLSTAT_VER_PST) + +#define FLASH_COLLATED_WRITE_MODE 0x01 +#define FLASH_IMMEDIATE_WRITE_MODE 0x02 + +#define __INFO_FLASH_TECH_START__ 0x00200000 +#define __INFO_FLASH_TECH_MIDDLE__ 0x00202000 + + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! Calculates the flash bank and sector number given an address. Stores the +//! results into the two pointers given as parameters. The user must provide +//! a valid memory address (an address in SRAM for example will give an invalid +//! result). +//! +//! \param addr Address to calculate the bank/sector information for +//! +//! \param sectorNum The sector number will be stored in here after the function +//! completes. +//! +//! \param sectorNum The bank number will be stored in here after the function +//! completes. +//! +//! \note For simplicity, this API only works with address in MAIN flash memory. +//! For calculating the sector/bank number of an address in info memory, +//! please refer to your device datasheet/ +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_getMemoryInfo(uint32_t addr, uint32_t *sectorNum, + uint32_t *bankNum); + +//***************************************************************************** +// +//! Enables read buffering on accesses to a specified bank of flash memory +//! +//! \param memoryBank is the value of the memory bank to enable read +//! buffering. Must be only one of the following values: +//! - \b FLASH_BANK0, +//! - \b FLASH_BANK1 +//! +//! \param accessMethod is the value of the access type to enable read +//! buffering. Must be only one of the following values: +//! - \b FLASH_DATA_READ, +//! - \b FLASH_INSTRUCTION_FETCH +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_enableReadBuffering(uint_fast8_t memoryBank, + uint_fast8_t accessMethod); + +//***************************************************************************** +// +//! Disables read buffering on accesses to a specified bank of flash memory +//! +//! \param memoryBank is the value of the memory bank to disable read +//! buffering. Must be only one of the following values: +//! - \b FLASH_BANK0, +//! - \b FLASH_BANK1 +//! +//! \param accessMethod is the value of the access type to disable read +//! buffering. Must ne only one of the following values: +//! - \b FLASH_DATA_READ, +//! - \b FLASH_INSTRUCTION_FETCH +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_disableReadBuffering(uint_fast8_t memoryBank, + uint_fast8_t accessMethod); + +//***************************************************************************** +// +//! Disables program protection on the given sector mask. This setting can be +//! applied on a sector-wise bases on a given memory space (INFO or MAIN). +//! +//! \param memorySpace is the value of the memory bank to disable program +//! protection. Must be only one of the following values: +//! - \b FLASH_MAIN_MEMORY_SPACE_BANK0, +//! - \b FLASH_MAIN_MEMORY_SPACE_BANK1, +//! - \b FLASH_INFO_MEMORY_SPACE_BANK0, +//! - \b FLASH_INFO_MEMORY_SPACE_BANK1 +//! +//! \param sectorMask is a bit mask of the sectors to disable program +//! protection. Must be a bitfield of the following values: +//! - \b FLASH_SECTOR0, +//! - \b FLASH_SECTOR1, +//! - \b FLASH_SECTOR2, +//! - \b FLASH_SECTOR3, +//! - \b FLASH_SECTOR4, +//! - \b FLASH_SECTOR5, +//! - \b FLASH_SECTOR6, +//! - \b FLASH_SECTOR7, +//! - \b FLASH_SECTOR8, +//! - \b FLASH_SECTOR9, +//! - \b FLASH_SECTOR10, +//! - \b FLASH_SECTOR11, +//! - \b FLASH_SECTOR12, +//! - \b FLASH_SECTOR13, +//! - \b FLASH_SECTOR14, +//! - \b FLASH_SECTOR15, +//! - \b FLASH_SECTOR16, +//! - \b FLASH_SECTOR17, +//! - \b FLASH_SECTOR18, +//! - \b FLASH_SECTOR19, +//! - \b FLASH_SECTOR20, +//! - \b FLASH_SECTOR21, +//! - \b FLASH_SECTOR22, +//! - \b FLASH_SECTOR23, +//! - \b FLASH_SECTOR24, +//! - \b FLASH_SECTOR25, +//! - \b FLASH_SECTOR26, +//! - \b FLASH_SECTOR27, +//! - \b FLASH_SECTOR28, +//! - \b FLASH_SECTOR29, +//! - \b FLASH_SECTOR30, +//! - \b FLASH_SECTOR31 +//! +//! \note Flash sector sizes are 4KB and the number of sectors may vary +//! depending on the specific device. Also, for INFO memory space, only sectors +//! \b FLASH_SECTOR0 and \b FLASH_SECTOR1 will exist. +//! +//! \note Not all devices will contain a dedicated INFO memory. Please check the +//! device datasheet to see if your device has INFO memory available for use. +//! For devices without INFO memory, any operation related to the INFO memory +//! will be ignored by the hardware. +//! +//! \return true if sector protection disabled false otherwise. +// +//***************************************************************************** +extern bool FlashCtl_unprotectSector(uint_fast8_t memorySpace, + uint32_t sectorMask); + +//***************************************************************************** +// +//! Enables program protection on the given sector mask. This setting can be +//! applied on a sector-wise bases on a given memory space (INFO or MAIN). +//! +//! \param memorySpace is the value of the memory bank to enable program +//! protection. Must be only one of the following values: +//! - \b FLASH_MAIN_MEMORY_SPACE_BANK0, +//! - \b FLASH_MAIN_MEMORY_SPACE_BANK1, +//! - \b FLASH_INFO_MEMORY_SPACE_BANK0, +//! - \b FLASH_INFO_MEMORY_SPACE_BANK1 +//! +//! \param sectorMask is a bit mask of the sectors to enable program +//! protection. Must be a bitfield of the following values: +//! - \b FLASH_SECTOR0, +//! - \b FLASH_SECTOR1, +//! - \b FLASH_SECTOR2, +//! - \b FLASH_SECTOR3, +//! - \b FLASH_SECTOR4, +//! - \b FLASH_SECTOR5, +//! - \b FLASH_SECTOR6, +//! - \b FLASH_SECTOR7, +//! - \b FLASH_SECTOR8, +//! - \b FLASH_SECTOR9, +//! - \b FLASH_SECTOR10, +//! - \b FLASH_SECTOR11, +//! - \b FLASH_SECTOR12, +//! - \b FLASH_SECTOR13, +//! - \b FLASH_SECTOR14, +//! - \b FLASH_SECTOR15, +//! - \b FLASH_SECTOR16, +//! - \b FLASH_SECTOR17, +//! - \b FLASH_SECTOR18, +//! - \b FLASH_SECTOR19, +//! - \b FLASH_SECTOR20, +//! - \b FLASH_SECTOR21, +//! - \b FLASH_SECTOR22, +//! - \b FLASH_SECTOR23, +//! - \b FLASH_SECTOR24, +//! - \b FLASH_SECTOR25, +//! - \b FLASH_SECTOR26, +//! - \b FLASH_SECTOR27, +//! - \b FLASH_SECTOR28, +//! - \b FLASH_SECTOR29, +//! - \b FLASH_SECTOR30, +//! - \b FLASH_SECTOR31 +//! +//! \note Flash sector sizes are 4KB and the number of sectors may vary +//! depending on the specific device. Also, for INFO memory space, only sectors +//! \b FLASH_SECTOR0 and \b FLASH_SECTOR1 will exist. +//! +//! \note Not all devices will contain a dedicated INFO memory. Please check the +//! device datasheet to see if your device has INFO memory available for use. +//! For devices without INFO memory, any operation related to the INFO memory +//! will be ignored by the hardware. +//! +//! \return true if sector protection enabled false otherwise. +// +//***************************************************************************** +extern bool FlashCtl_protectSector(uint_fast8_t memorySpace, + uint32_t sectorMask); + +//***************************************************************************** +// +//! Returns the sector protection for given sector mask and memory space +//! +//! \param memorySpace is the value of the memory bank to check for program +//! protection. Must be only one of the following values: +//! - \b FLASH_MAIN_MEMORY_SPACE_BANK0, +//! - \b FLASH_MAIN_MEMORY_SPACE_BANK1, +//! - \b FLASH_INFO_MEMORY_SPACE_BANK0, +//! - \b FLASH_INFO_MEMORY_SPACE_BANK1 +//! +//! \param sector is the sector to check for program protection. +//! Must be one of the following values: +//! - \b FLASH_SECTOR0, +//! - \b FLASH_SECTOR1, +//! - \b FLASH_SECTOR2, +//! - \b FLASH_SECTOR3, +//! - \b FLASH_SECTOR4, +//! - \b FLASH_SECTOR5, +//! - \b FLASH_SECTOR6, +//! - \b FLASH_SECTOR7, +//! - \b FLASH_SECTOR8, +//! - \b FLASH_SECTOR9, +//! - \b FLASH_SECTOR10, +//! - \b FLASH_SECTOR11, +//! - \b FLASH_SECTOR12, +//! - \b FLASH_SECTOR13, +//! - \b FLASH_SECTOR14, +//! - \b FLASH_SECTOR15, +//! - \b FLASH_SECTOR16, +//! - \b FLASH_SECTOR17, +//! - \b FLASH_SECTOR18, +//! - \b FLASH_SECTOR19, +//! - \b FLASH_SECTOR20, +//! - \b FLASH_SECTOR21, +//! - \b FLASH_SECTOR22, +//! - \b FLASH_SECTOR23, +//! - \b FLASH_SECTOR24, +//! - \b FLASH_SECTOR25, +//! - \b FLASH_SECTOR26, +//! - \b FLASH_SECTOR27, +//! - \b FLASH_SECTOR28, +//! - \b FLASH_SECTOR29, +//! - \b FLASH_SECTOR30, +//! - \b FLASH_SECTOR31 +//! +//! Note that flash sector sizes are 4KB and the number of sectors may vary +//! depending on the specific device. Also, for INFO memory space, only sectors +//! FLASH_SECTOR0 and FLASH_SECTOR1 will exist. +//! +//! \note Not all devices will contain a dedicated INFO memory. Please check the +//! device datasheet to see if your device has INFO memory available for use. +//! For devices without INFO memory, any operation related to the INFO memory +//! will be ignored by the hardware. +//! +//! \return true if sector protection enabled false otherwise. +// +//***************************************************************************** +extern bool FlashCtl_isSectorProtected(uint_fast8_t memorySpace, + uint32_t sector); + +//***************************************************************************** +// +//! Verifies a given segment of memory based off either a high (1) or low (0) +//! state. +//! +//! \param verifyAddr Start address where verification will begin +//! +//! \param length Length in bytes to verify based off the pattern +//! +//! \param pattern The pattern which verification will check versus. This can +//! either be a low pattern (each register will be checked versus a pattern +//! of 32 zeros, or a high pattern (each register will be checked versus a +//! pattern of 32 ones). Valid values are: FLASH_0_PATTERN, FLASH_1_PATTERN +//! +//! \note There are no sector/boundary restrictions for this function, +//! however it is encouraged to proved a start address aligned on 32-bit +//! boundaries. Providing an unaligned address will result in unaligned data +//! accesses and detriment efficiency. +//! +//! \note This function is blocking and will not exit until operation has +//! either completed or failed due to an error. Furthermore, given the +//! complex verification requirements of the flash controller, master +//! interrupts are disabled throughout execution of this function. The original +//! interrupt context is saved at the start of execution and restored prior +//! to exit of the API. +//! +//! \note Due to the hardware limitations of the flash controller, this +//! function cannot verify a memory adress in the same flash bank that it +//! is executing from. If using the ROM version of this API (by using the +//! (ROM_ or MAP_ prefixes) this is a don't care, however if this API resides +//! in flash then special care needs to be taken to ensure no code execution +//! or reads happen in the flash bank being programmed while this API is +//! being executed. +//! +//! \return true if memory verification is successful, false otherwise. +// +//***************************************************************************** +extern bool FlashCtl_verifyMemory(void* verifyAddr, uint32_t length, + uint_fast8_t pattern); + +//***************************************************************************** +// +//! Performs a mass erase on all unprotected flash sectors. Protected sectors +//! are ignored. +//! +//! \note This function is blocking and will not exit until operation has +//! either completed or failed due to an error. Furthermore, given the +//! complex verification requirements of the flash controller, master +//! interrupts are disabled throughout execution of this function. The original +//! interrupt context is saved at the start of execution and restored prior +//! to exit of the API. +//! +//! \note Due to the hardware limitations of the flash controller, this +//! function cannot erase a memory adress in the same flash bank that it +//! is executing from. If using the ROM version of this API (by using the +//! (ROM_ or MAP_ prefixes) this is a don't care, however if this API resides +//! in flash then special care needs to be taken to ensure no code execution +//! or reads happen in the flash bank being programmed while this API is +//! being executed. +//! +//! \return true if mass erase completes successfully, false otherwise +// +//***************************************************************************** +extern bool FlashCtl_performMassErase(void); + +//***************************************************************************** +// +//! Initiates a mass erase and returns control back to the program. This is a +//! non-blocking function, however it is the user's responsibility to perform +//! the necessary verification requirements after the interrupt is set to +//! signify completion. +//! +//! \return None +// +//***************************************************************************** +extern void FlashCtl_initiateMassErase(void); + +//***************************************************************************** +// +//! Erases a sector of MAIN or INFO flash memory. +//! +//! \param addr The start of the sector to erase. Note that with flash, +//! the minimum allowed size that can be erased is a flash sector +//! (which is 4KB on the MSP432 family). If an address is provided to +//! this function which is not on a 4KB boundary, the entire sector +//! will still be erased. +//! +//! \note This function is blocking and will not exit until operation has +//! either completed or failed due to an error. Furthermore, given the +//! complex verification requirements of the flash controller, master +//! interrupts are disabled throughout execution of this function. The original +//! interrupt context is saved at the start of execution and restored prior +//! to exit of the API. +//! +//! \note Due to the hardware limitations of the flash controller, this +//! function cannot erase a memory adress in the same flash bank that it +//! is executing from. If using the ROM version of this API (by using the +//! (ROM_ or MAP_ prefixes) this is a don't care, however if this API resides +//! in flash then special care needs to be taken to ensure no code execution +//! or reads happen in the flash bank being programmed while this API is +//! being executed. +//! +//! \return true if sector erase is successful, false otherwise. +// +//***************************************************************************** +extern bool FlashCtl_eraseSector(uint32_t addr); + +//***************************************************************************** +// +//! Program a portion of flash memory with the provided data +//! +//! \param src Pointer to the data source to program into flash +//! +//! \param dest Pointer to the destination in flash to program +//! +//! \param length Length in bytes to program +//! +//! \note There are no sector/boundary restrictions for this function, +//! however it is encouraged to proved a start address aligned on 32-bit +//! boundaries. Providing an unaligned address will result in unaligned data +//! accesses and detriment efficiency. +//! +//! \note This function is blocking and will not exit until operation has +//! either completed or failed due to an error. Furthermore, given the +//! complex verification requirements of the flash controller, master +//! interrupts are disabled throughout execution of this function. The original +//! interrupt context is saved at the start of execution and restored prior +//! to exit of the API. +//! +//! \note Due to the hardware limitations of the flash controller, this +//! function cannot program a memory adress in the same flash bank that it +//! is executing from. If using the ROM version of this API (by using the +//! (ROM_ or MAP_ prefixes) this is a don't care, however if this API resides +//! in flash then special care needs to be taken to ensure no code execution +//! or reads happen in the flash bank being programmed while this API is +//! being executed. +//! +//! \return Whether or not the program succeeded +// +//***************************************************************************** +extern bool FlashCtl_programMemory(void* src, void* dest, uint32_t length); + +//***************************************************************************** +// +//! Setups pre/post verification of burst and regular flash programming +//! instructions. Note that this API is for advanced users that are programming +//! their own flash drivers. The program/erase APIs are not affected by this +//! setting and take care of the verification requirements. +//! +//! \param verificationSetting Verification setting to set. This value can +//! be a bitwise OR of the following values: +//! - \b FLASH_BURSTPOST, +//! - \b FLASH_BURSTPRE, +//! - \b FLASH_REGPRE, +//! - \b FLASH_REGPOST +//! - \b FLASH_NOVER No verification enabled +//! - \b FLASH_FULLVER Full verification enabled +//! +//! \return none +// +//***************************************************************************** +extern void FlashCtl_setProgramVerification(uint32_t verificationSetting); + +//***************************************************************************** +// +//! Clears pre/post verification of burst and regular flash programming +//! instructions. Note that this API is for advanced users that are programming +//! their own flash drivers. The program/erase APIs are not affected by this +//! setting and take care of the verification requirements. +//! +//! \param verificationSetting Verification setting to clear. This value can +//! be a bitwise OR of the following values: +//! - \b FLASH_BURSTPOST, +//! - \b FLASH_BURSTPRE, +//! - \b FLASH_REGPRE, +//! - \b FLASH_REGPOST +//! - \b FLASH_NOVER No verification enabled +//! - \b FLASH_FULLVER Full verification enabled +//! +//! \return none +// +//***************************************************************************** +extern void FlashCtl_clearProgramVerification(uint32_t verificationSetting); + +//***************************************************************************** +// +//! Enables word programming of flash memory. +//! +//! This function will enable word programming of the flash memory and set the +//! mode of behavior when the flash write occurs. +//! +//! \param mode The mode specifies the behavior of the flash controller when +//! programming words to flash. In \b FLASH_IMMEDIATE_WRITE_MODE, the +//! program operation happens immediately on the write to flash while +//! in \b FLASH_COLLATED_WRITE_MODE the write will be delayed until a full +//! 128-bits have been collated. Possible values include: +//! - \b FLASH_IMMEDIATE_WRITE_MODE +//! - \b FLASH_COLLATED_WRITE_MODE +//! +//! +//! Refer to the user's guide for further documentation. +//! +//! \return none +// +//***************************************************************************** +extern void FlashCtl_enableWordProgramming(uint32_t mode); + +//***************************************************************************** +// +//! Disables word programming of flash memory. +//! +//! Refer to FlashCtl_enableWordProgramming and the user's guide for description +//! on the difference between full word and immediate programming +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_disableWordProgramming(void); + +//***************************************************************************** +// +//! Returns if word programming mode is enabled (and if it is, the specific mode) +//! +//! Refer to FlashCtl_enableWordProgramming and the user's guide for description +//! on the difference between full word and immediate programming +//! +//! \return a zero value if word programming is disabled, +//! - \b FLASH_IMMEDIATE_WRITE_MODE +//! - \b FLASH_COLLATED_WRITE_MODE +//! +// +//***************************************************************************** +extern uint32_t FlashCtl_isWordProgrammingEnabled(void); + +//***************************************************************************** +// +//! Sets the flash read mode to be used by default flash read operations. +//! Note that the proper wait states must be set prior to entering this +//! function. +//! +//! \param flashBank Flash bank to set read mode for. Valid values are: +//! - \b FLASH_BANK0 +//! - \b FLASH_BANK1 +//! +//! \param readMode The read mode to set. Valid values are: +//! - \b FLASH_NORMAL_READ_MODE, +//! - \b FLASH_MARGIN0_READ_MODE, +//! - \b FLASH_MARGIN1_READ_MODE, +//! - \b FLASH_PROGRAM_VERIFY_READ_MODE, +//! - \b FLASH_ERASE_VERIFY_READ_MODE, +//! - \b FLASH_LEAKAGE_VERIFY_READ_MODE, +//! - \b FLASH_MARGIN0B_READ_MODE, +//! - \b FLASH_MARGIN1B_READ_MODE +//! +//! \return None. +// +//***************************************************************************** +extern bool FlashCtl_setReadMode(uint32_t flashBank, uint32_t readMode); + +//***************************************************************************** +// +//! Gets the flash read mode to be used by default flash read operations. +//! +//! \param flashBank Flash bank to set read mode for. Valid values are: +//! - \b FLASH_BANK0 +//! - \b FLASH_BANK1 +//! +//! \return Returns the read mode to set. Valid values are: +//! - \b FLASH_NORMAL_READ_MODE, +//! - \b FLASH_MARGIN0_READ_MODE, +//! - \b FLASH_MARGIN1_READ_MODE, +//! - \b FLASH_PROGRAM_VERIFY_READ_MODE, +//! - \b FLASH_ERASE_VERIFY_READ_MODE, +//! - \b FLASH_LEAKAGE_VERIFY_READ_MODE, +//! - \b FLASH_MARGIN0B_READ_MODE, +//! - \b FLASH_MARGIN1B_READ_MODE +//! +// +//***************************************************************************** +extern uint32_t FlashCtl_getReadMode(uint32_t flashBank); + +//***************************************************************************** +// +//! Changes the number of wait states that are used by the flash controller +//! for read operations. When changing frequency ranges of the clock, this +//! functions must be used in order to allow for readable flash memory. +//! +//! \param waitState The number of wait states to set. Note that only +//! bits 0-3 are used. +//! +//! \param flashBank Flash bank to set wait state for. Valid values are: +//! - \b FLASH_BANK0 +//! - \b FLASH_BANK1 +//! +// +//***************************************************************************** +extern void FlashCtl_setWaitState(uint32_t bank, uint32_t waitState); + +//***************************************************************************** +// +//! Returns the set number of flash wait states for the given flash bank. +//! +//! \param flashBank Flash bank to set wait state for. Valid values are: +//! - \b FLASH_BANK0 +//! - \b FLASH_BANK1 +//! +//! \return The wait state setting for the specified flash bank +// +//***************************************************************************** +extern uint32_t FlashCtl_getWaitState(uint32_t bank); + +//***************************************************************************** +// +//! Enables individual flash control interrupt sources. +//! +//! \param flags is a bit mask of the interrupt sources to be enabled. Must +//! be a logical OR of: +//! - \b FLASH_PROGRAM_ERROR, +//! - \b FLASH_BENCHMARK_INT, +//! - \b FLASH_ERASE_COMPLETE, +//! - \b FLASH_BRSTPRGM_COMPLETE, +//! - \b FLASH_WRDPRGM_COMPLETE, +//! - \b FLASH_POSTVERIFY_FAILED, +//! - \b FLASH_PREVERIFY_FAILED, +//! - \b FLASH_BRSTRDCMP_COMPLETE +//! +//! This function enables the indicated flash system interrupt sources. Only +//! the sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_enableInterrupt(uint32_t flags); + +//***************************************************************************** +// +//! Disables individual flash system interrupt sources. +//! +//! \param flags is a bit mask of the interrupt sources to be disabled. Must +//! be a logical OR of: +//! - \b FLASH_PROGRAM_ERROR, +//! - \b FLASH_BENCHMARK_INT, +//! - \b FLASH_ERASE_COMPLETE, +//! - \b FLASH_BRSTPRGM_COMPLETE, +//! - \b FLASH_WRDPRGM_COMPLETE, +//! - \b FLASH_POSTVERIFY_FAILED, +//! - \b FLASH_PREVERIFY_FAILED, +//! - \b FLASH_BRSTRDCMP_COMPLETE +//! +//! This function disables the indicated flash system interrupt sources. +//! Only the sources that are enabled can be reflected to the processor +//! interrupt; disabled sources have no effect on the processor. +//! +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_disableInterrupt(uint32_t flags); + +//***************************************************************************** +// +//! Gets the current interrupt status masked with the enabled interrupts. +//! This function is useful to call in ISRs to get a list +//! of pending interrupts that are actually enabled and could have caused the +//! ISR. +//! +//! \return The current interrupt status, enumerated as a bit field of +//! - \b FLASH_PROGRAM_ERROR, +//! - \b FLASH_BENCHMARK_INT, +//! - \b FLASH_ERASE_COMPLETE, +//! - \b FLASH_BRSTPRGM_COMPLETE, +//! - \b FLASH_WRDPRGM_COMPLETE, +//! - \b FLASH_POSTVERIFY_FAILED, +//! - \b FLASH_PREVERIFY_FAILED, +//! - \b FLASH_BRSTRDCMP_COMPLETE +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +// +//***************************************************************************** +extern uint32_t FlashCtl_getEnabledInterruptStatus(void); + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \return The current interrupt status, enumerated as a bit field of: +//! - \b FLASH_PROGRAM_ERROR, +//! - \b FLASH_BENCHMARK_INT, +//! - \b FLASH_ERASE_COMPLETE, +//! - \b FLASH_BRSTPRGM_COMPLETE, +//! - \b FLASH_WRDPRGM_COMPLETE, +//! - \b FLASH_POSTVERIFY_FAILED, +//! - \b FLASH_PREVERIFY_FAILED, +//! - \b FLASH_BRSTRDCMP_COMPLETE +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +// +//***************************************************************************** +extern uint32_t FlashCtl_getInterruptStatus(void); + +//***************************************************************************** +// +//! Clears flash system interrupt sources. +//! +//! \param flags is a bit mask of the interrupt sources to be cleared. Must +//! be a logical OR of: +//! - \b FLASH_PROGRAM_ERROR, +//! - \b FLASH_BENCHMARK_INT, +//! - \b FLASH_ERASE_COMPLETE, +//! - \b FLASH_BRSTPRGM_COMPLETE, +//! - \b FLASH_WRDPRGM_COMPLETE, +//! - \b FLASH_POSTVERIFY_FAILED, +//! - \b FLASH_PREVERIFY_FAILED, +//! - \b FLASH_BRSTRDCMP_COMPLETE +//! +//! The specified flash system interrupt sources are cleared, so that they no +//! longer assert. This function must be called in the interrupt handler to +//! keep it from being called again immediately upon exit. +//! +//! \note Because there is a write buffer in the Cortex-M processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_clearInterruptFlag(uint32_t flags); + +//***************************************************************************** +// +//! Registers an interrupt handler for flash clock system interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the clock +//! system interrupt occurs. +//! +//! This function registers the handler to be called when a clock system +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific flash controller interrupts must be enabled +//! via FlashCtl_enableInterrupt(). It is the interrupt handler's +//! responsibility to clear the interrupt source via +//! FlashCtl_clearInterruptFlag(). +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the flash system. +//! +//! This function unregisters the handler to be called when a clock system +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void FlashCtl_unregisterInterrupt(void); + + +//***************************************************************************** +// +//! Initiates a sector erase of MAIN or INFO flash memory. Note that this +//! function simply initaites the sector erase, but does no verification +//! which is required by the flash controller. The user must manually set +//! and enable interrupts on the flash controller to fire on erase completion +//! and then use the FlashCtl_verifyMemory function to verify that the sector +//! was actually erased +//! +//! \param addr The start of the sector to erase. Note that with flash, +//! the minimum allowed size that can be erased is a flash sector +//! (which is 4KB on the MSP432 family). If an address is provided to +//! this function which is not on a 4KB boundary, the entire sector +//! will still be erased. +//! +//! \return None +// +//***************************************************************************** +extern void FlashCtl_initiateSectorErase(uint32_t addr); + + +/* The following functions are advanced functions that are used by the flash + * driver to remask a failed bit in the event of a post or pre verification + * failure. They are meant to be advanced functions and should not be used + * by the majority of users (unless you are writing your own flash driver). + */ +extern uint8_t __FlashCtl_remaskData8Post(uint8_t data, uint32_t addr); +extern uint8_t __FlashCtl_remaskData8Pre(uint8_t data, uint32_t addr); +extern uint32_t __FlashCtl_remaskData32Post(uint32_t data, uint32_t addr); +extern uint32_t __FlashCtl_remaskData32Pre(uint32_t data, uint32_t addr); +extern void __FlashCtl_remaskBurstDataPost(uint32_t addr, uint32_t size); +extern void __FlashCtl_remaskBurstDataPre(uint32_t addr, uint32_t size); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __FLASH_H__ diff --git a/example/rt_msp432/MSP432P4xx/fpu.c b/example/rt_msp432/MSP432P4xx/fpu.c new file mode 100644 index 0000000..6d31e94 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/fpu.c @@ -0,0 +1,115 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include + +void FPU_enableModule(void) +{ + // + // Enable the coprocessors used by the floating-point unit. + // + SCB->CPACR = ((SCB->CPACR & ~(SCB_CPACR_CP11_MASK | SCB_CPACR_CP10_MASK)) + | SCB_CPACR_CP11_MASK | SCB_CPACR_CP10_MASK); +} + +void FPU_disableModule(void) +{ + // + // Disable the coprocessors used by the floating-point unit. + // + SCB->CPACR = ((SCB->CPACR & ~(SCB_CPACR_CP10_MASK | SCB_CPACR_CP11_MASK))); +} + +void FPU_enableStacking(void) +{ + // + // Enable automatic state preservation for the floating-point unit, and + // disable lazy state preservation (meaning that the floating-point state + // is always stacked when floating-point instructions are used). + // + FPU->FPCCR = (FPU->FPCCR & ~FPU_FPCCR_LSPEN_Msk) | FPU_FPCCR_ASPEN_Msk; +} + +void FPU_enableLazyStacking(void) +{ + // + // Enable automatic and lazy state preservation for the floating-point + // unit. + // + FPU->FPCCR |= FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk; +} + +void FPU_disableStacking(void) +{ + // + // Disable automatic and lazy state preservation for the floating-point + // unit. + // + FPU->FPCCR &= ~(FPU_FPCCR_ASPEN_Msk | FPU_FPCCR_LSPEN_Msk); +} + +void FPU_setHalfPrecisionMode(uint32_t mode) +{ + // + // Set the half-precision floating-point format. + // + FPU->FPDSCR = (FPU->FPDSCR & ~(FPU_FPDSCR_AHP_Msk)) | mode; +} + +void FPU_setNaNMode(uint32_t mode) +{ + // + // Set the NaN mode. + // + FPU->FPDSCR = (FPU->FPDSCR & ~(FPU_FPDSCR_DN_Msk)) | mode; +} + +void FPU_setFlushToZeroMode(uint32_t mode) +{ + // + // Set the flush-to-zero mode. + // + FPU->FPDSCR = (FPU->FPDSCR & ~(FPU_FPDSCR_FZ_Msk)) | mode; +} + +void FPU_setRoundingMode(uint32_t mode) +{ + // + // Set the rounding mode. + // + FPU->FPDSCR = (FPU->FPDSCR & ~(FPU_FPDSCR_RMode_Msk)) | mode; +} + diff --git a/example/rt_msp432/MSP432P4xx/fpu.h b/example/rt_msp432/MSP432P4xx/fpu.h new file mode 100644 index 0000000..e54faec --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/fpu.h @@ -0,0 +1,285 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __FPU_H__ +#define __FPU_H__ + +//***************************************************************************** +// +//! +//! \addtogroup fpu_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +//***************************************************************************** +// +// Values that can be passed to FPUHalfPrecisionSet as the mode parameter. +// +//***************************************************************************** +#define FPU_HALF_IEEE 0x00000000 +#define FPU_HALF_ALTERNATE 0x04000000 + +//***************************************************************************** +// +// Values that can be passed to FPU_setNaNMode as the mode parameter. +// +//***************************************************************************** +#define FPU_NAN_PROPAGATE 0x00000000 +#define FPU_NAN_DEFAULT 0x02000000 + +//***************************************************************************** +// +// Values that can be passed to FPU_setFlushToZeroMode as the mode parameter. +// +//***************************************************************************** +#define FPU_FLUSH_TO_ZERO_DIS 0x00000000 +#define FPU_FLUSH_TO_ZERO_EN 0x01000000 + +//***************************************************************************** +// +// Values that can be passed to FPU_setRoundingMode as the mode parameter. +// +//***************************************************************************** +#define FPU_ROUND_NEAREST 0x00000000 +#define FPU_ROUND_POS_INF 0x00400000 +#define FPU_ROUND_NEG_INF 0x00800000 +#define FPU_ROUND_ZERO 0x00c00000 + +//***************************************************************************** +// +//! Enables the floating-point unit. +//! +//! This function enables the floating-point unit, allowing the floating-point +//! instructions to be executed. This function must be called prior to +//! performing any hardware floating-point operations; failure to do so results +//! in a NOCP usage fault. +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_enableModule(void); + +//***************************************************************************** +// +//! Disables the floating-point unit. +//! +//! This function disables the floating-point unit, preventing floating-point +//! instructions from executing (generating a NOCP usage fault instead). +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_disableModule(void); + +//***************************************************************************** +// +//! Enables the stacking of floating-point registers. +//! +//! This function enables the stacking of floating-point registers s0-s15 when +//! an interrupt is handled. When enabled, space is reserved on the stack for +//! the floating-point context and the floating-point state is saved into this +//! stack space. Upon return from the interrupt, the floating-point context is +//! restored. +//! +//! If the floating-point registers are not stacked, floating-point +//! instructions cannot be safely executed in an interrupt handler because the +//! values of s0-s15 are not likely to be preserved for the interrupted code. +//! On the other hand, stacking the floating-point registers increases the +//! stacking operation from 8 words to 26 words, also increasing the interrupt +//! response latency. +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_enableStacking(void); + +//***************************************************************************** +// +//! Enables the lazy stacking of floating-point registers. +//! +//! This function enables the lazy stacking of floating-point registers s0-s15 +//! when an interrupt is handled. When lazy stacking is enabled, space is +//! reserved on the stack for the floating-point context, but the +//! floating-point state is not saved. If a floating-point instruction is +//! executed from within the interrupt context, the floating-point context is +//! first saved into the space reserved on the stack. On completion of the +//! interrupt handler, the floating-point context is only restored if it was +//! saved (as the result of executing a floating-point instruction). +//! +//! This method provides a compromise between fast interrupt response (because +//! the floating-point state is not saved on interrupt entry) and the ability +//! to use floating-point in interrupt handlers (because the floating-point +//! state is saved if floating-point instructions are used). +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_enableLazyStacking(void); + +//***************************************************************************** +// +//! Disables the stacking of floating-point registers. +//! +//! This function disables the stacking of floating-point registers s0-s15 when +//! an interrupt is handled. When floating-point context stacking is disabled, +//! floating-point operations performed in an interrupt handler destroy the +//! floating-point context of the main thread of execution. +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_disableStacking(void); + +//***************************************************************************** +// +//! Selects the format of half-precision floating-point values. +//! +//! \param mode is the format for half-precision floating-point value, which +//! is either \b FPU_HALF_IEEE or \b FPU_HALF_ALTERNATE. +//! +//! This function selects between the IEEE half-precision floating-point +//! representation and the Cortex-M processor alternative representation. The +//! alternative representation has a larger range but does not have a way to +//! encode infinity (positive or negative) or NaN (quiet or signalling). The +//! default setting is the IEEE format. +//! +//! \note Unless this function is called prior to executing any floating-point +//! instructions, the default mode is used. +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_setHalfPrecisionMode(uint32_t mode); + +//***************************************************************************** +// +//! Selects the NaN mode. +//! +//! \param mode is the mode for NaN results; which is +//! either \b FPU_NAN_PROPAGATE or \b FPU_NAN_DEFAULT. +//! +//! This function selects the handling of NaN results during floating-point +//! computations. NaNs can either propagate (the default), or they can return +//! the default NaN. +//! +//! \note Unless this function is called prior to executing any floating-point +//! instructions, the default mode is used. +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_setNaNMode(uint32_t mode); + +//***************************************************************************** +// +//! Selects the flush-to-zero mode. +//! +//! \param mode is the flush-to-zero mode; which is either +//! \b FPU_FLUSH_TO_ZERO_DIS or \b FPU_FLUSH_TO_ZERO_EN. +//! +//! This function enables or disables the flush-to-zero mode of the +//! floating-point unit. When disabled (the default), the floating-point unit +//! is fully IEEE compliant. When enabled, values close to zero are treated as +//! zero, greatly improving the execution speed at the expense of some accuracy +//! (as well as IEEE compliance). +//! +//! \note Unless this function is called prior to executing any floating-point +//! instructions, the default mode is used. +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_setFlushToZeroMode(uint32_t mode); + +//***************************************************************************** +// +//! Selects the rounding mode for floating-point results. +//! +//! \param mode is the rounding mode. +//! +//! This function selects the rounding mode for floating-point results. After +//! a floating-point operation, the result is rounded toward the specified +//! value. The default mode is \b FPU_ROUND_NEAREST. +//! +//! The following rounding modes are available (as specified by \e mode): +//! +//! - \b FPU_ROUND_NEAREST - round toward the nearest value +//! - \b FPU_ROUND_POS_INF - round toward positive infinity +//! - \b FPU_ROUND_NEG_INF - round toward negative infinity +//! - \b FPU_ROUND_ZERO - round toward zero +//! +//! \note Unless this function is called prior to executing any floating-point +//! instructions, the default mode is used. +//! +//! \return None. +// +//***************************************************************************** +extern void FPU_setRoundingMode(uint32_t mode); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + + +#endif // __FPU_H__ diff --git a/example/rt_msp432/MSP432P4xx/gcc/msp432p4xx_driverlib.a b/example/rt_msp432/MSP432P4xx/gcc/msp432p4xx_driverlib.a new file mode 100644 index 0000000..51bcb94 Binary files /dev/null and b/example/rt_msp432/MSP432P4xx/gcc/msp432p4xx_driverlib.a differ diff --git a/example/rt_msp432/MSP432P4xx/gpio.c b/example/rt_msp432/MSP432P4xx/gpio.c new file mode 100644 index 0000000..6187a16 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/gpio.c @@ -0,0 +1,369 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include + +/* DriverLib Includes */ +#include +#include +#include +#include + +/* DriverLib internal GPIO register offset for optimized performance */ +#define OFS_LIB_PAIN ((uint32_t)&P1->IN - (uint32_t)P1) +#define OFS_LIB_PAOUT ((uint32_t)&P1->OUT - (uint32_t)P1) +#define OFS_LIB_PADIR ((uint32_t)&P1->DIR - (uint32_t)P1) +#define OFS_LIB_PAREN ((uint32_t)&P1->REN - (uint32_t)P1) +#define OFS_LIB_PADS ((uint32_t)&P1->DS - (uint32_t)P1) +#define OFS_LIB_PASEL0 ((uint32_t)&P1->SEL0 - (uint32_t)P1) +#define OFS_LIB_PASEL1 ((uint32_t)&P1->SEL1 - (uint32_t)P1) +#define OFS_LIB_PAIE ((uint32_t)&P1->IE - (uint32_t)P1) +#define OFS_LIB_PAIES ((uint32_t)&P1->IES - (uint32_t)P1) +#define OFS_LIB_PAIFG ((uint32_t)&P1->IFG - (uint32_t)P1) +#define OFS_LIB_P1IE ((uint32_t)&P1->IE - (uint32_t)P1) +#define OFS_LIB_P2IE OFS_LIB_P1IE + +static const uint32_t GPIO_PORT_TO_INT[] = +{ 0x00, +INT_PORT1, +INT_PORT2, +INT_PORT3, +INT_PORT4, +INT_PORT5, +INT_PORT6 }; + +static uint32_t GPIO_PORT_TO_BASE[] = +{ 0x00, + (uint32_t)P1, + (uint32_t)P1+1, + (uint32_t)P3, + (uint32_t)P3+1, + (uint32_t)P5, + (uint32_t)P5+1, + (uint32_t)P7, + (uint32_t)P7+1, + (uint32_t)P9, + (uint32_t)P9+1, + (uint32_t)PJ + }; + +void GPIO_setAsOutputPin(uint_fast8_t selectedPort, uint_fast16_t selectedPins) +{ + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PASEL0) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PADIR) |= selectedPins; +} + + +void GPIO_setAsInputPin(uint_fast8_t selectedPort, uint_fast16_t selectedPins) +{ + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PASEL0) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PADIR) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PAREN) &= ~selectedPins; +} + + +void GPIO_setAsPeripheralModuleFunctionOutputPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins, uint_fast8_t mode) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PADIR) |= selectedPins; + switch (mode) + { + case GPIO_PRIMARY_MODULE_FUNCTION: + HWREG16(baseAddress + OFS_LIB_PASEL0) |= selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) &= ~selectedPins; + break; + case GPIO_SECONDARY_MODULE_FUNCTION: + HWREG16(baseAddress + OFS_LIB_PASEL0) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) |= selectedPins; + break; + case GPIO_TERTIARY_MODULE_FUNCTION: + HWREG16(baseAddress + OFS_LIB_PASEL0) |= selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) |= selectedPins; + break; + } +} + + +void GPIO_setAsPeripheralModuleFunctionInputPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins, uint_fast8_t mode) +{ + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PADIR) &= ~selectedPins; + switch (mode) + { + case GPIO_PRIMARY_MODULE_FUNCTION: + HWREG16(baseAddress + OFS_LIB_PASEL0) |= selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) &= ~selectedPins; + break; + case GPIO_SECONDARY_MODULE_FUNCTION: + HWREG16(baseAddress + OFS_LIB_PASEL0) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) |= selectedPins; + break; + case GPIO_TERTIARY_MODULE_FUNCTION: + HWREG16(baseAddress + OFS_LIB_PASEL0) |= selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) |= selectedPins; + break; + } +} + + +void GPIO_setOutputHighOnPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PAOUT) |= selectedPins; +} + + +void GPIO_setOutputLowOnPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PAOUT) &= ~selectedPins; +} + + +void GPIO_toggleOutputOnPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PAOUT) ^= selectedPins; +} + + +void GPIO_setAsInputPinWithPullDownResistor(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PASEL0) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) &= ~selectedPins; + + HWREG16(baseAddress + OFS_LIB_PADIR) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PAREN) |= selectedPins; + HWREG16(baseAddress + OFS_LIB_PAOUT) &= ~selectedPins; +} + + +void GPIO_setAsInputPinWithPullUpResistor(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PASEL0) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PASEL1) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PADIR) &= ~selectedPins; + HWREG16(baseAddress + OFS_LIB_PAREN) |= selectedPins; + HWREG16(baseAddress + OFS_LIB_PAOUT) |= selectedPins; +} + + +uint8_t GPIO_getInputPinValue(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + uint_fast16_t inputPinValue; + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + inputPinValue = HWREG16(baseAddress + OFS_LIB_PAIN) & (selectedPins); + + if (inputPinValue > 0) + return GPIO_INPUT_PIN_HIGH; + return GPIO_INPUT_PIN_LOW; +} + + +void GPIO_enableInterrupt(uint_fast8_t selectedPort, uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PAIE) |= selectedPins; +} + + +void GPIO_disableInterrupt(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG16(baseAddress + OFS_LIB_PAIE) &= ~selectedPins; +} + + +uint_fast16_t GPIO_getInterruptStatus(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + return HWREG16(baseAddress + OFS_LIB_PAIFG) & selectedPins; +} + + +void GPIO_clearInterruptFlag(uint_fast8_t selectedPort, + uint_fast16_t selectedPins) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + + HWREG16(baseAddress + OFS_LIB_PAIFG) &= ~selectedPins; +} + + +void GPIO_interruptEdgeSelect(uint_fast8_t selectedPort, + uint_fast16_t selectedPins, uint_fast8_t edgeSelect) +{ + + uint32_t baseAddress = GPIO_PORT_TO_BASE[selectedPort]; + + + if (GPIO_LOW_TO_HIGH_TRANSITION == edgeSelect) + HWREG16(baseAddress + OFS_LIB_PAIES) &= ~selectedPins; + else + HWREG16(baseAddress + OFS_LIB_PAIES) |= selectedPins; +} + +uint_fast16_t GPIO_getEnabledInterruptStatus(uint_fast8_t selectedPort) +{ + uint_fast16_t pendingInts; + uint32_t baseAddr; + + pendingInts = GPIO_getInterruptStatus(selectedPort, 0xFFFF); + baseAddr = GPIO_PORT_TO_BASE[selectedPort]; + + ASSERT(baseAddr != 0xFFFF); + + switch (selectedPort) + { + case GPIO_PORT_P1: + case GPIO_PORT_P3: + case GPIO_PORT_P5: + case GPIO_PORT_P7: + case GPIO_PORT_P9: + return (HWREG8(baseAddr + OFS_LIB_P1IE) & pendingInts); + case GPIO_PORT_P2: + case GPIO_PORT_P4: + case GPIO_PORT_P6: + case GPIO_PORT_P8: + case GPIO_PORT_P10: + return (HWREG8(baseAddr + OFS_LIB_P2IE) & pendingInts); + case GPIO_PORT_PJ: + return (HWREG16(baseAddr + OFS_LIB_PAIE) & pendingInts); + default: + return 0; + } +} + + +void GPIO_setDriveStrengthHigh(uint_fast8_t selectedPort, + uint_fast8_t selectedPins) +{ + uint32_t baseAddr; + + baseAddr = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG8(baseAddr + OFS_LIB_PADS) |= selectedPins; + +} + +void GPIO_setDriveStrengthLow(uint_fast8_t selectedPort, + uint_fast8_t selectedPins) +{ + uint32_t baseAddr; + + baseAddr = GPIO_PORT_TO_BASE[selectedPort]; + + HWREG8(baseAddr + OFS_LIB_PADS) &= ~selectedPins; + +} + +void GPIO_registerInterrupt(uint_fast8_t selectedPort, void (*intHandler)(void)) +{ + uint32_t wPortInt; + + wPortInt = GPIO_PORT_TO_INT[selectedPort]; + + // + // Register the interrupt handler, returning an error if an error occurs. + // + Interrupt_registerInterrupt(wPortInt, intHandler); + + // + // Enable the system control interrupt. + // + Interrupt_enableInterrupt(wPortInt); +} + + +void GPIO_unregisterInterrupt(uint_fast8_t selectedPort) +{ + uint32_t wPortInt; + + wPortInt = GPIO_PORT_TO_INT[selectedPort]; + + // + // Disable the interrupt. + // + Interrupt_disableInterrupt(wPortInt); + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(wPortInt); +} + + diff --git a/example/rt_msp432/MSP432P4xx/gpio.h b/example/rt_msp432/MSP432P4xx/gpio.h new file mode 100644 index 0000000..ed47ac6 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/gpio.h @@ -0,0 +1,1026 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +//***************************************************************************** +// +//! \addtogroup gpio_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +#define GPIO_PORT_P1 1 +#define GPIO_PORT_P2 2 +#define GPIO_PORT_P3 3 +#define GPIO_PORT_P4 4 +#define GPIO_PORT_P5 5 +#define GPIO_PORT_P6 6 +#define GPIO_PORT_P7 7 +#define GPIO_PORT_P8 8 +#define GPIO_PORT_P9 9 +#define GPIO_PORT_P10 10 +#define GPIO_PORT_PA 1 +#define GPIO_PORT_PB 3 +#define GPIO_PORT_PC 5 +#define GPIO_PORT_PD 7 +#define GPIO_PORT_PE 9 +#define GPIO_PORT_PJ 11 + + +#define GPIO_PIN0 (0x0001) +#define GPIO_PIN1 (0x0002) +#define GPIO_PIN2 (0x0004) +#define GPIO_PIN3 (0x0008) +#define GPIO_PIN4 (0x0010) +#define GPIO_PIN5 (0x0020) +#define GPIO_PIN6 (0x0040) +#define GPIO_PIN7 (0x0080) +#define GPIO_PIN8 (0x0100) +#define GPIO_PIN9 (0x0200) +#define GPIO_PIN10 (0x0400) +#define GPIO_PIN11 (0x0800) +#define GPIO_PIN12 (0x1000) +#define GPIO_PIN13 (0x2000) +#define GPIO_PIN14 (0x4000) +#define GPIO_PIN15 (0x8000) +#define PIN_ALL8 (0xFF) +#define PIN_ALL16 (0xFFFF) + +#define GPIO_PRIMARY_MODULE_FUNCTION (0x01) +#define GPIO_SECONDARY_MODULE_FUNCTION (0x02) +#define GPIO_TERTIARY_MODULE_FUNCTION (0x03) + +#define GPIO_HIGH_TO_LOW_TRANSITION (0x01) +#define GPIO_LOW_TO_HIGH_TRANSITION (0x00) + +#define GPIO_INPUT_PIN_HIGH (0x01) +#define GPIO_INPUT_PIN_LOW (0x00) + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \brief This function configures the selected Pin as output pin +//! +//! This function selected pins on a selected port as output pins. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxDIR register and bits of \b PxSEL register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setAsOutputPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function configures the selected Pin as input pin +//! +//! This function selected pins on a selected port as input pins. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxDIR register, bits of \b PxREN register and bits of +//! \b PxSEL register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setAsInputPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function configures the peripheral module function in the +//! output direction for the selected pin for either primary, secondary or +//! ternary module function modes +//! +//! This function configures the peripheral module function in the output +//! direction for the selected pin for either primary, secondary or ternary +//! module function modes. Accepted values for mode are +//! GPIO_PRIMARY_MODULE_FUNCTION, GPIO_SECONDARY_MODULE_FUNCTION, and +//! GPIO_TERTIARY_MODULE_FUNCTION +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! \param mode is the specified mode that the pin should be configured for the +//! module function. +//! Valid values are: +//! - \b GPIO_PRIMARY_MODULE_FUNCTION +//! - \b GPIO_SECONDARY_MODULE_FUNCTION +//! - \b GPIO_TERTIARY_MODULE_FUNCTION +//! +//! Modified bits of \b PxDIR register and bits of \b PxSEL register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setAsPeripheralModuleFunctionOutputPin( + uint_fast8_t selectedPort, uint_fast16_t selectedPins, + uint_fast8_t mode); + +//***************************************************************************** +// +//! \brief This function configures the peripheral module function in the input +//! direction for the selected pin for either primary, secondary or ternary +//! module function modes. +//! +//! This function configures the peripheral module function in the input +//! direction for the selected pin for either primary, secondary or ternary +//! module function modes. Accepted values for mode are +//! GPIO_PRIMARY_MODULE_FUNCTION, GPIO_SECONDARY_MODULE_FUNCTION, and +//! GPIO_TERTIARY_MODULE_FUNCTION +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! \param mode is the specified mode that the pin should be configured for the +//! module function. +//! Valid values are: +//! - \b GPIO_PRIMARY_MODULE_FUNCTION +//! - \b GPIO_SECONDARY_MODULE_FUNCTION +//! - \b GPIO_TERTIARY_MODULE_FUNCTION +//! +//! Modified bits of \b PxDIR register and bits of \b PxSEL register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setAsPeripheralModuleFunctionInputPin( + uint_fast8_t selectedPort, uint_fast16_t selectedPins, + uint_fast8_t mode); + +//***************************************************************************** +// +//! \brief This function sets output HIGH on the selected Pin +//! +//! This function sets output HIGH on the selected port's pin. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxOUT register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setOutputHighOnPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function sets output LOW on the selected Pin +//! +//! This function sets output LOW on the selected port's pin. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setOutputLowOnPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function toggles the output on the selected Pin +//! +//! This function toggles the output on the selected port's pin. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxOUT register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_toggleOutputOnPin(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function sets the selected Pin in input Mode with Pull Down +//! resistor +//! +//! This function sets the selected Pin in input Mode with Pull Down resistor. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxDIR register, bits of \b PxOUT register and bits of +//! \b PxREN register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setAsInputPinWithPullDownResistor(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function sets the selected Pin in input Mode with Pull Up +//! resistor +//! +//! This function sets the selected Pin in input Mode with Pull Up resistor. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxDIR register, bits of \b PxOUT register and bits of +//! \b PxREN register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setAsInputPinWithPullUpResistor(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function gets the input value on the selected pin +//! +//! This function gets the input value on the selected pin. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Valid values are: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! \return One of the following: +//! - \b GPIO_INPUT_PIN_HIGH +//! - \b GPIO_INPUT_PIN_LOW +//! \n indicating the status of the pin +// +//***************************************************************************** +extern uint8_t GPIO_getInputPinValue(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function enables the port interrupt on the selected pin +//! +//! This function enables the port interrupt on the selected pin. Note that +//! only Port 1,2, A have this capability. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_PA +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxIE register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_enableInterrupt(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function disables the port interrupt on the selected pin +//! +//! This function disables the port interrupt on the selected pin. Note that +//! only Port 1,2, A have this capability. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_PA +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxIE register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_disableInterrupt(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function gets the interrupt status of the selected pin +//! +//! This function gets the interrupt status of the selected pin. Note that only +//! Port 1,2, A have this capability. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_PA +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! \return Logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! \n indicating the interrupt status of the selected pins [Default: +//! 0] +// +//***************************************************************************** +extern uint_fast16_t GPIO_getInterruptStatus(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function clears the interrupt flag on the selected pin +//! +//! This function clears the interrupt flag on the selected pin. Note that only +//! Port 1,2,A have this capability. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_PA +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! +//! Modified bits of \b PxIFG register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_clearInterruptFlag(uint_fast8_t selectedPort, + uint_fast16_t selectedPins); + +//***************************************************************************** +// +//! \brief This function selects on what edge the port interrupt flag should be +//! set for a transition +//! +//! This function selects on what edge the port interrupt flag should be set +//! for a transition. Values for edgeSelect should be +//! GPIO_LOW_TO_HIGH_TRANSITION or GPIO_HIGH_TO_LOW_TRANSITION. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Mask value is the logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15 +//! \param edgeSelect specifies what transition sets the interrupt flag +//! Valid values are: +//! - \b GPIO_HIGH_TO_LOW_TRANSITION +//! - \b GPIO_LOW_TO_HIGH_TRANSITION +//! +//! Modified bits of \b PxIES register. +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_interruptEdgeSelect(uint_fast8_t selectedPort, + uint_fast16_t selectedPins, uint_fast8_t edgeSelect); + +//***************************************************************************** +// +//! \brief This function gets the interrupt status of the provided PIN and +//! masks it with the interrupts that are actually enabled. This is +//! useful for inside ISRs where the status of only the enabled +//! interrupts needs to be checked. +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1 +//! - \b GPIO_PORT_P2 +//! - \b GPIO_PORT_P3 +//! - \b GPIO_PORT_P4 +//! - \b GPIO_PORT_P5 +//! - \b GPIO_PORT_P6 +//! - \b GPIO_PORT_P7 +//! - \b GPIO_PORT_P8 +//! - \b GPIO_PORT_P9 +//! - \b GPIO_PORT_P10 +//! - \b GPIO_PORT_P11 +//! - \b GPIO_PORT_PJ +//! +//! \return Logical OR of any of the following: +//! - \b GPIO_PIN0 +//! - \b GPIO_PIN1 +//! - \b GPIO_PIN2 +//! - \b GPIO_PIN3 +//! - \b GPIO_PIN4 +//! - \b GPIO_PIN5 +//! - \b GPIO_PIN6 +//! - \b GPIO_PIN7 +//! - \b GPIO_PIN8 +//! - \b GPIO_PIN9 +//! - \b GPIO_PIN10 +//! - \b GPIO_PIN11 +//! - \b GPIO_PIN12 +//! - \b GPIO_PIN13 +//! - \b GPIO_PIN14 +//! - \b GPIO_PIN15, +//! - \b PIN_ALL8, +//! - \b PIN_ALL16 +//! \n indicating the interrupt status of the selected pins [Default: +//! 0] +// +//***************************************************************************** +extern uint_fast16_t GPIO_getEnabledInterruptStatus(uint_fast8_t selectedPort); + + +//***************************************************************************** +// +//! Registers an interrupt handler for the port interrupt. +//! +//! \param selectedPort is the port to register the interrupt handler +//! +//! \param intHandler is a pointer to the function to be called when the port +//! interrupt occurs. +//! +//! This function registers the handler to be called when a port +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific GPIO interrupts must be enabled +//! via GPIO_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via GPIO_clearInterruptFlag(). +//! +//! Clock System can generate interrupts when +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void GPIO_registerInterrupt(uint_fast8_t selectedPort, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the port. +//! +//! \param selectedPort is the port to unregister the interrupt handler +//! +//! This function unregisters the handler to be called when a port +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void GPIO_unregisterInterrupt(uint_fast8_t selectedPort); + +//***************************************************************************** +// +//! This function sets the drive strength to high for the selected port +//! +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1, +//! - \b GPIO_PORT_P2, +//! - \b GPIO_PORT_P3, +//! - \b GPIO_PORT_P4, +//! - \b GPIO_PORT_P5, +//! - \b GPIO_PORT_P6, +//! - \b GPIO_PORT_P7, +//! - \b GPIO_PORT_P8, +//! - \b GPIO_PORT_P9, +//! - \b GPIO_PORT_P10, +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Valid values are: +//! - \b GPIO_PIN0, +//! - \b GPIO_PIN1, +//! - \b GPIO_PIN2, +//! - \b GPIO_PIN3, +//! - \b GPIO_PIN4, +//! - \b GPIO_PIN5, +//! - \b GPIO_PIN6, +//! - \b GPIO_PIN7, +//! - \b GPIO_PIN8, +//! - \b PIN_ALL8, +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setDriveStrengthHigh(uint_fast8_t selectedPort, + uint_fast8_t selectedPins); + +//***************************************************************************** +// +//! This function sets the drive strength to low for the selected port +//! +//! +//! \param selectedPort is the selected port. +//! Valid values are: +//! - \b GPIO_PORT_P1, +//! - \b GPIO_PORT_P2, +//! - \b GPIO_PORT_P3, +//! - \b GPIO_PORT_P4, +//! - \b GPIO_PORT_P5, +//! - \b GPIO_PORT_P6, +//! - \b GPIO_PORT_P7, +//! - \b GPIO_PORT_P8, +//! - \b GPIO_PORT_P9, +//! - \b GPIO_PORT_P10, +//! - \b GPIO_PORT_PJ +//! \param selectedPins is the specified pin in the selected port. +//! Valid values are: +//! - \b GPIO_PIN0, +//! - \b GPIO_PIN1, +//! - \b GPIO_PIN2, +//! - \b GPIO_PIN3, +//! - \b GPIO_PIN4, +//! - \b GPIO_PIN5, +//! - \b GPIO_PIN6, +//! - \b GPIO_PIN7, +//! - \b GPIO_PIN8, +//! - \b PIN_ALL8, +//! +//! \return None +// +//***************************************************************************** +extern void GPIO_setDriveStrengthLow(uint_fast8_t selectedPort, + uint_fast8_t selectedPins); + +/* Backwards Compatibility Layer */ +#define GPIO_selectInterruptEdge GPIO_interruptEdgeSelect +#define GPIO_clearInterrupt GPIO_clearInterruptFlag + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __GPIO_H__ diff --git a/example/rt_msp432/MSP432P4xx/hw_memmap.h b/example/rt_msp432/MSP432P4xx/hw_memmap.h new file mode 100644 index 0000000..54d77b5 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/hw_memmap.h @@ -0,0 +1,87 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __HW_MEMMAP__ +#define __HW_MEMMAP__ + +#define __DRIVERLIB_MSP432P4XX_FAMILY__ +//***************************************************************************** +// +// Include device specific header file +// +//***************************************************************************** + + +//***************************************************************************** +// +// SUCCESS and FAILURE for API return value +// +//***************************************************************************** +#define STATUS_SUCCESS 0x01 +#define STATUS_FAIL 0x00 + +//***************************************************************************** +// +// Macros for hardware access +// +//***************************************************************************** +#define HWREG8(x) (*((volatile uint8_t *)(x))) +#define HWREG16(x) (*((volatile uint16_t *)(x))) +#define HWREG32(x) (*((volatile uint32_t *)(x))) +#define HWREG(x) (HWREG16(x)) +#define HWREG8_L(x) (*((volatile uint8_t *)((uint8_t *)&x))) +#define HWREG8_H(x) (*((volatile uint8_t *)(((uint8_t *)&x)+1))) +#define HWREG16_L(x) (*((volatile uint16_t *)((uint16_t *)&x))) +#define HWREG16_H(x) (*((volatile uint16_t *)(((uint16_t *)&x)+1))) + +/****************************************************************************** +* Device memory map * +******************************************************************************/ +#define __MAIN_MEMORY_START__ (0x00000000) /**< Main Flash memory start address */ +#define __MAIN_MEMORY_END__ (0x0003FFFF) /**< Main Flash memory end address */ +#define __BSL_MEMORY_START__ (0x00202000) /**< BSL memory start address */ +#define __BSL_MEMORY_END__ (0x00203FFF) /**< BSL memory end address */ +#define __SRAM_START__ (0x20000000) /**< SRAM memory start address */ +#define __SRAM_END__ (0x2000FFFF) /**< SRAM memory end address */ + +/****************************************************************************** +* Definitions for 8/16/32-bit wide bit band access * +******************************************************************************/ +#define HWREGBIT8(x, b) (HWREG8(((uint32_t)(x) & 0xF0000000) | 0x02000000 | (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2))) +#define HWREGBIT16(x, b) (HWREG16(((uint32_t)(x) & 0xF0000000) | 0x02000000 | (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2))) +#define HWREGBIT32(x, b) (HWREG32(((uint32_t)(x) & 0xF0000000) | 0x02000000 | (((uint32_t)(x) & 0x000FFFFF) << 5) | ((b) << 2))) + +#endif // #ifndef __HW_MEMMAP__ diff --git a/example/rt_msp432/MSP432P4xx/i2c.c b/example/rt_msp432/MSP432P4xx/i2c.c new file mode 100644 index 0000000..d46e00e --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/i2c.c @@ -0,0 +1,765 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include +#include + +void I2C_initMaster(uint32_t moduleInstance, const eUSCI_I2C_MasterConfig *config) +{ + uint_fast16_t preScalarValue; + + ASSERT( + (EUSCI_B_I2C_CLOCKSOURCE_ACLK == config->selectClockSource) + || (EUSCI_B_I2C_CLOCKSOURCE_SMCLK + == config->selectClockSource)); + + ASSERT( + (EUSCI_B_I2C_SET_DATA_RATE_400KBPS == config->dataRate) + || (EUSCI_B_I2C_SET_DATA_RATE_100KBPS == config->dataRate) + || (EUSCI_B_I2C_SET_DATA_RATE_1MBPS == config->dataRate)); + + ASSERT( + (EUSCI_B_I2C_NO_AUTO_STOP == config->autoSTOPGeneration) + || (EUSCI_B_I2C_SET_BYTECOUNT_THRESHOLD_FLAG + == config->autoSTOPGeneration) + || (EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD + == config->autoSTOPGeneration)); + + /* Disable the USCI module and clears the other bits of control register */ + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_SWRST_OFS) = + 1; + + /* Configure Automatic STOP condition generation */ + EUSCI_B_CMSIS(moduleInstance)->CTLW1 = + (EUSCI_B_CMSIS(moduleInstance)->CTLW1 & ~EUSCI_B_CTLW1_ASTP_MASK) + | (config->autoSTOPGeneration); + + /* Byte Count Threshold */ + EUSCI_B_CMSIS(moduleInstance)->TBCNT = config->byteCounterThreshold; + + /* + * Configure as I2C master mode. + * UCMST = Master mode + * UCMODE_3 = I2C mode + * UCSYNC = Synchronous mode + */ + EUSCI_B_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_B_CMSIS(moduleInstance)->CTLW0 & ~EUSCI_B_CTLW0_SSEL_MASK) + | (config->selectClockSource | EUSCI_B_CTLW0_MST + | EUSCI_B_CTLW0_MODE_3 | EUSCI_B_CTLW0_SYNC + | EUSCI_B_CTLW0_SWRST); + + /* + * Compute the clock divider that achieves the fastest speed less than or + * equal to the desired speed. The numerator is biased to favor a larger + * clock divider so that the resulting clock is always less than or equal + * to the desired clock, never greater. + */ + preScalarValue = (uint16_t) (config->i2cClk / config->dataRate); + + EUSCI_B_CMSIS(moduleInstance)->BRW = preScalarValue; +} + +void I2C_initSlave(uint32_t moduleInstance, uint_fast16_t slaveAddress, + uint_fast8_t slaveAddressOffset, uint32_t slaveOwnAddressEnable) +{ + ASSERT( + (EUSCI_B_I2C_OWN_ADDRESS_OFFSET0 == slaveAddressOffset) + || (EUSCI_B_I2C_OWN_ADDRESS_OFFSET1 == slaveAddressOffset) + || (EUSCI_B_I2C_OWN_ADDRESS_OFFSET2 == slaveAddressOffset) + || (EUSCI_B_I2C_OWN_ADDRESS_OFFSET3 == slaveAddressOffset)); + + /* Disable the USCI module */ + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_SWRST_OFS) = + 1; + + /* Clear USCI master mode */ + EUSCI_B_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_B_CMSIS(moduleInstance)->CTLW0 & (~EUSCI_B_CTLW0_MST)) + | (EUSCI_B_CTLW0_MODE_3 + EUSCI_B_CTLW0_SYNC); + + /* Set up the slave address. */ + HWREG16((uint32_t)&EUSCI_B_CMSIS(moduleInstance)->I2COA0 + slaveAddressOffset) = + slaveAddress + slaveOwnAddressEnable; +} + +void I2C_enableModule(uint32_t moduleInstance) +{ + /* Reset the UCSWRST bit to enable the USCI Module */ + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_SWRST_OFS) = + 0; +} + +void I2C_disableModule(uint32_t moduleInstance) +{ + /* Set the UCSWRST bit to disable the USCI Module */ + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_SWRST_OFS) = + 1; + ; +} + +void I2C_setSlaveAddress(uint32_t moduleInstance, uint_fast16_t slaveAddress) +{ + /* Set the address of the slave with which the master will communicate */ + EUSCI_B_CMSIS(moduleInstance)->I2CSA = (slaveAddress); +} + +void I2C_setMode(uint32_t moduleInstance, uint_fast8_t mode) +{ + ASSERT( + (EUSCI_B_I2C_TRANSMIT_MODE == mode) + || (EUSCI_B_I2C_RECEIVE_MODE == mode)); + + EUSCI_B_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_B_CMSIS(moduleInstance)->CTLW0 + & (~EUSCI_B_I2C_TRANSMIT_MODE)) | mode; + +} + +uint8_t I2C_masterReceiveSingleByte(uint32_t moduleInstance) +{ + //Set USCI in Receive mode + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TR_OFS) = 0; + + //Send start + EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= (EUSCI_B_CTLW0_TXSTT + EUSCI_B_CTLW0_TXSTP); + + //Poll for receive interrupt flag. + while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_RXIFG_OFS)) + ; + + //Send single byte data. + return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK); +} + +void I2C_slavePutData(uint32_t moduleInstance, uint8_t transmitData) +{ + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = transmitData; +} + +uint8_t I2C_slaveGetData(uint32_t moduleInstance) +{ + //Read a byte. + return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK); +} + +uint8_t I2C_isBusBusy(uint32_t moduleInstance) +{ + //Return the bus busy status. + return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->STATW, + EUSCI_B_STATW_BBUSY_OFS); +} + +void I2C_masterSendSingleByte(uint32_t moduleInstance, uint8_t txData) +{ + //Store current TXIE status + uint16_t txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0; + + //Disable transmit interrupt enable + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0; + + //Send start condition. + EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR + EUSCI_B_CTLW0_TXSTT; + + //Poll for transmit interrupt flag. + while (!(EUSCI_B_CMSIS(moduleInstance)->IFG & EUSCI_B_IFG_TXIFG)) + ; + + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; + + //Poll for transmit interrupt flag. + while (!(EUSCI_B_CMSIS(moduleInstance)->IFG & EUSCI_B_IFG_TXIFG)) + ; + + //Send stop condition. + EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TXSTP; + + //Clear transmit interrupt flag before enabling interrupt again + EUSCI_B_CMSIS(moduleInstance)->IFG &= ~(EUSCI_B_IFG_TXIFG); + + //Reinstate transmit interrupt enable + EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus; +} + +bool I2C_masterSendSingleByteWithTimeout(uint32_t moduleInstance, + uint8_t txData, uint32_t timeout) +{ + uint_fast16_t txieStatus; + uint32_t timeout2 = timeout; + + ASSERT(timeout > 0); + + //Store current TXIE status + txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0; + + //Disable transmit interrupt enable + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE,EUSCI_B_IE_TXIE0_OFS) = 0; + + //Send start condition. + EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR + EUSCI_B_CTLW0_TXSTT; + + //Poll for transmit interrupt flag. + while ((!(EUSCI_B_CMSIS(moduleInstance)->IFG & EUSCI_B_IFG_TXIFG)) && --timeout) + ; + + //Check if transfer timed out + if (timeout == 0) + return false; + + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; + + //Poll for transmit interrupt flag. + while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)) + && --timeout2) + ; + + //Check if transfer timed out + if (timeout2 == 0) + return false; + + //Send stop condition. + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS) = 1; + + //Clear transmit interrupt flag before enabling interrupt again + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,EUSCI_B_IFG_TXIFG0_OFS) = 0; + + //Reinstate transmit interrupt enable + EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus; + + return true; +} + +void I2C_masterSendMultiByteStart(uint32_t moduleInstance, uint8_t txData) +{ + //Store current transmit interrupt enable + uint16_t txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0; + + //Disable transmit interrupt enable + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0; + + //Send start condition. + EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR + EUSCI_B_CTLW0_TXSTT; + + //Poll for transmit interrupt flag. + while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)) + ; + + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; + + //Reinstate transmit interrupt enable + EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus; +} + +bool I2C_masterSendMultiByteStartWithTimeout(uint32_t moduleInstance, + uint8_t txData, uint32_t timeout) +{ + uint_fast16_t txieStatus; + + ASSERT(timeout > 0); + + //Store current transmit interrupt enable + txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0; + + //Disable transmit interrupt enable + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE,EUSCI_B_IE_TXIE0_OFS) = 0; + + //Send start condition. + EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR + EUSCI_B_CTLW0_TXSTT; + + //Poll for transmit interrupt flag. + while ((!(BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)) + && --timeout)) + ; + + //Check if transfer timed out + if (timeout == 0) + return false; + + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; + + //Reinstate transmit interrupt enable + EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus; + + return true; +} + +void I2C_masterSendMultiByteNext(uint32_t moduleInstance, uint8_t txData) +{ + //If interrupts are not used, poll for flags + if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS)) + { + //Poll for transmit interrupt flag. + while + (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)) + ; + } + + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; +} + +bool I2C_masterSendMultiByteNextWithTimeout(uint32_t moduleInstance, + uint8_t txData, uint32_t timeout) +{ + ASSERT(timeout > 0); + + //If interrupts are not used, poll for flags + if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS)) + { + //Poll for transmit interrupt flag. + while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, + EUSCI_B_IFG_TXIFG0_OFS)) && --timeout) + ; + + //Check if transfer timed out + if (timeout == 0) + return false; + } + + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; + + return true; +} + +void I2C_masterSendMultiByteFinish(uint32_t moduleInstance, uint8_t txData) +{ + //If interrupts are not used, poll for flags + if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS)) + { + //Poll for transmit interrupt flag. + while + (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)) + ; + } + + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; + + //Poll for transmit interrupt flag. + while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)) + ; + + //Send stop condition. + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS) = 1; +} + +bool I2C_masterSendMultiByteFinishWithTimeout(uint32_t moduleInstance, + uint8_t txData, uint32_t timeout) +{ + uint32_t timeout2 = timeout; + + ASSERT(timeout > 0); + + //If interrupts are not used, poll for flags + if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS)) + { + //Poll for transmit interrupt flag. + while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, + EUSCI_B_IFG_TXIFG0_OFS)) && --timeout) + ; + + //Check if transfer timed out + if (timeout == 0) + return false; + } + + //Send single byte data. + EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; + + //Poll for transmit interrupt flag. + while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)) + && --timeout2) + ; + + //Check if transfer timed out + if (timeout2 == 0) + return false; + + //Send stop condition. + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS) = 1; + + return true; +} + +void I2C_masterSendMultiByteStop(uint32_t moduleInstance) +{ + //If interrupts are not used, poll for flags + if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS)) + { + //Poll for transmit interrupt flag. + while + (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)) + ; + } + + //Send stop condition. + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS) = 1; +} + +bool I2C_masterSendMultiByteStopWithTimeout(uint32_t moduleInstance, + uint32_t timeout) +{ + ASSERT(timeout > 0); + + //If interrupts are not used, poll for flags + if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS)) + { + //Poll for transmit interrupt flag. + while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, + EUSCI_B_IFG_TXIFG0_OFS)) && --timeout) + ; + + //Check if transfer timed out + if (timeout == 0) + return false; + } + + //Send stop condition. + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS) = 1; + + return 0x01; +} + +void I2C_masterReceiveStart(uint32_t moduleInstance) +{ + //Set USCI in Receive mode + EUSCI_B_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_B_CMSIS(moduleInstance)->CTLW0 & (~EUSCI_B_CTLW0_TR)) + | EUSCI_B_CTLW0_TXSTT; +} + +uint8_t I2C_masterReceiveMultiByteNext(uint32_t moduleInstance) +{ + return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK); +} + +uint8_t I2C_masterReceiveMultiByteFinish(uint32_t moduleInstance) +{ + //Send stop condition. + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS) = + 1; + + //Wait for Stop to finish + while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS)) + { + // Wait for RX buffer + while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_RXIFG_OFS)) + ; + } + + /* Capture data from receive buffer after setting stop bit due to + MSP430 I2C critical timing. */ + return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK); +} + +bool I2C_masterReceiveMultiByteFinishWithTimeout(uint32_t moduleInstance, + uint8_t *txData, uint32_t timeout) +{ + uint32_t timeout2 = timeout; + + ASSERT(timeout > 0); + + //Send stop condition. + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS) = 1; + + //Wait for Stop to finish + while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) + && --timeout) + ; + + //Check if transfer timed out + if (timeout == 0) + return false; + + // Wait for RX buffer + while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_RXIFG_OFS)) + && --timeout2) + ; + + //Check if transfer timed out + if (timeout2 == 0) + return false; + + //Capture data from receive buffer after setting stop bit due to + //MSP430 I2C critical timing. + *txData = (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK); + + return true; +} + +void I2C_masterReceiveMultiByteStop(uint32_t moduleInstance) +{ + //Send stop condition. + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTP_OFS) = 1; +} + +uint8_t I2C_masterReceiveSingle(uint32_t moduleInstance) +{ + //Polling RXIFG0 if RXIE is not enabled + if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_RXIE0_OFS)) + { + while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, + EUSCI_B_IFG_RXIFG0_OFS)) + ; + } + + //Read a byte. + return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK) ; +} + +uint32_t I2C_getReceiveBufferAddressForDMA(uint32_t moduleInstance) +{ + return (uint32_t)&EUSCI_B_CMSIS(moduleInstance)->RXBUF; +} + +uint32_t I2C_getTransmitBufferAddressForDMA(uint32_t moduleInstance) +{ + return (uint32_t)&EUSCI_B_CMSIS(moduleInstance)->TXBUF; +} + +uint8_t I2C_masterIsStopSent(uint32_t moduleInstance) +{ + return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, + EUSCI_B_CTLW0_TXSTP_OFS); +} + +bool I2C_masterIsStartSent(uint32_t moduleInstance) +{ + return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, + EUSCI_B_CTLW0_TXSTT_OFS); +} + +void I2C_masterSendStart(uint32_t moduleInstance) +{ + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXSTT_OFS) = + 1; +} + +void I2C_enableMultiMasterMode(uint32_t moduleInstance) +{ + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_SWRST_OFS) = + 1; + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_MM_OFS) = 1; +} + +void I2C_disableMultiMasterMode(uint32_t moduleInstance) +{ + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_SWRST_OFS) = + 1; + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_MM_OFS) = 0; +} + +void I2C_enableInterrupt(uint32_t moduleInstance, uint_fast16_t mask) +{ + ASSERT( + 0x00 + == (mask + & ~(EUSCI_B_I2C_STOP_INTERRUPT + + EUSCI_B_I2C_START_INTERRUPT + + EUSCI_B_I2C_NAK_INTERRUPT + + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT + + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT + + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT + + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT1 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT2 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT3 + + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + + EUSCI_B_I2C_RECEIVE_INTERRUPT1 + + EUSCI_B_I2C_RECEIVE_INTERRUPT2 + + EUSCI_B_I2C_RECEIVE_INTERRUPT3))); + + //Enable the interrupt masked bit + EUSCI_B_CMSIS(moduleInstance)->IE |= mask; +} + +void I2C_disableInterrupt(uint32_t moduleInstance, uint_fast16_t mask) +{ + ASSERT( + 0x00 + == (mask + & ~(EUSCI_B_I2C_STOP_INTERRUPT + + EUSCI_B_I2C_START_INTERRUPT + + EUSCI_B_I2C_NAK_INTERRUPT + + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT + + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT + + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT + + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT1 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT2 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT3 + + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + + EUSCI_B_I2C_RECEIVE_INTERRUPT1 + + EUSCI_B_I2C_RECEIVE_INTERRUPT2 + + EUSCI_B_I2C_RECEIVE_INTERRUPT3))); + + //Disable the interrupt masked bit + EUSCI_B_CMSIS(moduleInstance)->IE &= ~(mask); +} + +void I2C_clearInterruptFlag(uint32_t moduleInstance, uint_fast16_t mask) +{ + ASSERT( + 0x00 + == (mask + & ~(EUSCI_B_I2C_STOP_INTERRUPT + + EUSCI_B_I2C_START_INTERRUPT + + EUSCI_B_I2C_NAK_INTERRUPT + + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT + + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT + + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT + + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT1 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT2 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT3 + + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + + EUSCI_B_I2C_RECEIVE_INTERRUPT1 + + EUSCI_B_I2C_RECEIVE_INTERRUPT2 + + EUSCI_B_I2C_RECEIVE_INTERRUPT3))); + //Clear the I2C interrupt source. + EUSCI_B_CMSIS(moduleInstance)->IFG &= ~(mask); +} + +uint_fast16_t I2C_getInterruptStatus(uint32_t moduleInstance, uint16_t mask) +{ + ASSERT( + 0x00 + == (mask + & ~(EUSCI_B_I2C_STOP_INTERRUPT + + EUSCI_B_I2C_START_INTERRUPT + + EUSCI_B_I2C_NAK_INTERRUPT + + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT + + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT + + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT + + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT + + EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT1 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT2 + + EUSCI_B_I2C_TRANSMIT_INTERRUPT3 + + EUSCI_B_I2C_RECEIVE_INTERRUPT0 + + EUSCI_B_I2C_RECEIVE_INTERRUPT1 + + EUSCI_B_I2C_RECEIVE_INTERRUPT2 + + EUSCI_B_I2C_RECEIVE_INTERRUPT3))); + //Return the interrupt status of the request masked bit. + return EUSCI_B_CMSIS(moduleInstance)->IFG & mask; +} + +uint_fast16_t I2C_getEnabledInterruptStatus(uint32_t moduleInstance) +{ + return I2C_getInterruptStatus(moduleInstance, + EUSCI_B_CMSIS(moduleInstance)->IE); +} + +uint_fast16_t I2C_getMode(uint32_t moduleInstance) +{ + //Read the I2C mode. + return (EUSCI_B_CMSIS(moduleInstance)->CTLW0 & EUSCI_B_CTLW0_TR); +} + +void I2C_registerInterrupt(uint32_t moduleInstance, void (*intHandler)(void)) +{ + switch (moduleInstance) + { + case EUSCI_B0_BASE: + Interrupt_registerInterrupt(INT_EUSCIB0, intHandler); + Interrupt_enableInterrupt(INT_EUSCIB0); + break; + case EUSCI_B1_BASE: + Interrupt_registerInterrupt(INT_EUSCIB1, intHandler); + Interrupt_enableInterrupt(INT_EUSCIB1); + break; +#ifdef EUSCI_B2_BASE + case EUSCI_B2_BASE: + Interrupt_registerInterrupt(INT_EUSCIB2, intHandler); + Interrupt_enableInterrupt(INT_EUSCIB2); + break; +#endif +#ifdef EUSCI_B3_BASE + case EUSCI_B3_BASE: + Interrupt_registerInterrupt(INT_EUSCIB3, intHandler); + Interrupt_enableInterrupt(INT_EUSCIB3); + break; +#endif + default: + ASSERT(false); + } +} + +void I2C_unregisterInterrupt(uint32_t moduleInstance) +{ + switch (moduleInstance) + { + case EUSCI_B0_BASE: + Interrupt_disableInterrupt(INT_EUSCIB0); + Interrupt_unregisterInterrupt(INT_EUSCIB0); + break; + case EUSCI_B1_BASE: + Interrupt_disableInterrupt(INT_EUSCIB1); + Interrupt_unregisterInterrupt(INT_EUSCIB1); + break; +#ifdef EUSCI_B2_BASE + case EUSCI_B2_BASE: + Interrupt_disableInterrupt(INT_EUSCIB2); + Interrupt_unregisterInterrupt(INT_EUSCIB2); + break; +#endif +#ifdef EUSCI_B3_BASE + case EUSCI_B3_BASE: + Interrupt_disableInterrupt(INT_EUSCIB3); + Interrupt_unregisterInterrupt(INT_EUSCIB3); + break; +#endif + default: + ASSERT(false); + } +} + +void I2C_slaveSendNAK(uint32_t moduleInstance) +{ + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,EUSCI_B_CTLW0_TXNACK_OFS) + = 1; +} diff --git a/example/rt_msp432/MSP432P4xx/i2c.h b/example/rt_msp432/MSP432P4xx/i2c.h new file mode 100644 index 0000000..cc6a576 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/i2c.h @@ -0,0 +1,1426 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef I2C_H_ +#define I2C_H_ + +//***************************************************************************** +// +//! \addtogroup i2c_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include "eusci.h" + +#define EUSCI_B_I2C_NO_AUTO_STOP EUSCI_B_CTLW1_ASTP_0 +#define EUSCI_B_I2C_SET_BYTECOUNT_THRESHOLD_FLAG EUSCI_B_CTLW1_ASTP_1 +#define EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD \ + EUSCI_B_CTLW1_ASTP_2 + +#define EUSCI_B_I2C_SET_DATA_RATE_1MBPS 1000000 +#define EUSCI_B_I2C_SET_DATA_RATE_400KBPS 400000 +#define EUSCI_B_I2C_SET_DATA_RATE_100KBPS 100000 + +#define EUSCI_B_I2C_CLOCKSOURCE_ACLK EUSCI_B_CTLW0_SSEL__ACLK +#define EUSCI_B_I2C_CLOCKSOURCE_SMCLK EUSCI_B_CTLW0_SSEL__SMCLK + +#define EUSCI_B_I2C_OWN_ADDRESS_OFFSET0 0x00 +#define EUSCI_B_I2C_OWN_ADDRESS_OFFSET1 0x02 +#define EUSCI_B_I2C_OWN_ADDRESS_OFFSET2 0x04 +#define EUSCI_B_I2C_OWN_ADDRESS_OFFSET3 0x06 + +#define EUSCI_B_I2C_OWN_ADDRESS_DISABLE 0x00 +#define EUSCI_B_I2C_OWN_ADDRESS_ENABLE EUSCI_B_I2COA0_OAEN + +#define EUSCI_B_I2C_TRANSMIT_MODE EUSCI_B_CTLW0_TR +#define EUSCI_B_I2C_RECEIVE_MODE 0x00 + +#define EUSCI_B_I2C_NAK_INTERRUPT EUSCI_B_IE_NACKIE +#define EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT EUSCI_B_IE_ALIE +#define EUSCI_B_I2C_STOP_INTERRUPT EUSCI_B_IE_STPIE +#define EUSCI_B_I2C_START_INTERRUPT EUSCI_B_IE_STTIE +#define EUSCI_B_I2C_TRANSMIT_INTERRUPT0 EUSCI_B_IE_TXIE0 +#define EUSCI_B_I2C_TRANSMIT_INTERRUPT1 EUSCI_B_IE_TXIE1 +#define EUSCI_B_I2C_TRANSMIT_INTERRUPT2 EUSCI_B_IE_TXIE2 +#define EUSCI_B_I2C_TRANSMIT_INTERRUPT3 EUSCI_B_IE_TXIE3 +#define EUSCI_B_I2C_RECEIVE_INTERRUPT0 EUSCI_B_IE_RXIE0 +#define EUSCI_B_I2C_RECEIVE_INTERRUPT1 EUSCI_B_IE_RXIE1 +#define EUSCI_B_I2C_RECEIVE_INTERRUPT2 EUSCI_B_IE_RXIE2 +#define EUSCI_B_I2C_RECEIVE_INTERRUPT3 EUSCI_B_IE_RXIE3 +#define EUSCI_B_I2C_BIT9_POSITION_INTERRUPT EUSCI_B_IE_BIT9IE +#define EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT EUSCI_B_IE_CLTOIE +#define EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT EUSCI_B_IE_BCNTIE + +#define EUSCI_B_I2C_BUS_BUSY EUSCI_B_STATW_BBUSY +#define EUSCI_B_I2C_BUS_NOT_BUSY 0x00 + +#define EUSCI_B_I2C_STOP_SEND_COMPLETE 0x00 +#define EUSCI_B_I2C_SENDING_STOP EUSCI_B_CTLW0_TXSTP + +#define EUSCI_B_I2C_START_SEND_COMPLETE 0x00 +#define EUSCI_B_I2C_SENDING_START EUSCI_B_CTLW0_TXSTT + +//***************************************************************************** +// +//! ypedef eUSCI_I2C_MasterConfig +//! \brief Type definition for \link _eUSCI_I2C_MasterConfig \endlink structure +//! +//! \struct _eUSCI_I2C_MasterConfig +//! \brief Configuration structure for master mode in the \b I2C module. See +//! \link I2C_initMaster \endlink for parameter documentation. +// +//***************************************************************************** +typedef struct +{ + uint_fast8_t selectClockSource; + uint32_t i2cClk; + uint32_t dataRate; + uint_fast8_t byteCounterThreshold; + uint_fast8_t autoSTOPGeneration; +} eUSCI_I2C_MasterConfig; + + +//***************************************************************************** +// +//! Initializes the I2C Master block. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! \param config Configuration structure for I2C master mode +//! +//!
+//! Configuration options for \link eUSCI_I2C_MasterConfig \endlink structure. +//!
+//! +//! \param selectClockSource is the clock source. +//! Valid values are +//! - \b EUSCI_B_I2C_CLOCKSOURCE_ACLK +//! - \b EUSCI_B_I2C_CLOCKSOURCE_SMCLK +//! \param i2cClk is the rate of the clock supplied to the I2C module +//! (the frequency in Hz of the clock source specified in +//! selectClockSource). +//! \param dataRate set up for selecting data transfer rate. +//! Valid values are +//! - \b EUSCI_B_I2C_SET_DATA_RATE_1MBPS +//! - \b EUSCI_B_I2C_SET_DATA_RATE_400KBPS +//! - \b EUSCI_B_I2C_SET_DATA_RATE_100KBPS +//! \param byteCounterThreshold sets threshold for automatic STOP or UCSTPIFG +//! \param autoSTOPGeneration sets up the STOP condition generation. +//! Valid values are +//! - \b EUSCI_B_I2C_NO_AUTO_STOP +//! - \b EUSCI_B_I2C_SET_BYTECOUNT_THRESHOLD_FLAG +//! - \b EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD +//! +//! This function initializes operation of the I2C Master block. Upon +//! successful initialization of the I2C block, this function will have set the +//! bus speed for the master; however I2C module is still disabled till +//! I2C_enableModule is invoked +//! +//! Modified bits are \b UCMST,UCMODE_3,\b UCSYNC of \b UCBxCTL0 register +//! \b UCSSELx, \b UCSWRST, of \b UCBxCTL1 register +//! \b UCBxBR0 and \b UCBxBR1 registers +//! \return None. +// +//***************************************************************************** +extern void I2C_initMaster(uint32_t moduleInstance, + const eUSCI_I2C_MasterConfig *config); + +//***************************************************************************** +// +//! Initializes the I2C Slave block. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param slaveAddress 7-bit or 10-bit slave address +//! \param slaveAddressOffset Own address Offset referred to- 'x' value of +//! UCBxI2COAx. Valid values are: +//! - \b EUSCI_B_I2C_OWN_ADDRESS_OFFSET0, +//! - \b EUSCI_B_I2C_OWN_ADDRESS_OFFSET1, +//! - \b EUSCI_B_I2C_OWN_ADDRESS_OFFSET2, +//! - \b EUSCI_B_I2C_OWN_ADDRESS_OFFSET3 +//! \param slaveOwnAddressEnable selects if the specified address is enabled +//! or disabled. Valid values are: +//! - \b EUSCI_B_I2C_OWN_ADDRESS_DISABLE, +//! - \b EUSCI_B_I2C_OWN_ADDRESS_ENABLE +//! +//! This function initializes operation of the I2C as a Slave mode. Upon +//! successful initialization of the I2C blocks, this function will have set +//! the slave address but the I2C module is still disabled till +//! I2C_enableModule is invoked. +//! +//! The parameter slaveAddress is the value that will be compared against the +//! slave address sent by an I2C master. +//! +//! Modified bits are \b UCMODE_3, \b UCSYNC of \b UCBxCTL0 register +//! \b UCSWRST of \b UCBxCTL1 register +//! \b UCBxI2COA register +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_initSlave(uint32_t moduleInstance, uint_fast16_t slaveAddress, + uint_fast8_t slaveAddressOffset, uint32_t slaveOwnAddressEnable); + +//***************************************************************************** +// +//! Enables the I2C block. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! This will enable operation of the I2C block. +//! Modified bits are \b UCSWRST of \b UCBxCTL1 register. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_enableModule(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Disables the I2C block. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! This will disable operation of the I2C block. +//! Modified bits are \b UCSWRST of \b UCBxCTL1 register. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_disableModule(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Sets the address that the I2C Master will place on the bus. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param slaveAddress 7-bit or 10-bit slave address +//! +//! This function will set the address that the I2C Master will place on the +//! bus when initiating a transaction. +//! Modified register is \b UCBxI2CSA register +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_setSlaveAddress(uint32_t moduleInstance, + uint_fast16_t slaveAddress); + +//***************************************************************************** +// +//! Sets the mode of the I2C device +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param mode indicates whether module is in transmit/receive mode +//! - \b EUSCI_B_I2C_TRANSMIT_MODE +//! - \b EUSCI_B_I2C_RECEIVE_MODE [Default value] +//! +//! Modified bits are \b UCTR of \b UCBxCTL1 register +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_setMode(uint32_t moduleInstance, uint_fast8_t mode); + +//***************************************************************************** +// +//! \brief Gets the mode of the I2C device +//! +//! Current I2C transmit/receive mode. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! Modified bits are \b UCTR of \b UCBxCTL1 register. +//! +//! \return None +//! Return one of the following: +//! - \b EUSCI_B_I2C_TRANSMIT_MODE +//! - \b EUSCI_B_I2C_RECEIVE_MODE +//! \n indicating the current mode +// +//***************************************************************************** +extern uint_fast8_t I2C_getMode(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Transmits a byte from the I2C Module. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param transmitData data to be transmitted from the I2C module +//! +//! This function will place the supplied data into I2C transmit data register +//! to start transmission +//! Modified register is \b UCBxTXBUF register +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_slavePutData(uint32_t moduleInstance, uint8_t transmitData); + +//***************************************************************************** +// +//! Receives a byte that has been sent to the I2C Module. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! This function reads a byte of data from the I2C receive data Register. +//! +//! \return Returns the byte received from by the I2C module, cast as an +//! uint8_t. +//! Modified bit is \b UCBxRXBUF register +// +//***************************************************************************** +extern uint8_t I2C_slaveGetData(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Indicates whether or not the I2C bus is busy. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function returns an indication of whether or not the I2C bus is +//! busy.This function checks the status of the bus via UCBBUSY bit in +//! UCBxSTAT register. +//! +//! \return Returns EUSCI_B_I2C_BUS_BUSY if the I2C Master is busy; otherwise, +//! returns EUSCI_B_I2C_BUS_NOT_BUSY. +// +//***************************************************************************** +extern uint8_t I2C_isBusBusy(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Does single byte transmission from Master to Slave +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is the data byte to be transmitted +//! +//! This function is used by the Master module to send a single byte. +//! This function +//! - Sends START +//! - Transmits the byte to the Slave +//! - Sends STOP +//! +//! Modified registers are \b UCBxIE, \b UCBxCTL1, \b UCBxIFG, \b UCBxTXBUF, +//! \b UCBxIE +//! +//! \return none +// +//***************************************************************************** +extern void I2C_masterSendSingleByte(uint32_t moduleInstance, uint8_t txData); + +//***************************************************************************** +// +//! Does single byte transmission from Master to Slave with timeout +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is the data byte to be transmitted +//! \param timeout is the amount of time to wait until giving up +//! +//! This function is used by the Master module to send a single byte. +//! This function +//! - Sends START +//! - Transmits the byte to the Slave +//! - Sends STOP +//! +//! Modified registers are \b UCBxIE, \b UCBxCTL1, \b UCBxIFG, \b UCBxTXBUF, +//! \b UCBxIE +//! +//! \return 0x01 or 0x00URE of the transmission process. +// +//***************************************************************************** +extern bool I2C_masterSendSingleByteWithTimeout(uint32_t moduleInstance, + uint8_t txData, uint32_t timeout); + +//***************************************************************************** +// +//! Starts multi-byte transmission from Master to Slave +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is the first data byte to be transmitted +//! +//! This function is used by the Master module to send a single byte. +//! This function +//! - Sends START +//! - Transmits the first data byte of a multi-byte transmission to the Slave +//! +//! Modified registers are \b UCBxIE, \b UCBxCTL1, \b UCBxIFG, \b UCBxTXBUF, +//! \b UCBxIE +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_masterSendMultiByteStart(uint32_t moduleInstance, + uint8_t txData); + +//***************************************************************************** +// +//! Starts multi-byte transmission from Master to Slave with timeout +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is the first data byte to be transmitted +//! \param timeout is the amount of time to wait until giving up +//! +//! This function is used by the Master module to send a single byte. +//! This function +//! - Sends START +//! - Transmits the first data byte of a multi-byte transmission to the Slave +//! +//! Modified registers are \b UCBxIE, \b UCBxCTL1, \b UCBxIFG, \b UCBxTXBUF, +//! \b UCBxIE +//! +//! \return 0x01 or 0x00URE of the transmission process. +// +//***************************************************************************** +extern bool I2C_masterSendMultiByteStartWithTimeout(uint32_t moduleInstance, + uint8_t txData, uint32_t timeout); + +//***************************************************************************** +// +//! Continues multi-byte transmission from Master to Slave +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is the next data byte to be transmitted +//! +//! This function is used by the Master module continue each byte of a +//! multi-byte trasmission. This function +//! - Transmits each data byte of a multi-byte transmission to the Slave +//! +//! Modified registers are \b UCBxTXBUF +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_masterSendMultiByteNext(uint32_t moduleInstance, + uint8_t txData); + +//***************************************************************************** +// +//! Continues multi-byte transmission from Master to Slave with timeout +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is the next data byte to be transmitted +//! +//! \param timeout is the amount of time to wait until giving up +//! +//! This function is used by the Master module continue each byte of a +//! multi-byte transmission. This function +//! - Transmits each data byte of a multi-byte transmission to the Slave +//! +//! Modified registers are \b UCBxTXBUF +//! +//! \return 0x01 or 0x00URE of the transmission process. +// +//***************************************************************************** +extern bool I2C_masterSendMultiByteNextWithTimeout(uint32_t moduleInstance, + uint8_t txData, uint32_t timeout); + +//***************************************************************************** +// +//! Finishes multi-byte transmission from Master to Slave +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is the last data byte to be transmitted in a multi-byte +//! transmsission +//! +//! This function is used by the Master module to send the last byte and STOP. +//! This function +//! - Transmits the last data byte of a multi-byte transmission to the Slave +//! - Sends STOP +//! +//! Modified registers are \b UCBxTXBUF and \b UCBxCTL1. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_masterSendMultiByteFinish(uint32_t moduleInstance, + uint8_t txData); + +//***************************************************************************** +// +//! Finishes multi-byte transmission from Master to Slave with timeout +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is the last data byte to be transmitted in a multi-byte +//! transmission +//! \param timeout is the amount of time to wait until giving up +//! +//! This function is used by the Master module to send the last byte and STOP. +//! This function +//! - Transmits the last data byte of a multi-byte transmission to the Slave +//! - Sends STOP +//! +//! Modified registers are \b UCBxTXBUF and \b UCBxCTL1. +//! +//! \return 0x01 or 0x00URE of the transmission process. +// +//***************************************************************************** +extern bool I2C_masterSendMultiByteFinishWithTimeout(uint32_t moduleInstance, + uint8_t txData, uint32_t timeout); + +//***************************************************************************** +// +//! Send STOP byte at the end of a multi-byte transmission from Master to Slave +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function is used by the Master module send STOP at the end of a +//! multi-byte transmission +//! +//! This function +//! - Send a STOP after current transmission is complete +//! +//! Modified bits are \b UCTXSTP bit of \b UCBxCTL1. +//! \return None. +// +//***************************************************************************** +extern void I2C_masterSendMultiByteStop(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Send STOP byte at the end of a multi-byte transmission from Master to Slave +//! with timeout +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param timeout is the amount of time to wait until giving up +//! +//! This function is used by the Master module send STOP at the end of a +//! multi-byte transmission +//! +//! This function +//! - Send a STOP after current transmission is complete +//! +//! Modified bits are \b UCTXSTP bit of \b UCBxCTL1. +//! \return 0x01 or 0x00URE of the transmission process. +// +//***************************************************************************** +extern bool I2C_masterSendMultiByteStopWithTimeout(uint32_t moduleInstance, + uint32_t timeout); + +//***************************************************************************** +// +//! Starts reception at the Master end +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function is used by the Master module initiate reception of a single +//! byte. This function +//! - Sends START +//! +//! Modified bits are \b UCTXSTT bit of \b UCBxCTL1. +//! \return None. +// +//***************************************************************************** +extern void I2C_masterReceiveStart(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Starts multi-byte reception at the Master end one byte at a time +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function is used by the Master module to receive each byte of a +//! multi-byte reception +//! This function reads currently received byte +//! +//! Modified register is \b UCBxRXBUF. +//! \return Received byte at Master end. +// +//***************************************************************************** +extern uint8_t I2C_masterReceiveMultiByteNext(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Finishes multi-byte reception at the Master end +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function is used by the Master module to initiate completion of a +//! multi-byte reception +//! This function +//! - Receives the current byte and initiates the STOP from Master to Slave +//! +//! Modified bits are \b UCTXSTP bit of \b UCBxCTL1. +//! +//! \return Received byte at Master end. +// +//***************************************************************************** +extern uint8_t I2C_masterReceiveMultiByteFinish(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Finishes multi-byte reception at the Master end with timeout +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param txData is a pointer to the location to store the received byte at +//! master end +//! \param timeout is the amount of time to wait until giving up +//! +//! This function is used by the Master module to initiate completion of a +//! multi-byte reception +//! This function +//! - Receives the current byte and initiates the STOP from Master to Slave +//! +//! Modified bits are \b UCTXSTP bit of \b UCBxCTL1. +//! +//! \return 0x01 or 0x00URE of the transmission process. +// +//***************************************************************************** +extern bool I2C_masterReceiveMultiByteFinishWithTimeout(uint32_t moduleInstance, + uint8_t *txData, uint32_t timeout); + +//***************************************************************************** +// +//! Sends the STOP at the end of a multi-byte reception at the Master end +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function is used by the Master module to initiate STOP +//! +//! Modified bits are UCTXSTP bit of UCBxCTL1. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_masterReceiveMultiByteStop(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Does single byte reception from the slave +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! This function is used by the Master module to receive a single byte. +//! This function: +//! - Sends START and STOP +//! - Waits for data reception +//! - Receives one byte from the Slave +//! +//! Modified registers are \b UCBxIE, \b UCBxCTL1, \b UCBxIFG, \b UCBxTXBUF, +//! \b UCBxIE +//! +//! \return The byte that has been received from the slave +// +//***************************************************************************** +extern uint8_t I2C_masterReceiveSingleByte(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Receives a byte that has been sent to the I2C Master Module. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function reads a byte of data from the I2C receive data Register. +//! +//! \return Returns the byte received from by the I2C module, cast as an +//! uint8_t. +// +//***************************************************************************** +extern uint8_t I2C_masterReceiveSingle(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Returns the address of the RX Buffer of the I2C for the DMA module. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! Returns the address of the I2C RX Buffer. This can be used in conjunction +//! with the DMA to store the received data directly to memory. +//! +//! \return NONE +// +//***************************************************************************** +extern uint32_t I2C_getReceiveBufferAddressForDMA(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Returns the address of the TX Buffer of the I2C for the DMA module. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! Returns the address of the I2C TX Buffer. This can be used in conjunction +//! with the DMA to obtain transmitted data directly from memory. +//! +//! \return NONE +// +//***************************************************************************** +extern uint32_t I2C_getTransmitBufferAddressForDMA(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Indicates whether STOP got sent. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function returns an indication of whether or not STOP got sent +//! This function checks the status of the bus via UCTXSTP bit in +//! UCBxCTL1 register. +//! +//! \return Returns EUSCI_B_I2C_STOP_SEND_COMPLETE if the I2C Master +//! finished sending STOP; otherwise, returns EUSCI_B_I2C_SENDING_STOP. +// +//***************************************************************************** +extern uint8_t I2C_masterIsStopSent(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Indicates whether Start got sent. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function returns an indication of whether or not Start got sent +//! This function checks the status of the bus via UCTXSTT bit in +//! UCBxCTL1 register. +//! +//! \return Returns true if the START has been sent, false if it is sending +// +//***************************************************************************** +extern bool I2C_masterIsStartSent(uint32_t moduleInstance); + +//***************************************************************************** +// +//! This function is used by the Master module to initiate START +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! This function is used by the Master module to initiate STOP +//! +//! Modified bits are UCTXSTT bit of UCBxCTLW0. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_masterSendStart(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Enables Multi Master Mode +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! At the end of this function, the I2C module is still disabled till +//! I2C_enableModule is invoked +//! +//! Modified bits are \b UCSWRST of \b OFS_UCBxCTLW0, \b UCMM bit of +//! \b UCBxCTLW0 +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_enableMultiMasterMode(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Disables Multi Master Mode +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! +//! At the end of this function, the I2C module is still disabled till +//! I2C_enableModule is invoked +//! +//! Modified bits are \b UCSWRST of \b OFS_UCBxCTLW0, \b UCMM bit of +//! \b UCBxCTLW0 +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_disableMultiMasterMode(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Enables individual I2C interrupt sources. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param mask is the bit mask of the interrupt sources to +//! be enabled. +//! +//! Enables the indicated I2C interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. +//! +//! The mask parameter is the logical OR of any of the following: +//! +//! - \b EUSCI_B_I2C_STOP_INTERRUPT - STOP condition interrupt +//! - \b EUSCI_B_I2C_START_INTERRUPT - START condition interrupt +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT0 - Transmit interrupt0 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT1 - Transmit interrupt1 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT2 - Transmit interrupt2 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT3 - Transmit interrupt3 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT0 - Receive interrupt0 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT1 - Receive interrupt1 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT2 - Receive interrupt2 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT3 - Receive interrupt3 +//! - \b EUSCI_B_I2C_NAK_INTERRUPT - Not-acknowledge interrupt +//! - \b EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT - Arbitration lost interrupt +//! - \b EUSCI_B_I2C_BIT9_POSITION_INTERRUPT - Bit position 9 interrupt enable +//! - \b EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT - Clock low timeout interrupt +//! enable +//! - \b EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT - Byte counter interrupt enable +//! +//! Modified registers are UCBxIFG and OFS_UCBxIE. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_enableInterrupt(uint32_t moduleInstance, uint_fast16_t mask); + +//***************************************************************************** +// +//! Disables individual I2C interrupt sources. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param mask is the bit mask of the interrupt sources to be +//! disabled. +//! +//! Disables the indicated I2C interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. +//! +//! The mask parameter is the logical OR of any of the following: +//! +//! - \b EUSCI_B_I2C_STOP_INTERRUPT - STOP condition interrupt +//! - \b EUSCI_B_I2C_START_INTERRUPT - START condition interrupt +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT0 - Transmit interrupt0 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT1 - Transmit interrupt1 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT2 - Transmit interrupt2 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT3 - Transmit interrupt3 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT0 - Receive interrupt0 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT1 - Receive interrupt1 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT2 - Receive interrupt2 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT3 - Receive interrupt3 +//! - \b EUSCI_B_I2C_NAK_INTERRUPT - Not-acknowledge interrupt +//! - \b EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT - Arbitration lost interrupt +//! - \b EUSCI_B_I2C_BIT9_POSITION_INTERRUPT - Bit position 9 interrupt enable +//! - \b EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT - Clock low timeout interrupt +//! enable +//! - \b EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT - Byte counter interrupt enable +//! +//! Modified register is \b UCBxIE. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_disableInterrupt(uint32_t moduleInstance, uint_fast16_t mask); + +//***************************************************************************** +// +//! Clears I2C interrupt sources. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param mask is a bit mask of the interrupt sources to be cleared. +//! +//! The I2C interrupt source is cleared, so that it no longer asserts. +//! The highest interrupt flag is automatically cleared when an interrupt vector +//! generator is used. +//! +//! The mask parameter has the same definition as the mask +//! parameter to I2C_enableInterrupt(). +//! +//! Modified register is \b UCBxIFG. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_clearInterruptFlag(uint32_t moduleInstance, uint_fast16_t mask); + +//***************************************************************************** +// +//! Gets the current I2C interrupt status. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! \param mask is the masked interrupt flag status to be returned. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_B_I2C_NAK_INTERRUPT - Not-acknowledge interrupt +//! - \b EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT - Arbitration lost +//! interrupt +//! - \b EUSCI_B_I2C_STOP_INTERRUPT - STOP condition interrupt +//! - \b EUSCI_B_I2C_START_INTERRUPT - START condition interrupt +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT0 - Transmit interrupt0 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT1 - Transmit interrupt1 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT2 - Transmit interrupt2 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT3 - Transmit interrupt3 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT0 - Receive interrupt0 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT1 - Receive interrupt1 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT2 - Receive interrupt2 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT3 - Receive interrupt3 +//! - \b EUSCI_B_I2C_BIT9_POSITION_INTERRUPT - Bit position 9 interrupt +//! - \b EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT - Clock low timeout +//! interrupt enable +//! - \b EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT - Byte counter interrupt +//! enable +//! +//! \return the masked status of the interrupt flag +//! - \b EUSCI_B_I2C_STOP_INTERRUPT - STOP condition interrupt +//! - \b EUSCI_B_I2C_START_INTERRUPT - START condition interrupt +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT0 - Transmit interrupt0 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT1 - Transmit interrupt1 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT2 - Transmit interrupt2 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT3 - Transmit interrupt3 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT0 - Receive interrupt0 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT1 - Receive interrupt1 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT2 - Receive interrupt2 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT3 - Receive interrupt3 +//! - \b EUSCI_B_I2C_NAK_INTERRUPT - Not-acknowledge interrupt +//! - \b EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT - Arbitration lost interrupt +//! - \b EUSCI_B_I2C_BIT9_POSITION_INTERRUPT - Bit position 9 interrupt enable +//! - \b EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT - Clock low timeout interrupt +//! enable +//! - \b EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT - Byte counter interrupt enable +// +//***************************************************************************** +extern uint_fast16_t I2C_getInterruptStatus(uint32_t moduleInstance, uint16_t mask); + +//***************************************************************************** +// +//! Gets the current I2C interrupt status masked with the enabled interrupts. +//! This function is useful to call in ISRs to get a list of pending interrupts +//! that are actually enabled and could have caused the ISR. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \return the masked status of the interrupt flag +//! - \b EUSCI_B_I2C_STOP_INTERRUPT - STOP condition interrupt +//! - \b EUSCI_B_I2C_START_INTERRUPT - START condition interrupt +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT0 - Transmit interrupt0 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT1 - Transmit interrupt1 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT2 - Transmit interrupt2 +//! - \b EUSCI_B_I2C_TRANSMIT_INTERRUPT3 - Transmit interrupt3 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT0 - Receive interrupt0 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT1 - Receive interrupt1 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT2 - Receive interrupt2 +//! - \b EUSCI_B_I2C_RECEIVE_INTERRUPT3 - Receive interrupt3 +//! - \b EUSCI_B_I2C_NAK_INTERRUPT - Not-acknowledge interrupt +//! - \b EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT - Arbitration lost interrupt +//! - \b EUSCI_B_I2C_BIT9_POSITION_INTERRUPT - Bit position 9 interrupt enable +//! - \b EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT - Clock low timeout interrupt +//! enable +//! - \b EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT - Byte counter interrupt enable +// +//***************************************************************************** +extern uint_fast16_t I2C_getEnabledInterruptStatus(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Registers an interrupt handler for I2C interrupts. +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param intHandler is a pointer to the function to be called when the +//! timer capture compare interrupt occurs. +//! +//! This function registers the handler to be called when an I2C +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific I2C interrupts must be enabled +//! via I2C_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via I2C_clearInterruptFlag(). +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_registerInterrupt(uint32_t moduleInstance, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the timer +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! This function unregisters the handler to be called when timer +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_unregisterInterrupt(uint32_t moduleInstance); + + +//***************************************************************************** +// +//! This function is used by the slave to send a NAK out over the I2C line +//! +//! \param moduleInstance is the instance of the eUSCI B (I2C) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//!
It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \return None. +// +//***************************************************************************** +extern void I2C_slaveSendNAK(uint32_t moduleInstance); + +/* Backwards Compatibility Layer */ +#define EUSCI_B_I2C_slaveInit I2C_initSlave +#define EUSCI_B_I2C_enable I2C_enableModule +#define EUSCI_B_I2C_disable I2C_disableModule +#define EUSCI_B_I2C_setSlaveAddress I2C_setSlaveAddress +#define EUSCI_B_I2C_setMode I2C_setMode +#define EUSCI_B_I2C_getMode I2C_getMode +#define EUSCI_B_I2C_slaveDataPut I2C_slavePutData +#define EUSCI_B_I2C_slaveDataGet I2C_slaveGetData +#define EUSCI_B_I2C_isBusBusy I2C_isBusBusy +#define EUSCI_B_I2C_masterIsStopSent I2C_masterIsStopSent +#define EUSCI_B_I2C_masterIsStartSent I2C_masterIsStartSent +#define EUSCI_B_I2C_enableInterrupt I2C_enableInterrupt +#define EUSCI_B_I2C_disableInterrupt I2C_disableInterrupt +#define EUSCI_B_I2C_clearInterruptFlag I2C_clearInterruptFlag +#define EUSCI_B_I2C_getInterruptStatus I2C_getEnabledInterruptStatus +#define EUSCI_B_I2C_masterSendSingleByte I2C_masterSendSingleByte +#define EUSCI_B_I2C_masterReceiveSingleByte I2C_masterReceiveSingleByte +#define EUSCI_B_I2C_masterSendSingleByteWithTimeout I2C_masterSendSingleByteWithTimeout +#define EUSCI_B_I2C_masterMultiByteSendStart I2C_masterSendMultiByteStart +#define EUSCI_B_I2C_masterMultiByteSendStartWithTimeout I2C_masterSendMultiByteStartWithTimeout +#define EUSCI_B_I2C_masterMultiByteSendNext I2C_masterSendMultiByteNext +#define EUSCI_B_I2C_masterMultiByteSendNextWithTimeout I2C_masterSendMultiByteNextWithTimeout +#define EUSCI_B_I2C_masterMultiByteSendFinish I2C_masterSendMultiByteFinish +#define EUSCI_B_I2C_masterMultiByteSendFinishWithTimeout I2C_masterSendMultiByteFinishWithTimeout +#define EUSCI_B_I2C_masterSendStart I2C_masterSendStart +#define EUSCI_B_I2C_masterMultiByteSendStop I2C_masterSendMultiByteStop +#define EUSCI_B_I2C_masterMultiByteSendStopWithTimeout I2C_masterSendMultiByteStopWithTimeout +#define EUSCI_B_I2C_masterReceiveStart I2C_masterReceiveStart +#define EUSCI_B_I2C_masterMultiByteReceiveNext I2C_masterReceiveMultiByteNext +#define EUSCI_B_I2C_masterMultiByteReceiveFinish I2C_masterReceiveMultiByteFinish +#define EUSCI_B_I2C_masterMultiByteReceiveFinishWithTimeout I2C_masterReceiveMultiByteFinishWithTimeout +#define EUSCI_B_I2C_masterMultiByteReceiveStop I2C_masterReceiveMultiByteStop +#define EUSCI_B_I2C_enableMultiMasterMode I2C_enableMultiMasterMode +#define EUSCI_B_I2C_disableMultiMasterMode I2C_disableMultiMasterMode +#define EUSCI_B_I2C_masterSingleReceive I2C_masterReceiveSingle +#define EUSCI_B_I2C_getReceiveBufferAddressForDMA I2C_getReceiveBufferAddressForDMA +#define EUSCI_B_I2C_getTransmitBufferAddressForDMA I2C_getTransmitBufferAddressForDMA + + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif /* I2C_H_ */ + diff --git a/example/rt_msp432/MSP432P4xx/interrupt.c b/example/rt_msp432/MSP432P4xx/interrupt.c new file mode 100644 index 0000000..62bf55c --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/interrupt.c @@ -0,0 +1,538 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include + +/* DriverLib Includes */ +#include +#include +#include +#include + +//***************************************************************************** +// +// This is a mapping between priority grouping encodings and the number of +// preemption priority bits. +// +//***************************************************************************** +static const uint32_t g_pulPriority[] = +{ NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6, +NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4, +NVIC_APINT_PRIGROUP_5_3, NVIC_APINT_PRIGROUP_6_2, +NVIC_APINT_PRIGROUP_7_1 }; + +//***************************************************************************** +// +// This is a mapping between interrupt number and the register that contains +// the priority encoding for that interrupt. +// +//***************************************************************************** +static const uint32_t g_pulRegs[] = +{ 0, NVIC_SYS_PRI1_R, NVIC_SYS_PRI2_R, NVIC_SYS_PRI3_R, NVIC_PRI0_R, +NVIC_PRI1_R, NVIC_PRI2_R, NVIC_PRI3_R, NVIC_PRI4_R, NVIC_PRI5_R, +NVIC_PRI6_R, NVIC_PRI7_R, NVIC_PRI8_R, NVIC_PRI9_R, NVIC_PRI10_R, +NVIC_PRI11_R, NVIC_PRI12_R, NVIC_PRI13_R, NVIC_PRI14_R, NVIC_PRI15_R }; + +//***************************************************************************** +// +// This is a mapping between interrupt number (for the peripheral interrupts +// only) and the register that contains the interrupt enable for that +// interrupt. +// +//***************************************************************************** +static const uint32_t g_pulEnRegs[] = +{ NVIC_EN0_R, NVIC_EN1_R }; + +//***************************************************************************** +// +// This is a mapping between interrupt number (for the peripheral interrupts +// only) and the register that contains the interrupt disable for that +// interrupt. +// +//***************************************************************************** +static const uint32_t g_pulDisRegs[] = +{ NVIC_DIS0_R, NVIC_DIS1_R }; + +//***************************************************************************** +// +// This is a mapping between interrupt number (for the peripheral interrupts +// only) and the register that contains the interrupt pend for that interrupt. +// +//***************************************************************************** +static const uint32_t g_pulPendRegs[] = +{ NVIC_PEND0_R, NVIC_PEND1_R }; + +//***************************************************************************** +// +// This is a mapping between interrupt number (for the peripheral interrupts +// only) and the register that contains the interrupt unpend for that +// interrupt. +// +//***************************************************************************** +static const uint32_t g_pulUnpendRegs[] = +{ NVIC_UNPEND0_R, NVIC_UNPEND1_R }; + +//***************************************************************************** +// +//! \internal +//! The default interrupt handler. +//! +//! This is the default interrupt handler for all interrupts. It simply loops +//! forever so that the system state is preserved for observation by a +//! debugger. Since interrupts should be disabled before unregistering the +//! corresponding handler, this should never be called. +//! +//! \return None. +// +//***************************************************************************** +static void IntDefaultHandler(void) +{ + // + // Go into an infinite loop. + // + while (1) + { + } +} + +//***************************************************************************** +// +// The processor vector table. +// +// This contains a list of the handlers for the various interrupt sources in +// the system. The layout of this list is defined by the hardware; assertion +// of an interrupt causes the processor to start executing directly at the +// address given in the corresponding location in this list. +// +//***************************************************************************** +#if defined(ewarm) +#pragma data_alignment=1024 +static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS+1])(void) @ "VTABLE"; +#elif defined(ccs) +#pragma DATA_ALIGN(g_pfnRAMVectors, 1024) +#pragma DATA_SECTION(g_pfnRAMVectors, ".vtable") +void (*g_pfnRAMVectors[NUM_INTERRUPTS + 1])(void); +#else +static __attribute__((section("vtable"))) +void (*g_pfnRAMVectors[NUM_INTERRUPTS+1])(void) __attribute__((aligned(1024))); +#endif + +bool Interrupt_enableMaster(void) +{ + // + // Enable processor interrupts. + // + return (CPU_cpsie()); +} + +bool Interrupt_disableMaster(void) +{ + // + // Disable processor interrupts. + // + return (CPU_cpsid()); +} + +void Interrupt_registerInterrupt(uint32_t interruptNumber, + void (*intHandler)(void)) +{ + uint32_t ulIdx, ulValue; + + // + // Check the arguments. + // + ASSERT(interruptNumber < (NUM_INTERRUPTS+1)); + + // + // Make sure that the RAM vector table is correctly aligned. + // + ASSERT(((uint32_t) g_pfnRAMVectors & 0x000000ff) == 0); + + // + // See if the RAM vector table has been initialized. + // + if (SCB->VTOR != (uint32_t) g_pfnRAMVectors) + { + // + // Copy the vector table from the beginning of FLASH to the RAM vector + // table. + // + ulValue = SCB->VTOR; + for (ulIdx = 0; ulIdx < (NUM_INTERRUPTS + 1); ulIdx++) + { + g_pfnRAMVectors[ulIdx] = (void (*)(void)) HWREG32( + (ulIdx * 4) + ulValue); + } + + // + // Point the NVIC at the RAM vector table. + // + SCB->VTOR = (uint32_t) g_pfnRAMVectors; + } + + // + // Save the interrupt handler. + // + g_pfnRAMVectors[interruptNumber] = intHandler; +} + +void Interrupt_unregisterInterrupt(uint32_t interruptNumber) +{ + // + // Check the arguments. + // + ASSERT(interruptNumber < (NUM_INTERRUPTS+1)); + + // + // Reset the interrupt handler. + // + g_pfnRAMVectors[interruptNumber] = IntDefaultHandler; +} + +void Interrupt_setPriorityGrouping(uint32_t bits) +{ + // + // Check the arguments. + // + ASSERT(bits < NUM_PRIORITY); + + // + // Set the priority grouping. + // + SCB->AIRCR = SCB_AIRCR_VECTKEY_Msk | g_pulPriority[bits]; +} + +uint32_t Interrupt_getPriorityGrouping(void) +{ + uint32_t ulLoop, ulValue; + + // + // Read the priority grouping. + // + ulValue = SCB->AIRCR & NVIC_APINT_PRIGROUP_M; + + // + // Loop through the priority grouping values. + // + for (ulLoop = 0; ulLoop < NUM_PRIORITY; ulLoop++) + { + // + // Stop looping if this value matches. + // + if (ulValue == g_pulPriority[ulLoop]) + { + break; + } + } + + // + // Return the number of priority bits. + // + return (ulLoop); +} + +void Interrupt_setPriority(uint32_t interruptNumber, uint8_t priority) +{ + uint32_t ulTemp; + + // + // Check the arguments. + // + ASSERT((interruptNumber >= 4) && (interruptNumber < (NUM_INTERRUPTS+1))); + + // + // Set the interrupt priority. + // + ulTemp = HWREG32(g_pulRegs[interruptNumber >> 2]); + ulTemp &= ~(0xFF << (8 * (interruptNumber & 3))); + ulTemp |= priority << (8 * (interruptNumber & 3)); + HWREG32 (g_pulRegs[interruptNumber >> 2]) = ulTemp; +} + +uint8_t Interrupt_getPriority(uint32_t interruptNumber) +{ + // + // Check the arguments. + // + ASSERT((interruptNumber >= 4) && (interruptNumber < (NUM_INTERRUPTS+1))); + + // + // Return the interrupt priority. + // + return ((HWREG32(g_pulRegs[interruptNumber >> 2]) + >> (8 * (interruptNumber & 3))) & 0xFF); +} + +void Interrupt_enableInterrupt(uint32_t interruptNumber) +{ + // + // Check the arguments. + // + ASSERT(interruptNumber < (NUM_INTERRUPTS+1)); + + // + // Determine the interrupt to enable. + // + if (interruptNumber == FAULT_MPU) + { + // + // Enable the MemManage interrupt. + // + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; + } else if (interruptNumber == FAULT_BUS) + { + // + // Enable the bus fault interrupt. + // + SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk; + } else if (interruptNumber == FAULT_USAGE) + { + // + // Enable the usage fault interrupt. + // + SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk; + } else if (interruptNumber == FAULT_SYSTICK) + { + // + // Enable the System Tick interrupt. + // + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + } else if (interruptNumber >= 16) + { + // + // Enable the general interrupt. + // + HWREG32 (g_pulEnRegs[(interruptNumber - 16) / 32]) = 1 + << ((interruptNumber - 16) & 31); + } +} + +void Interrupt_disableInterrupt(uint32_t interruptNumber) +{ + // + // Check the arguments. + // + ASSERT(interruptNumber < (NUM_INTERRUPTS+1)); + + // + // Determine the interrupt to disable. + // + if (interruptNumber == FAULT_MPU) + { + // + // Disable the MemManage interrupt. + // + SCB->SHCSR &= ~(SCB_SHCSR_MEMFAULTENA_Msk); + } else if (interruptNumber == FAULT_BUS) + { + // + // Disable the bus fault interrupt. + // + SCB->SHCSR &= ~(SCB_SHCSR_BUSFAULTENA_Msk); + } else if (interruptNumber == FAULT_USAGE) + { + // + // Disable the usage fault interrupt. + // + SCB->SHCSR &= ~(SCB_SHCSR_USGFAULTENA_Msk); + } else if (interruptNumber == FAULT_SYSTICK) + { + // + // Disable the System Tick interrupt. + // + SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk); + } else if (interruptNumber >= 16) + { + // + // Disable the general interrupt. + // + HWREG32 (g_pulDisRegs[(interruptNumber - 16) / 32]) = 1 + << ((interruptNumber - 16) & 31); + } +} + +bool Interrupt_isEnabled(uint32_t interruptNumber) +{ + uint32_t ulRet; + + // + // Check the arguments. + // + ASSERT(interruptNumber < (NUM_INTERRUPTS+1)); + + // + // Initialize the return value. + // + ulRet = 0; + + // + // Determine the interrupt to disable. + // + if (interruptNumber == FAULT_MPU) + { + // + // Check the MemManage interrupt. + // + ulRet = SCB->SHCSR & SCB_SHCSR_MEMFAULTENA_Msk; + } else if (interruptNumber == FAULT_BUS) + { + // + // Check the bus fault interrupt. + // + ulRet = SCB->SHCSR & SCB_SHCSR_BUSFAULTENA_Msk; + } else if (interruptNumber == FAULT_USAGE) + { + // + // Check the usage fault interrupt. + // + ulRet = SCB->SHCSR & SCB_SHCSR_USGFAULTENA_Msk; + } else if (interruptNumber == FAULT_SYSTICK) + { + // + // Check the System Tick interrupt. + // + ulRet = SysTick->CTRL & SysTick_CTRL_ENABLE_Msk; + } else if (interruptNumber >= 16) + { + // + // Check the general interrupt. + // + ulRet = HWREG32(g_pulEnRegs[(interruptNumber - 16) / 32]) + & (1 << ((interruptNumber - 16) & 31)); + } + return (ulRet); +} + +void Interrupt_pendInterrupt(uint32_t interruptNumber) +{ + // + // Check the arguments. + // + ASSERT(interruptNumber < (NUM_INTERRUPTS+1)); + + // + // Determine the interrupt to pend. + // + if (interruptNumber == FAULT_NMI) + { + // + // Pend the NMI interrupt. + // + SCB->ICSR |= SCB_ICSR_NMIPENDSET_Msk; + } else if (interruptNumber == FAULT_PENDSV) + { + // + // Pend the PendSV interrupt. + // + SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; + } else if (interruptNumber == FAULT_SYSTICK) + { + // + // Pend the SysTick interrupt. + // + SCB->ICSR |= SCB_ICSR_PENDSTSET_Msk; + } else if (interruptNumber >= 16) + { + // + // Pend the general interrupt. + // + HWREG32 (g_pulPendRegs[(interruptNumber - 16) / 32]) = 1 + << ((interruptNumber - 16) & 31); + } +} + +void Interrupt_unpendInterrupt(uint32_t interruptNumber) +{ + // + // Check the arguments. + // + ASSERT(interruptNumber < (NUM_INTERRUPTS+1)); + + // + // Determine the interrupt to unpend. + // + if (interruptNumber == FAULT_PENDSV) + { + // + // Unpend the PendSV interrupt. + // + SCB->ICSR |= SCB_ICSR_PENDSVCLR_Msk; + } else if (interruptNumber == FAULT_SYSTICK) + { + // + // Unpend the SysTick interrupt. + // + SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; + } else if (interruptNumber >= 16) + { + // + // Unpend the general interrupt. + // + HWREG32 (g_pulUnpendRegs[(interruptNumber - 16) / 32]) = 1 + << ((interruptNumber - 16) & 31); + } +} + +void Interrupt_setPriorityMask(uint8_t priorityMask) +{ + CPU_basepriSet(priorityMask); +} + +uint8_t Interrupt_getPriorityMask(void) +{ + return (CPU_basepriGet()); +} + +void Interrupt_setVectorTableAddress(uint32_t addr) +{ + SCB->VTOR = addr; +} + +uint32_t Interrupt_getVectorTableAddress(void) +{ + return SCB->VTOR; +} + +void Interrupt_enableSleepOnIsrExit(void) +{ + SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; +} + +void Interrupt_disableSleepOnIsrExit(void) +{ + SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; +} diff --git a/example/rt_msp432/MSP432P4xx/interrupt.h b/example/rt_msp432/MSP432P4xx/interrupt.h new file mode 100644 index 0000000..ec2a71e --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/interrupt.h @@ -0,0 +1,580 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __INTERRUPT_H__ +#define __INTERRUPT_H__ + +//***************************************************************************** +// +//! \addtogroup interrupt_api +//! @{ +// +//***************************************************************************** + + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +/****************************************************************************** +* NVIC interrupts * +******************************************************************************/ +/* System exceptions */ +#define FAULT_NMI ( 2) /* NMI fault */ +#define FAULT_HARD ( 3) /* Hard fault */ +#define FAULT_MPU ( 4) /* MPU fault */ +#define FAULT_BUS ( 5) /* Bus fault */ +#define FAULT_USAGE ( 6) /* Usage fault */ +#define FAULT_SVCALL (11) /* SVCall */ +#define FAULT_DEBUG (12) /* Debug monitor */ +#define FAULT_PENDSV (14) /* PendSV */ +#define FAULT_SYSTICK (15) /* System Tick */ + +/* External interrupts */ +#define INT_PSS (16) /* PSS IRQ */ +#define INT_CS (17) /* CS IRQ */ +#define INT_PCM (18) /* PCM IRQ */ +#define INT_WDT_A (19) /* WDT_A IRQ */ +#define INT_FPU (20) /* FPU IRQ */ +#define INT_FLCTL (21) /* FLCTL IRQ */ +#define INT_COMP_E0 (22) /* COMP_E0 IRQ */ +#define INT_COMP_E1 (23) /* COMP_E1 IRQ */ +#define INT_TA0_0 (24) /* TA0_0 IRQ */ +#define INT_TA0_N (25) /* TA0_N IRQ */ +#define INT_TA1_0 (26) /* TA1_0 IRQ */ +#define INT_TA1_N (27) /* TA1_N IRQ */ +#define INT_TA2_0 (28) /* TA2_0 IRQ */ +#define INT_TA2_N (29) /* TA2_N IRQ */ +#define INT_TA3_0 (30) /* TA3_0 IRQ */ +#define INT_TA3_N (31) /* TA3_N IRQ */ +#define INT_EUSCIA0 (32) /* EUSCIA0 IRQ */ +#define INT_EUSCIA1 (33) /* EUSCIA1 IRQ */ +#define INT_EUSCIA2 (34) /* EUSCIA2 IRQ */ +#define INT_EUSCIA3 (35) /* EUSCIA3 IRQ */ +#define INT_EUSCIB0 (36) /* EUSCIB0 IRQ */ +#define INT_EUSCIB1 (37) /* EUSCIB1 IRQ */ +#define INT_EUSCIB2 (38) /* EUSCIB2 IRQ */ +#define INT_EUSCIB3 (39) /* EUSCIB3 IRQ */ +#define INT_ADC14 (40) /* ADC14 IRQ */ +#define INT_T32_INT1 (41) /* T32_INT1 IRQ */ +#define INT_T32_INT2 (42) /* T32_INT2 IRQ */ +#define INT_T32_INTC (43) /* T32_INTC IRQ */ +#define INT_AES256 (44) /* AES256 IRQ */ +#define INT_RTC_C (45) /* RTC_C IRQ */ +#define INT_DMA_ERR (46) /* DMA_ERR IRQ */ +#define INT_DMA_INT3 (47) /* DMA_INT3 IRQ */ +#define INT_DMA_INT2 (48) /* DMA_INT2 IRQ */ +#define INT_DMA_INT1 (49) /* DMA_INT1 IRQ */ +#define INT_DMA_INT0 (50) /* DMA_INT0 IRQ */ +#define INT_PORT1 (51) /* PORT1 IRQ */ +#define INT_PORT2 (52) /* PORT2 IRQ */ +#define INT_PORT3 (53) /* PORT3 IRQ */ +#define INT_PORT4 (54) /* PORT4 IRQ */ +#define INT_PORT5 (55) /* PORT5 IRQ */ +#define INT_PORT6 (56) /* PORT6 IRQ */ + +#define NUM_INTERRUPTS (56) +//***************************************************************************** +// +// Macro to generate an interrupt priority mask based on the number of bits +// of priority supported by the hardware. +// +//***************************************************************************** +#define INT_PRIORITY_MASK ((0xFF << (8 - NUM_PRIORITY_BITS)) & 0xFF) +#define NUM_PRIORITY 8 + +#define NVIC_APINT_PRIGROUP_M 0x00000700 // Interrupt Priority Grouping +#define NVIC_APINT_PRIGROUP_7_1 0x00000000 // Priority group 7.1 split +#define NVIC_APINT_PRIGROUP_6_2 0x00000100 // Priority group 6.2 split +#define NVIC_APINT_PRIGROUP_5_3 0x00000200 // Priority group 5.3 split +#define NVIC_APINT_PRIGROUP_4_4 0x00000300 // Priority group 4.4 split +#define NVIC_APINT_PRIGROUP_3_5 0x00000400 // Priority group 3.5 split +#define NVIC_APINT_PRIGROUP_2_6 0x00000500 // Priority group 2.6 split +#define NVIC_APINT_PRIGROUP_1_7 0x00000600 // Priority group 1.7 split +#define NVIC_APINT_PRIGROUP_0_8 0x00000700 // Priority group 0.8 split +#define NVIC_SYS_PRI1_R 0xE000ED18 // System Handler Priority 1 +#define NVIC_SYS_PRI2_R 0xE000ED1C // System Handler Priority 2 +#define NVIC_SYS_PRI3_R 0xE000ED20 // System Handler Priority 3 +#define NVIC_PRI0_R 0xE000E400 // Interrupt 0-3 Priority +#define NVIC_PRI1_R 0xE000E404 // Interrupt 4-7 Priority +#define NVIC_PRI2_R 0xE000E408 // Interrupt 8-11 Priority +#define NVIC_PRI3_R 0xE000E40C // Interrupt 12-15 Priority +#define NVIC_PRI4_R 0xE000E410 // Interrupt 16-19 Priority +#define NVIC_PRI5_R 0xE000E414 // Interrupt 20-23 Priority +#define NVIC_PRI6_R 0xE000E418 // Interrupt 24-27 Priority +#define NVIC_PRI7_R 0xE000E41C // Interrupt 28-31 Priority +#define NVIC_PRI8_R 0xE000E420 // Interrupt 32-35 Priority +#define NVIC_PRI9_R 0xE000E424 // Interrupt 36-39 Priority +#define NVIC_PRI10_R 0xE000E428 // Interrupt 40-43 Priority +#define NVIC_PRI11_R 0xE000E42C // Interrupt 44-47 Priority +#define NVIC_PRI12_R 0xE000E430 // Interrupt 48-51 Priority +#define NVIC_PRI13_R 0xE000E434 // Interrupt 52-55 Priority +#define NVIC_PRI14_R 0xE000E438 // Interrupt 56-59 Priority +#define NVIC_PRI15_R 0xE000E43C // Interrupt 60-63 Priority +#define NVIC_EN0_R 0xE000E100 // Interrupt 0-31 Set Enable +#define NVIC_EN1_R 0xE000E104 // Interrupt 32-54 Set Enable +#define NVIC_DIS0_R 0xE000E180 // Interrupt 0-31 Clear Enable +#define NVIC_DIS1_R 0xE000E184 // Interrupt 32-54 Clear Enable +#define NVIC_PEND0_R 0xE000E200 // Interrupt 0-31 Set Pending +#define NVIC_PEND1_R 0xE000E204 // Interrupt 32-54 Set Pending +#define NVIC_UNPEND0_R 0xE000E280 // Interrupt 0-31 Clear Pending +#define NVIC_UNPEND1_R 0xE000E284 // Interrupt 32-54 Clear Pending +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! Enables the processor interrupt. +//! +//! This function allows the processor to respond to interrupts. This function +//! does not affect the set of interrupts enabled in the interrupt controller; +//! it just gates the single interrupt from the controller to the processor. +//! +//! \return Returns \b true if interrupts were disabled when the function was +//! called or \b false if they were initially enabled. +// +//***************************************************************************** +extern bool Interrupt_enableMaster(void); + +//***************************************************************************** +// +//! Disables the processor interrupt. +//! +//! This function prevents the processor from receiving interrupts. This +//! function does not affect the set of interrupts enabled in the interrupt +//! controller; it just gates the single interrupt from the controller to the +//! processor. +//! +//! \return Returns \b true if interrupts were already disabled when the +//! function was called or \b false if they were initially enabled. +// +//***************************************************************************** +extern bool Interrupt_disableMaster(void); + +//***************************************************************************** +// +//! Registers a function to be called when an interrupt occurs. +//! +//! \param interruptNumber specifies the interrupt in question. +//! \param intHandler is a pointer to the function to be called. +//! +//! \note The use of this function (directly or indirectly via a peripheral +//! driver interrupt register function) moves the interrupt vector table from +//! flash to SRAM. Therefore, care must be taken when linking the application +//! to ensure that the SRAM vector table is located at the beginning of SRAM; +//! otherwise the NVIC does not look in the correct portion of memory for the +//! vector table (it requires the vector table be on a 1 kB memory alignment). +//! Normally, the SRAM vector table is so placed via the use of linker scripts. +//! See the discussion of compile-time versus run-time interrupt handler +//! registration in the introduction to this chapter. +//! +//! \note This function is only used if the customer wants to specify the +//! interrupt handler at run time. In most cases, this is done through means +//! of the user setting the ISR function pointer in the startup file. Refer +//! Refer to the Module Operation section for more details. +//! +//! See \link Interrupt_enableInterrupt \endlink for details about the interrupt +//! parameter +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_registerInterrupt(uint32_t interruptNumber, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the function to be called when an interrupt occurs. +//! +//! \param interruptNumber specifies the interrupt in question. +//! +//! This function is used to indicate that no handler should be called when the +//! given interrupt is asserted to the processor. The interrupt source is +//! automatically disabled (via Interrupt_disableInterrupt()) if necessary. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! See \link Interrupt_enableInterrupt \endlink for details about the interrupt +//! parameter +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_unregisterInterrupt(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Sets the priority grouping of the interrupt controller. +//! +//! \param bits specifies the number of bits of preemptable priority. +//! +//! This function specifies the split between preemptable priority levels and +//! sub-priority levels in the interrupt priority specification. The range of +//! the grouping values are dependent upon the hardware implementation; on +//! the MSP432 family, three bits are available for hardware interrupt +//! prioritization and therefore priority grouping values of three through +//! seven have the same effect. +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_setPriorityGrouping(uint32_t bits); + +//***************************************************************************** +// +//! Gets the priority grouping of the interrupt controller. +//! +//! This function returns the split between preemptable priority levels and +//! sub-priority levels in the interrupt priority specification. +//! +//! \return The number of bits of preemptable priority. +// +//***************************************************************************** +extern uint32_t Interrupt_getPriorityGrouping(void); + +//***************************************************************************** +// +//! Sets the priority of an interrupt. +//! +//! \param interruptNumber specifies the interrupt in question. +//! \param priority specifies the priority of the interrupt. +//! +//! This function is used to set the priority of an interrupt. When multiple +//! interrupts are asserted simultaneously, the ones with the highest priority +//! are processed before the lower priority interrupts. Smaller numbers +//! correspond to higher interrupt priorities; priority 0 is the highest +//! interrupt priority. +//! +//! The hardware priority mechanism only looks at the upper N bits of the +//! priority level (where N is 3 for the MSP432 family), so any +//! prioritization must be performed in those bits. The remaining bits can be +//! used to sub-prioritize the interrupt sources, and may be used by the +//! hardware priority mechanism on a future part. This arrangement allows +//! priorities to migrate to different NVIC implementations without changing +//! the gross prioritization of the interrupts. +//! +//! See \link Interrupt_enableInterrupt \endlink for details about the interrupt +//! parameter +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_setPriority(uint32_t interruptNumber, uint8_t priority); + +//***************************************************************************** +// +//! Gets the priority of an interrupt. +//! +//! \param interruptNumber specifies the interrupt in question. +//! +//! This function gets the priority of an interrupt. See +//! Interrupt_setPriority() for a definition of the priority value. +//! +//! See \link Interrupt_enableInterrupt \endlink for details about the interrupt +//! parameter +//! +//! \return Returns the interrupt priority, or -1 if an invalid interrupt was +//! specified. +// +//***************************************************************************** +extern uint8_t Interrupt_getPriority(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Enables an interrupt. +//! +//! \param interruptNumber specifies the interrupt to be enabled. +//! +//! The specified interrupt is enabled in the interrupt controller. Other +//! enables for the interrupt (such as at the peripheral level) are unaffected +//! by this function. +//! +//! Valid values will vary from part to part, so it is important to check the +//! device specific datasheet, however for MSP432 101 the following values can +//! be provided: +//! - \b FAULT_NMI +//! - \b FAULT_HARD +//! - \b FAULT_MPU +//! - \b FAULT_BUS +//! - \b FAULT_USAGE +//! - \b FAULT_SVCALL +//! - \b FAULT_DEBUG +//! - \b FAULT_PENDSV +//! - \b FAULT_SYSTICK +//! - \b INT_PSS +//! - \b INT_CS +//! - \b INT_PCM +//! - \b INT_WDT_A +//! - \b INT_FPU +//! - \b INT_FLCTL +//! - \b INT_COMP0 +//! - \b INT_COMP1 +//! - \b INT_TA0_0 +//! - \b INT_TA0_N +//! - \b INT_TA1_0 +//! - \b INT_TA1_N +//! - \b INT_TA2_0 +//! - \b INT_TA2_N +//! - \b INT_TA3_0 +//! - \b INT_TA3_N +//! - \b INT_EUSCIA0 +//! - \b INT_EUSCIA1 +//! - \b INT_EUSCIA2 +//! - \b INT_EUSCIA3 +//! - \b INT_EUSCIB0 +//! - \b INT_EUSCIB1 +//! - \b INT_EUSCIB2 +//! - \b INT_EUSCIB3 +//! - \b INT_ADC14 +//! - \b INT_T32_INT1 +//! - \b INT_T32_INT2 +//! - \b INT_T32_INTC +//! - \b INT_AES +//! - \b INT_RTCC +//! - \b INT_DMA_ERR +//! - \b INT_DMA_INT3 +//! - \b INT_DMA_INT2 +//! - \b INT_DMA_INT1 +//! - \b INT_DMA_INT0 +//! - \b INT_PORT1 +//! - \b INT_PORT2 +//! - \b INT_PORT3 +//! - \b INT_PORT4 +//! - \b INT_PORT5 +//! - \b INT_PORT6 +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_enableInterrupt(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Disables an interrupt. +//! +//! \param interruptNumber specifies the interrupt to be disabled. +//! +//! The specified interrupt is disabled in the interrupt controller. Other +//! enables for the interrupt (such as at the peripheral level) are unaffected +//! by this function. +//! +//! See \link Interrupt_enableInterrupt \endlink for details about the interrupt +//! parameter +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_disableInterrupt(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Returns if a peripheral interrupt is enabled. +//! +//! \param interruptNumber specifies the interrupt to check. +//! +//! This function checks if the specified interrupt is enabled in the interrupt +//! controller. +//! +//! See \link Interrupt_enableInterrupt \endlink for details about the interrupt +//! parameter +//! +//! \return A non-zero value if the interrupt is enabled. +// +//***************************************************************************** +extern bool Interrupt_isEnabled(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Pends an interrupt. +//! +//! \param interruptNumber specifies the interrupt to be pended. +//! +//! The specified interrupt is pended in the interrupt controller. Pending an +//! interrupt causes the interrupt controller to execute the corresponding +//! interrupt handler at the next available time, based on the current +//! interrupt state priorities. For example, if called by a higher priority +//! interrupt handler, the specified interrupt handler is not called until +//! after the current interrupt handler has completed execution. The interrupt +//! must have been enabled for it to be called. +//! +//! See \link Interrupt_enableInterrupt \endlink for details about the interrupt +//! parameter +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_pendInterrupt(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Un-pends an interrupt. +//! +//! \param interruptNumber specifies the interrupt to be un-pended. +//! +//! The specified interrupt is un-pended in the interrupt controller. This +//! will cause any previously generated interrupts that have not been handled +//! yet (due to higher priority interrupts or the interrupt no having been +//! enabled yet) to be discarded. +//! +//! See \link Interrupt_enableInterrupt \endlink for details about the interrupt +//! parameter +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_unpendInterrupt(uint32_t interruptNumber); + +//***************************************************************************** +// +//! Sets the priority masking level +//! +//! \param priorityMask is the priority level that is masked. +//! +//! This function sets the interrupt priority masking level so that all +//! interrupts at the specified or lesser priority level are masked. Masking +//! interrupts can be used to globally disable a set of interrupts with +//! priority below a predetermined threshold. A value of 0 disables priority +//! masking. +//! +//! Smaller numbers correspond to higher interrupt priorities. So for example +//! a priority level mask of 4 allows interrupts of priority level 0-3, +//! and interrupts with a numerical priority of 4 and greater are blocked. +//! +//! The hardware priority mechanism only looks at the upper N bits of the +//! priority level (where N is 3 for the MSP432 family), so any +//! prioritization must be performed in those bits. +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_setPriorityMask(uint8_t priorityMask); + +//***************************************************************************** +// +//! Gets the priority masking level +//! +//! This function gets the current setting of the interrupt priority masking +//! level. The value returned is the priority level such that all interrupts +//! of that and lesser priority are masked. A value of 0 means that priority +//! masking is disabled. +//! +//! Smaller numbers correspond to higher interrupt priorities. So for example +//! a priority level mask of 4 allows interrupts of priority level 0-3, +//! and interrupts with a numerical priority of 4 and greater are blocked. +//! +//! The hardware priority mechanism only looks at the upper N bits of the +//! priority level (where N is 3 for the MSP432 family), so any +//! prioritization must be performed in those bits. +//! +//! \return Returns the value of the interrupt priority level mask. +// +//***************************************************************************** +extern uint8_t Interrupt_getPriorityMask(void); + +//***************************************************************************** +// +//! Sets the address of the vector table. This function is for advanced users +//! who might want to switch between multiple instances of vector tables +//! (perhaps between flash/ram). +//! +//! \param addr is the new address of the vector table. +//! +//! \return None. +// +//***************************************************************************** +extern void Interrupt_setVectorTableAddress(uint32_t addr); + +//***************************************************************************** +// +//! Returns the address of the interrupt vector table. +//! +//! \return Address of the vector table. +// +//***************************************************************************** +extern uint32_t Interrupt_getVectorTableAddress(void); + +//***************************************************************************** +// +//! Enables the processor to sleep when exiting an ISR. For low power operation, +//! this is ideal as power cycles are not wasted with the processing required +//! for waking up from an ISR and going back to sleep. +//! +//! \return None +// +//***************************************************************************** +extern void Interrupt_enableSleepOnIsrExit(void); + +//***************************************************************************** +// +//! Disables the processor to sleep when exiting an ISR. +//! +//! \return None +// +//***************************************************************************** +extern void Interrupt_disableSleepOnIsrExit(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __INTERRUPT_H__ diff --git a/example/rt_msp432/MSP432P4xx/keil/msp432p4xx_driverlib.lib b/example/rt_msp432/MSP432P4xx/keil/msp432p4xx_driverlib.lib new file mode 100644 index 0000000..ed2a142 Binary files /dev/null and b/example/rt_msp432/MSP432P4xx/keil/msp432p4xx_driverlib.lib differ diff --git a/example/rt_msp432/MSP432P4xx/mpu.c b/example/rt_msp432/MSP432P4xx/mpu.c new file mode 100644 index 0000000..100de00 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/mpu.c @@ -0,0 +1,194 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include + +void MPU_enableModule(uint32_t mpuConfig) +{ + // + // Check the arguments. + // + ASSERT(!(mpuConfig & ~(MPU_CONFIG_PRIV_DEFAULT | MPU_CONFIG_HARDFLT_NMI))); + + // + // Set the MPU control bits according to the flags passed by the user, + // and also set the enable bit. + // + MPU->CTRL = mpuConfig | MPU_CTRL_ENABLE_Msk; +} + +void MPU_disableModule(void) +{ + // + // Turn off the MPU enable bit. + // + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; + +} + +uint32_t MPU_getRegionCount(void) +{ + // + // Read the DREGION field of the MPU type register and mask off + // the bits of interest to get the count of regions. + // + return ((MPU->TYPE & MPU_TYPE_DREGION_Msk) >> NVIC_MPU_TYPE_DREGION_S); +} + +void MPU_enableRegion(uint32_t region) +{ + // + // Check the arguments. + // + ASSERT(region < 8); + + // + // Select the region to modify. + // + MPU->RNR = region; + + // + // Modify the enable bit in the region attributes. + // + MPU->RASR |= MPU_RASR_ENABLE_Msk; +} + +void MPU_disableRegion(uint32_t region) +{ + // + // Check the arguments. + // + ASSERT(region < 8); + + // + // Select the region to modify. + // + MPU->RNR = region; + + // + // Modify the enable bit in the region attributes. + // + MPU->RASR &= ~MPU_RASR_ENABLE_Msk; +} + +void MPU_setRegion(uint32_t region, uint32_t addr, uint32_t flags) +{ + // + // Check the arguments. + // + ASSERT(region < 8); + + // + // Program the base address, use the region field to select the + // region at the same time. + // + MPU->RBAR = addr | region | MPU_RBAR_VALID_Msk; + + // + // Program the region attributes. Set the TEX field and the S, C, + // and B bits to fixed values that are suitable for all Stellaris + // memory. + // + MPU->RASR = (flags & ~(MPU_RASR_TEX_Msk | MPU_RASR_C_Msk)) | MPU_RASR_S_Msk + | MPU_RASR_B_Msk; +} + +void MPU_getRegion(uint32_t region, uint32_t *addr, uint32_t *pflags) +{ + // + // Check the arguments. + // + ASSERT(region < 8); + ASSERT(addr); + ASSERT(pflags); + + // + // Select the region to get. + // + MPU->RNR = region; + + // + // Read and store the base address for the region. + // + *addr = MPU->RBAR & MPU_RBAR_ADDR_Msk; + + // + // Read and store the region attributes. + // + *pflags = MPU->RASR; +} + +void MPU_registerInterrupt(void (*intHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(intHandler); + + // + // Register the interrupt handler. + // + Interrupt_registerInterrupt(FAULT_MPU, intHandler); + +} + +void MPU_unregisterInterrupt(void) +{ + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(FAULT_MPU); +} + +void MPU_enableInterrupt(void) +{ + + // + // Enable the memory management fault. + // + Interrupt_enableInterrupt(FAULT_MPU); + +} + +void MPU_disableInterrupt(void) +{ + // + // Disable the interrupt. + // + Interrupt_disableInterrupt(FAULT_MPU); +} diff --git a/example/rt_msp432/MSP432P4xx/mpu.h b/example/rt_msp432/MSP432P4xx/mpu.h new file mode 100644 index 0000000..d4a2bc4 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/mpu.h @@ -0,0 +1,449 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __MPU_H__ +#define __MPU_H__ + +//***************************************************************************** +// +//! \addtogroup mpu_api +//! @{ +// +//***************************************************************************** + + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +//***************************************************************************** +// +// Flags that can be passed to MPU_enableModule. +// +//***************************************************************************** +#define MPU_CONFIG_PRIV_DEFAULT MPU_CTRL_PRIVDEFENA_Msk +#define MPU_CONFIG_HARDFLT_NMI MPU_CTRL_HFNMIENA_Msk +#define MPU_CONFIG_NONE 0 + +//***************************************************************************** +// +// Flags for the region size to be passed to MPU_setRegion. +// +//***************************************************************************** +#define MPU_RGN_SIZE_32B (4 << 1) +#define MPU_RGN_SIZE_64B (5 << 1) +#define MPU_RGN_SIZE_128B (6 << 1) +#define MPU_RGN_SIZE_256B (7 << 1) +#define MPU_RGN_SIZE_512B (8 << 1) + +#define MPU_RGN_SIZE_1K (9 << 1) +#define MPU_RGN_SIZE_2K (10 << 1) +#define MPU_RGN_SIZE_4K (11 << 1) +#define MPU_RGN_SIZE_8K (12 << 1) +#define MPU_RGN_SIZE_16K (13 << 1) +#define MPU_RGN_SIZE_32K (14 << 1) +#define MPU_RGN_SIZE_64K (15 << 1) +#define MPU_RGN_SIZE_128K (16 << 1) +#define MPU_RGN_SIZE_256K (17 << 1) +#define MPU_RGN_SIZE_512K (18 << 1) + +#define MPU_RGN_SIZE_1M (19 << 1) +#define MPU_RGN_SIZE_2M (20 << 1) +#define MPU_RGN_SIZE_4M (21 << 1) +#define MPU_RGN_SIZE_8M (22 << 1) +#define MPU_RGN_SIZE_16M (23 << 1) +#define MPU_RGN_SIZE_32M (24 << 1) +#define MPU_RGN_SIZE_64M (25 << 1) +#define MPU_RGN_SIZE_128M (26 << 1) +#define MPU_RGN_SIZE_256M (27 << 1) +#define MPU_RGN_SIZE_512M (28 << 1) + +#define MPU_RGN_SIZE_1G (29 << 1) +#define MPU_RGN_SIZE_2G (30 << 1) +#define MPU_RGN_SIZE_4G (31 << 1) + +//***************************************************************************** +// +// Flags for the permissions to be passed to MPU_setRegion. +// +//***************************************************************************** +#define MPU_RGN_PERM_EXEC 0x00000000 +#define MPU_RGN_PERM_NOEXEC 0x10000000 +#define MPU_RGN_PERM_PRV_NO_USR_NO 0x00000000 +#define MPU_RGN_PERM_PRV_RW_USR_NO 0x01000000 +#define MPU_RGN_PERM_PRV_RW_USR_RO 0x02000000 +#define MPU_RGN_PERM_PRV_RW_USR_RW 0x03000000 +#define MPU_RGN_PERM_PRV_RO_USR_NO 0x05000000 +#define MPU_RGN_PERM_PRV_RO_USR_RO 0x06000000 + +//***************************************************************************** +// +// Flags for the sub-region to be passed to MPU_setRegion. +// +//***************************************************************************** +#define MPU_SUB_RGN_DISABLE_0 0x00000100 +#define MPU_SUB_RGN_DISABLE_1 0x00000200 +#define MPU_SUB_RGN_DISABLE_2 0x00000400 +#define MPU_SUB_RGN_DISABLE_3 0x00000800 +#define MPU_SUB_RGN_DISABLE_4 0x00001000 +#define MPU_SUB_RGN_DISABLE_5 0x00002000 +#define MPU_SUB_RGN_DISABLE_6 0x00004000 +#define MPU_SUB_RGN_DISABLE_7 0x00008000 + +//***************************************************************************** +// +// Flags to enable or disable a region, to be passed to MPU_setRegion. +// +//***************************************************************************** +#define MPU_RGN_ENABLE 1 +#define MPU_RGN_DISABLE 0 + +#define NVIC_MPU_TYPE_DREGION_S 8 + +//***************************************************************************** +// +// API Function prototypes +// +//***************************************************************************** + +//***************************************************************************** +// +//! Enables and configures the MPU for use. +//! +//! \param mpuConfig is the logical OR of the possible configurations. +//! +//! This function enables the Cortex-M memory protection unit. It also +//! configures the default behavior when in privileged mode and while handling +//! a hard fault or NMI. Prior to enabling the MPU, at least one region must +//! be set by calling MPU_setRegion() or else by enabling the default region for +//! privileged mode by passing the \b MPU_CONFIG_PRIV_DEFAULT flag to +//! MPU_enableModule(). Once the MPU is enabled, a memory management fault is +//! generated for memory access violations. +//! +//! The \e mpuConfig parameter should be the logical OR of any of the +//! following: +//! +//! - \b MPU_CONFIG_PRIV_DEFAULT enables the default memory map when in +//! privileged mode and when no other regions are defined. If this option +//! is not enabled, then there must be at least one valid region already +//! defined when the MPU is enabled. +//! - \b MPU_CONFIG_HARDFLT_NMI enables the MPU while in a hard fault or NMI +//! exception handler. If this option is not enabled, then the MPU is +//! disabled while in one of these exception handlers and the default +//! memory map is applied. +//! - \b MPU_CONFIG_NONE chooses none of the above options. In this case, +//! no default memory map is provided in privileged mode, and the MPU is +//! not enabled in the fault handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_enableModule(uint32_t mpuConfig); + +//***************************************************************************** +// +//! Disables the MPU for use. +//! +//! This function disables the Cortex-M memory protection unit. When the +//! MPU is disabled, the default memory map is used and memory management +//! faults are not generated. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_disableModule(void); + +//***************************************************************************** +// +//! Gets the count of regions supported by the MPU. +//! +//! This function is used to get the total number of regions that are supported +//! by the MPU, including regions that are already programmed. +//! +//! \return The number of memory protection regions that are available +//! for programming using MPU_setRegion(). +// +//***************************************************************************** +extern uint32_t MPU_getRegionCount(void); + +//***************************************************************************** +// +//! Enables a specific region. +//! +//! \param region is the region number to enable. Valid values are between +//! 0 and 7 inclusively. +//! +//! This function is used to enable a memory protection region. The region +//! should already be configured with the MPU_setRegion() function. Once +//! enabled, the memory protection rules of the region are applied and access +//! violations cause a memory management fault. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_enableRegion(uint32_t region); + +//***************************************************************************** +// +//! Disables a specific region. +//! +//! \param region is the region number to disable. Valid values are between +//! 0 and 7 inclusively. +//! +//! This function is used to disable a previously enabled memory protection +//! region. The region remains configured if it is not overwritten with +//! another call to MPU_setRegion(), and can be enabled again by calling +//! MPU_enableRegion(). +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_disableRegion(uint32_t region); + +//***************************************************************************** +// +//! Sets up the access rules for a specific region. +//! +//! \param region is the region number to set up. +//! \param addr is the base address of the region. It must be aligned +//! according to the size of the region specified in flags. +//! \param flags is a set of flags to define the attributes of the region. +//! +//! This function sets up the protection rules for a region. The region has +//! a base address and a set of attributes including the size. The base +//! address parameter, \e addr, must be aligned according to the size, and +//! the size must be a power of 2. +//! +//! \param region is the region number to set. Valid values are between +//! 0 and 7 inclusively. +//! +//! The \e flags parameter is the logical OR of all of the attributes +//! of the region. It is a combination of choices for region size, +//! execute permission, read/write permissions, disabled sub-regions, +//! and a flag to determine if the region is enabled. +//! +//! The size flag determines the size of a region and must be one of the +//! following: +//! +//! - \b MPU_RGN_SIZE_32B +//! - \b MPU_RGN_SIZE_64B +//! - \b MPU_RGN_SIZE_128B +//! - \b MPU_RGN_SIZE_256B +//! - \b MPU_RGN_SIZE_512B +//! - \b MPU_RGN_SIZE_1K +//! - \b MPU_RGN_SIZE_2K +//! - \b MPU_RGN_SIZE_4K +//! - \b MPU_RGN_SIZE_8K +//! - \b MPU_RGN_SIZE_16K +//! - \b MPU_RGN_SIZE_32K +//! - \b MPU_RGN_SIZE_64K +//! - \b MPU_RGN_SIZE_128K +//! - \b MPU_RGN_SIZE_256K +//! - \b MPU_RGN_SIZE_512K +//! - \b MPU_RGN_SIZE_1M +//! - \b MPU_RGN_SIZE_2M +//! - \b MPU_RGN_SIZE_4M +//! - \b MPU_RGN_SIZE_8M +//! - \b MPU_RGN_SIZE_16M +//! - \b MPU_RGN_SIZE_32M +//! - \b MPU_RGN_SIZE_64M +//! - \b MPU_RGN_SIZE_128M +//! - \b MPU_RGN_SIZE_256M +//! - \b MPU_RGN_SIZE_512M +//! - \b MPU_RGN_SIZE_1G +//! - \b MPU_RGN_SIZE_2G +//! - \b MPU_RGN_SIZE_4G +//! +//! The execute permission flag must be one of the following: +//! +//! - \b MPU_RGN_PERM_EXEC enables the region for execution of code +//! - \b MPU_RGN_PERM_NOEXEC disables the region for execution of code +//! +//! The read/write access permissions are applied separately for the +//! privileged and user modes. The read/write access flags must be one +//! of the following: +//! +//! - \b MPU_RGN_PERM_PRV_NO_USR_NO - no access in privileged or user mode +//! - \b MPU_RGN_PERM_PRV_RW_USR_NO - privileged read/write, user no access +//! - \b MPU_RGN_PERM_PRV_RW_USR_RO - privileged read/write, user read-only +//! - \b MPU_RGN_PERM_PRV_RW_USR_RW - privileged read/write, user read/write +//! - \b MPU_RGN_PERM_PRV_RO_USR_NO - privileged read-only, user no access +//! - \b MPU_RGN_PERM_PRV_RO_USR_RO - privileged read-only, user read-only +//! +//! The region is automatically divided into 8 equally-sized sub-regions by +//! the MPU. Sub-regions can only be used in regions of size 256 bytes +//! or larger. Any of these 8 sub-regions can be disabled, allowing for +//! creation of ``holes'' in a region which can be left open, or overlaid +//! by another region with different attributes. Any of the 8 sub-regions +//! can be disabled with a logical OR of any of the following flags: +//! +//! - \b MPU_SUB_RGN_DISABLE_0 +//! - \b MPU_SUB_RGN_DISABLE_1 +//! - \b MPU_SUB_RGN_DISABLE_2 +//! - \b MPU_SUB_RGN_DISABLE_3 +//! - \b MPU_SUB_RGN_DISABLE_4 +//! - \b MPU_SUB_RGN_DISABLE_5 +//! - \b MPU_SUB_RGN_DISABLE_6 +//! - \b MPU_SUB_RGN_DISABLE_7 +//! +//! Finally, the region can be initially enabled or disabled with one of +//! the following flags: +//! +//! - \b MPU_RGN_ENABLE +//! - \b MPU_RGN_DISABLE +//! +//! As an example, to set a region with the following attributes: size of +//! 32 KB, execution enabled, read-only for both privileged and user, one +//! sub-region disabled, and initially enabled; the \e flags parameter would +//! have the following value: +//! +//! +//! (MPU_RGN_SIZE_32K | MPU_RGN_PERM_EXEC | MPU_RGN_PERM_PRV_RO_USR_RO | +//! MPU_SUB_RGN_DISABLE_2 | MPU_RGN_ENABLE) +//! +//! +//! \note This function writes to multiple registers and is not protected +//! from interrupts. It is possible that an interrupt which accesses a +//! region may occur while that region is in the process of being changed. +//! The safest way to handle this is to disable a region before changing it. +//! Refer to the discussion of this in the API Detailed Description section. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_setRegion(uint32_t region, uint32_t addr, uint32_t flags); + +//***************************************************************************** +// +//! Gets the current settings for a specific region. +//! +//! \param region is the region number to get. Valid values are between +//! 0 and 7 inclusively. +//! \param addr points to storage for the base address of the region. +//! \param pflags points to the attribute flags for the region. +//! +//! This function retrieves the configuration of a specific region. The +//! meanings and format of the parameters is the same as that of the +//! MPU_setRegion() function. +//! +//! This function can be used to save the configuration of a region for later +//! use with the MPU_setRegion() function. The region's enable state is +//! preserved in the attributes that are saved. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_getRegion(uint32_t region, uint32_t *addr, uint32_t *pflags); + +//***************************************************************************** +// +//! Registers an interrupt handler for the memory management fault. +//! +//! \param intHandler is a pointer to the function to be called when the +//! memory management fault occurs. +//! +//! This function sets and enables the handler to be called when the MPU +//! generates a memory management fault due to a protection region access +//! violation. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters an interrupt handler for the memory management fault. +//! +//! This function disables and clears the handler to be called when a +//! memory management fault occurs. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_unregisterInterrupt(void); + +//***************************************************************************** +// +//! Enables the interrupt for the memory management fault. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_enableInterrupt(void); + +//***************************************************************************** +// +//! Disables the interrupt for the memory management fault. +//! +//! \return None. +// +//***************************************************************************** +extern void MPU_disableInterrupt(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __MPU_H__ diff --git a/example/rt_msp432/MSP432P4xx/pcm.c b/example/rt_msp432/MSP432P4xx/pcm.c new file mode 100644 index 0000000..1849ed6 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/pcm.c @@ -0,0 +1,609 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include + +/* DriverLib Includes */ +#include +#include +#include +#include +#include +#include + +static bool __PCM_setCoreVoltageLevelAdvanced(uint_fast8_t voltageLevel, + uint32_t timeOut, bool blocking) +{ + uint8_t powerMode, bCurrentVoltageLevel; + uint32_t regValue; + bool boolTimeout; + + ASSERT(voltageLevel == PCM_VCORE0 || voltageLevel == PCM_VCORE1); + + /* Getting current power mode and level */ + powerMode = PCM_getPowerMode(); + bCurrentVoltageLevel = PCM_getCoreVoltageLevel(); + + boolTimeout = timeOut > 0 ? true : false; + + /* If we are already at the power mode they requested, return */ + if (bCurrentVoltageLevel == voltageLevel) + return true; + + while (bCurrentVoltageLevel != voltageLevel) + { + regValue = PCM->CTL0; + + switch (PCM_getPowerState()) + { + case PCM_AM_LF_VCORE1: + case PCM_AM_DCDC_VCORE1: + case PCM_AM_LDO_VCORE0: + PCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE1) + | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK))); + break; + case PCM_AM_LF_VCORE0: + case PCM_AM_DCDC_VCORE0: + case PCM_AM_LDO_VCORE1: + PCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE0) + | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK))); + break; + default: + ASSERT(false); + } + + if(blocking) + { + while (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) + { + if (boolTimeout && !(--timeOut)) + return false; + + } + } + else + { + return true; + } + + bCurrentVoltageLevel = PCM_getCoreVoltageLevel(); + } + + /* Changing the power mode if we are stuck in LDO mode */ + if (powerMode != PCM_getPowerMode()) + { + if (powerMode == PCM_DCDC_MODE) + return PCM_setPowerMode(PCM_DCDC_MODE); + else + return PCM_setPowerMode(PCM_LF_MODE); + } + + return true; + +} + + +bool PCM_setCoreVoltageLevel(uint_fast8_t voltageLevel) +{ + return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, 0, true); +} + +bool PCM_setCoreVoltageLevelWithTimeout(uint_fast8_t voltageLevel, + uint32_t timeOut) +{ + return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, timeOut, true); +} + +bool PCM_setCoreVoltageLevelNonBlocking(uint_fast8_t voltageLevel) +{ + return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, 0, false); +} + +uint8_t PCM_getPowerMode(void) +{ + uint8_t currentPowerState; + + currentPowerState = PCM_getPowerState(); + + switch (currentPowerState) + { + case PCM_AM_LDO_VCORE0: + case PCM_AM_LDO_VCORE1: + case PCM_LPM0_LDO_VCORE0: + case PCM_LPM0_LDO_VCORE1: + return PCM_LDO_MODE; + case PCM_AM_DCDC_VCORE0: + case PCM_AM_DCDC_VCORE1: + case PCM_LPM0_DCDC_VCORE0: + case PCM_LPM0_DCDC_VCORE1: + return PCM_DCDC_MODE; + case PCM_LPM0_LF_VCORE0: + case PCM_LPM0_LF_VCORE1: + case PCM_AM_LF_VCORE1: + case PCM_AM_LF_VCORE0: + return PCM_LF_MODE; + default: + ASSERT(false); + return false; + + } +} + +uint8_t PCM_getCoreVoltageLevel(void) +{ + uint8_t currentPowerState = PCM_getPowerState(); + + switch (currentPowerState) + { + case PCM_AM_LDO_VCORE0: + case PCM_AM_DCDC_VCORE0: + case PCM_AM_LF_VCORE0: + case PCM_LPM0_LDO_VCORE0: + case PCM_LPM0_DCDC_VCORE0: + case PCM_LPM0_LF_VCORE0: + return PCM_VCORE0; + case PCM_AM_LDO_VCORE1: + case PCM_AM_DCDC_VCORE1: + case PCM_AM_LF_VCORE1: + case PCM_LPM0_LDO_VCORE1: + case PCM_LPM0_DCDC_VCORE1: + case PCM_LPM0_LF_VCORE1: + return PCM_VCORE1; + case PCM_LPM3: + return PCM_VCORELPM3; + default: + ASSERT(false); + return false; + + } +} + +static bool __PCM_setPowerModeAdvanced(uint_fast8_t powerMode, uint32_t timeOut, +bool blocking) +{ + uint8_t bCurrentPowerMode, bCurrentPowerState; + uint32_t regValue; + bool boolTimeout; + + ASSERT( + powerMode == PCM_LDO_MODE || powerMode == PCM_DCDC_MODE + || powerMode == PCM_LF_MODE); + + /* Getting Current Power Mode */ + bCurrentPowerMode = PCM_getPowerMode(); + + /* If the power mode being set it the same as the current mode, return */ + if (powerMode == bCurrentPowerMode) + return true; + + bCurrentPowerState = PCM_getPowerState(); + + boolTimeout = timeOut > 0 ? true : false; + + /* Go through the while loop while we haven't achieved the power mode */ + while (bCurrentPowerMode != powerMode) + { + regValue = PCM->CTL0; + + switch (bCurrentPowerState) + { + case PCM_AM_DCDC_VCORE0: + case PCM_AM_LF_VCORE0: + PCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE0 + | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK))); + break; + case PCM_AM_LF_VCORE1: + case PCM_AM_DCDC_VCORE1: + PCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE1 + | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK))); + break; + case PCM_AM_LDO_VCORE1: + { + if (powerMode == PCM_DCDC_MODE) + { + PCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE1 + | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK))); + } else if (powerMode == PCM_LF_MODE) + { + PCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE1 + | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK))); + } else + ASSERT(false); + + break; + } + case PCM_AM_LDO_VCORE0: + { + if (powerMode == PCM_DCDC_MODE) + { + PCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE0 + | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK))); + } else if (powerMode == PCM_LF_MODE) + { + PCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE0 + | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK))); + } else + ASSERT(false); + + break; + } + default: + ASSERT(false); + } + + if (blocking) + { + while (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) + { + if (boolTimeout && !(--timeOut)) + return false; + + } + } else + return true; + + bCurrentPowerMode = PCM_getPowerMode(); + bCurrentPowerState = PCM_getPowerState(); + } + + return true; + +} + +bool PCM_setPowerMode(uint_fast8_t powerMode) +{ + return __PCM_setPowerModeAdvanced(powerMode, 0, true); +} + +bool PCM_setPowerModeNonBlocking(uint_fast8_t powerMode) +{ + return __PCM_setPowerModeAdvanced(powerMode, 0, false); +} + +bool PCM_setPowerModeWithTimeout(uint_fast8_t powerMode, uint32_t timeOut) +{ + return __PCM_setPowerModeAdvanced(powerMode, timeOut, true); +} + +static bool __PCM_setPowerStateAdvanced(uint_fast8_t powerState, + uint32_t timeout, + bool blocking) +{ + uint8_t bCurrentPowerState; + bCurrentPowerState = PCM_getPowerState(); + + ASSERT( + powerState == PCM_AM_LDO_VCORE0 || powerState == PCM_AM_LDO_VCORE1 + || powerState == PCM_AM_DCDC_VCORE0 || powerState == PCM_AM_DCDC_VCORE1 + || powerState == PCM_AM_LF_VCORE0 || powerState == PCM_AM_LF_VCORE1 + || powerState == PCM_LPM0_LDO_VCORE0 || powerState == PCM_LPM0_LDO_VCORE1 + || powerState == PCM_LPM0_DCDC_VCORE0 || powerState == PCM_LPM0_DCDC_VCORE1 + || powerState == PCM_LPM3 || powerState == PCM_LPM35_VCORE0 + || powerState == PCM_LPM45 || powerState == PCM_LPM4); + + if (bCurrentPowerState == powerState) + return true; + + switch (powerState) + { + case PCM_AM_LDO_VCORE0: + return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking) + && __PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking)); + case PCM_AM_LDO_VCORE1: + return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking) + && __PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking)); + case PCM_AM_DCDC_VCORE0: + return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking) + && __PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout, blocking)); + case PCM_AM_DCDC_VCORE1: + return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking) + && __PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout, blocking)); + case PCM_AM_LF_VCORE0: + return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking) + && __PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking)); + case PCM_AM_LF_VCORE1: + return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking) + && __PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking)); + case PCM_LPM0_LDO_VCORE0: + if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking) + || !__PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking)) + break; + return PCM_gotoLPM0(); + case PCM_LPM0_LDO_VCORE1: + if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking) + || !__PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking)) + break; + return PCM_gotoLPM0(); + case PCM_LPM0_DCDC_VCORE0: + if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking) + || !__PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout, + blocking)) + break; + return PCM_gotoLPM0(); + case PCM_LPM0_DCDC_VCORE1: + if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking) + || !__PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout, + blocking)) + break; + return PCM_gotoLPM0(); + case PCM_LPM0_LF_VCORE0: + if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking) + || !__PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking)) + break; + return PCM_gotoLPM0(); + case PCM_LPM0_LF_VCORE1: + if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking) + || !__PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking)) + break; + return PCM_gotoLPM0(); + case PCM_LPM3: + return PCM_gotoLPM3(); + case PCM_LPM4: + return PCM_gotoLPM4(); + case PCM_LPM45: + return PCM_shutdownDevice(PCM_LPM45); + case PCM_LPM35_VCORE0: + return PCM_shutdownDevice(PCM_LPM35_VCORE0); + default: + ASSERT(false); + return false; + } + + return false; + +} + +bool PCM_setPowerState(uint_fast8_t powerState) +{ + return __PCM_setPowerStateAdvanced(powerState, 0, true); +} + +bool PCM_setPowerStateWithTimeout(uint_fast8_t powerState, uint32_t timeout) +{ + return __PCM_setPowerStateAdvanced(powerState, timeout, true); +} + +bool PCM_setPowerStateNonBlocking(uint_fast8_t powerState) +{ + return __PCM_setPowerStateAdvanced(powerState, 0, false); +} + +bool PCM_shutdownDevice(uint32_t shutdownMode) +{ + uint32_t shutdownModeBits = (shutdownMode == PCM_LPM45) ? + PCM_CTL0_LPMR_12 : PCM_CTL0_LPMR_10; + + ASSERT( + shutdownMode == PCM_SHUTDOWN_PARTIAL + || shutdownMode == PCM_SHUTDOWN_COMPLETE); + + /* If a power transition is occuring, return false */ + if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) + return false; + + /* Initiating the shutdown */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + PCM->CTL0 = (PCM_KEY | shutdownModeBits + | (PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK))); + + CPU_wfi(); + + return true; +} + +bool PCM_gotoLPM4(void) +{ + /* Disabling RTC_C and WDT_A */ + WDT_A_holdTimer(); + RTC_C_holdClock(); + + /* LPM4 is just LPM3 with WDT_A/RTC_C disabled... */ + return PCM_gotoLPM3(); +} + +bool PCM_gotoLPM4InterruptSafe(void) +{ + bool slHappenedCorrect; + + /* Disabling master interrupts. In Cortex M, if an interrupt is enabled but + master interrupts are disabled and a WFI happens the WFI will + immediately exit. */ + Interrupt_disableMaster(); + + slHappenedCorrect = PCM_gotoLPM4(); + + /* Enabling and Disabling Interrupts very quickly so that the + processor catches any pending interrupts */ + Interrupt_enableMaster(); + Interrupt_disableMaster(); + + return slHappenedCorrect; +} + +bool PCM_gotoLPM0(void) +{ + /* If we are in the middle of a state transition, return false */ + if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) + return false; + + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + CPU_wfi(); + + return true; +} + +bool PCM_gotoLPM0InterruptSafe(void) +{ + bool slHappenedCorrect; + + /* Disabling master interrupts. In Cortex M, if an interrupt is enabled but + master interrupts are disabled and a WFI happens the WFI will + immediately exit. */ + Interrupt_disableMaster(); + + slHappenedCorrect = PCM_gotoLPM0(); + + /* Enabling and Disabling Interrupts very quickly so that the + processor catches any pending interrupts */ + Interrupt_enableMaster(); + Interrupt_disableMaster(); + + return slHappenedCorrect; +} + +bool PCM_gotoLPM3(void) +{ + uint_fast8_t bCurrentPowerState; + uint_fast8_t currentPowerMode; + + /* If we are in the middle of a state transition, return false */ + if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) + return false; + + /* If we are in the middle of a shutdown, return false */ + if ((PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_10 + || (PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_12) + return false; + + currentPowerMode = PCM_getPowerMode(); + bCurrentPowerState = PCM_getPowerState(); + + if (currentPowerMode == PCM_DCDC_MODE || currentPowerMode == PCM_LF_MODE) + PCM_setPowerMode(PCM_LDO_MODE); + + /* Clearing the SDR */ + PCM->CTL0 = (PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)) | PCM_KEY; + + /* Setting the sleep deep bit */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + CPU_wfi(); + + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + + return PCM_setPowerState(bCurrentPowerState); +} + +bool PCM_gotoLPM3InterruptSafe(void) +{ + bool lpmHappenedCorrect; + + /* Disabling master interrupts. In Cortex M, if an interrupt is enabled but + master interrupts are disabled and a WFI happens the WFI will + immediately exit. */ + Interrupt_disableMaster(); + + lpmHappenedCorrect = PCM_gotoLPM3(); + + /* Enabling and Disabling Interrupts very quickly so that the + processor catches any pending interrupts */ + Interrupt_enableMaster(); + Interrupt_disableMaster(); + + return lpmHappenedCorrect; +} + +uint8_t PCM_getPowerState(void) +{ + return (PCM->CTL0 | PCM_CTL0_CPM_MASK); +} + +void PCM_enableRudeMode(void) +{ + + PCM->CTL1 = (PCM->CTL1 & ~(PCM_CTL0_KEY_MASK)) | PCM_KEY + | PCM_CTL1_FORCE_LPM_ENTRY; +} + +void PCM_disableRudeMode(void) +{ + PCM->CTL1 = (PCM->CTL1 & ~(PCM_CTL0_KEY_MASK | PCM_CTL1_FORCE_LPM_ENTRY)) + | PCM_KEY; +} + +void PCM_enableInterrupt(uint32_t flags) +{ + PCM->IE |= flags; +} + +void PCM_disableInterrupt(uint32_t flags) +{ + PCM->IE &= ~flags; +} + +uint32_t PCM_getInterruptStatus(void) +{ + return PCM->IFG; +} + +uint32_t PCM_getEnabledInterruptStatus(void) +{ + return PCM_getInterruptStatus() & PCM->IE; +} + +void PCM_clearInterruptFlag(uint32_t flags) +{ + PCM->CLRIFG |= flags; +} + +void PCM_registerInterrupt(void (*intHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + Interrupt_registerInterrupt(INT_PCM, intHandler); + + // + // Enable the system control interrupt. + // + Interrupt_enableInterrupt(INT_PCM); +} + +void PCM_unregisterInterrupt(void) +{ + // + // Disable the interrupt. + // + Interrupt_disableInterrupt(INT_PCM); + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(INT_PCM); +} diff --git a/example/rt_msp432/MSP432P4xx/pcm.h b/example/rt_msp432/MSP432P4xx/pcm.h new file mode 100644 index 0000000..9988073 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/pcm.h @@ -0,0 +1,711 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __PCM_H__ +#define __PCM_H__ + +//***************************************************************************** +// +//! \addtogroup pcm_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +//***************************************************************************** +// +// Control specific variables +// +//***************************************************************************** +#define PCM_KEY 0x695A0000 + +/* Power Modes */ +#define PCM_AM_LDO_VCORE0 0x00 +#define PCM_AM_LDO_VCORE1 0x01 +#define PCM_AM_DCDC_VCORE0 0x04 +#define PCM_AM_DCDC_VCORE1 0x05 +#define PCM_AM_LF_VCORE0 0x08 +#define PCM_AM_LF_VCORE1 0x09 +#define PCM_LPM0_LDO_VCORE0 0x10 +#define PCM_LPM0_LDO_VCORE1 0x11 +#define PCM_LPM0_DCDC_VCORE0 0x14 +#define PCM_LPM0_DCDC_VCORE1 0x15 +#define PCM_LPM0_LF_VCORE0 0x18 +#define PCM_LPM0_LF_VCORE1 0x19 +#define PCM_LPM3 0x20 +#define PCM_LPM4 0x21 +#define PCM_LPM35_VCORE0 0xC0 +#define PCM_LPM45 0xA0 + +#define PCM_VCORE0 0x00 +#define PCM_VCORE1 0x01 +#define PCM_VCORELPM3 0x02 + +#define PCM_LDO_MODE 0x00 +#define PCM_DCDC_MODE 0x01 +#define PCM_LF_MODE 0x02 + +#define PCM_SHUTDOWN_PARTIAL PCM_LPM35_VCORE0 +#define PCM_SHUTDOWN_COMPLETE PCM_LPM45 + +#define PCM_DCDCERROR PCM_IE_DCDC_ERROR_IE +#define PCM_AM_INVALIDTRANSITION PCM_IE_AM_INVALID_TR_IE +#define PCM_SM_INVALIDCLOCK PCM_IE_LPM_INVALID_CLK_IE +#define PCM_SM_INVALIDTRANSITION PCM_IE_LPM_INVALID_TR_IE + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//****************************************************************************** +// +//! Sets the core voltage level (Vcore). The function will take care of all +//! power state transitions needed to shift between core voltage levels. +//! Because transitions between voltage levels may require changes power modes, +//! the power mode might temporarily be change. The power mode will be returned +//! to the original state (with the new voltage level) at the end of a +//! successful execution of this function. +//! +//! Refer to the device specific data sheet for specifics about core voltage +//! levels. +//! +//! \param voltageLevel The voltage level to be shifted to. +//! - \b PCM_VCORE0, +//! - \b PCM_VCORE1 +//! +//! \return true if voltage level set, false otherwise. +// +//****************************************************************************** +extern bool PCM_setCoreVoltageLevel(uint_fast8_t voltageLevel); + +//****************************************************************************** +// +//! Returns the current powers state of the system see the +//! PCM_setCoreVoltageLevel function for specific information about the modes. +//! +//! \return The current voltage of the system +//! +//! Possible return values include: +//! - \b PCM_VCORE0 +//! - \b PCM_VCORE1 +//! - \b PCM_VCORELPM3 +//! +// +//****************************************************************************** +extern uint8_t PCM_getCoreVoltageLevel(void); + +//****************************************************************************** +// +//! Sets the core voltage level (Vcore). This function will take care of all +//! power state transitions needed to shift between core voltage levels. +//! Because transitions between voltage levels may require changes power modes, +//! the power mode might temporarily be change. The power mode will be returned +//! to the original state (with the new voltage level) at the end of a +//! successful execution of this function. +//! +//! This function is similar to PCMSetCoreVoltageLevel, however a timeout +//! mechanism is used. +//! +//! Refer to the device specific data sheet for specifics about core voltage +//! levels. +//! +//! \param voltageLevel The voltage level to be shifted to. +//! - \b PCM_VCORE0, +//! - \b PCM_VCORE1 +//! +//! \param timeOut Number of loop iterations to timeout when checking for +//! power state transitions. This should be used for debugging initial +//! power/hardware configurations. After a stable hardware base is +//! established, the PCMSetCoreVoltageLevel function should be used +//! +//! \return true if voltage level set, false otherwise. +// +//****************************************************************************** +extern bool PCM_setCoreVoltageLevelWithTimeout(uint_fast8_t voltageLevel, + uint32_t timeOut); + +//****************************************************************************** +// +//! Sets the core voltage level (Vcore). This function is similar to +//! PCM_setCoreVoltageLevel, however there are no polling flags to ensure +//! a state has changed. Execution is returned back to the calling program +// and it is up to the user to ensure proper state transitions happen +//! correctly. For MSP432, changing into different power modes/states +//! require very specific logic. This function will initiate only one state +//! transition and then return. It is up to the user to keep calling this +//! function until the correct power state has been achieved. +//! +//! Refer to the device specific data sheet for specifics about core voltage +//! levels. +//! +//! \param voltageLevel The voltage level to be shifted to. +//! - \b PCM_VCORE0, +//! - \b PCM_VCORE1 +//! +//! \return true if voltage level set, false otherwise. +// +//****************************************************************************** +extern bool PCM_setCoreVoltageLevelNonBlocking(uint_fast8_t voltageLevel); + +//****************************************************************************** +// +//! Switches between power modes. This function will take care of all +//! power state transitions needed to shift between power modes. Note for +//! changing to DCDC mode, specific hardware considerations are required. +//! +//! Refer to the device specific data sheet for specifics about power modes. +//! +//! \param powerMode The voltage modes to be shifted to. Valid values are: +//! - \b PCM_LDO_MODE, +//! - \b PCM_DCDC_MODE, +//! - \b PCM_LF_MODE +//! +//! \return true if power mode is set, false otherwise. +// +//****************************************************************************** +extern bool PCM_setPowerMode(uint_fast8_t powerMode); + +//****************************************************************************** +// +//! Switches between power modes. This function will take care of all +//! power state transitions needed to shift between power modes. Note for +//! changing to DCDC mode, specific hardware considerations are required. +//! +//! This function is similar to PCMSetPowerMode, however a timeout +//! mechanism is used. +//! +//! Refer to the device specific data sheet for specifics about power modes. +//! +//! \param powerMode The voltage modes to be shifted to. Valid values are: +//! - \b PCM_LDO_MODE, +//! - \b PCM_DCDC_MODE, +//! - \b PCM_LF_MODE +//! +//! \param timeOut Number of loop iterations to timeout when checking for +//! power state transitions. This should be used for debugging initial +//! power/hardware configurations. After a stable hardware base is +//! established, the PCMSetPowerMode function should be used +//! +//! \return true if power mode is set, false otherwise. +// +//****************************************************************************** +extern bool PCM_setPowerModeWithTimeout(uint_fast8_t powerMode, + uint32_t timeOut); + +//****************************************************************************** +// +//! Sets the core voltage level (Vcore). This function is similar to +//! PCM_setPowerMode, however there are no polling flags to ensure +//! a state has changed. Execution is returned back to the calling program +// and it is up to the user to ensure proper state transitions happen +//! correctly. For MSP432, changing into different power modes/states +//! require very specific logic. This function will initiate only one state +//! transition and then return. It is up to the user to keep calling this +//! function until the correct power state has been achieved. +//! +//! Refer to the device specific data sheet for specifics about core voltage +//! levels. +//! +//! \param powerMode The voltage modes to be shifted to. Valid values are: +//! - \b PCM_LDO_MODE, +//! - \b PCM_DCDC_MODE, +//! - \b PCM_LF_MODE +//! +//! \return true if power mode change was initiated, false otherwise +// +//****************************************************************************** +extern bool PCM_setPowerModeNonBlocking(uint_fast8_t powerMode); + +//****************************************************************************** +// +//! Returns the current powers state of the system see the \b PCM_setPowerState +//! function for specific information about the modes. +//! +//! \return The current power mode of the system +//! +// +//****************************************************************************** +extern uint8_t PCM_getPowerMode(void); + +//****************************************************************************** +// +//! Switches between power states. This is a convenience function that combines +//! the functionality of PCM_setPowerMode and PCM_setCoreVoltageLevel as well as +//! the LPM0/LPM3 functions. +//! +//! Refer to the device specific data sheet for specifics about power states. +//! +//! \param powerState The voltage modes to be shifted to. Valid values are: +//! - \b PCM_AM_LDO_VCORE0, [Active Mode, LDO, VCORE0] +//! - \b PCM_AM_LDO_VCORE1, [Active Mode, LDO, VCORE1] +//! - \b PCM_AM_DCDC_VCORE0, [Active Mode, DCDC, VCORE0] +//! - \b PCM_AM_DCDC_VCORE1, [Active Mode, DCDC, VCORE1] +//! - \b PCM_AM_LF_VCORE0, [Active Mode, Low Frequency, VCORE0] +//! - \b PCM_AM_LF_VCORE1, [Active Mode, Low Frequency, VCORE1] +//! - \b PCM_LPM0_LDO_VCORE0, [LMP0, LDO, VCORE0] +//! - \b PCM_LPM0_LDO_VCORE1, [LMP0, LDO, VCORE1] +//! - \b PCM_LPM0_DCDC_VCORE0, [LMP0, DCDC, VCORE0] +//! - \b PCM_LPM0_DCDC_VCORE1, [LMP0, DCDC, VCORE1] +//! - \b PCM_LPM0_LF_VCORE0, [LMP0, Low Frequency, VCORE0] +//! - \b PCM_LPM0_LF_VCORE1, [LMP0, Low Frequency, VCORE1] +//! - \b PCM_LPM3, [LPM3] +//! - \b PCM_LPM35_VCORE0, [LPM3.5 VCORE 0] +//! - \b PCM_LPM4, [LPM4] +//! - \b PCM_LPM45, [LPM4.5] +//! +//! \return true if power state is set, false otherwise. +// +//****************************************************************************** +extern bool PCM_setPowerState(uint_fast8_t powerState); + +//****************************************************************************** +// +//! Switches between power states. This is a convenience function that combines +//! the functionality of PCM_setPowerMode and PCM_setCoreVoltageLevel as well as +//! the LPM modes. +//! +//! This function is similar to PCM_setPowerState, however a timeout +//! mechanism is used. +//! +//! Refer to the device specific data sheet for specifics about power states. +//! +//! \param powerState The voltage modes to be shifted to. Valid values are: +//! - \b PCM_AM_LDO_VCORE0, [Active Mode, LDO, VCORE0] +//! - \b PCM_AM_LDO_VCORE1, [Active Mode, LDO, VCORE1] +//! - \b PCM_AM_DCDC_VCORE0, [Active Mode, DCDC, VCORE0] +//! - \b PCM_AM_DCDC_VCORE1, [Active Mode, DCDC, VCORE1] +//! - \b PCM_AM_LF_VCORE0, [Active Mode, Low Frequency, VCORE0] +//! - \b PCM_AM_LF_VCORE1, [Active Mode, Low Frequency, VCORE1] +//! - \b PCM_LPM0_LDO_VCORE0, [LMP0, LDO, VCORE0] +//! - \b PCM_LPM0_LDO_VCORE1, [LMP0, LDO, VCORE1] +//! - \b PCM_LPM0_DCDC_VCORE0, [LMP0, DCDC, VCORE0] +//! - \b PCM_LPM0_DCDC_VCORE1, [LMP0, DCDC, VCORE1] +//! - \b PCM_LPM0_LF_VCORE0, [LMP0, Low Frequency, VCORE0] +//! - \b PCM_LPM0_LF_VCORE1, [LMP0, Low Frequency, VCORE1] +//! - \b PCM_LPM3, [LPM3] +//! - \b PCM_LPM35_VCORE0, [LPM3.5 VCORE 0] +//! - \b PCM_LPM4, [LPM4] +//! - \b PCM_LPM45, [LPM4.5] +//! +//! \param timeout Number of loop iterations to timeout when checking for +//! power state transitions. This should be used for debugging initial +//! power/hardware configurations. After a stable hardware base is +//! established, the PCMSetPowerMode function should be used +//! +//! \return true if power state is set, false otherwise. It is important to +//! note that if a timeout occurs, false will be returned, however the +//! power state at this point is not guaranteed to be the same as the +//! state prior to the function call +// +//****************************************************************************** +extern bool PCM_setPowerStateWithTimeout(uint_fast8_t powerState, + uint32_t timeout); + +//****************************************************************************** +// +//! Returns the current powers state of the system see the PCMChangePowerState +//! function for specific information about the states. +//! +//! Refer to \link PCM_setPowerState \endlink for possible return values. +//! +//! \return The current power state of the system +// +//****************************************************************************** +extern uint8_t PCM_getPowerState(void); + +//****************************************************************************** +// +//! Sets the power state of the part. This function is similar to +//! PCM_getPowerState, however there are no polling flags to ensure +//! a state has changed. Execution is returned back to the calling program +// and it is up to the user to ensure proper state transitions happen +//! correctly. For MSP432, changing into different power modes/states +//! require very specific logic. This function will initiate only one state +//! transition and then return. It is up to the user to keep calling this +//! function until the correct power state has been achieved. +//! +//! Refer to the device specific data sheet for specifics about core voltage +//! levels. +//! +//! \param powerState The voltage modes to be shifted to. Valid values are: +//! - \b PCM_AM_LDO_VCORE0, [Active Mode, LDO, VCORE0] +//! - \b PCM_AM_LDO_VCORE1, [Active Mode, LDO, VCORE1] +//! - \b PCM_AM_DCDC_VCORE0, [Active Mode, DCDC, VCORE0] +//! - \b PCM_AM_DCDC_VCORE1, [Active Mode, DCDC, VCORE1] +//! - \b PCM_AM_LF_VCORE0, [Active Mode, Low Frequency, VCORE0] +//! - \b PCM_AM_LF_VCORE1, [Active Mode, Low Frequency, VCORE1] +//! - \b PCM_LPM0_LDO_VCORE0, [LMP0, LDO, VCORE0] +//! - \b PCM_LPM0_LDO_VCORE1, [LMP0, LDO, VCORE1] +//! - \b PCM_LPM0_DCDC_VCORE0, [LMP0, DCDC, VCORE0] +//! - \b PCM_LPM0_DCDC_VCORE1, [LMP0, DCDC, VCORE1] +//! - \b PCM_LPM0_LF_VCORE0, [LMP0, Low Frequency, VCORE0] +//! - \b PCM_LPM0_LF_VCORE1, [LMP0, Low Frequency, VCORE1] +//! - \b PCM_LPM3, [LPM3] +//! - \b PCM_LPM35_VCORE0, [LPM3.5 VCORE 0] +//! - \b PCM_LPM45, [LPM4.5] +//! +//! \return true if power state change was initiated, false otherwise +// +//****************************************************************************** +extern bool PCM_setPowerStateNonBlocking(uint_fast8_t powerState); + +//****************************************************************************** +// +//! Transitions the device into LPM3.5/LPM4.5 mode. +//! +//! Refer to the device specific data sheet for specifics about shutdown modes. +//! +//! The following events will cause a wake up from LPM3.5 mode: +//! - Device reset +//! - External reset RST +//! - Enabled RTC, WDT, and wake-up I/O only interrupt events +//! +//! The following events will cause a wake up from the LPM4.5 mode: +//! - Device reset +//! - External reset RST +//! - Wake-up I/O only interrupt events +//! +//! \param shutdownMode Specific mode to go to. Valid values are: +//! - \b PCM_LPM35_VCORE0 +//! - \b PCM_LPM45 +//! +//! +//! \return false if shutdown state cannot be entered, true otherwise. +// +//****************************************************************************** +extern bool PCM_shutdownDevice(uint32_t shutdownMode); + +//****************************************************************************** +// +//! Transitions the device into LPM0. +//! +//! Refer to the device specific data sheet for specifics about low power modes. +//! +//! \return false if sleep state cannot be entered, true otherwise. +// +//****************************************************************************** +extern bool PCM_gotoLPM0(void); + +//****************************************************************************** +// +//! Transitions the device into LPM3 +//! +//! Refer to the device specific data sheet for specifics about low power modes. +//! Note that since LPM3 cannot be entered from a DCDC power modes, the +//! power mode is first switched to LDO operation (if in DCDC mode), the deep +//! sleep is entered, and the DCDC mode is restored on wake up. +//! +//! \return false if sleep state cannot be entered, true otherwise. +// +//****************************************************************************** +extern bool PCM_gotoLPM3(void); + +//****************************************************************************** +// +//! Transitions the device into LPM0 while maintaining a safe +//! interrupt handling mentality. This function is meant to be used in +//! situations where the user wants to go to sleep, however does not want +//! to go to "miss" any interrupts due to the fact that going to LPM0 is not +//! an atomic operation. This function will modify the PRIMASK and on exit of +//! the program the master interrupts will be disabled. +//! +//! Refer to the device specific data sheet for specifics about low power modes. +//! +//! \return false if sleep state cannot be entered, true otherwise. +// +//****************************************************************************** +extern bool PCM_gotoLPM0InterruptSafe(void); + +//****************************************************************************** +// +//! Transitions the device into LPM3 while maintaining a safe +//! interrupt handling mentality. This function is meant to be used in +//! situations where the user wants to go to LPM3, however does not want +//! to go to "miss" any interrupts due to the fact that going to LPM3 is not +//! an atomic operation. This function will modify the PRIMASK and on exit of +//! the program the master interrupts will be disabled. +//! +//! Refer to the device specific data sheet for specifics about low power modes. +//! Note that since LPM3 cannot be entered from a DCDC power modes, the +//! power mode is first switched to LDO operation (if in DCDC mode), the deep +//! sleep is entered, and the DCDC mode is restored on wake up. +//! +//! \return false if sleep state cannot be entered, true otherwise. +// +//****************************************************************************** +extern bool PCM_gotoLPM3InterruptSafe(void); + +//****************************************************************************** +// +//! Transitions the device into LPM4. LPM4 is the exact same with LPM3, just +//! with RTC_C and WDT_A disabled. When waking up, RTC_C and WDT_A will remain +//! disabled until reconfigured by the user. +//! +//! \return false if sleep state cannot be entered, true otherwise. +// +//****************************************************************************** +extern bool PCM_gotoLPM4(void); + +//****************************************************************************** +// +//! Transitions the device into LPM4 while maintaining a safe +//! interrupt handling mentality. This function is meant to be used in +//! situations where the user wants to go to LPM4, however does not want +//! to go to "miss" any interrupts due to the fact that going to LPM4 is not +//! an atomic operation. This function will modify the PRIMASK and on exit of +//! the program the master interrupts will be disabled. +//! +//! Refer to the device specific data sheet for specifics about low power modes. +//! Note that since LPM3 cannot be entered from a DCDC power modes, the +//! power mode is first switched to LDO operation (if in DCDC mode), the deep +//! sleep is entered, and the DCDC mode is restored on wake up. +//! +//! \return false if sleep state cannot be entered, true otherwise. +// +//****************************************************************************** +extern bool PCM_gotoLPM4InterruptSafe(void); + +//****************************************************************************** +// +//! Enables "rude mode" entry into LPM3 and shutdown modes. With this mode +//! enabled, an entry into shutdown or LPM3 will occur even if there are +//! clock systems active. The system will forcibly turn off all clock/systems +//! when going into these modes. +//! +//! \return None +// +//****************************************************************************** +extern void PCM_enableRudeMode(void); + +//****************************************************************************** +// +//! Disables "rude mode" entry into LPM3 and shutdown modes. With this +//! mode disabled, an entry into shutdown or LPM3 will wait for any +//! active clock requests to free up before going into LPM3 or shutdown. +//! +//! \return None +// +//****************************************************************************** +extern void PCM_disableRudeMode(void); + +//***************************************************************************** +// +//! Enables individual power control interrupt sources. +//! +//! \param flags is a bit mask of the interrupt sources to be enabled. Must +//! be a logical OR of: +//! - \b PCM_DCDCERROR, +//! - \b PCM_AM_INVALIDTRANSITION, +//! - \b PCM_SM_INVALIDCLOCK, +//! - \b PCM_SM_INVALIDTRANSITION +//! +//! This function enables the indicated power control interrupt sources. Only +//! the sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +//! +//! \return None. +// +//***************************************************************************** +extern void PCM_enableInterrupt(uint32_t flags); + +//***************************************************************************** +// +//! Disables individual power control interrupt sources. +//! +//! \param flags is a bit mask of the interrupt sources to be enabled. Must +//! be a logical OR of: +//! - \b PCM_DCDCERROR, +//! - \b PCM_AM_INVALIDTRANSITION, +//! - \b PCM_SM_INVALIDCLOCK, +//! - \b PCM_SM_INVALIDTRANSITION +//! +//! This function disables the indicated power control interrupt sources. Only +//! the sources that are enabled can be reflected to the processor interrupt; +//! disabled sources have no effect on the processor. +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +//! +//! \return None. +// +//***************************************************************************** +extern void PCM_disableInterrupt(uint32_t flags); + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \return The current interrupt status, enumerated as a bit field of: +//! - \b PCM_DCDCERROR, +//! - \b PCM_AM_INVALIDTRANSITION, +//! - \b PCM_SM_INVALIDCLOCK, +//! - \b PCM_SM_INVALIDTRANSITION +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +// +//***************************************************************************** +extern uint32_t PCM_getInterruptStatus(void); + +//***************************************************************************** +// +//! Gets the current interrupt status masked with the enabled interrupts. +//! This function is useful to call in ISRs to get a list of pending +//! interrupts that are actually enabled and could have caused +//! the ISR. +//! +//! \return The current interrupt status, enumerated as a bit field of: +//! - \b PCM_DCDCERROR, +//! - \b PCM_AM_INVALIDTRANSITION, +//! - \b PCM_SM_INVALIDCLOCK, +//! - \b PCM_SM_INVALIDTRANSITION +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +// +//***************************************************************************** +extern uint32_t PCM_getEnabledInterruptStatus(void); + +//***************************************************************************** +// +//! Clears power system interrupt sources. +//! +//! The specified power system interrupt sources are cleared, so that they no +//! longer assert. This function must be called in the interrupt handler to +//! keep it from being called again immediately upon exit. +//! +//! \note Because there is a write buffer in the Cortex-M processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \param flags is a bit mask of the interrupt sources to be cleared. Must +//! be a logical OR of +//! - \b PCM_DCDCERROR, +//! - \b PCM_AM_INVALIDTRANSITION, +//! - \b PCM_SM_INVALIDCLOCK, +//! - \b PCM_SM_INVALIDTRANSITION +//! +//! \note The interrupt sources vary based on the part in use. +//! Please consult the data sheet for the part you are using to determine +//! which interrupt sources are available. +//! +//! \return None. +// +//***************************************************************************** +extern void PCM_clearInterruptFlag(uint32_t flags); + +//***************************************************************************** +// +//! Registers an interrupt handler for the power system interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the power +//! system interrupt occurs. +//! +//! This function registers the handler to be called when a clock system +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific PCM interrupts must be enabled +//! via PCM_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via \link PCM_clearInterruptFlag \endlink . +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void PCM_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the power system. +//! +//! This function unregisters the handler to be called when a power system +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void PCM_unregisterInterrupt(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __PCM_H__ diff --git a/example/rt_msp432/MSP432P4xx/pmap.c b/example/rt_msp432/MSP432P4xx/pmap.c new file mode 100644 index 0000000..1d41957 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/pmap.c @@ -0,0 +1,66 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include + +void PMAP_configurePorts(const uint8_t *portMapping, uint8_t pxMAPy, + uint8_t numberOfPorts, uint8_t portMapReconfigure) +{ + uint_fast16_t i; + + ASSERT( + (portMapReconfigure == PMAP_ENABLE_RECONFIGURATION) + || (portMapReconfigure == PMAP_DISABLE_RECONFIGURATION)); + + //Get write-access to port mapping registers: + PMAP->KEYID = PMAP_KEYID_VAL; + + //Enable/Disable reconfiguration during runtime + PMAP->CTL = (PMAP->CTL & ~PMAP_CTL_PRECFG) | portMapReconfigure; + + //Configure Port Mapping: + + for (i = 0; i < numberOfPorts * 8; i++) + { + HWREG8(PMAP_BASE + i + pxMAPy) = portMapping[i]; + } + + //Disable write-access to port mapping registers: + PMAP->KEYID = 0; +} + diff --git a/example/rt_msp432/MSP432P4xx/pmap.h b/example/rt_msp432/MSP432P4xx/pmap.h new file mode 100644 index 0000000..a10479e --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/pmap.h @@ -0,0 +1,129 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __PMAP_H__ +#define __PMAP_H__ + +//***************************************************************************** +// +//! \addtogroup pmap_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +//***************************************************************************** +// +//The following are values that can be passed to the PMAP_configurePorts() API +//as the portMapReconfigure parameter. +// +//***************************************************************************** +#define PMAP_ENABLE_RECONFIGURATION PMAP_CTL_PRECFG +#define PMAP_DISABLE_RECONFIGURATION 0x00 + +//***************************************************************************** +// +//The following are values that can be passed to the PMAP_configurePorts() API +//as the portMapReconfigure parameter. +// +//***************************************************************************** +#define PMAP_P1MAP ((uint32_t)P1MAP - PMAP_BASE) +#define PMAP_P2MAP ((uint32_t)P2MAP - PMAP_BASE) +#define PMAP_P3MAP ((uint32_t)P3MAP - PMAP_BASE) +#define PMAP_P4MAP ((uint32_t)P4MAP - PMAP_BASE) +#define PMAP_P5MAP ((uint32_t)P5MAP - PMAP_BASE) +#define PMAP_P6MAP ((uint32_t)P6MAP - PMAP_BASE) +#define PMAP_P7MAP ((uint32_t)P7MAP - PMAP_BASE) + + +//***************************************************************************** +// +//Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! This function configures the MSP432 Port Mapper +//! +//! \param portMapping is the pointer to init Data +//! \param pxMAPy is the Port Mapper to initialize +//! \param numberOfPorts is the number of Ports to initialize +//! \param portMapReconfigure is used to enable/disable reconfiguration +//! Valid values are +//! \b PMAP_ENABLE_RECONFIGURATION +//! \b PMAP_DISABLE_RECONFIGURATION [Default value] +//! Modified registers are \b PMAPKEYID, \b PMAPCTL +//! +//! \return None +// +//***************************************************************************** +extern void PMAP_configurePorts(const uint8_t *portMapping, uint8_t pxMAPy, + uint8_t numberOfPorts, uint8_t portMapReconfigure); + +/* Defines for future devices that might have multiple instances */ +#define PMAP_configurePortsMultipleInstance(a,b,c,d,e) PMAP_configurePorts(b,c,d,e) + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif diff --git a/example/rt_msp432/MSP432P4xx/pss.c b/example/rt_msp432/MSP432P4xx/pss.c new file mode 100644 index 0000000..865d690 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/pss.c @@ -0,0 +1,224 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include + +/* DriverLib Includes */ +#include +#include +#include +#include + +static void __PSSUnlock() +{ + PSS->KEY = PSS_KEY_VALUE; +} + +static void __PSSLock() +{ + PSS->KEY = 0; +} + + +void PSS_enableForcedDCDCOperation(void) +{ + __PSSUnlock(); + + BITBAND_PERI(PSS->CTL0, PSS_CTL0_DCDC_FORCE_OFS) = 1; + + __PSSLock(); +} + +void PSS_disableForcedDCDCOperation(void) +{ + __PSSUnlock(); + + BITBAND_PERI(PSS->CTL0, PSS_CTL0_DCDC_FORCE_OFS) = 0; + + __PSSLock(); + +} + +void PSS_enableHighSidePinToggle(bool activeLow) +{ + __PSSUnlock(); + + if (activeLow) + PSS->CTL0 |= (PSS_CTL0_SVMHOE | PSS_CTL0_SVMHOUTPOLAL); + else + { + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVMHOUTPOLAL_OFS) = 0; + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVMHOE_OFS) = 1; + } + + __PSSLock(); +} + +void PSS_disableHighSidePinToggle(void) +{ + __PSSUnlock(); + + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVMHOE_OFS) = 0; + + __PSSLock(); +} + +void PSS_enableHighSide(void) +{ + __PSSUnlock(); + + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVSMHOFF_OFS) = 0; + + __PSSLock(); +} + +void PSS_disableHighSide(void) +{ + __PSSUnlock(); + + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVSMHOFF_OFS) = 1; + + __PSSLock(); +} + +void PSS_setHighSidePerformanceMode(uint_fast8_t powerMode) +{ + __PSSUnlock(); + + if (powerMode == PSS_FULL_PERFORMANCE_MODE) + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVSMHLP_OFS) = 0; + else + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVSMHLP_OFS) = 1; + + __PSSLock(); +} + +uint_fast8_t PSS_getHighSidePerformanceMode(void) +{ + if (BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVSMHLP_OFS)) + return PSS_NORMAL_PERFORMANCE_MODE; + else + return PSS_FULL_PERFORMANCE_MODE; +} + +void PSS_enableHighSideMonitor(void) +{ + __PSSUnlock(); + + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVSMHS_OFS) = 1; + + __PSSLock(); +} + +void PSS_disableHighSideMonitor(void) +{ + __PSSUnlock(); + + BITBAND_PERI(PSS->CTL0, PSS_CTL0_SVSMHS_OFS) = 0; + + __PSSLock(); +} + +void PSS_setHighSideVoltageTrigger(uint_fast8_t triggerVoltage) +{ + __PSSUnlock(); + + ASSERT(!(triggerVoltage & 0xF8)) + + PSS->CTL0 &= ~PSS_CTL0_SVSMHTH_MASK; + PSS->CTL0 |= (triggerVoltage & 0x07) << PSS_CTL0_SVSMHTH_OFS; + + __PSSLock(); +} + +uint_fast8_t PSS_getHighSideVoltageTrigger(void) +{ + return (uint_fast8_t)((PSS->CTL0 & PSS_CTL0_SVSMHTH_MASK) + >> PSS_CTL0_SVSMHTH_OFS); +} + +void PSS_enableInterrupt(void) +{ + __PSSUnlock(); + BITBAND_PERI(PSS->IE,PSS_IE_SVSMHIE_OFS) = 1; + __PSSLock(); +} + +void PSS_disableInterrupt(void) +{ + __PSSUnlock(); + BITBAND_PERI(PSS->IE,PSS_IE_SVSMHIE_OFS) = 0; + __PSSLock(); +} + +uint32_t PSS_getInterruptStatus(void) +{ + return PSS->IFG; +} + +void PSS_clearInterruptFlag(void) +{ + __PSSUnlock(); + BITBAND_PERI(PSS->CLRIFG,PSS_CLRIFG_CLRSVSMHIFG_OFS) = 0; + __PSSLock(); +} + +void PSS_registerInterrupt(void (*intHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + Interrupt_registerInterrupt(INT_PSS, intHandler); + + // + // Enable the system control interrupt. + // + Interrupt_enableInterrupt(INT_PSS); +} + +void PSS_unregisterInterrupt(void) +{ + // + // Disable the interrupt. + // + Interrupt_disableInterrupt(INT_PSS); + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(INT_PSS); +} diff --git a/example/rt_msp432/MSP432P4xx/pss.h b/example/rt_msp432/MSP432P4xx/pss.h new file mode 100644 index 0000000..f651bc5 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/pss.h @@ -0,0 +1,321 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __PSS_H__ +#define __PSS_H__ + +//***************************************************************************** +// +//! \addtogroup pss_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +//***************************************************************************** +// +// Control specific variables +// +//***************************************************************************** +#define PSS_KEY_VALUE PSS_KEY_KEY_VAL + +#define PSS_SVSMH PSS_IE_SVSMHIE + +#define PSS_FULL_PERFORMANCE_MODE 0x01 +#define PSS_NORMAL_PERFORMANCE_MODE 0x00 + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! Enables output of the High Side interrupt flag on the device \b SVMHOUT pin +//! +//! \param activeLow True if the signal should be logic low when SVSMHIFG +//! is set. False if signal should be high when \b SVSMHIFG is set. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_enableHighSidePinToggle(bool activeLow); + +//***************************************************************************** +// +//! Disables output of the High Side interrupt flag on the device \b SVMHOUT pin +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_disableHighSidePinToggle(void); + +//***************************************************************************** +// +//! Enables high side voltage supervisor/monitor. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_enableHighSide(void); + +//***************************************************************************** +// +//! Disables high side voltage supervisor/monitor. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_disableHighSide(void); + +//***************************************************************************** +// +//! Sets the performance mode of the high side regulator. Full performance +//! mode allows for the best response times while normal performance mode is +//! optimized for the lowest possible current consumption. +//! +//! \param powerMode is the performance mode to set. Valid values are one of +//! the following: +//! - \b PSS_FULL_PERFORMANCE_MODE, +//! - \b PSS_NORMAL_PERFORMANCE_MODE +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_setHighSidePerformanceMode(uint_fast8_t powerMode); + +//***************************************************************************** +// +//! Gets the performance mode of the high side voltage regulator. Refer to the +//! user's guide for specific information about information about the different +//! performance modes. +//! +//! \return Performance mode of the voltage regulator +// +//***************************************************************************** +extern uint_fast8_t PSS_getHighSidePerformanceMode(void); + +//***************************************************************************** +// +//! Sets the high side voltage supervisor to monitor mode +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_enableHighSideMonitor(void); + +//***************************************************************************** +// +//! Switches the high side of the power supply system to be a supervisor instead +//! of a monitor +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_disableHighSideMonitor(void); + +//***************************************************************************** +// +//! Sets the voltage level at which the high side of the device voltage +//! regulator triggers a reset. This value is represented as an unsigned eight +//! bit integer where only the lowest three bits are most significant. +//! +//! \param triggerVoltage Voltage level in which high side supervisor/monitor +//! triggers a reset. See the device specific data sheet for details +//! on these voltage levels. +//! +//! Typical values will vary from part to part (so it is very important to +//! check the SVSH section of the data sheet. For reference only, the typical +//! MSP432 101 values are listed below: +//! - 0 --> 1.57V +//! - 1 --> 1.62V +//! - 2 --> 1.83V +//! - 3 --> 2V +//! - 4 --> 2.25V +//! - 5 --> 2.4V +//! - 6 --> 2.6V +//! - 7 --> 2.8V +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_setHighSideVoltageTrigger(uint_fast8_t triggerVoltage); + +//***************************************************************************** +// +//! Returns the voltage level at which the high side of the device voltage +//! regulator triggers a reset. +//! +//! \return The voltage level that the high side voltage supervisor/monitor +//! triggers a reset. This value is represented as an unsigned eight +//! bit integer where only the lowest three bits are most significant. +//! See \link PSS_setHighSideVoltageTrigger \endlink for information regarding +//! the return value +// +//***************************************************************************** +extern uint_fast8_t PSS_getHighSideVoltageTrigger(void); + +//***************************************************************************** +// +//! Enables the power supply system interrupt source. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_enableInterrupt(void); + +//***************************************************************************** +// +//! Disables the power supply system interrupt source. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_disableInterrupt(void); + +//***************************************************************************** +// +//! Gets the current interrupt status. +//! +//! \return The current interrupt status ( \b PSS_SVSMH ) +//! +//***************************************************************************** +extern uint32_t PSS_getInterruptStatus(void); + +//***************************************************************************** +// +//! Clears power supply system interrupt source. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_clearInterruptFlag(void); + + +//***************************************************************************** +// +//! Enables the "forced" mode of the DCDC regulator. In this mode, the fail +//! safe mechanism that disables the regulator to LDO mode when the supply +//! voltage falls below the minimum supply voltage required for DCDC operation +//! is turned off. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_enableForcedDCDCOperation(void); + + +//***************************************************************************** +// +//! Disables the "forced" mode of the DCDC regulator. In this mode, the fail +//! safe mechanism that disables the regulator to LDO mode when the supply +//! voltage falls below the minimum supply voltage required for DCDC operation +//! is turned on. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_disableForcedDCDCOperation(void); + +//***************************************************************************** +// +//! Registers an interrupt handler for the power supply system interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the power +//! supply system interrupt occurs. +//! +//! This function registers the handler to be called when a power supply system +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific PSS interrupts must be enabled +//! via PSS_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via PSS_clearInterruptFlag(). +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the power supply system +//! +//! This function unregisters the handler to be called when a power supply +//! system interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void PSS_unregisterInterrupt(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __PSS_H__ diff --git a/example/rt_msp432/MSP432P4xx/ref_a.c b/example/rt_msp432/MSP432P4xx/ref_a.c new file mode 100644 index 0000000..90f60d9 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/ref_a.c @@ -0,0 +1,116 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include + +void REF_A_setReferenceVoltage(uint_fast8_t referenceVoltageSelect) +{ + ASSERT(referenceVoltageSelect <= REF_A_VREF2_5V); + + REF_A->CTL0 = (REF_A->CTL0 & ~REF_A_CTL0_VSEL_3) | referenceVoltageSelect; +} + +void REF_A_disableTempSensor(void) +{ + BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_TCOFF_OFS) = 1; +} + +void REF_A_enableTempSensor(void) +{ + BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_TCOFF_OFS) = 0; +} + +void REF_A_enableReferenceVoltageOutput(void) +{ + BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_OUT_OFS) = 1; +} + +void REF_A_disableReferenceVoltageOutput(void) +{ + BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_OUT_OFS) = 0; +} + +void REF_A_enableReferenceVoltage(void) +{ + BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_ON_OFS) = 1; +} + +void REF_A_disableReferenceVoltage(void) +{ + BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_ON_OFS) = 0; +} + +uint_fast8_t REF_A_getBandgapMode(void) +{ + return (REF_A->CTL0 & REF_A_CTL0_BGMODE); +} + +bool REF_A_isBandgapActive(void) +{ + return BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_BGACT_OFS); +} + +bool REF_A_isRefGenBusy(void) +{ + return BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_GENBUSY_OFS); +} + +bool REF_A_isRefGenActive(void) +{ + return BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_GENACT_OFS); +} + +bool REF_A_getBufferedBandgapVoltageStatus(void) +{ + return BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_BGRDY_OFS); +} + +bool REF_A_getVariableReferenceVoltageStatus(void) +{ + return BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_GENRDY_OFS); +} + +void REF_A_setReferenceVoltageOneTimeTrigger(void) +{ + BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_GENOT_OFS) = 1; +} + +void REF_A_setBufferedBandgapVoltageOneTimeTrigger(void) +{ + BITBAND_PERI(REF_A->CTL0,REF_A_CTL0_BGOT_OFS) = 1; +} + diff --git a/example/rt_msp432/MSP432P4xx/ref_a.h b/example/rt_msp432/MSP432P4xx/ref_a.h new file mode 100644 index 0000000..9d9dd17 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/ref_a.h @@ -0,0 +1,346 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __REF_B_H__ +#define __REF_B_H__ + +//***************************************************************************** +// +//! \addtogroup ref_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +//***************************************************************************** +// +//The following are values that can be passed to Ref_setReferenceVoltage() +//in the referenceVoltageSelect parameter. +// +//***************************************************************************** +#define REF_A_VREF1_2V REF_A_CTL0_VSEL_0 +#define REF_A_VREF1_45V REF_A_CTL0_VSEL_1 +#define REF_A_VREF2_5V REF_A_CTL0_VSEL_3 + +//***************************************************************************** +// +//The following are values that are returned by Ref_getBandgapMode(). +// +//***************************************************************************** +#define REF_A_STATICMODE 0x0 +#define REF_A_SAMPLEMODE REF_A_CTL0_BGMODE + +//***************************************************************************** +// +//! Sets the reference voltage for the voltage generator. +//! +//! \param referenceVoltageSelect is the desired voltage to generate for a +//! reference voltage. +//! Valid values are: +//! - \b REF_A_VREF1_2V [Default] +//! - \b REF_A_VREF1_45V +//! - \b REF_A_VREF2_5V +//! Modified bits are \b REFVSEL of \b REFCTL0 register. +//! +//! This function sets the reference voltage generated by the voltage generator +//! to be used by other peripherals. This reference voltage will only be valid +//! while the REF module is in control. +//! Please note, if the \link REF_A_isRefGenBusy() \endlink returns \b REF_BUSY, +//! this function will have no effect. +//! +//! \return none +// +//***************************************************************************** +extern void REF_A_setReferenceVoltage(uint_fast8_t referenceVoltageSelect); + +//***************************************************************************** +// +//! Disables the internal temperature sensor to save power consumption. +//! +//! This function is used to turn off the internal temperature sensor to save +//! on power consumption. The temperature sensor is enabled by default. Please +//! note, that giving ADC12 module control over the REF module, the state of the +//! temperature sensor is dependent on the controls of the ADC12 module. +//! Please note, if the \link REF_A_isRefGenBusy() \endlink returns +//! \b REF_A_BUSY, this function will have no effect. +//! +//! Modified bits are \b REFTCOFF of \b REFCTL0 register. +//! \return none +// +//***************************************************************************** +extern void REF_A_disableTempSensor(void); + +//***************************************************************************** +// +//! Enables the internal temperature sensor. +//! +//! This function is used to turn on the internal temperature sensor to use by +//! other peripherals. The temperature sensor is enabled by default. +//! Please note, if the \link REF_A_isRefGenBusy() \endlink returns +//! \b REF_A_BUSY, this function will have no effect. +//! +//! Modified bits are \b REFTCOFF of \b REFCTL0 register. +//! +//! \return none +// +//***************************************************************************** +extern void REF_A_enableTempSensor(void); + +//***************************************************************************** +// +//! Outputs the reference voltage to an output pin. +//! +//! This function is used to output the reference voltage being generated to an +//! output pin. Please note, the output pin is device specific. Please note, +//! that giving ADC12 module control over the REF module, the state of the +//! reference voltage as an output to a pin is dependent on the controls of the +//! ADC12 module. +//! Please note, if the \link REF_A_isRefGenBusy() \endlink returns +//! \b REF_A_BUSY, this function will have no effect. +//! +//! Modified bits are \b REFOUT of \b REFCTL0 register. +//! \return none +// +//***************************************************************************** +extern void REF_A_enableReferenceVoltageOutput(void); + +//***************************************************************************** +// +//! Disables the reference voltage as an output to a pin. +//! +//! This function is used to disables the reference voltage being generated to +//! be given to an output pin. +//! Please note, if the \link REF_A_isRefGenBusy() \endlink returns +//! \b REF_A_BUSY, this function will have no effect. +//! +//! Modified bits are \b REFOUT of \b REFCTL0 register. +//! \return none +// +//***************************************************************************** +extern void REF_A_disableReferenceVoltageOutput(void); + +//***************************************************************************** +// +//! Enables the reference voltage to be used by peripherals. +//! +//! This function is used to enable the generated reference voltage to be used +//! other peripherals or by an output pin, if enabled. Please note, that giving +//! ADC12 module control over the REF module, the state of the reference voltage +//! is dependent on the controls of the ADC12 module. +//! Please note, if the \link REF_A_isRefGenBusy() \endlink returns +//! REF_A_BUSY, this function will have no effect. +//! +//! Modified bits are \b REFON of \b REFCTL0 register. +//! \return none +// +//***************************************************************************** +extern void REF_A_enableReferenceVoltage(void); + +//***************************************************************************** +// +//! Disables the reference voltage. +//! +//! This function is used to disable the generated reference voltage. +//! Please note, if the \link REF_A_isRefGenBusy() \endlink returns +//! \b REF_A_BUSY, this function will have no effect. +//! +//! Modified bits are \b REFON of \b REFCTL0 register. +//! \return none +// +//***************************************************************************** +extern void REF_A_disableReferenceVoltage(void); + +//***************************************************************************** +// +//! Returns the bandgap mode of the REF module. +//! +//! This function is used to return the bandgap mode of the REF module, +//! requested by the peripherals using the bandgap. If a peripheral requests +//! static mode, then the bandgap mode will be static for all modules, whereas +//! if all of the peripherals using the bandgap request sample mode, then that +//! will be the mode returned. Sample mode allows the bandgap to be active only +//! when necessary to save on power consumption, static mode requires the +//! bandgap to be active until no peripherals are using it anymore. +//! +//! \return The bandgap mode of the REF module: +//! - \b REF_A_STATICMODE if the bandgap is operating in static mode +//! - \b REF_A_SAMPLEMODE if the bandgap is operating in sample mode +// +//***************************************************************************** +extern uint_fast8_t REF_A_getBandgapMode(void); + +//***************************************************************************** +// +//! Returns the active status of the bandgap in the REF module. +//! +//! This function is used to return the active status of the bandgap in the REF +//! module. If the bandgap is in use by a peripheral, then the status will be +//! seen as active. +//! +//! \return true if the bandgap is being used, false otherwise +// +//***************************************************************************** +extern bool REF_A_isBandgapActive(void); + +//***************************************************************************** +// +//! Returns the busy status of the reference generator in the REF module. +//! +//! This function is used to return the busy status of the reference generator +//! in the REF module. If the ref. generator is in use by a peripheral, then the +//! status will be seen as busy. +//! +//! \return true if the reference generator is being used, false otherwise. +//***************************************************************************** +extern bool REF_A_isRefGenBusy(void); + +//***************************************************************************** +// +//! Returns the active status of the reference generator in the REF module. +//! +//! This function is used to return the active status of the reference generator +//! in the REF module. If the ref. generator is on and ready to use, then the +//! status will be seen as active. +//! +//! \return true if the reference generator is active, false otherwise. +// +//***************************************************************************** +extern bool REF_A_isRefGenActive(void); + +//***************************************************************************** +// +//! Returns the busy status of the reference generator in the REF module. +//! +//! This function is used to return the buys status of the buffered bandgap +//! voltage in the REF module. If the ref. generator is on and ready to use, +//! then the status will be seen as active. +//! +//! \return true if the buffered bandgap voltage is ready to be used, false +//! otherwise +// +//***************************************************************************** +extern bool REF_A_getBufferedBandgapVoltageStatus(void); + +//***************************************************************************** +// +//! Returns the busy status of the variable reference voltage in the REF module. +//! +//! This function is used to return the buys status of the variable reference +//! voltage in the REF module. If the ref. generator is on and ready to use, +//! then the status will be seen as active. +//! +//! \return true if the variable bandgap voltage is ready to be used, false +//! otherwise +// +//***************************************************************************** +extern bool REF_A_getVariableReferenceVoltageStatus(void); + +//***************************************************************************** +// +//! Enables the one-time trigger of the reference voltage. +//! +//! Triggers the one-time generation of the variable reference voltage. Once +//! the reference voltage request is set, this bit is cleared by hardware +//! +//! Modified bits are \b REFGENOT of \b REFCTL0 register. +//! +//! \return none +// +//***************************************************************************** +extern void REF_A_setReferenceVoltageOneTimeTrigger(void); + +//***************************************************************************** +// +//! Enables the one-time trigger of the buffered bandgap voltage. +//! +//! Triggers the one-time generation of the buffered bandgap voltage. Once +//! the buffered bandgap voltage request is set, this bit is cleared by hardware +//! +//! Modified bits are \b RefGOT of \b REFCTL0 register. +//! +//! \return none +// +//***************************************************************************** +extern void REF_A_setBufferedBandgapVoltageOneTimeTrigger(void); + +/* Defines for future devices that might have multiple instances */ +#define REF_A_setReferenceVoltageMultipleInstance(a,b) REF_A_setReferenceVoltage(b) +#define REF_A_disableTempSensorMultipleInstance(a) REF_A_disableTempSensor() +#define REF_A_enableTempSensorMultipleInstance(a) REF_A_enableTempSensor() +#define REF_A_enableReferenceVoltageOutputMultipleInstance(a) REF_A_enableReferenceVoltageOutput() +#define REF_A_disableReferenceVoltageOutputMultipleInstance(a) REF_A_disableReferenceVoltageOutput() +#define REF_A_enableReferenceVoltageMultipleInstance(a) REF_A_enableReferenceVoltage() +#define REF_A_disableReferenceVoltageMultipleInstance(a) REF_A_disableReferenceVoltage() +#define REF_A_getBandgapModeMultipleInstance(a) REF_A_getBandgapMode() +#define REF_A_isBandgapActiveMultipleInstance(a) REF_A_isBandgapActive() +#define REF_A_isRefGenBusyMultipleInstance(a) REF_A_isRefGenBusy() +#define REF_A_isRefGenActiveMultipleInstance(a) REF_A_isRefGenActive() +#define REF_A_getBufferedBandgapVoltageStatusMultipleInstance(a) REF_A_getBufferedBandgapVoltageStatus() +#define REF_A_getVariableReferenceVoltageStatusMultipleInstance(a) REF_A_getVariableReferenceVoltageStatus() +#define REF_A_setReferenceVoltageOneTimeTriggerMultipleInstance(a) REF_A_setReferenceVoltageOneTimeTrigger() +#define REF_A_setBufferedBandgapVoltageOneTimeTriggerMultipleInstance(a) REF_A_setBufferedBandgapVoltageOneTimeTrigger() + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __REF_A_H__ diff --git a/example/rt_msp432/MSP432P4xx/reset.c b/example/rt_msp432/MSP432P4xx/reset.c new file mode 100644 index 0000000..98017a3 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/reset.c @@ -0,0 +1,99 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include + +void ResetCtl_initiateSoftReset(void) +{ + RSTCTL->RESET_REQ |= (RESET_KEY | RESET_SOFT_RESET); +} + +void ResetCtl_initiateSoftResetWithSource(uint32_t source) +{ + RSTCTL->SOFTRESET_SET |= (source); +} + +uint32_t ResetCtl_getSoftResetSource(void) +{ + return RSTCTL->SOFTRESET_STAT; +} + +void ResetCtl_clearSoftResetSource(uint32_t mask) +{ + RSTCTL->SOFTRESET_CLR |= mask; +} + +void ResetCtl_initiateHardReset(void) +{ + RSTCTL->RESET_REQ |= (RESET_KEY | RESET_HARD_RESET); +} + +void ResetCtl_initiateHardResetWithSource(uint32_t source) +{ + RSTCTL->HARDRESET_SET |= (source); +} + +uint32_t ResetCtl_getHardResetSource(void) +{ + return RSTCTL->HARDRESET_STAT; +} + +void ResetCtl_clearHardResetSource(uint32_t mask) +{ + RSTCTL->HARDRESET_CLR |= mask; +} + +uint32_t ResetCtl_getPSSSource(void) +{ + return RSTCTL->PSSRESET_STAT; +} + +void ResetCtl_clearPSSFlags(void) +{ + RSTCTL->PSSRESET_CLR |= RSTCTL_PSSRESET_CLR_CLR; +} + +uint32_t ResetCtl_getPCMSource(void) +{ + return RSTCTL->PCMRESET_STAT; +} + +void ResetCtl_clearPCMFlags(void) +{ + RSTCTL->PCMRESET_CLR |= RSTCTL_PCMRESET_CLR_CLR; +} + diff --git a/example/rt_msp432/MSP432P4xx/reset.h b/example/rt_msp432/MSP432P4xx/reset.h new file mode 100644 index 0000000..5bd9638 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/reset.h @@ -0,0 +1,343 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __RESET_H__ +#define __RESET_H__ + +//***************************************************************************** +// +//! \addtogroup reset_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +//***************************************************************************** +// +// Control specific variables +// +//***************************************************************************** +#define RESET_KEY 0x6900 +#define RESET_HARD_RESET RSTCTL_RESET_REQ_HARD_REQ +#define RESET_SOFT_RESET RSTCTL_RESET_REQ_SOFT_REQ + +#define RESET_SRC_0 RSTCTL_HARDRESET_CLR_SRC0 +#define RESET_SRC_1 RSTCTL_HARDRESET_CLR_SRC1 +#define RESET_SRC_2 RSTCTL_HARDRESET_CLR_SRC2 +#define RESET_SRC_3 RSTCTL_HARDRESET_CLR_SRC3 +#define RESET_SRC_4 RSTCTL_HARDRESET_CLR_SRC4 +#define RESET_SRC_5 RSTCTL_HARDRESET_CLR_SRC5 +#define RESET_SRC_6 RSTCTL_HARDRESET_CLR_SRC6 +#define RESET_SRC_7 RSTCTL_HARDRESET_CLR_SRC7 +#define RESET_SRC_8 RSTCTL_HARDRESET_CLR_SRC8 +#define RESET_SRC_9 RSTCTL_HARDRESET_CLR_SRC9 +#define RESET_SRC_10 RSTCTL_HARDRESET_CLR_SRC10 +#define RESET_SRC_11 RSTCTL_HARDRESET_CLR_SRC11 +#define RESET_SRC_12 RSTCTL_HARDRESET_CLR_SRC12 +#define RESET_SRC_13 RSTCTL_HARDRESET_CLR_SRC13 +#define RESET_SRC_14 RSTCTL_HARDRESET_CLR_SRC14 +#define RESET_SRC_15 RSTCTL_HARDRESET_CLR_SRC15 + +#define RESET_VCCDET RSTCTL_PSSRESET_CLR_BGREF +#define RESET_SVSH_TRIP RSTCTL_PSSRESET_CLR_SVSMH +#define RESET_BGREF_BAD RSTCTL_PSSRESET_CLR_BGREF + +#define RESET_LPM35 RSTCTL_PCMRESET_CLR_LPM35 +#define RESET_LPM45 RSTCTL_PCMRESET_CLR_LPM45 + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! Initiates a soft system reset. +//! +//! \return none +// +//***************************************************************************** +extern void ResetCtl_initiateSoftReset(void); + +//***************************************************************************** +// +//! Initiates a soft system reset with a particular source given. This source +//! is generic and can be assigned by the user. +//! +//! \param source Source of the reset. Valid values are: +//! - \b RESET_SRC_0, +//! - \b RESET_SRC_1, +//! - \b RESET_SRC_2, +//! - \b RESET_SRC_3, +//! - \b RESET_SRC_4, +//! - \b RESET_SRC_5, +//! - \b RESET_SRC_6, +//! - \b RESET_SRC_7, +//! - \b RESET_SRC_8, +//! - \b RESET_SRC_9, +//! - \b RESET_SRC_10, +//! - \b RESET_SRC_11, +//! - \b RESET_SRC_12, +//! - \b RESET_SRC_13, +//! - \b RESET_SRC_14, +//! - \b RESET_SRC_15 +//! +//! \return none +// +//***************************************************************************** +extern void ResetCtl_initiateSoftResetWithSource(uint32_t source); + +//***************************************************************************** +// +//! Retrieves previous soft reset sources +//! +//! \return the bitwise or of previous reset sources. These sources must be +//! cleared using the \link ResetCtl_clearSoftResetSource \endlink function to +//! be cleared. +//! Possible values include: +//! - \b RESET_SRC_0, +//! - \b RESET_SRC_1, +//! - \b RESET_SRC_2, +//! - \b RESET_SRC_3, +//! - \b RESET_SRC_4, +//! - \b RESET_SRC_5, +//! - \b RESET_SRC_6, +//! - \b RESET_SRC_7, +//! - \b RESET_SRC_8, +//! - \b RESET_SRC_9, +//! - \b RESET_SRC_10, +//! - \b RESET_SRC_11, +//! - \b RESET_SRC_12, +//! - \b RESET_SRC_13, +//! - \b RESET_SRC_14, +//! - \b RESET_SRC_15 +// +//***************************************************************************** +extern uint32_t ResetCtl_getSoftResetSource(void); + +//***************************************************************************** +// +//! Clears the reset sources associated with at soft reset +//! +//! \param mask - Bitwise OR of any of the following values: +//! - \b RESET_SRC_0, +//! - \b RESET_SRC_1, +//! - \b RESET_SRC_2, +//! - \b RESET_SRC_3, +//! - \b RESET_SRC_4, +//! - \b RESET_SRC_5, +//! - \b RESET_SRC_6, +//! - \b RESET_SRC_7, +//! - \b RESET_SRC_8, +//! - \b RESET_SRC_9, +//! - \b RESET_SRC_10, +//! - \b RESET_SRC_11, +//! - \b RESET_SRC_12, +//! - \b RESET_SRC_13, +//! - \b RESET_SRC_14, +//! - \b RESET_SRC_15 +//! +//! \return none +// +//***************************************************************************** +extern void ResetCtl_clearSoftResetSource(uint32_t mask); + +//***************************************************************************** +// +//! Initiates a hard system reset. +//! +//! \return none +// +//***************************************************************************** +extern void ResetCtl_initiateHardReset(void); + +//***************************************************************************** +// +//! Initiates a hard system reset with a particular source given. This source +//! is generic and can be assigned by the user. +//! +//! \param source - Valid values are one the following values: +//! - \b RESET_SRC_0, +//! - \b RESET_SRC_1, +//! - \b RESET_SRC_2, +//! - \b RESET_SRC_3, +//! - \b RESET_SRC_4, +//! - \b RESET_SRC_5, +//! - \b RESET_SRC_6, +//! - \b RESET_SRC_7, +//! - \b RESET_SRC_8, +//! - \b RESET_SRC_9, +//! - \b RESET_SRC_10, +//! - \b RESET_SRC_11, +//! - \b RESET_SRC_12, +//! - \b RESET_SRC_13, +//! - \b RESET_SRC_14, +//! - \b RESET_SRC_15 +//! \return none +// +//***************************************************************************** +extern void ResetCtl_initiateHardResetWithSource(uint32_t source); + +//***************************************************************************** +// +//! Retrieves previous hard reset sources +//! +//! \return the bitwise or of previous reset sources. These sources must be +//! cleared using the \link ResetCtl_clearHardResetSource \endlink function to +//! be cleared. +//! Possible values include: +//! - \b RESET_SRC_0, +//! - \b RESET_SRC_1, +//! - \b RESET_SRC_2, +//! - \b RESET_SRC_3, +//! - \b RESET_SRC_4, +//! - \b RESET_SRC_5, +//! - \b RESET_SRC_6, +//! - \b RESET_SRC_7, +//! - \b RESET_SRC_8, +//! - \b RESET_SRC_9, +//! - \b RESET_SRC_10, +//! - \b RESET_SRC_11, +//! - \b RESET_SRC_12, +//! - \b RESET_SRC_13, +//! - \b RESET_SRC_14, +//! - \b RESET_SRC_15 +// +//***************************************************************************** +extern uint32_t ResetCtl_getHardResetSource(void); + +//***************************************************************************** +// +//! Clears the reset sources associated with at hard reset +//! +//! \param mask - Bitwise OR of any of the following values: +//! - \b RESET_SRC_0, +//! - \b RESET_SRC_1, +//! - \b RESET_SRC_2, +//! - \b RESET_SRC_3, +//! - \b RESET_SRC_4, +//! - \b RESET_SRC_5, +//! - \b RESET_SRC_6, +//! - \b RESET_SRC_7, +//! - \b RESET_SRC_8, +//! - \b RESET_SRC_9, +//! - \b RESET_SRC_10, +//! - \b RESET_SRC_11, +//! - \b RESET_SRC_12, +//! - \b RESET_SRC_13, +//! - \b RESET_SRC_14, +//! - \b RESET_SRC_15 +//! +//! \return none +// +//***************************************************************************** +extern void ResetCtl_clearHardResetSource(uint32_t mask); + +//***************************************************************************** +// +//! Indicates the last cause of a power-on reset (POR) due to PSS operation. +//! Note that the bits returned from this function may be set in different +//! combinations. When a cold power up occurs, the value of all the values ORed +//! together could be returned as a cold power up causes these conditions. +//! +//! \return Bitwise OR of any of the following values: +//! - RESET_VCCDET, +//! - RESET_SVSH_TRIP, +//! - RESET_BGREF_BAD +// +//***************************************************************************** +extern uint32_t ResetCtl_getPSSSource(void); + +//***************************************************************************** +// +//! Clears the PSS reset source flags +//! +//! \return none +// +//***************************************************************************** +extern void ResetCtl_clearPSSFlags(void); + +//***************************************************************************** +// +//! Indicates the last cause of a power-on reset (POR) due to PCM operation. +//! +//! \return Bitwise OR of any of the following values: +//! - RESET_LPM35, +//! - RESET_LPM45 +// +//***************************************************************************** +extern uint32_t ResetCtl_getPCMSource(void); + +//***************************************************************************** +// +//! Clears the corresponding PCM reset source flags +//! +//! \return none +// +//***************************************************************************** +extern void ResetCtl_clearPCMFlags(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __RESET_H__ diff --git a/example/rt_msp432/MSP432P4xx/rom.h b/example/rt_msp432/MSP432P4xx/rom.h new file mode 100644 index 0000000..ab563e5 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/rom.h @@ -0,0 +1,2154 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __ROM_H__ +#define __ROM_H__ + +//***************************************************************************** +// +// Pointers to the main API tables. +// +//***************************************************************************** +#define ROM_APITABLE ((unsigned long *)0x02000800) +#define ROM_VERSION (ROM_APITABLE[0]) +#define ROM_ADC14TABLE ((unsigned long *)(ROM_APITABLE[1])) +#define ROM_AES256TABLE ((unsigned long *)(ROM_APITABLE[2])) +#define ROM_COMPTABLE ((unsigned long *)(ROM_APITABLE[3])) +#define ROM_CRC32TABLE ((unsigned long *)(ROM_APITABLE[4])) +#define ROM_CSTABLE ((unsigned long *)(ROM_APITABLE[5])) +#define ROM_DMATABLE ((unsigned long *)(ROM_APITABLE[6])) +#define ROM_FLASHCTLTABLE ((unsigned long *)(ROM_APITABLE[7])) +#define ROM_FPUTABLE ((unsigned long *)(ROM_APITABLE[8])) +#define ROM_GPIOTABLE ((unsigned long *)(ROM_APITABLE[9])) +#define ROM_I2CTABLE ((unsigned long *)(ROM_APITABLE[10])) +#define ROM_INTTABLE ((unsigned long *)(ROM_APITABLE[11])) +#define ROM_MPUTABLE ((unsigned long *)(ROM_APITABLE[12])) +#define ROM_PCMTABLE ((unsigned long *)(ROM_APITABLE[13])) +#define ROM_PMAPTABLE ((unsigned long *)(ROM_APITABLE[14])) +#define ROM_PSSTABLE ((unsigned long *)(ROM_APITABLE[15])) +#define ROM_REFTABLE ((unsigned long *)(ROM_APITABLE[16])) +#define ROM_RESETCTLTABLE ((unsigned long *)(ROM_APITABLE[17])) +#define ROM_RTCTABLE ((unsigned long *)(ROM_APITABLE[18])) +#define ROM_SPITABLE ((unsigned long *)(ROM_APITABLE[19])) +#define ROM_SYSCTLTABLE ((unsigned long *)(ROM_APITABLE[20])) +#define ROM_SYSTICKTABLE ((unsigned long *)(ROM_APITABLE[21])) +#define ROM_TIMER_ATABLE ((unsigned long *)(ROM_APITABLE[22])) +#define ROM_TIMER32TABLE ((unsigned long *)(ROM_APITABLE[23])) +#define ROM_UARTTABLE ((unsigned long *)(ROM_APITABLE[24])) +#define ROM_WDTTABLE ((unsigned long *)(ROM_APITABLE[25])) + +//***************************************************************************** +// +// Macros for calling ROM functions in the ADC14 API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_enableModule \ + ((void (*)(void))ROM_ADC14TABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_disableModule \ + ((bool (*)(void))ROM_ADC14TABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_initModule \ + ((bool (*)(uint32_t clockSource, \ + uint32_t clockPredivider, \ + uint32_t clockDivider, \ + uint32_t internalChannelMask))ROM_ADC14TABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_setResolution \ + ((void (*)(uint32_t resolution))ROM_ADC14TABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_getResolution \ + ((uint_fast32_t (*)(void))ROM_ADC14TABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_setSampleHoldTrigger \ + ((bool (*)(uint32_t source, \ + bool invertSignal))ROM_ADC14TABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_setSampleHoldTime \ + ((bool (*)(uint32_t firstPulseWidth, \ + uint32_t secondPulseWidth))ROM_ADC14TABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_configureMultiSequenceMode \ + ((bool (*)(uint32_t memoryStart, \ + uint32_t memoryEnd, \ + bool repeatMode))ROM_ADC14TABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_configureSingleSampleMode \ + ((bool (*)(uint32_t memoryDestination, \ + bool repeatMode))ROM_ADC14TABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_enableConversion \ + ((bool (*)(void))ROM_ADC14TABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_disableConversion \ + ((void (*)(void))ROM_ADC14TABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_isBusy \ + ((bool (*)(void))ROM_ADC14TABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_configureConversionMemory \ + ((bool (*)(uint32_t memorySelect, \ + uint32_t refSelect, \ + uint32_t channelSelect, \ + bool differntialMode))ROM_ADC14TABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_enableComparatorWindow \ + ((bool (*)(uint32_t memorySelect, \ + uint32_t windowSelect))ROM_ADC14TABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_disableComparatorWindow \ + ((bool (*)(uint32_t memorySelect))ROM_ADC14TABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_setComparatorWindowValue \ + ((bool (*)(uint32_t window, \ + int16_t low, \ + int16_t high))ROM_ADC14TABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_setResultFormat \ + ((bool (*)(uint32_t resultFormat))ROM_ADC14TABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_getResult \ + ((uint_fast16_t (*)(uint32_t memorySelect))ROM_ADC14TABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_getResultArray \ + ((void (*)(uint32_t memoryStart, \ + uint32_t memoryEnd, \ + uint16_t* res))ROM_ADC14TABLE[19]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_enableReferenceBurst \ + ((bool (*)(void))ROM_ADC14TABLE[20]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_disableReferenceBurst \ + ((bool (*)(void))ROM_ADC14TABLE[21]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_setPowerMode \ + ((bool (*)(uint32_t powerMode))ROM_ADC14TABLE[22]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_enableInterrupt \ + ((void (*)(uint_fast64_t mask))ROM_ADC14TABLE[23]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_disableInterrupt \ + ((void (*)(uint_fast64_t mask))ROM_ADC14TABLE[24]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_getInterruptStatus \ + ((uint_fast64_t (*)(void))ROM_ADC14TABLE[25]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_getEnabledInterruptStatus \ + ((uint_fast64_t (*)(void))ROM_ADC14TABLE[26]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_clearInterruptFlag \ + ((void (*)(uint_fast64_t mask))ROM_ADC14TABLE[27]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_toggleConversionTrigger \ + ((bool (*)(void))ROM_ADC14TABLE[28]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_enableSampleTimer \ + ((bool (*)(uint32_t multiSampleConvert))ROM_ADC14TABLE[29]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ADC14_disableSampleTimer \ + ((bool (*)(void))ROM_ADC14TABLE[30]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the AES256 API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_setCipherKey \ + ((bool (*)(uint32_t moduleInstance, \ + const uint8_t *cipherKey, \ + uint_fast16_t keyLength))ROM_AES256TABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_encryptData \ + ((void (*)(uint32_t moduleInstance, \ + const uint8_t *data, \ + uint8_t *encryptedData))ROM_AES256TABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_decryptData \ + ((void (*)(uint32_t moduleInstance, \ + const uint8_t *data, \ + uint8_t *decryptedData))ROM_AES256TABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_setDecipherKey \ + ((bool (*)(uint32_t moduleInstance, \ + const uint8_t *cipherKey, \ + uint_fast16_t keyLength))ROM_AES256TABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_reset \ + ((void (*)(uint32_t moduleInstance))ROM_AES256TABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_startEncryptData \ + ((void (*)(uint32_t moduleInstance, \ + const uint8_t *data))ROM_AES256TABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_startDecryptData \ + ((void (*)(uint32_t moduleInstance, \ + const uint8_t *data))ROM_AES256TABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_startSetDecipherKey \ + ((bool (*)(uint32_t moduleInstance, \ + const uint8_t *cipherKey, \ + uint_fast16_t keyLength))ROM_AES256TABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_getDataOut \ + ((bool (*)(uint32_t moduleInstance, \ + uint8_t *outputData))ROM_AES256TABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_isBusy \ + ((bool (*)(uint32_t moduleInstance))ROM_AES256TABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_clearErrorFlag \ + ((void (*)(uint32_t moduleInstance))ROM_AES256TABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_getErrorFlagStatus \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_AES256TABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_clearInterruptFlag \ + ((void (*)(uint32_t moduleInstance))ROM_AES256TABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_getInterruptStatus \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_AES256TABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_enableInterrupt \ + ((void (*)(uint32_t moduleInstance))ROM_AES256TABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_disableInterrupt \ + ((void (*)(uint32_t moduleInstance))ROM_AES256TABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_AES256_getInterruptFlagStatus \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_AES256TABLE[18]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the Comp API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_initModule \ + ((bool (*)(uint32_t comparator, \ + const COMP_E_Config *config))ROM_COMPTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_setReferenceVoltage \ + ((void (*)(uint32_t comparator, \ + uint_fast16_t supplyVoltageReferenceBase, \ + uint_fast16_t lowerLimitSupplyVoltageFractionOf32, \ + uint_fast16_t upperLimitSupplyVoltageFractionOf32))ROM_COMPTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_setReferenceAccuracy \ + ((void (*)(uint32_t comparator, \ + uint_fast16_t referenceAccuracy))ROM_COMPTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_setPowerMode \ + ((void (*)(uint32_t comparator, \ + uint_fast16_t powerMode))ROM_COMPTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_enableModule \ + ((void (*)(uint32_t comparator))ROM_COMPTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_disableModule \ + ((void (*)(uint32_t comparator))ROM_COMPTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_shortInputs \ + ((void (*)(uint32_t comparator))ROM_COMPTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_unshortInputs \ + ((void (*)(uint32_t comparator))ROM_COMPTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_disableInputBuffer \ + ((void (*)(uint32_t comparator, \ + uint_fast16_t inputPort))ROM_COMPTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_enableInputBuffer \ + ((void (*)(uint32_t comparator, \ + uint_fast16_t inputPort))ROM_COMPTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_swapIO \ + ((void (*)(uint32_t comparator))ROM_COMPTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_outputValue \ + ((uint8_t (*)(uint32_t comparator))ROM_COMPTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_enableInterrupt \ + ((void (*)(uint32_t comparator, \ + uint_fast16_t mask))ROM_COMPTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_disableInterrupt \ + ((void (*)(uint32_t comparator, \ + uint_fast16_t mask))ROM_COMPTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_clearInterruptFlag \ + ((void (*)(uint32_t comparator, \ + uint_fast16_t mask))ROM_COMPTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_getInterruptStatus \ + ((uint_fast16_t (*)(uint32_t comparator))ROM_COMPTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_getEnabledInterruptStatus \ + ((uint_fast16_t (*)(uint32_t comparator))ROM_COMPTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_setInterruptEdgeDirection \ + ((void (*)(uint32_t comparator, \ + uint_fast8_t edgeDirection))ROM_COMPTABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_COMP_E_toggleInterruptEdgeDirection \ + ((void (*)(uint32_t comparator))ROM_COMPTABLE[18]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the CRC32 API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_setSeed \ + ((void (*)(uint32_t seed, \ + uint_fast8_t crcType))ROM_CRC32TABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_set8BitData \ + ((void (*)(uint8_t dataIn, \ + uint_fast8_t crcType))ROM_CRC32TABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_set16BitData \ + ((void (*)(uint16_t dataIn, \ + uint_fast8_t crcType))ROM_CRC32TABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_set32BitData \ + ((void (*)(uint32_t dataIn))ROM_CRC32TABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_set8BitDataReversed \ + ((void (*)(uint8_t dataIn, \ + uint_fast8_t crcType))ROM_CRC32TABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_set16BitDataReversed \ + ((void (*)(uint16_t dataIn, \ + uint_fast8_t crcType))ROM_CRC32TABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_set32BitDataReversed \ + ((void (*)(uint32_t dataIn))ROM_CRC32TABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_getResult \ + ((uint32_t (*)(uint_fast8_t crcType))ROM_CRC32TABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CRC32_getResultReversed \ + ((uint32_t (*)(uint_fast8_t crcType))ROM_CRC32TABLE[8]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the CS API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_initClockSignal \ + ((void (*)(uint32_t selectedClockSignal, \ + uint32_t clockSource, \ + uint32_t clockSourceDivider))ROM_CSTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_setReferenceOscillatorFrequency \ + ((void (*)(uint8_t referenceFrequency))ROM_CSTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_enableClockRequest \ + ((void (*)(uint32_t selectClock))ROM_CSTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_disableClockRequest \ + ((void (*)(uint32_t selectClock))ROM_CSTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_setDCOCenteredFrequency \ + ((void (*)(uint32_t dcoFreq))ROM_CSTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_tuneDCOFrequency \ + ((void (*)(int16_t tuneParameter))ROM_CSTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_enableDCOExternalResistor \ + ((void (*)(void))ROM_CSTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_disableDCOExternalResistor \ + ((void (*)(void))ROM_CSTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_enableInterrupt \ + ((void (*)(uint32_t flags))ROM_CSTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_disableInterrupt \ + ((void (*)(uint32_t flags))ROM_CSTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_getEnabledInterruptStatus \ + ((uint32_t (*)(void))ROM_CSTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_getInterruptStatus \ + ((uint32_t (*)(void))ROM_CSTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_setDCOFrequency \ + ((void (*)(uint32_t dcoFrequency))ROM_CSTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_getDCOFrequency \ + ((uint32_t (*)(void))ROM_CSTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_enableFaultCounter \ + ((void (*)(uint_fast8_t counterSelect))ROM_CSTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_disableFaultCounter \ + ((void (*)(uint_fast8_t counterSelect))ROM_CSTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_resetFaultCounter \ + ((void (*)(uint_fast8_t counterSelect))ROM_CSTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_startFaultCounter \ + ((void (*)(uint_fast8_t counterSelect, \ + uint_fast8_t countValue))ROM_CSTABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_clearInterruptFlag \ + ((void (*)(uint32_t flags))ROM_CSTABLE[20]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_CS_setDCOExternalResistorCalibration \ + ((void (*)(uint_fast8_t uiCalData, \ + uint_fast8_t freqRange))ROM_CSTABLE[31]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the DMA API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_enableModule \ + ((void (*)(void))ROM_DMATABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_disableModule \ + ((void (*)(void))ROM_DMATABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_getErrorStatus \ + ((uint32_t (*)(void))ROM_DMATABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_clearErrorStatus \ + ((void (*)(void))ROM_DMATABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_enableChannel \ + ((void (*)(uint32_t channelNum))ROM_DMATABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_disableChannel \ + ((void (*)(uint32_t channelNum))ROM_DMATABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_isChannelEnabled \ + ((bool (*)(uint32_t channelNum))ROM_DMATABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_setControlBase \ + ((void (*)(void *controlTable))ROM_DMATABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_getControlBase \ + ((void* (*)(void))ROM_DMATABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_getControlAlternateBase \ + ((void* (*)(void))ROM_DMATABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_requestChannel \ + ((void (*)(uint32_t channelNum))ROM_DMATABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_enableChannelAttribute \ + ((void (*)(uint32_t channelNum, \ + uint32_t attr))ROM_DMATABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_disableChannelAttribute \ + ((void (*)(uint32_t channelNum, \ + uint32_t attr))ROM_DMATABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_getChannelAttribute \ + ((uint32_t (*)(uint32_t channelNum))ROM_DMATABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_setChannelControl \ + ((void (*)(uint32_t channelStructIndex, \ + uint32_t control))ROM_DMATABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_setChannelTransfer \ + ((void (*)(uint32_t channelStructIndex, \ + uint32_t mode, \ + void *srcAddr, \ + void *dstAddr, \ + uint32_t transferSize))ROM_DMATABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_setChannelScatterGather \ + ((void (*)(uint32_t channelNum, \ + uint32_t taskCount, \ + void *taskList, \ + uint32_t isPeriphSG))ROM_DMATABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_getChannelSize \ + ((uint32_t (*)(uint32_t channelStructIndex))ROM_DMATABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_getChannelMode \ + ((uint32_t (*)(uint32_t channelStructIndex))ROM_DMATABLE[18]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_assignChannel \ + ((void (*)(uint32_t mapping))ROM_DMATABLE[19]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_requestSoftwareTransfer \ + ((void (*)(uint32_t channel))ROM_DMATABLE[20]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_assignInterrupt \ + ((void (*)(uint32_t interruptNumber, \ + uint32_t channel))ROM_DMATABLE[21]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_enableInterrupt \ + ((void (*)(uint32_t interruptNumber))ROM_DMATABLE[22]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_disableInterrupt \ + ((void (*)(uint32_t interruptNumber))ROM_DMATABLE[23]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_getInterruptStatus \ + ((uint32_t (*)(void))ROM_DMATABLE[24]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_DMA_clearInterruptFlag \ + ((void (*)(uint32_t intChannel))ROM_DMATABLE[25]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the Flash API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_enableReadBuffering \ + ((void (*)(uint_fast8_t memoryBank, \ + uint_fast8_t accessMethod))ROM_FLASHCTLTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_disableReadBuffering \ + ((void (*)(uint_fast8_t memoryBank, \ + uint_fast8_t accessMethod))ROM_FLASHCTLTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_unprotectSector \ + ((bool (*)(uint_fast8_t memorySpace, \ + uint32_t sectorMask))ROM_FLASHCTLTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_protectSector \ + ((bool (*)(uint_fast8_t memorySpace, \ + uint32_t sectorMask))ROM_FLASHCTLTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_isSectorProtected \ + ((bool (*)(uint_fast8_t memorySpace, \ + uint32_t sector))ROM_FLASHCTLTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_verifyMemory \ + ((bool (*)(void* verifyAddr, \ + uint32_t length, \ + uint_fast8_t pattern))ROM_FLASHCTLTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_performMassErase \ + ((bool (*)(void))ROM_FLASHCTLTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_eraseSector \ + ((bool (*)(uint32_t addr))ROM_FLASHCTLTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_programMemory \ + ((bool (*)(void* src, \ + void* dest, \ + uint32_t length))ROM_FLASHCTLTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_setProgramVerification \ + ((void (*)(uint32_t verificationSetting))ROM_FLASHCTLTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_clearProgramVerification \ + ((void (*)(uint32_t verificationSetting))ROM_FLASHCTLTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_enableWordProgramming \ + ((void (*)(uint32_t mode))ROM_FLASHCTLTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_disableWordProgramming \ + ((void (*)(void))ROM_FLASHCTLTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_isWordProgrammingEnabled \ + ((uint32_t (*)(void))ROM_FLASHCTLTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_enableInterrupt \ + ((void (*)(uint32_t flags))ROM_FLASHCTLTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_disableInterrupt \ + ((void (*)(uint32_t flags))ROM_FLASHCTLTABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_getEnabledInterruptStatus \ + ((uint32_t (*)(void))ROM_FLASHCTLTABLE[18]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_getInterruptStatus \ + ((uint32_t (*)(void))ROM_FLASHCTLTABLE[19]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_clearInterruptFlag \ + ((void (*)(uint32_t flags))ROM_FLASHCTLTABLE[20]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_setWaitState \ + ((void (*)(uint32_t bank, \ + uint32_t waitState))ROM_FLASHCTLTABLE[21]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_getWaitState \ + ((uint32_t (*)(uint32_t bank))ROM_FLASHCTLTABLE[22]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_setReadMode \ + ((bool (*)(uint32_t flashBank, \ + uint32_t readMode))ROM_FLASHCTLTABLE[23]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_getReadMode \ + ((uint32_t (*)(uint32_t flashBank))ROM_FLASHCTLTABLE[24]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM___FlashCtl_remaskData8Post \ + ((uint8_t (*)(uint8_t data, \ + uint32_t addr))ROM_FLASHCTLTABLE[27]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM___FlashCtl_remaskData8Pre \ + ((uint8_t (*)(uint8_t data, \ + uint32_t addr))ROM_FLASHCTLTABLE[28]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM___FlashCtl_remaskData32Pre \ + ((uint32_t (*)(uint32_t data, \ + uint32_t addr))ROM_FLASHCTLTABLE[29]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM___FlashCtl_remaskData32Post \ + ((uint32_t (*)(uint32_t data, \ + uint32_t addr))ROM_FLASHCTLTABLE[30]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM___FlashCtl_remaskBurstDataPre \ + ((void (*)(uint32_t addr, \ + uint32_t size))ROM_FLASHCTLTABLE[31]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM___FlashCtl_remaskBurstDataPost \ + ((void (*)(uint32_t addr, \ + uint32_t size))ROM_FLASHCTLTABLE[32]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_initiateSectorErase \ + ((void (*)(uint32_t addr))ROM_FLASHCTLTABLE[33]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FlashCtl_initiateMassErase \ + ((void (*)(void))ROM_FLASHCTLTABLE[34]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the FPU API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_enableModule \ + ((void (*)(void))ROM_FPUTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_disableModule \ + ((void (*)(void))ROM_FPUTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_enableStacking \ + ((void (*)(void))ROM_FPUTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_enableLazyStacking \ + ((void (*)(void))ROM_FPUTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_disableStacking \ + ((void (*)(void))ROM_FPUTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_setHalfPrecisionMode \ + ((void (*)(uint32_t mode))ROM_FPUTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_setNaNMode \ + ((void (*)(uint32_t mode))ROM_FPUTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_setFlushToZeroMode \ + ((void (*)(uint32_t mode))ROM_FPUTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_FPU_setRoundingMode \ + ((void (*)(uint32_t mode))ROM_FPUTABLE[8]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the GPIO API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setAsOutputPin \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setOutputHighOnPin \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setOutputLowOnPin \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_toggleOutputOnPin \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setAsInputPinWithPullDownResistor \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setAsInputPinWithPullUpResistor \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setAsPeripheralModuleFunctionOutputPin \ + ((void (*)( uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins, \ + uint_fast8_t mode))ROM_GPIOTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setAsPeripheralModuleFunctionInputPin \ + ((void (*)( uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins, \ + uint_fast8_t mode))ROM_GPIOTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_getInputPinValue \ + ((uint8_t (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_interruptEdgeSelect \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins, \ + uint_fast8_t edgeSelect))ROM_GPIOTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_enableInterrupt \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_disableInterrupt \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_getInterruptStatus \ + ((uint_fast16_t (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_clearInterruptFlag \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setAsInputPin \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast16_t selectedPins))ROM_GPIOTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_getEnabledInterruptStatus \ + ((uint_fast16_t (*)(uint_fast8_t selectedPort))ROM_GPIOTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setDriveStrengthHigh \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast8_t selectedPins))ROM_GPIOTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_GPIO_setDriveStrengthLow \ + ((void (*)(uint_fast8_t selectedPort, \ + uint_fast8_t selectedPins))ROM_GPIOTABLE[17]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the I2C API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_initMaster \ + ((void (*)(uint32_t moduleInstance, \ + const eUSCI_I2C_MasterConfig *config))ROM_I2CTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_initSlave \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast16_t slaveAddress, \ + uint_fast8_t slaveAddressOffset, \ + uint32_t slaveOwnAddressEnable))ROM_I2CTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_enableModule \ + ((void (*)(uint32_t moduleInstance))ROM_I2CTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_disableModule \ + ((void (*)(uint32_t moduleInstance))ROM_I2CTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_setSlaveAddress \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast16_t slaveAddress))ROM_I2CTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_setMode \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t mode))ROM_I2CTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_slavePutData \ + ((void (*)(uint32_t moduleInstance, \ + uint8_t transmitData))ROM_I2CTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_slaveGetData \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_isBusBusy \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendSingleByte \ + ((void (*)(uint32_t moduleInstance, \ + uint8_t txData))ROM_I2CTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendSingleByteWithTimeout \ + ((bool (*)(uint32_t moduleInstance, \ + uint8_t txData, \ + uint32_t timeout))ROM_I2CTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendMultiByteStart \ + ((void (*)(uint32_t moduleInstance, \ + uint8_t txData))ROM_I2CTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendMultiByteStartWithTimeout \ + ((bool (*)(uint32_t moduleInstance, \ + uint8_t txData, \ + uint32_t timeout))ROM_I2CTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendMultiByteNext \ + ((void (*)(uint32_t moduleInstance, \ + uint8_t txData))ROM_I2CTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendMultiByteNextWithTimeout \ + ((bool (*)(uint32_t moduleInstance, \ + uint8_t txData, \ + uint32_t timeout))ROM_I2CTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendMultiByteFinish \ + ((void (*)(uint32_t moduleInstance, \ + uint8_t txData))ROM_I2CTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendMultiByteFinishWithTimeout \ + ((bool (*)(uint32_t moduleInstance, \ + uint8_t txData, \ + uint32_t timeout))ROM_I2CTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendMultiByteStop \ + ((void (*)(uint32_t moduleInstance))ROM_I2CTABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendMultiByteStopWithTimeout \ + ((bool (*)(uint32_t moduleInstance, \ + uint32_t timeout))ROM_I2CTABLE[18]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterReceiveStart \ + ((void (*)(uint32_t moduleInstance))ROM_I2CTABLE[19]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterReceiveMultiByteNext \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[20]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterReceiveMultiByteFinish \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[21]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterReceiveMultiByteFinishWithTimeout \ + ((bool (*)(uint32_t moduleInstance, \ + uint8_t *txData, \ + uint32_t timeout))ROM_I2CTABLE[22]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterReceiveMultiByteStop \ + ((void (*)(uint32_t moduleInstance))ROM_I2CTABLE[23]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterReceiveSingleByte \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[24]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterReceiveSingle \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[25]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_getReceiveBufferAddressForDMA \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[26]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_getTransmitBufferAddressForDMA \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[27]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterIsStopSent \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[28]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterIsStartSent \ + ((bool (*)(uint32_t moduleInstance))ROM_I2CTABLE[29]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_masterSendStart \ + ((void (*)(uint32_t moduleInstance))ROM_I2CTABLE[30]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_enableMultiMasterMode \ + ((void (*)(uint32_t moduleInstance))ROM_I2CTABLE[31]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_disableMultiMasterMode \ + ((void (*)(uint32_t moduleInstance))ROM_I2CTABLE[32]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_enableInterrupt \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast16_t mask))ROM_I2CTABLE[33]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_disableInterrupt \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast16_t mask))ROM_I2CTABLE[34]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_clearInterruptFlag \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast16_t mask))ROM_I2CTABLE[35]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_getInterruptStatus \ + ((uint_fast16_t (*)(uint32_t moduleInstance, \ + uint16_t mask))ROM_I2CTABLE[36]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_getEnabledInterruptStatus \ + ((uint_fast16_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[37]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_I2C_getMode \ + ((uint_fast8_t (*)(uint32_t moduleInstance))ROM_I2CTABLE[38]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the Interrupt API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_enableMaster \ + ((bool (*)(void))ROM_INTTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_disableMaster \ + ((bool (*)(void))ROM_INTTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_setPriorityGrouping \ + ((void (*)(uint32_t bits))ROM_INTTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_getPriorityGrouping \ + ((uint32_t (*)(void))ROM_INTTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_setPriority \ + ((void (*)(uint32_t interruptNumber, \ + uint8_t priority))ROM_INTTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_getPriority \ + ((uint8_t (*)(uint32_t interruptNumber))ROM_INTTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_enableInterrupt \ + ((void (*)(uint32_t interruptNumber))ROM_INTTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_disableInterrupt \ + ((void (*)(uint32_t interruptNumber))ROM_INTTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_isEnabled \ + ((bool (*)(uint32_t interruptNumber))ROM_INTTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_pendInterrupt \ + ((void (*)(uint32_t interruptNumber))ROM_INTTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_setPriorityMask \ + ((void (*)(uint8_t priorityMask))ROM_INTTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_getPriorityMask \ + ((uint8_t (*)(void))ROM_INTTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_setVectorTableAddress \ + ((void (*)(uint32_t addr))ROM_INTTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_getVectorTableAddress \ + ((uint32_t (*)(void))ROM_INTTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_enableSleepOnIsrExit \ + ((void (*)(void))ROM_INTTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_disableSleepOnIsrExit \ + ((void (*)(void))ROM_INTTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Interrupt_unpendInterrupt \ + ((void (*)(uint32_t interruptNumber))ROM_INTTABLE[18]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the MPU API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_enableModule \ + ((void (*)(uint32_t mpuConfig))ROM_MPUTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_disableModule \ + ((void (*)(void))ROM_MPUTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_getRegionCount \ + ((uint32_t (*)(void))ROM_MPUTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_enableRegion \ + ((void (*)(uint32_t region))ROM_MPUTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_disableRegion \ + ((void (*)(uint32_t region))ROM_MPUTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_setRegion \ + ((void (*)(uint32_t region, \ + uint32_t addr, \ + uint32_t flags))ROM_MPUTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_getRegion \ + ((void (*)(uint32_t region, \ + uint32_t *addr, \ + uint32_t *pflags))ROM_MPUTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_enableInterrupt \ + ((void (*)(void))ROM_MPUTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_MPU_disableInterrupt \ + ((void (*)(void))ROM_MPUTABLE[8]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the PCM API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setCoreVoltageLevel \ + ((bool (*)(uint_fast8_t voltageLevel))ROM_PCMTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_getCoreVoltageLevel \ + ((uint8_t (*)(void))ROM_PCMTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setCoreVoltageLevelWithTimeout \ + ((bool (*)(uint_fast8_t voltageLevel, \ + uint32_t timeOut))ROM_PCMTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setPowerMode \ + ((bool (*)(uint_fast8_t powerMode))ROM_PCMTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setPowerModeWithTimeout \ + ((bool (*)(uint_fast8_t powerMode, \ + uint32_t timeOut))ROM_PCMTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_getPowerMode \ + ((uint8_t (*)(void))ROM_PCMTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setPowerState \ + ((bool (*)(uint_fast8_t powerState))ROM_PCMTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setPowerStateWithTimeout \ + ((bool (*)(uint_fast8_t powerState, \ + uint32_t timeout))ROM_PCMTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_getPowerState \ + ((uint8_t (*)(void))ROM_PCMTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_shutdownDevice \ + ((bool (*)(uint32_t shutdownMode))ROM_PCMTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_gotoLPM0 \ + ((bool (*)(void))ROM_PCMTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_gotoLPM3 \ + ((bool (*)(void))ROM_PCMTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_enableInterrupt \ + ((void (*)(uint32_t flags))ROM_PCMTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_disableInterrupt \ + ((void (*)(uint32_t flags))ROM_PCMTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_getInterruptStatus \ + ((uint32_t (*)(void))ROM_PCMTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_getEnabledInterruptStatus \ + ((uint32_t (*)(void))ROM_PCMTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_clearInterruptFlag \ + ((void (*)(uint32_t flags))ROM_PCMTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_enableRudeMode \ + ((void (*)(void))ROM_PCMTABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_disableRudeMode \ + ((void (*)(void))ROM_PCMTABLE[18]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_gotoLPM0InterruptSafe \ + ((bool (*)(void))ROM_PCMTABLE[19]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_gotoLPM3InterruptSafe \ + ((bool (*)(void))ROM_PCMTABLE[20]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setCoreVoltageLevelNonBlocking \ + ((bool (*)(uint_fast8_t voltageLevel))ROM_PCMTABLE[23]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setPowerModeNonBlocking \ + ((bool (*)(uint_fast8_t powerMode))ROM_PCMTABLE[24]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_setPowerStateNonBlocking \ + ((bool (*)(uint_fast8_t powerState))ROM_PCMTABLE[25]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_gotoLPM4 \ + ((bool (*)(void))ROM_PCMTABLE[26]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PCM_gotoLPM4InterruptSafe \ + ((bool (*)(void))ROM_PCMTABLE[27]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the PMAP API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PMAP_configurePorts \ + ((void (*)(const uint8_t *portMapping, \ + uint8_t pxMAPy, \ + uint8_t numberOfPorts, \ + uint8_t portMapReconfigure))ROM_PMAPTABLE[0]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the PSS API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_enableHighSidePinToggle \ + ((void (*)(bool activeLow))ROM_PSSTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_disableHighSidePinToggle \ + ((void (*)(void))ROM_PSSTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_enableHighSide \ + ((void (*)(void))ROM_PSSTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_disableHighSide \ + ((void (*)(void))ROM_PSSTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_setHighSidePerformanceMode \ + ((void (*)(uint_fast8_t powerMode))ROM_PSSTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_getHighSidePerformanceMode \ + ((uint_fast8_t (*)(void))ROM_PSSTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_enableHighSideMonitor \ + ((void (*)(void))ROM_PSSTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_disableHighSideMonitor \ + ((void (*)(void))ROM_PSSTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_setHighSideVoltageTrigger \ + ((void (*)(uint_fast8_t triggerVoltage))ROM_PSSTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_getHighSideVoltageTrigger \ + ((uint_fast8_t (*)(void))ROM_PSSTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_enableInterrupt \ + ((void (*)(void))ROM_PSSTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_disableInterrupt \ + ((void (*)(void))ROM_PSSTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_getInterruptStatus \ + ((uint32_t (*)(void))ROM_PSSTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_clearInterruptFlag \ + ((void (*)(void))ROM_PSSTABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_enableForcedDCDCOperation \ + ((void (*)(void))ROM_PSSTABLE[20]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_PSS_disableForcedDCDCOperation \ + ((void (*)(void))ROM_PSSTABLE[21]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the Ref API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_setReferenceVoltage \ + ((void (*)(uint_fast8_t referenceVoltageSelect))ROM_REFTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_disableTempSensor \ + ((void (*)(void))ROM_REFTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_enableTempSensor \ + ((void (*)(void))ROM_REFTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_enableReferenceVoltageOutput \ + ((void (*)(void))ROM_REFTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_disableReferenceVoltageOutput \ + ((void (*)(void))ROM_REFTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_enableReferenceVoltage \ + ((void (*)(void))ROM_REFTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_disableReferenceVoltage \ + ((void (*)(void))ROM_REFTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_getBandgapMode \ + ((uint_fast8_t (*)(void))ROM_REFTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_isBandgapActive \ + ((bool (*)(void))ROM_REFTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_isRefGenBusy \ + ((bool (*)(void))ROM_REFTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_isRefGenActive \ + ((bool (*)(void))ROM_REFTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_getBufferedBandgapVoltageStatus \ + ((bool (*)(void))ROM_REFTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_getVariableReferenceVoltageStatus \ + ((bool (*)(void))ROM_REFTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_setReferenceVoltageOneTimeTrigger \ + ((void (*)(void))ROM_REFTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_REF_A_setBufferedBandgapVoltageOneTimeTrigger \ + ((void (*)(void))ROM_REFTABLE[14]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the ResetCtl API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_initiateSoftReset \ + ((void (*)(void))ROM_RESETCTLTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_initiateSoftResetWithSource \ + ((void (*)(uint32_t source))ROM_RESETCTLTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_getSoftResetSource \ + ((uint32_t (*)(void))ROM_RESETCTLTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_clearSoftResetSource \ + ((void (*)(uint32_t mask))ROM_RESETCTLTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_initiateHardReset \ + ((void (*)(void))ROM_RESETCTLTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_initiateHardResetWithSource \ + ((void (*)(uint32_t source))ROM_RESETCTLTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_getHardResetSource \ + ((uint32_t (*)(void))ROM_RESETCTLTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_clearHardResetSource \ + ((void (*)(uint32_t mask))ROM_RESETCTLTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_getPSSSource \ + ((uint32_t (*)(void))ROM_RESETCTLTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_clearPSSFlags \ + ((void (*)(void))ROM_RESETCTLTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_getPCMSource \ + ((uint32_t (*)(void))ROM_RESETCTLTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_ResetCtl_clearPCMFlags \ + ((void (*)(void))ROM_RESETCTLTABLE[11]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the RTC API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_startClock \ + ((void (*)(void))ROM_RTCTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_holdClock \ + ((void (*)(void))ROM_RTCTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_setCalibrationFrequency \ + ((void (*)(uint_fast16_t frequencySelect))ROM_RTCTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_setCalibrationData \ + ((void (*)(uint_fast8_t offsetDirection, \ + uint_fast8_t offsetValue))ROM_RTCTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_setTemperatureCompensation \ + ((bool (*)(uint_fast16_t offsetDirection, \ + uint_fast8_t offsetValue))ROM_RTCTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_initCalendar \ + ((void (*)(const RTC_C_Calendar *calendarTime, \ + uint_fast16_t formatSelect))ROM_RTCTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_getCalendarTime \ + ((RTC_C_Calendar (*)(void))ROM_RTCTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_setCalendarAlarm \ + ((void (*)(uint_fast8_t minutesAlarm, \ + uint_fast8_t hoursAlarm, \ + uint_fast8_t dayOfWeekAlarm, \ + uint_fast8_t dayOfmonthAlarm))ROM_RTCTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_setCalendarEvent \ + ((void (*)(uint_fast16_t eventSelect))ROM_RTCTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_definePrescaleEvent \ + ((void (*)(uint_fast8_t prescaleSelect, \ + uint_fast8_t prescaleEventDivider))ROM_RTCTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_getPrescaleValue \ + ((uint_fast8_t (*)(uint_fast8_t prescaleSelect))ROM_RTCTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_setPrescaleValue \ + ((void (*)(uint_fast8_t prescaleSelect, \ + uint_fast8_t prescaleCounterValue))ROM_RTCTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_convertBCDToBinary \ + ((uint16_t (*)(uint16_t valueToConvert))ROM_RTCTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_convertBinaryToBCD \ + ((uint16_t (*)(uint16_t valueToConvert))ROM_RTCTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_enableInterrupt \ + ((void (*)(uint8_t interruptMask))ROM_RTCTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_disableInterrupt \ + ((void (*)(uint8_t interruptMask))ROM_RTCTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_getInterruptStatus \ + ((uint_fast8_t (*)(void))ROM_RTCTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_getEnabledInterruptStatus \ + ((uint_fast8_t (*)(void))ROM_RTCTABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_RTC_C_clearInterruptFlag \ + ((void (*)(uint_fast8_t interruptFlagMask))ROM_RTCTABLE[18]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the SPI API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_initMaster \ + ((bool (*)(uint32_t moduleInstance, \ + const eUSCI_SPI_MasterConfig *config))ROM_SPITABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_selectFourPinFunctionality \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t select4PinFunctionality))ROM_SPITABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_changeMasterClock \ + ((void (*)(uint32_t moduleInstance, \ + uint32_t clockSourceFrequency, \ + uint32_t desiredSpiClock))ROM_SPITABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_initSlave \ + ((bool (*)(uint32_t moduleInstance, \ + const eUSCI_SPI_SlaveConfig *config))ROM_SPITABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_changeClockPhasePolarity \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast16_t clockPhase, \ + uint_fast16_t clockPolarity))ROM_SPITABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_transmitData \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t transmitData))ROM_SPITABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_receiveData \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_SPITABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_enableModule \ + ((void (*)(uint32_t moduleInstance))ROM_SPITABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_disableModule \ + ((void (*)(uint32_t moduleInstance))ROM_SPITABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_getReceiveBufferAddressForDMA \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_SPITABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_getTransmitBufferAddressForDMA \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_SPITABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_isBusy \ + ((uint_fast8_t (*)(uint32_t moduleInstance))ROM_SPITABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_enableInterrupt \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t mask))ROM_SPITABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_disableInterrupt \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t mask))ROM_SPITABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_getInterruptStatus \ + ((uint_fast8_t (*)(uint32_t moduleInstance, \ + uint16_t mask))ROM_SPITABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_getEnabledInterruptStatus \ + ((uint_fast8_t (*)(uint32_t moduleInstance))ROM_SPITABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SPI_clearInterruptFlag \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t mask))ROM_SPITABLE[16]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the SysCtl API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_getSRAMSize \ + ((uint_least32_t (*)(void))ROM_SYSCTLTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_getFlashSize \ + ((uint_least32_t (*)(void))ROM_SYSCTLTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_rebootDevice \ + ((void (*)(void))ROM_SYSCTLTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_enableSRAMBank \ + ((void (*)(uint_fast8_t sramBank))ROM_SYSCTLTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_disableSRAMBank \ + ((void (*)(uint_fast8_t sramBank))ROM_SYSCTLTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_enableSRAMBankRetention \ + ((void (*)(uint_fast8_t sramBank))ROM_SYSCTLTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_disableSRAMBankRetention \ + ((void (*)(uint_fast8_t sramBank))ROM_SYSCTLTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_enablePeripheralAtCPUHalt \ + ((void (*)(uint_fast16_t devices))ROM_SYSCTLTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_disablePeripheralAtCPUHalt \ + ((void (*)(uint_fast16_t devices))ROM_SYSCTLTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_setWDTTimeoutResetType \ + ((void (*)(uint_fast8_t resetType))ROM_SYSCTLTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_setWDTPasswordViolationResetType \ + ((void (*)(uint_fast8_t resetType))ROM_SYSCTLTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_disableNMISource \ + ((void (*)(uint_fast8_t flags))ROM_SYSCTLTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_enableNMISource \ + ((void (*)(uint_fast8_t flags))ROM_SYSCTLTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_getNMISourceStatus \ + ((uint_fast8_t (*)(void))ROM_SYSCTLTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_getTempCalibrationConstant \ + ((uint_fast16_t (*)(uint32_t refVoltage, \ + uint32_t temperature))ROM_SYSCTLTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_enableGlitchFilter \ + ((void (*)(void))ROM_SYSCTLTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_disableGlitchFilter \ + ((void (*)(void))ROM_SYSCTLTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysCtl_getTLVInfo \ + ((void (*)(uint_fast8_t tag, \ + uint_fast8_t instance, \ + uint_fast8_t *length, \ + uint32_t **data_address))ROM_SYSCTLTABLE[17]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the SysTick API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysTick_enableModule \ + ((void (*)(void))ROM_SYSTICKTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysTick_disableModule \ + ((void (*)(void))ROM_SYSTICKTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysTick_enableInterrupt \ + ((void (*)(void))ROM_SYSTICKTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysTick_disableInterrupt \ + ((void (*)(void))ROM_SYSTICKTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysTick_setPeriod \ + ((void (*)(uint32_t period))ROM_SYSTICKTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysTick_getPeriod \ + ((uint32_t (*)(void))ROM_SYSTICKTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_SysTick_getValue \ + ((uint32_t (*)(void))ROM_SYSTICKTABLE[6]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the Timer_A API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_startCounter \ + ((void (*)(uint32_t timer, \ + uint_fast16_t timerMode))ROM_TIMER_ATABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_configureContinuousMode \ + ((void (*)(uint32_t timer, \ + const Timer_A_ContinuousModeConfig *config))ROM_TIMER_ATABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_configureUpMode \ + ((void (*)(uint32_t timer, \ + const Timer_A_UpModeConfig *config))ROM_TIMER_ATABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_configureUpDownMode \ + ((void (*)(uint32_t timer, \ + const Timer_A_UpDownModeConfig *config))ROM_TIMER_ATABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_initCapture \ + ((void (*)(uint32_t timer, \ + const Timer_A_CaptureModeConfig *config))ROM_TIMER_ATABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_initCompare \ + ((void (*)(uint32_t timer, \ + const Timer_A_CompareModeConfig *config))ROM_TIMER_ATABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_clearTimer \ + ((void (*)(uint32_t timer))ROM_TIMER_ATABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_getSynchronizedCaptureCompareInput \ + ((uint_fast8_t (*)(uint32_t timer, \ + uint_fast16_t captureCompareRegister, \ + uint_fast16_t synchronizedSetting))ROM_TIMER_ATABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_getOutputForOutputModeOutBitValue \ + ((uint_fast8_t (*)(uint32_t timer, \ + uint_fast16_t captureCompareRegister))ROM_TIMER_ATABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_getCaptureCompareCount \ + ((uint_fast16_t (*)(uint32_t timer, \ + uint_fast16_t captureCompareRegister))ROM_TIMER_ATABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_generatePWM \ + ((void (*)(uint32_t timer, \ + const Timer_A_PWMConfig *config))ROM_TIMER_ATABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_stopTimer \ + ((void (*)(uint32_t timer))ROM_TIMER_ATABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_setCompareValue \ + ((void (*)(uint32_t timer, \ + uint_fast16_t compareRegister, \ + uint_fast16_t compareValue))ROM_TIMER_ATABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_clearInterruptFlag \ + ((void (*)(uint32_t timer))ROM_TIMER_ATABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_clearCaptureCompareInterrupt \ + ((void (*)(uint32_t timer, \ + uint_fast16_t captureCompareRegister))ROM_TIMER_ATABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_enableInterrupt \ + ((void (*)(uint32_t timer))ROM_TIMER_ATABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_disableInterrupt \ + ((void (*)(uint32_t timer))ROM_TIMER_ATABLE[17]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_getInterruptStatus \ + ((uint32_t (*)(uint32_t timer))ROM_TIMER_ATABLE[18]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_getEnabledInterruptStatus \ + ((uint32_t (*)(uint32_t timer))ROM_TIMER_ATABLE[19]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_enableCaptureCompareInterrupt \ + ((void (*)(uint32_t timer, \ + uint_fast16_t captureCompareRegister))ROM_TIMER_ATABLE[20]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_disableCaptureCompareInterrupt \ + ((void (*)(uint32_t timer, \ + uint_fast16_t captureCompareRegister))ROM_TIMER_ATABLE[21]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_getCaptureCompareInterruptStatus \ + ((uint32_t (*)(uint32_t timer, \ + uint_fast16_t captureCompareRegister, \ + uint_fast16_t mask))ROM_TIMER_ATABLE[22]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_getCaptureCompareEnabledInterruptStatus \ + ((uint32_t (*)(uint32_t timer, \ + uint_fast16_t captureCompareRegister))ROM_TIMER_ATABLE[23]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer_A_getCounterValue \ + ((uint16_t (*)(uint32_t timer))ROM_TIMER_ATABLE[26]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the Timer32 API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_initModule \ + ((void (*)(uint32_t timer, \ + uint32_t preScaler, \ + uint32_t resolution, \ + uint32_t mode))ROM_TIMER32TABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_setCount \ + ((void (*)(uint32_t timer, \ + uint32_t count))ROM_TIMER32TABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_setCountInBackground \ + ((void (*)(uint32_t timer, \ + uint32_t count))ROM_TIMER32TABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_getValue \ + ((uint32_t (*)(uint32_t timer))ROM_TIMER32TABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_startTimer \ + ((void (*)(uint32_t timer, \ + bool oneShot))ROM_TIMER32TABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_haltTimer \ + ((void (*)(uint32_t timer))ROM_TIMER32TABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_enableInterrupt \ + ((void (*)(uint32_t timer))ROM_TIMER32TABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_disableInterrupt \ + ((void (*)(uint32_t timer))ROM_TIMER32TABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_clearInterruptFlag \ + ((void (*)(uint32_t timer))ROM_TIMER32TABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_Timer32_getInterruptStatus \ + ((uint32_t (*)(uint32_t timer))ROM_TIMER32TABLE[9]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the UART API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_initModule \ + ((bool (*)(uint32_t moduleInstance, \ + const eUSCI_UART_Config *config))ROM_UARTTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_transmitData \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t transmitData))ROM_UARTTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_enableModule \ + ((void (*)(uint32_t moduleInstance))ROM_UARTTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_disableModule \ + ((void (*)(uint32_t moduleInstance))ROM_UARTTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_queryStatusFlags \ + ((uint_fast8_t (*)(uint32_t moduleInstance, \ + uint_fast8_t mask))ROM_UARTTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_setDormant \ + ((void (*)(uint32_t moduleInstance))ROM_UARTTABLE[5]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_resetDormant \ + ((void (*)(uint32_t moduleInstance))ROM_UARTTABLE[6]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_transmitAddress \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t transmitAddress))ROM_UARTTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_transmitBreak \ + ((void (*)(uint32_t moduleInstance))ROM_UARTTABLE[8]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_getReceiveBufferAddressForDMA \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_UARTTABLE[9]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_getTransmitBufferAddressForDMA \ + ((uint32_t (*)(uint32_t moduleInstance))ROM_UARTTABLE[10]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_selectDeglitchTime \ + ((void (*)(uint32_t moduleInstance, \ + uint32_t deglitchTime))ROM_UARTTABLE[11]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_enableInterrupt \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t mask))ROM_UARTTABLE[12]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_disableInterrupt \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t mask))ROM_UARTTABLE[13]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_getInterruptStatus \ + ((uint_fast8_t (*)(uint32_t moduleInstance, \ + uint8_t mask))ROM_UARTTABLE[14]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_clearInterruptFlag \ + ((void (*)(uint32_t moduleInstance, \ + uint_fast8_t mask))ROM_UARTTABLE[15]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_receiveData \ + ((uint8_t (*)(uint32_t moduleInstance))ROM_UARTTABLE[16]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_UART_getEnabledInterruptStatus \ + ((uint_fast8_t (*)(uint32_t moduleInstance))ROM_UARTTABLE[17]) +#endif + +//***************************************************************************** +// +// Macros for calling ROM functions in the WDT API. +// +//***************************************************************************** +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_WDT_A_holdTimer \ + ((void (*)(void))ROM_WDTTABLE[0]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_WDT_A_startTimer \ + ((void (*)(void))ROM_WDTTABLE[1]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_WDT_A_clearTimer \ + ((void (*)(void))ROM_WDTTABLE[2]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_WDT_A_initWatchdogTimer \ + ((void (*)(uint_fast8_t clockSelect, \ + uint_fast8_t clockDivider))ROM_WDTTABLE[3]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_WDT_A_initIntervalTimer \ + ((void (*)(uint_fast8_t clockSelect, \ + uint_fast8_t clockDivider))ROM_WDTTABLE[4]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_WDT_A_setPasswordViolationReset \ + ((void (*)(uint_fast8_t resetType))ROM_WDTTABLE[7]) +#endif +#if defined(TARGET_IS_MSP432P4XX) +#define ROM_WDT_A_setTimeoutReset \ + ((void (*)(uint_fast8_t resetType))ROM_WDTTABLE[8]) +#endif + +#endif // __ROM_H__ diff --git a/example/rt_msp432/MSP432P4xx/rom_map.h b/example/rt_msp432/MSP432P4xx/rom_map.h new file mode 100644 index 0000000..a82ad80 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/rom_map.h @@ -0,0 +1,3634 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __ROM_MAP_H__ +#define __ROM_MAP_H__ + +//***************************************************************************** +// +// Macros for the ADC14 API. +// +//***************************************************************************** +#ifdef ROM_ADC14_enableModule +#define MAP_ADC14_enableModule \ + ROM_ADC14_enableModule +#else +#define MAP_ADC14_enableModule \ + ADC14_enableModule +#endif +#ifdef ROM_ADC14_disableModule +#define MAP_ADC14_disableModule \ + ROM_ADC14_disableModule +#else +#define MAP_ADC14_disableModule \ + ADC14_disableModule +#endif +#ifdef ROM_ADC14_initModule +#define MAP_ADC14_initModule \ + ROM_ADC14_initModule +#else +#define MAP_ADC14_initModule \ + ADC14_initModule +#endif +#ifdef ROM_ADC14_setResolution +#define MAP_ADC14_setResolution \ + ROM_ADC14_setResolution +#else +#define MAP_ADC14_setResolution \ + ADC14_setResolution +#endif +#ifdef ROM_ADC14_getResolution +#define MAP_ADC14_getResolution \ + ROM_ADC14_getResolution +#else +#define MAP_ADC14_getResolution \ + ADC14_getResolution +#endif +#ifdef ROM_ADC14_setSampleHoldTrigger +#define MAP_ADC14_setSampleHoldTrigger \ + ROM_ADC14_setSampleHoldTrigger +#else +#define MAP_ADC14_setSampleHoldTrigger \ + ADC14_setSampleHoldTrigger +#endif +#ifdef ROM_ADC14_setSampleHoldTime +#define MAP_ADC14_setSampleHoldTime \ + ROM_ADC14_setSampleHoldTime +#else +#define MAP_ADC14_setSampleHoldTime \ + ADC14_setSampleHoldTime +#endif +#ifdef ROM_ADC14_configureMultiSequenceMode +#define MAP_ADC14_configureMultiSequenceMode \ + ROM_ADC14_configureMultiSequenceMode +#else +#define MAP_ADC14_configureMultiSequenceMode \ + ADC14_configureMultiSequenceMode +#endif +#ifdef ROM_ADC14_configureSingleSampleMode +#define MAP_ADC14_configureSingleSampleMode \ + ROM_ADC14_configureSingleSampleMode +#else +#define MAP_ADC14_configureSingleSampleMode \ + ADC14_configureSingleSampleMode +#endif +#ifdef ROM_ADC14_enableConversion +#define MAP_ADC14_enableConversion \ + ROM_ADC14_enableConversion +#else +#define MAP_ADC14_enableConversion \ + ADC14_enableConversion +#endif +#ifdef ROM_ADC14_disableConversion +#define MAP_ADC14_disableConversion \ + ROM_ADC14_disableConversion +#else +#define MAP_ADC14_disableConversion \ + ADC14_disableConversion +#endif +#ifdef ROM_ADC14_isBusy +#define MAP_ADC14_isBusy \ + ROM_ADC14_isBusy +#else +#define MAP_ADC14_isBusy \ + ADC14_isBusy +#endif +#ifdef ROM_ADC14_configureConversionMemory +#define MAP_ADC14_configureConversionMemory \ + ROM_ADC14_configureConversionMemory +#else +#define MAP_ADC14_configureConversionMemory \ + ADC14_configureConversionMemory +#endif +#ifdef ROM_ADC14_enableComparatorWindow +#define MAP_ADC14_enableComparatorWindow \ + ROM_ADC14_enableComparatorWindow +#else +#define MAP_ADC14_enableComparatorWindow \ + ADC14_enableComparatorWindow +#endif +#ifdef ROM_ADC14_disableComparatorWindow +#define MAP_ADC14_disableComparatorWindow \ + ROM_ADC14_disableComparatorWindow +#else +#define MAP_ADC14_disableComparatorWindow \ + ADC14_disableComparatorWindow +#endif +#ifdef ROM_ADC14_setComparatorWindowValue +#define MAP_ADC14_setComparatorWindowValue \ + ROM_ADC14_setComparatorWindowValue +#else +#define MAP_ADC14_setComparatorWindowValue \ + ADC14_setComparatorWindowValue +#endif +#ifdef ROM_ADC14_setResultFormat +#define MAP_ADC14_setResultFormat \ + ROM_ADC14_setResultFormat +#else +#define MAP_ADC14_setResultFormat \ + ADC14_setResultFormat +#endif +#ifdef ROM_ADC14_getResult +#define MAP_ADC14_getResult \ + ROM_ADC14_getResult +#else +#define MAP_ADC14_getResult \ + ADC14_getResult +#endif +#ifdef ROM_ADC14_getMultiSequenceResult +#define MAP_ADC14_getMultiSequenceResult \ + ROM_ADC14_getMultiSequenceResult +#else +#define MAP_ADC14_getMultiSequenceResult \ + ADC14_getMultiSequenceResult +#endif +#ifdef ROM_ADC14_getResultArray +#define MAP_ADC14_getResultArray \ + ROM_ADC14_getResultArray +#else +#define MAP_ADC14_getResultArray \ + ADC14_getResultArray +#endif +#ifdef ROM_ADC14_enableReferenceBurst +#define MAP_ADC14_enableReferenceBurst \ + ROM_ADC14_enableReferenceBurst +#else +#define MAP_ADC14_enableReferenceBurst \ + ADC14_enableReferenceBurst +#endif +#ifdef ROM_ADC14_disableReferenceBurst +#define MAP_ADC14_disableReferenceBurst \ + ROM_ADC14_disableReferenceBurst +#else +#define MAP_ADC14_disableReferenceBurst \ + ADC14_disableReferenceBurst +#endif +#ifdef ROM_ADC14_setPowerMode +#define MAP_ADC14_setPowerMode \ + ROM_ADC14_setPowerMode +#else +#define MAP_ADC14_setPowerMode \ + ADC14_setPowerMode +#endif +#ifdef ROM_ADC14_enableInterrupt +#define MAP_ADC14_enableInterrupt \ + ROM_ADC14_enableInterrupt +#else +#define MAP_ADC14_enableInterrupt \ + ADC14_enableInterrupt +#endif +#ifdef ROM_ADC14_disableInterrupt +#define MAP_ADC14_disableInterrupt \ + ROM_ADC14_disableInterrupt +#else +#define MAP_ADC14_disableInterrupt \ + ADC14_disableInterrupt +#endif +#ifdef ROM_ADC14_getInterruptStatus +#define MAP_ADC14_getInterruptStatus \ + ROM_ADC14_getInterruptStatus +#else +#define MAP_ADC14_getInterruptStatus \ + ADC14_getInterruptStatus +#endif +#ifdef ROM_ADC14_getEnabledInterruptStatus +#define MAP_ADC14_getEnabledInterruptStatus \ + ROM_ADC14_getEnabledInterruptStatus +#else +#define MAP_ADC14_getEnabledInterruptStatus \ + ADC14_getEnabledInterruptStatus +#endif +#ifdef ROM_ADC14_clearInterruptFlag +#define MAP_ADC14_clearInterruptFlag \ + ROM_ADC14_clearInterruptFlag +#else +#define MAP_ADC14_clearInterruptFlag \ + ADC14_clearInterruptFlag +#endif +#ifdef ROM_ADC14_toggleConversionTrigger +#define MAP_ADC14_toggleConversionTrigger \ + ROM_ADC14_toggleConversionTrigger +#else +#define MAP_ADC14_toggleConversionTrigger \ + ADC14_toggleConversionTrigger +#endif +#ifdef ROM_ADC14_enableSampleTimer +#define MAP_ADC14_enableSampleTimer \ + ROM_ADC14_enableSampleTimer +#else +#define MAP_ADC14_enableSampleTimer \ + ADC14_enableSampleTimer +#endif +#ifdef ROM_ADC14_disableSampleTimer +#define MAP_ADC14_disableSampleTimer \ + ROM_ADC14_disableSampleTimer +#else +#define MAP_ADC14_disableSampleTimer \ + ADC14_disableSampleTimer +#endif +#ifdef ROM_ADC14_registerInterrupt +#define MAP_ADC14_registerInterrupt \ + ROM_ADC14_registerInterrupt +#else +#define MAP_ADC14_registerInterrupt \ + ADC14_registerInterrupt +#endif +#ifdef ROM_ADC14_unregisterInterrupt +#define MAP_ADC14_unregisterInterrupt \ + ROM_ADC14_unregisterInterrupt +#else +#define MAP_ADC14_unregisterInterrupt \ + ADC14_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the AES256 API. +// +//***************************************************************************** +#ifdef ROM_AES256_setCipherKey +#define MAP_AES256_setCipherKey \ + ROM_AES256_setCipherKey +#else +#define MAP_AES256_setCipherKey \ + AES256_setCipherKey +#endif +#ifdef ROM_AES256_encryptData +#define MAP_AES256_encryptData \ + ROM_AES256_encryptData +#else +#define MAP_AES256_encryptData \ + AES256_encryptData +#endif +#ifdef ROM_AES256_decryptData +#define MAP_AES256_decryptData \ + ROM_AES256_decryptData +#else +#define MAP_AES256_decryptData \ + AES256_decryptData +#endif +#ifdef ROM_AES256_setDecipherKey +#define MAP_AES256_setDecipherKey \ + ROM_AES256_setDecipherKey +#else +#define MAP_AES256_setDecipherKey \ + AES256_setDecipherKey +#endif +#ifdef ROM_AES256_reset +#define MAP_AES256_reset \ + ROM_AES256_reset +#else +#define MAP_AES256_reset \ + AES256_reset +#endif +#ifdef ROM_AES256_startEncryptData +#define MAP_AES256_startEncryptData \ + ROM_AES256_startEncryptData +#else +#define MAP_AES256_startEncryptData \ + AES256_startEncryptData +#endif +#ifdef ROM_AES256_startDecryptData +#define MAP_AES256_startDecryptData \ + ROM_AES256_startDecryptData +#else +#define MAP_AES256_startDecryptData \ + AES256_startDecryptData +#endif +#ifdef ROM_AES256_startSetDecipherKey +#define MAP_AES256_startSetDecipherKey \ + ROM_AES256_startSetDecipherKey +#else +#define MAP_AES256_startSetDecipherKey \ + AES256_startSetDecipherKey +#endif +#ifdef ROM_AES256_getDataOut +#define MAP_AES256_getDataOut \ + ROM_AES256_getDataOut +#else +#define MAP_AES256_getDataOut \ + AES256_getDataOut +#endif +#ifdef ROM_AES256_isBusy +#define MAP_AES256_isBusy \ + ROM_AES256_isBusy +#else +#define MAP_AES256_isBusy \ + AES256_isBusy +#endif +#ifdef ROM_AES256_clearErrorFlag +#define MAP_AES256_clearErrorFlag \ + ROM_AES256_clearErrorFlag +#else +#define MAP_AES256_clearErrorFlag \ + AES256_clearErrorFlag +#endif +#ifdef ROM_AES256_getErrorFlagStatus +#define MAP_AES256_getErrorFlagStatus \ + ROM_AES256_getErrorFlagStatus +#else +#define MAP_AES256_getErrorFlagStatus \ + AES256_getErrorFlagStatus +#endif +#ifdef ROM_AES256_clearInterruptFlag +#define MAP_AES256_clearInterruptFlag \ + ROM_AES256_clearInterruptFlag +#else +#define MAP_AES256_clearInterruptFlag \ + AES256_clearInterruptFlag +#endif +#ifdef ROM_AES256_getInterruptStatus +#define MAP_AES256_getInterruptStatus \ + ROM_AES256_getInterruptStatus +#else +#define MAP_AES256_getInterruptStatus \ + AES256_getInterruptStatus +#endif +#ifdef ROM_AES256_enableInterrupt +#define MAP_AES256_enableInterrupt \ + ROM_AES256_enableInterrupt +#else +#define MAP_AES256_enableInterrupt \ + AES256_enableInterrupt +#endif +#ifdef ROM_AES256_disableInterrupt +#define MAP_AES256_disableInterrupt \ + ROM_AES256_disableInterrupt +#else +#define MAP_AES256_disableInterrupt \ + AES256_disableInterrupt +#endif +#ifdef ROM_AES256_registerInterrupt +#define MAP_AES256_registerInterrupt \ + ROM_AES256_registerInterrupt +#else +#define MAP_AES256_registerInterrupt \ + AES256_registerInterrupt +#endif +#ifdef ROM_AES256_unregisterInterrupt +#define MAP_AES256_unregisterInterrupt \ + ROM_AES256_unregisterInterrupt +#else +#define MAP_AES256_unregisterInterrupt \ + AES256_unregisterInterrupt +#endif +#ifdef ROM_AES256_getInterruptFlagStatus +#define MAP_AES256_getInterruptFlagStatus \ + ROM_AES256_getInterruptFlagStatus +#else +#define MAP_AES256_getInterruptFlagStatus \ + AES256_getInterruptFlagStatus +#endif + +//***************************************************************************** +// +// Macros for the Comp API. +// +//***************************************************************************** +#ifdef ROM_COMP_E_initModule +#define MAP_COMP_E_initModule \ + ROM_COMP_E_initModule +#else +#define MAP_COMP_E_initModule \ + COMP_E_initModule +#endif +#ifdef ROM_COMP_E_setReferenceVoltage +#define MAP_COMP_E_setReferenceVoltage \ + ROM_COMP_E_setReferenceVoltage +#else +#define MAP_COMP_E_setReferenceVoltage \ + COMP_E_setReferenceVoltage +#endif +#ifdef ROM_COMP_E_setReferenceAccuracy +#define MAP_COMP_E_setReferenceAccuracy \ + ROM_COMP_E_setReferenceAccuracy +#else +#define MAP_COMP_E_setReferenceAccuracy \ + COMP_E_setReferenceAccuracy +#endif +#ifdef ROM_COMP_E_setPowerMode +#define MAP_COMP_E_setPowerMode \ + ROM_COMP_E_setPowerMode +#else +#define MAP_COMP_E_setPowerMode \ + COMP_E_setPowerMode +#endif +#ifdef ROM_COMP_E_enableModule +#define MAP_COMP_E_enableModule \ + ROM_COMP_E_enableModule +#else +#define MAP_COMP_E_enableModule \ + COMP_E_enableModule +#endif +#ifdef ROM_COMP_E_disableModule +#define MAP_COMP_E_disableModule \ + ROM_COMP_E_disableModule +#else +#define MAP_COMP_E_disableModule \ + COMP_E_disableModule +#endif +#ifdef ROM_COMP_E_shortInputs +#define MAP_COMP_E_shortInputs \ + ROM_COMP_E_shortInputs +#else +#define MAP_COMP_E_shortInputs \ + COMP_E_shortInputs +#endif +#ifdef ROM_COMP_E_unshortInputs +#define MAP_COMP_E_unshortInputs \ + ROM_COMP_E_unshortInputs +#else +#define MAP_COMP_E_unshortInputs \ + COMP_E_unshortInputs +#endif +#ifdef ROM_COMP_E_disableInputBuffer +#define MAP_COMP_E_disableInputBuffer \ + ROM_COMP_E_disableInputBuffer +#else +#define MAP_COMP_E_disableInputBuffer \ + COMP_E_disableInputBuffer +#endif +#ifdef ROM_COMP_E_enableInputBuffer +#define MAP_COMP_E_enableInputBuffer \ + ROM_COMP_E_enableInputBuffer +#else +#define MAP_COMP_E_enableInputBuffer \ + COMP_E_enableInputBuffer +#endif +#ifdef ROM_COMP_E_swapIO +#define MAP_COMP_E_swapIO \ + ROM_COMP_E_swapIO +#else +#define MAP_COMP_E_swapIO \ + COMP_E_swapIO +#endif +#ifdef ROM_COMP_E_outputValue +#define MAP_COMP_E_outputValue \ + ROM_COMP_E_outputValue +#else +#define MAP_COMP_E_outputValue \ + COMP_E_outputValue +#endif +#ifdef ROM_COMP_E_enableInterrupt +#define MAP_COMP_E_enableInterrupt \ + ROM_COMP_E_enableInterrupt +#else +#define MAP_COMP_E_enableInterrupt \ + COMP_E_enableInterrupt +#endif +#ifdef ROM_COMP_E_disableInterrupt +#define MAP_COMP_E_disableInterrupt \ + ROM_COMP_E_disableInterrupt +#else +#define MAP_COMP_E_disableInterrupt \ + COMP_E_disableInterrupt +#endif +#ifdef ROM_COMP_E_clearInterruptFlag +#define MAP_COMP_E_clearInterruptFlag \ + ROM_COMP_E_clearInterruptFlag +#else +#define MAP_COMP_E_clearInterruptFlag \ + COMP_E_clearInterruptFlag +#endif +#ifdef ROM_COMP_E_getInterruptStatus +#define MAP_COMP_E_getInterruptStatus \ + ROM_COMP_E_getInterruptStatus +#else +#define MAP_COMP_E_getInterruptStatus \ + COMP_E_getInterruptStatus +#endif +#ifdef ROM_COMP_E_getEnabledInterruptStatus +#define MAP_COMP_E_getEnabledInterruptStatus \ + ROM_COMP_E_getEnabledInterruptStatus +#else +#define MAP_COMP_E_getEnabledInterruptStatus \ + COMP_E_getEnabledInterruptStatus +#endif +#ifdef ROM_COMP_E_setInterruptEdgeDirection +#define MAP_COMP_E_setInterruptEdgeDirection \ + ROM_COMP_E_setInterruptEdgeDirection +#else +#define MAP_COMP_E_setInterruptEdgeDirection \ + COMP_E_setInterruptEdgeDirection +#endif +#ifdef ROM_COMP_E_toggleInterruptEdgeDirection +#define MAP_COMP_E_toggleInterruptEdgeDirection \ + ROM_COMP_E_toggleInterruptEdgeDirection +#else +#define MAP_COMP_E_toggleInterruptEdgeDirection \ + COMP_E_toggleInterruptEdgeDirection +#endif +#ifdef ROM_COMP_E_registerInterrupt +#define MAP_COMP_E_registerInterrupt \ + ROM_COMP_E_registerInterrupt +#else +#define MAP_COMP_E_registerInterrupt \ + COMP_E_registerInterrupt +#endif +#ifdef ROM_COMP_E_unregisterInterrupt +#define MAP_COMP_E_unregisterInterrupt \ + ROM_COMP_E_unregisterInterrupt +#else +#define MAP_COMP_E_unregisterInterrupt \ + COMP_E_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the CRC32 API. +// +//***************************************************************************** +#ifdef ROM_CRC32_setSeed +#define MAP_CRC32_setSeed \ + ROM_CRC32_setSeed +#else +#define MAP_CRC32_setSeed \ + CRC32_setSeed +#endif +#ifdef ROM_CRC32_set8BitData +#define MAP_CRC32_set8BitData \ + ROM_CRC32_set8BitData +#else +#define MAP_CRC32_set8BitData \ + CRC32_set8BitData +#endif +#ifdef ROM_CRC32_set16BitData +#define MAP_CRC32_set16BitData \ + ROM_CRC32_set16BitData +#else +#define MAP_CRC32_set16BitData \ + CRC32_set16BitData +#endif +#ifdef ROM_CRC32_set32BitData +#define MAP_CRC32_set32BitData \ + ROM_CRC32_set32BitData +#else +#define MAP_CRC32_set32BitData \ + CRC32_set32BitData +#endif +#ifdef ROM_CRC32_set8BitDataReversed +#define MAP_CRC32_set8BitDataReversed \ + ROM_CRC32_set8BitDataReversed +#else +#define MAP_CRC32_set8BitDataReversed \ + CRC32_set8BitDataReversed +#endif +#ifdef ROM_CRC32_set16BitDataReversed +#define MAP_CRC32_set16BitDataReversed \ + ROM_CRC32_set16BitDataReversed +#else +#define MAP_CRC32_set16BitDataReversed \ + CRC32_set16BitDataReversed +#endif +#ifdef ROM_CRC32_set32BitDataReversed +#define MAP_CRC32_set32BitDataReversed \ + ROM_CRC32_set32BitDataReversed +#else +#define MAP_CRC32_set32BitDataReversed \ + CRC32_set32BitDataReversed +#endif +#ifdef ROM_CRC32_getResult +#define MAP_CRC32_getResult \ + ROM_CRC32_getResult +#else +#define MAP_CRC32_getResult \ + CRC32_getResult +#endif +#ifdef ROM_CRC32_getResultReversed +#define MAP_CRC32_getResultReversed \ + ROM_CRC32_getResultReversed +#else +#define MAP_CRC32_getResultReversed \ + CRC32_getResultReversed +#endif + +//***************************************************************************** +// +// Macros for the CS API. +// +//***************************************************************************** +#ifdef ROM_CS_initClockSignal +#define MAP_CS_initClockSignal \ + ROM_CS_initClockSignal +#else +#define MAP_CS_initClockSignal \ + CS_initClockSignal +#endif +#ifdef ROM_CS_setReferenceOscillatorFrequency +#define MAP_CS_setReferenceOscillatorFrequency \ + ROM_CS_setReferenceOscillatorFrequency +#else +#define MAP_CS_setReferenceOscillatorFrequency \ + CS_setReferenceOscillatorFrequency +#endif +#ifdef ROM_CS_enableClockRequest +#define MAP_CS_enableClockRequest \ + ROM_CS_enableClockRequest +#else +#define MAP_CS_enableClockRequest \ + CS_enableClockRequest +#endif +#ifdef ROM_CS_disableClockRequest +#define MAP_CS_disableClockRequest \ + ROM_CS_disableClockRequest +#else +#define MAP_CS_disableClockRequest \ + CS_disableClockRequest +#endif +#ifdef ROM_CS_setDCOCenteredFrequency +#define MAP_CS_setDCOCenteredFrequency \ + ROM_CS_setDCOCenteredFrequency +#else +#define MAP_CS_setDCOCenteredFrequency \ + CS_setDCOCenteredFrequency +#endif +#ifdef ROM_CS_tuneDCOFrequency +#define MAP_CS_tuneDCOFrequency \ + ROM_CS_tuneDCOFrequency +#else +#define MAP_CS_tuneDCOFrequency \ + CS_tuneDCOFrequency +#endif +#ifdef ROM_CS_enableDCOExternalResistor +#define MAP_CS_enableDCOExternalResistor \ + ROM_CS_enableDCOExternalResistor +#else +#define MAP_CS_enableDCOExternalResistor \ + CS_enableDCOExternalResistor +#endif +#ifdef ROM_CS_disableDCOExternalResistor +#define MAP_CS_disableDCOExternalResistor \ + ROM_CS_disableDCOExternalResistor +#else +#define MAP_CS_disableDCOExternalResistor \ + CS_disableDCOExternalResistor +#endif +#ifdef ROM_CS_enableInterrupt +#define MAP_CS_enableInterrupt \ + ROM_CS_enableInterrupt +#else +#define MAP_CS_enableInterrupt \ + CS_enableInterrupt +#endif +#ifdef ROM_CS_disableInterrupt +#define MAP_CS_disableInterrupt \ + ROM_CS_disableInterrupt +#else +#define MAP_CS_disableInterrupt \ + CS_disableInterrupt +#endif +#ifdef ROM_CS_getEnabledInterruptStatus +#define MAP_CS_getEnabledInterruptStatus \ + ROM_CS_getEnabledInterruptStatus +#else +#define MAP_CS_getEnabledInterruptStatus \ + CS_getEnabledInterruptStatus +#endif +#ifdef ROM_CS_getInterruptStatus +#define MAP_CS_getInterruptStatus \ + ROM_CS_getInterruptStatus +#else +#define MAP_CS_getInterruptStatus \ + CS_getInterruptStatus +#endif +#ifdef ROM_CS_setDCOFrequency +#define MAP_CS_setDCOFrequency \ + ROM_CS_setDCOFrequency +#else +#define MAP_CS_setDCOFrequency \ + CS_setDCOFrequency +#endif +#ifdef ROM_CS_getDCOFrequency +#define MAP_CS_getDCOFrequency \ + ROM_CS_getDCOFrequency +#else +#define MAP_CS_getDCOFrequency \ + CS_getDCOFrequency +#endif +#ifdef ROM_CS_enableFaultCounter +#define MAP_CS_enableFaultCounter \ + ROM_CS_enableFaultCounter +#else +#define MAP_CS_enableFaultCounter \ + CS_enableFaultCounter +#endif +#ifdef ROM_CS_disableFaultCounter +#define MAP_CS_disableFaultCounter \ + ROM_CS_disableFaultCounter +#else +#define MAP_CS_disableFaultCounter \ + CS_disableFaultCounter +#endif +#ifdef ROM_CS_resetFaultCounter +#define MAP_CS_resetFaultCounter \ + ROM_CS_resetFaultCounter +#else +#define MAP_CS_resetFaultCounter \ + CS_resetFaultCounter +#endif +#ifdef ROM_CS_startFaultCounter +#define MAP_CS_startFaultCounter \ + ROM_CS_startFaultCounter +#else +#define MAP_CS_startFaultCounter \ + CS_startFaultCounter +#endif +#ifdef ROM_CS_registerInterrupt +#define MAP_CS_registerInterrupt \ + ROM_CS_registerInterrupt +#else +#define MAP_CS_registerInterrupt \ + CS_registerInterrupt +#endif +#ifdef ROM_CS_unregisterInterrupt +#define MAP_CS_unregisterInterrupt \ + ROM_CS_unregisterInterrupt +#else +#define MAP_CS_unregisterInterrupt \ + CS_unregisterInterrupt +#endif +#ifdef ROM_CS_clearInterruptFlag +#define MAP_CS_clearInterruptFlag \ + ROM_CS_clearInterruptFlag +#else +#define MAP_CS_clearInterruptFlag \ + CS_clearInterruptFlag +#endif +#ifdef ROM_CS_getACLK +#define MAP_CS_getACLK \ + ROM_CS_getACLK +#else +#define MAP_CS_getACLK \ + CS_getACLK +#endif +#ifdef ROM_CS_getSMCLK +#define MAP_CS_getSMCLK \ + ROM_CS_getSMCLK +#else +#define MAP_CS_getSMCLK \ + CS_getSMCLK +#endif +#ifdef ROM_CS_getMCLK +#define MAP_CS_getMCLK \ + ROM_CS_getMCLK +#else +#define MAP_CS_getMCLK \ + CS_getMCLK +#endif +#ifdef ROM_CS_getBCLK +#define MAP_CS_getBCLK \ + ROM_CS_getBCLK +#else +#define MAP_CS_getBCLK \ + CS_getBCLK +#endif +#ifdef ROM_CS_getHSMCLK +#define MAP_CS_getHSMCLK \ + ROM_CS_getHSMCLK +#else +#define MAP_CS_getHSMCLK \ + CS_getHSMCLK +#endif +#ifdef ROM_CS_startHFXT +#define MAP_CS_startHFXT \ + ROM_CS_startHFXT +#else +#define MAP_CS_startHFXT \ + CS_startHFXT +#endif +#ifdef ROM_CS_startHFXTWithTimeout +#define MAP_CS_startHFXTWithTimeout \ + ROM_CS_startHFXTWithTimeout +#else +#define MAP_CS_startHFXTWithTimeout \ + CS_startHFXTWithTimeout +#endif +#ifdef ROM_CS_startLFXT +#define MAP_CS_startLFXT \ + ROM_CS_startLFXT +#else +#define MAP_CS_startLFXT \ + CS_startLFXT +#endif +#ifdef ROM_CS_startLFXTWithTimeout +#define MAP_CS_startLFXTWithTimeout \ + ROM_CS_startLFXTWithTimeout +#else +#define MAP_CS_startLFXTWithTimeout \ + CS_startLFXTWithTimeout +#endif +#ifdef ROM_CS_setExternalClockSourceFrequency +#define MAP_CS_setExternalClockSourceFrequency \ + ROM_CS_setExternalClockSourceFrequency +#else +#define MAP_CS_setExternalClockSourceFrequency \ + CS_setExternalClockSourceFrequency +#endif +#ifdef ROM_CS_setDCOExternalResistorCalibration +#define MAP_CS_setDCOExternalResistorCalibration \ + ROM_CS_setDCOExternalResistorCalibration +#else +#define MAP_CS_setDCOExternalResistorCalibration \ + CS_setDCOExternalResistorCalibration +#endif + +//***************************************************************************** +// +// Macros for the DMA API. +// +//***************************************************************************** +#ifdef ROM_DMA_enableModule +#define MAP_DMA_enableModule \ + ROM_DMA_enableModule +#else +#define MAP_DMA_enableModule \ + DMA_enableModule +#endif +#ifdef ROM_DMA_disableModule +#define MAP_DMA_disableModule \ + ROM_DMA_disableModule +#else +#define MAP_DMA_disableModule \ + DMA_disableModule +#endif +#ifdef ROM_DMA_getErrorStatus +#define MAP_DMA_getErrorStatus \ + ROM_DMA_getErrorStatus +#else +#define MAP_DMA_getErrorStatus \ + DMA_getErrorStatus +#endif +#ifdef ROM_DMA_clearErrorStatus +#define MAP_DMA_clearErrorStatus \ + ROM_DMA_clearErrorStatus +#else +#define MAP_DMA_clearErrorStatus \ + DMA_clearErrorStatus +#endif +#ifdef ROM_DMA_enableChannel +#define MAP_DMA_enableChannel \ + ROM_DMA_enableChannel +#else +#define MAP_DMA_enableChannel \ + DMA_enableChannel +#endif +#ifdef ROM_DMA_disableChannel +#define MAP_DMA_disableChannel \ + ROM_DMA_disableChannel +#else +#define MAP_DMA_disableChannel \ + DMA_disableChannel +#endif +#ifdef ROM_DMA_isChannelEnabled +#define MAP_DMA_isChannelEnabled \ + ROM_DMA_isChannelEnabled +#else +#define MAP_DMA_isChannelEnabled \ + DMA_isChannelEnabled +#endif +#ifdef ROM_DMA_setControlBase +#define MAP_DMA_setControlBase \ + ROM_DMA_setControlBase +#else +#define MAP_DMA_setControlBase \ + DMA_setControlBase +#endif +#ifdef ROM_DMA_getControlBase +#define MAP_DMA_getControlBase \ + ROM_DMA_getControlBase +#else +#define MAP_DMA_getControlBase \ + DMA_getControlBase +#endif +#ifdef ROM_DMA_getControlAlternateBase +#define MAP_DMA_getControlAlternateBase \ + ROM_DMA_getControlAlternateBase +#else +#define MAP_DMA_getControlAlternateBase \ + DMA_getControlAlternateBase +#endif +#ifdef ROM_DMA_requestChannel +#define MAP_DMA_requestChannel \ + ROM_DMA_requestChannel +#else +#define MAP_DMA_requestChannel \ + DMA_requestChannel +#endif +#ifdef ROM_DMA_enableChannelAttribute +#define MAP_DMA_enableChannelAttribute \ + ROM_DMA_enableChannelAttribute +#else +#define MAP_DMA_enableChannelAttribute \ + DMA_enableChannelAttribute +#endif +#ifdef ROM_DMA_disableChannelAttribute +#define MAP_DMA_disableChannelAttribute \ + ROM_DMA_disableChannelAttribute +#else +#define MAP_DMA_disableChannelAttribute \ + DMA_disableChannelAttribute +#endif +#ifdef ROM_DMA_getChannelAttribute +#define MAP_DMA_getChannelAttribute \ + ROM_DMA_getChannelAttribute +#else +#define MAP_DMA_getChannelAttribute \ + DMA_getChannelAttribute +#endif +#ifdef ROM_DMA_setChannelControl +#define MAP_DMA_setChannelControl \ + ROM_DMA_setChannelControl +#else +#define MAP_DMA_setChannelControl \ + DMA_setChannelControl +#endif +#ifdef ROM_DMA_setChannelTransfer +#define MAP_DMA_setChannelTransfer \ + ROM_DMA_setChannelTransfer +#else +#define MAP_DMA_setChannelTransfer \ + DMA_setChannelTransfer +#endif +#ifdef ROM_DMA_setChannelScatterGather +#define MAP_DMA_setChannelScatterGather \ + ROM_DMA_setChannelScatterGather +#else +#define MAP_DMA_setChannelScatterGather \ + DMA_setChannelScatterGather +#endif +#ifdef ROM_DMA_getChannelSize +#define MAP_DMA_getChannelSize \ + ROM_DMA_getChannelSize +#else +#define MAP_DMA_getChannelSize \ + DMA_getChannelSize +#endif +#ifdef ROM_DMA_getChannelMode +#define MAP_DMA_getChannelMode \ + ROM_DMA_getChannelMode +#else +#define MAP_DMA_getChannelMode \ + DMA_getChannelMode +#endif +#ifdef ROM_DMA_assignChannel +#define MAP_DMA_assignChannel \ + ROM_DMA_assignChannel +#else +#define MAP_DMA_assignChannel \ + DMA_assignChannel +#endif +#ifdef ROM_DMA_requestSoftwareTransfer +#define MAP_DMA_requestSoftwareTransfer \ + ROM_DMA_requestSoftwareTransfer +#else +#define MAP_DMA_requestSoftwareTransfer \ + DMA_requestSoftwareTransfer +#endif +#ifdef ROM_DMA_assignInterrupt +#define MAP_DMA_assignInterrupt \ + ROM_DMA_assignInterrupt +#else +#define MAP_DMA_assignInterrupt \ + DMA_assignInterrupt +#endif +#ifdef ROM_DMA_enableInterrupt +#define MAP_DMA_enableInterrupt \ + ROM_DMA_enableInterrupt +#else +#define MAP_DMA_enableInterrupt \ + DMA_enableInterrupt +#endif +#ifdef ROM_DMA_disableInterrupt +#define MAP_DMA_disableInterrupt \ + ROM_DMA_disableInterrupt +#else +#define MAP_DMA_disableInterrupt \ + DMA_disableInterrupt +#endif +#ifdef ROM_DMA_getInterruptStatus +#define MAP_DMA_getInterruptStatus \ + ROM_DMA_getInterruptStatus +#else +#define MAP_DMA_getInterruptStatus \ + DMA_getInterruptStatus +#endif +#ifdef ROM_DMA_clearInterruptFlag +#define MAP_DMA_clearInterruptFlag \ + ROM_DMA_clearInterruptFlag +#else +#define MAP_DMA_clearInterruptFlag \ + DMA_clearInterruptFlag +#endif +#ifdef ROM_DMA_registerInterrupt +#define MAP_DMA_registerInterrupt \ + ROM_DMA_registerInterrupt +#else +#define MAP_DMA_registerInterrupt \ + DMA_registerInterrupt +#endif +#ifdef ROM_DMA_unregisterInterrupt +#define MAP_DMA_unregisterInterrupt \ + ROM_DMA_unregisterInterrupt +#else +#define MAP_DMA_unregisterInterrupt \ + DMA_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the Flash API. +// +//***************************************************************************** +#ifdef ROM_FlashCtl_enableReadParityCheck +#define MAP_FlashCtl_enableReadParityCheck \ + ROM_FlashCtl_enableReadParityCheck +#else +#define MAP_FlashCtl_enableReadParityCheck \ + FlashCtl_enableReadParityCheck +#endif +#ifdef ROM_FlashCtl_disableReadParityCheck +#define MAP_FlashCtl_disableReadParityCheck \ + ROM_FlashCtl_disableReadParityCheck +#else +#define MAP_FlashCtl_disableReadParityCheck \ + FlashCtl_disableReadParityCheck +#endif +#ifdef ROM_FlashCtl_enableReadBuffering +#define MAP_FlashCtl_enableReadBuffering \ + ROM_FlashCtl_enableReadBuffering +#else +#define MAP_FlashCtl_enableReadBuffering \ + FlashCtl_enableReadBuffering +#endif +#ifdef ROM_FlashCtl_disableReadBuffering +#define MAP_FlashCtl_disableReadBuffering \ + ROM_FlashCtl_disableReadBuffering +#else +#define MAP_FlashCtl_disableReadBuffering \ + FlashCtl_disableReadBuffering +#endif +#ifdef ROM_FlashCtl_unprotectSector +#define MAP_FlashCtl_unprotectSector \ + ROM_FlashCtl_unprotectSector +#else +#define MAP_FlashCtl_unprotectSector \ + FlashCtl_unprotectSector +#endif +#ifdef ROM_FlashCtl_protectSector +#define MAP_FlashCtl_protectSector \ + ROM_FlashCtl_protectSector +#else +#define MAP_FlashCtl_protectSector \ + FlashCtl_protectSector +#endif +#ifdef ROM_FlashCtl_isSectorProtected +#define MAP_FlashCtl_isSectorProtected \ + ROM_FlashCtl_isSectorProtected +#else +#define MAP_FlashCtl_isSectorProtected \ + FlashCtl_isSectorProtected +#endif +#ifdef ROM_FlashCtl_verifyMemory +#define MAP_FlashCtl_verifyMemory \ + ROM_FlashCtl_verifyMemory +#else +#define MAP_FlashCtl_verifyMemory \ + FlashCtl_verifyMemory +#endif +#ifdef ROM_FlashCtl_performMassErase +#define MAP_FlashCtl_performMassErase \ + ROM_FlashCtl_performMassErase +#else +#define MAP_FlashCtl_performMassErase \ + FlashCtl_performMassErase +#endif +#ifdef ROM_FlashCtl_eraseSector +#define MAP_FlashCtl_eraseSector \ + ROM_FlashCtl_eraseSector +#else +#define MAP_FlashCtl_eraseSector \ + FlashCtl_eraseSector +#endif +#ifdef ROM_FlashCtl_programMemory +#define MAP_FlashCtl_programMemory \ + ROM_FlashCtl_programMemory +#else +#define MAP_FlashCtl_programMemory \ + FlashCtl_programMemory +#endif +#ifdef ROM_FlashCtl_setProgramVerification +#define MAP_FlashCtl_setProgramVerification \ + ROM_FlashCtl_setProgramVerification +#else +#define MAP_FlashCtl_setProgramVerification \ + FlashCtl_setProgramVerification +#endif +#ifdef ROM_FlashCtl_clearProgramVerification +#define MAP_FlashCtl_clearProgramVerification \ + ROM_FlashCtl_clearProgramVerification +#else +#define MAP_FlashCtl_clearProgramVerification \ + FlashCtl_clearProgramVerification +#endif +#ifdef ROM_FlashCtl_enableWordProgramming +#define MAP_FlashCtl_enableWordProgramming \ + ROM_FlashCtl_enableWordProgramming +#else +#define MAP_FlashCtl_enableWordProgramming \ + FlashCtl_enableWordProgramming +#endif +#ifdef ROM_FlashCtl_disableWordProgramming +#define MAP_FlashCtl_disableWordProgramming \ + ROM_FlashCtl_disableWordProgramming +#else +#define MAP_FlashCtl_disableWordProgramming \ + FlashCtl_disableWordProgramming +#endif +#ifdef ROM_FlashCtl_isWordProgrammingEnabled +#define MAP_FlashCtl_isWordProgrammingEnabled \ + ROM_FlashCtl_isWordProgrammingEnabled +#else +#define MAP_FlashCtl_isWordProgrammingEnabled \ + FlashCtl_isWordProgrammingEnabled +#endif +#ifdef ROM_FlashCtl_enableInterrupt +#define MAP_FlashCtl_enableInterrupt \ + ROM_FlashCtl_enableInterrupt +#else +#define MAP_FlashCtl_enableInterrupt \ + FlashCtl_enableInterrupt +#endif +#ifdef ROM_FlashCtl_disableInterrupt +#define MAP_FlashCtl_disableInterrupt \ + ROM_FlashCtl_disableInterrupt +#else +#define MAP_FlashCtl_disableInterrupt \ + FlashCtl_disableInterrupt +#endif +#ifdef ROM_FlashCtl_getEnabledInterruptStatus +#define MAP_FlashCtl_getEnabledInterruptStatus \ + ROM_FlashCtl_getEnabledInterruptStatus +#else +#define MAP_FlashCtl_getEnabledInterruptStatus \ + FlashCtl_getEnabledInterruptStatus +#endif +#ifdef ROM_FlashCtl_getInterruptStatus +#define MAP_FlashCtl_getInterruptStatus \ + ROM_FlashCtl_getInterruptStatus +#else +#define MAP_FlashCtl_getInterruptStatus \ + FlashCtl_getInterruptStatus +#endif +#ifdef ROM_FlashCtl_clearInterruptFlag +#define MAP_FlashCtl_clearInterruptFlag \ + ROM_FlashCtl_clearInterruptFlag +#else +#define MAP_FlashCtl_clearInterruptFlag \ + FlashCtl_clearInterruptFlag +#endif +#ifdef ROM_FlashCtl_setWaitState +#define MAP_FlashCtl_setWaitState \ + ROM_FlashCtl_setWaitState +#else +#define MAP_FlashCtl_setWaitState \ + FlashCtl_setWaitState +#endif +#ifdef ROM_FlashCtl_getWaitState +#define MAP_FlashCtl_getWaitState \ + ROM_FlashCtl_getWaitState +#else +#define MAP_FlashCtl_getWaitState \ + FlashCtl_getWaitState +#endif +#ifdef ROM_FlashCtl_setReadMode +#define MAP_FlashCtl_setReadMode \ + ROM_FlashCtl_setReadMode +#else +#define MAP_FlashCtl_setReadMode \ + FlashCtl_setReadMode +#endif +#ifdef ROM_FlashCtl_getReadMode +#define MAP_FlashCtl_getReadMode \ + ROM_FlashCtl_getReadMode +#else +#define MAP_FlashCtl_getReadMode \ + FlashCtl_getReadMode +#endif +#ifdef ROM_FlashCtl_registerInterrupt +#define MAP_FlashCtl_registerInterrupt \ + ROM_FlashCtl_registerInterrupt +#else +#define MAP_FlashCtl_registerInterrupt \ + FlashCtl_registerInterrupt +#endif +#ifdef ROM_FlashCtl_unregisterInterrupt +#define MAP_FlashCtl_unregisterInterrupt \ + ROM_FlashCtl_unregisterInterrupt +#else +#define MAP_FlashCtl_unregisterInterrupt \ + FlashCtl_unregisterInterrupt +#endif +#ifdef ROM___FlashCtl_remaskData8Post +#define MAP___FlashCtl_remaskData8Post \ + ROM___FlashCtl_remaskData8Post +#else +#define MAP___FlashCtl_remaskData8Post \ + __FlashCtl_remaskData8Post +#endif +#ifdef ROM___FlashCtl_remaskData8Pre +#define MAP___FlashCtl_remaskData8Pre \ + ROM___FlashCtl_remaskData8Pre +#else +#define MAP___FlashCtl_remaskData8Pre \ + __FlashCtl_remaskData8Pre +#endif +#ifdef ROM___FlashCtl_remaskData32Pre +#define MAP___FlashCtl_remaskData32Pre \ + ROM___FlashCtl_remaskData32Pre +#else +#define MAP___FlashCtl_remaskData32Pre \ + __FlashCtl_remaskData32Pre +#endif +#ifdef ROM___FlashCtl_remaskData32Post +#define MAP___FlashCtl_remaskData32Post \ + ROM___FlashCtl_remaskData32Post +#else +#define MAP___FlashCtl_remaskData32Post \ + __FlashCtl_remaskData32Post +#endif +#ifdef ROM___FlashCtl_remaskBurstDataPre +#define MAP___FlashCtl_remaskBurstDataPre \ + ROM___FlashCtl_remaskBurstDataPre +#else +#define MAP___FlashCtl_remaskBurstDataPre \ + __FlashCtl_remaskBurstDataPre +#endif +#ifdef ROM___FlashCtl_remaskBurstDataPost +#define MAP___FlashCtl_remaskBurstDataPost \ + ROM___FlashCtl_remaskBurstDataPost +#else +#define MAP___FlashCtl_remaskBurstDataPost \ + __FlashCtl_remaskBurstDataPost +#endif +#ifdef ROM_FlashCtl_initiateSectorErase +#define MAP_FlashCtl_initiateSectorErase \ + ROM_FlashCtl_initiateSectorErase +#else +#define MAP_FlashCtl_initiateSectorErase \ + FlashCtl_initiateSectorErase +#endif +#ifdef ROM_FlashCtl_initiateMassErase +#define MAP_FlashCtl_initiateMassErase \ + ROM_FlashCtl_initiateMassErase +#else +#define MAP_FlashCtl_initiateMassErase \ + FlashCtl_initiateMassErase +#endif +#ifdef ROM_FlashCtl_getMemoryInfo +#define MAP_FlashCtl_getMemoryInfo \ + ROM_FlashCtl_getMemoryInfo +#else +#define MAP_FlashCtl_getMemoryInfo \ + FlashCtl_getMemoryInfo +#endif + +//***************************************************************************** +// +// Macros for the FPU API. +// +//***************************************************************************** +#ifdef ROM_FPU_enableModule +#define MAP_FPU_enableModule \ + ROM_FPU_enableModule +#else +#define MAP_FPU_enableModule \ + FPU_enableModule +#endif +#ifdef ROM_FPU_disableModule +#define MAP_FPU_disableModule \ + ROM_FPU_disableModule +#else +#define MAP_FPU_disableModule \ + FPU_disableModule +#endif +#ifdef ROM_FPU_enableStacking +#define MAP_FPU_enableStacking \ + ROM_FPU_enableStacking +#else +#define MAP_FPU_enableStacking \ + FPU_enableStacking +#endif +#ifdef ROM_FPU_enableLazyStacking +#define MAP_FPU_enableLazyStacking \ + ROM_FPU_enableLazyStacking +#else +#define MAP_FPU_enableLazyStacking \ + FPU_enableLazyStacking +#endif +#ifdef ROM_FPU_disableStacking +#define MAP_FPU_disableStacking \ + ROM_FPU_disableStacking +#else +#define MAP_FPU_disableStacking \ + FPU_disableStacking +#endif +#ifdef ROM_FPU_setHalfPrecisionMode +#define MAP_FPU_setHalfPrecisionMode \ + ROM_FPU_setHalfPrecisionMode +#else +#define MAP_FPU_setHalfPrecisionMode \ + FPU_setHalfPrecisionMode +#endif +#ifdef ROM_FPU_setNaNMode +#define MAP_FPU_setNaNMode \ + ROM_FPU_setNaNMode +#else +#define MAP_FPU_setNaNMode \ + FPU_setNaNMode +#endif +#ifdef ROM_FPU_setFlushToZeroMode +#define MAP_FPU_setFlushToZeroMode \ + ROM_FPU_setFlushToZeroMode +#else +#define MAP_FPU_setFlushToZeroMode \ + FPU_setFlushToZeroMode +#endif +#ifdef ROM_FPU_setRoundingMode +#define MAP_FPU_setRoundingMode \ + ROM_FPU_setRoundingMode +#else +#define MAP_FPU_setRoundingMode \ + FPU_setRoundingMode +#endif + +//***************************************************************************** +// +// Macros for the GPIO API. +// +//***************************************************************************** +#ifdef ROM_GPIO_setAsOutputPin +#define MAP_GPIO_setAsOutputPin \ + ROM_GPIO_setAsOutputPin +#else +#define MAP_GPIO_setAsOutputPin \ + GPIO_setAsOutputPin +#endif +#ifdef ROM_GPIO_setOutputHighOnPin +#define MAP_GPIO_setOutputHighOnPin \ + ROM_GPIO_setOutputHighOnPin +#else +#define MAP_GPIO_setOutputHighOnPin \ + GPIO_setOutputHighOnPin +#endif +#ifdef ROM_GPIO_setOutputLowOnPin +#define MAP_GPIO_setOutputLowOnPin \ + ROM_GPIO_setOutputLowOnPin +#else +#define MAP_GPIO_setOutputLowOnPin \ + GPIO_setOutputLowOnPin +#endif +#ifdef ROM_GPIO_toggleOutputOnPin +#define MAP_GPIO_toggleOutputOnPin \ + ROM_GPIO_toggleOutputOnPin +#else +#define MAP_GPIO_toggleOutputOnPin \ + GPIO_toggleOutputOnPin +#endif +#ifdef ROM_GPIO_setAsInputPinWithPullDownResistor +#define MAP_GPIO_setAsInputPinWithPullDownResistor \ + ROM_GPIO_setAsInputPinWithPullDownResistor +#else +#define MAP_GPIO_setAsInputPinWithPullDownResistor \ + GPIO_setAsInputPinWithPullDownResistor +#endif +#ifdef ROM_GPIO_setAsInputPinWithPullUpResistor +#define MAP_GPIO_setAsInputPinWithPullUpResistor \ + ROM_GPIO_setAsInputPinWithPullUpResistor +#else +#define MAP_GPIO_setAsInputPinWithPullUpResistor \ + GPIO_setAsInputPinWithPullUpResistor +#endif +#ifdef ROM_GPIO_setAsPeripheralModuleFunctionOutputPin +#define MAP_GPIO_setAsPeripheralModuleFunctionOutputPin \ + ROM_GPIO_setAsPeripheralModuleFunctionOutputPin +#else +#define MAP_GPIO_setAsPeripheralModuleFunctionOutputPin \ + GPIO_setAsPeripheralModuleFunctionOutputPin +#endif +#ifdef ROM_GPIO_setAsPeripheralModuleFunctionInputPin +#define MAP_GPIO_setAsPeripheralModuleFunctionInputPin \ + ROM_GPIO_setAsPeripheralModuleFunctionInputPin +#else +#define MAP_GPIO_setAsPeripheralModuleFunctionInputPin \ + GPIO_setAsPeripheralModuleFunctionInputPin +#endif +#ifdef ROM_GPIO_getInputPinValue +#define MAP_GPIO_getInputPinValue \ + ROM_GPIO_getInputPinValue +#else +#define MAP_GPIO_getInputPinValue \ + GPIO_getInputPinValue +#endif +#ifdef ROM_GPIO_interruptEdgeSelect +#define MAP_GPIO_interruptEdgeSelect \ + ROM_GPIO_interruptEdgeSelect +#else +#define MAP_GPIO_interruptEdgeSelect \ + GPIO_interruptEdgeSelect +#endif +#ifdef ROM_GPIO_enableInterrupt +#define MAP_GPIO_enableInterrupt \ + ROM_GPIO_enableInterrupt +#else +#define MAP_GPIO_enableInterrupt \ + GPIO_enableInterrupt +#endif +#ifdef ROM_GPIO_disableInterrupt +#define MAP_GPIO_disableInterrupt \ + ROM_GPIO_disableInterrupt +#else +#define MAP_GPIO_disableInterrupt \ + GPIO_disableInterrupt +#endif +#ifdef ROM_GPIO_getInterruptStatus +#define MAP_GPIO_getInterruptStatus \ + ROM_GPIO_getInterruptStatus +#else +#define MAP_GPIO_getInterruptStatus \ + GPIO_getInterruptStatus +#endif +#ifdef ROM_GPIO_clearInterruptFlag +#define MAP_GPIO_clearInterruptFlag \ + ROM_GPIO_clearInterruptFlag +#else +#define MAP_GPIO_clearInterruptFlag \ + GPIO_clearInterruptFlag +#endif +#ifdef ROM_GPIO_setAsInputPin +#define MAP_GPIO_setAsInputPin \ + ROM_GPIO_setAsInputPin +#else +#define MAP_GPIO_setAsInputPin \ + GPIO_setAsInputPin +#endif +#ifdef ROM_GPIO_getEnabledInterruptStatus +#define MAP_GPIO_getEnabledInterruptStatus \ + ROM_GPIO_getEnabledInterruptStatus +#else +#define MAP_GPIO_getEnabledInterruptStatus \ + GPIO_getEnabledInterruptStatus +#endif +#ifdef ROM_GPIO_setDriveStrengthHigh +#define MAP_GPIO_setDriveStrengthHigh \ + ROM_GPIO_setDriveStrengthHigh +#else +#define MAP_GPIO_setDriveStrengthHigh \ + GPIO_setDriveStrengthHigh +#endif +#ifdef ROM_GPIO_setDriveStrengthLow +#define MAP_GPIO_setDriveStrengthLow \ + ROM_GPIO_setDriveStrengthLow +#else +#define MAP_GPIO_setDriveStrengthLow \ + GPIO_setDriveStrengthLow +#endif +#ifdef ROM_GPIO_registerInterrupt +#define MAP_GPIO_registerInterrupt \ + ROM_GPIO_registerInterrupt +#else +#define MAP_GPIO_registerInterrupt \ + GPIO_registerInterrupt +#endif +#ifdef ROM_GPIO_unregisterInterrupt +#define MAP_GPIO_unregisterInterrupt \ + ROM_GPIO_unregisterInterrupt +#else +#define MAP_GPIO_unregisterInterrupt \ + GPIO_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the I2C API. +// +//***************************************************************************** +#ifdef ROM_I2C_initMaster +#define MAP_I2C_initMaster \ + ROM_I2C_initMaster +#else +#define MAP_I2C_initMaster \ + I2C_initMaster +#endif +#ifdef ROM_I2C_initSlave +#define MAP_I2C_initSlave \ + ROM_I2C_initSlave +#else +#define MAP_I2C_initSlave \ + I2C_initSlave +#endif +#ifdef ROM_I2C_enableModule +#define MAP_I2C_enableModule \ + ROM_I2C_enableModule +#else +#define MAP_I2C_enableModule \ + I2C_enableModule +#endif +#ifdef ROM_I2C_disableModule +#define MAP_I2C_disableModule \ + ROM_I2C_disableModule +#else +#define MAP_I2C_disableModule \ + I2C_disableModule +#endif +#ifdef ROM_I2C_setSlaveAddress +#define MAP_I2C_setSlaveAddress \ + ROM_I2C_setSlaveAddress +#else +#define MAP_I2C_setSlaveAddress \ + I2C_setSlaveAddress +#endif +#ifdef ROM_I2C_setMode +#define MAP_I2C_setMode \ + ROM_I2C_setMode +#else +#define MAP_I2C_setMode \ + I2C_setMode +#endif +#ifdef ROM_I2C_slavePutData +#define MAP_I2C_slavePutData \ + ROM_I2C_slavePutData +#else +#define MAP_I2C_slavePutData \ + I2C_slavePutData +#endif +#ifdef ROM_I2C_slaveGetData +#define MAP_I2C_slaveGetData \ + ROM_I2C_slaveGetData +#else +#define MAP_I2C_slaveGetData \ + I2C_slaveGetData +#endif +#ifdef ROM_I2C_isBusBusy +#define MAP_I2C_isBusBusy \ + ROM_I2C_isBusBusy +#else +#define MAP_I2C_isBusBusy \ + I2C_isBusBusy +#endif +#ifdef ROM_I2C_masterSendSingleByte +#define MAP_I2C_masterSendSingleByte \ + ROM_I2C_masterSendSingleByte +#else +#define MAP_I2C_masterSendSingleByte \ + I2C_masterSendSingleByte +#endif +#ifdef ROM_I2C_masterSendSingleByteWithTimeout +#define MAP_I2C_masterSendSingleByteWithTimeout \ + ROM_I2C_masterSendSingleByteWithTimeout +#else +#define MAP_I2C_masterSendSingleByteWithTimeout \ + I2C_masterSendSingleByteWithTimeout +#endif +#ifdef ROM_I2C_masterSendMultiByteStart +#define MAP_I2C_masterSendMultiByteStart \ + ROM_I2C_masterSendMultiByteStart +#else +#define MAP_I2C_masterSendMultiByteStart \ + I2C_masterSendMultiByteStart +#endif +#ifdef ROM_I2C_masterSendMultiByteStartWithTimeout +#define MAP_I2C_masterSendMultiByteStartWithTimeout \ + ROM_I2C_masterSendMultiByteStartWithTimeout +#else +#define MAP_I2C_masterSendMultiByteStartWithTimeout \ + I2C_masterSendMultiByteStartWithTimeout +#endif +#ifdef ROM_I2C_masterSendMultiByteNext +#define MAP_I2C_masterSendMultiByteNext \ + ROM_I2C_masterSendMultiByteNext +#else +#define MAP_I2C_masterSendMultiByteNext \ + I2C_masterSendMultiByteNext +#endif +#ifdef ROM_I2C_masterSendMultiByteNextWithTimeout +#define MAP_I2C_masterSendMultiByteNextWithTimeout \ + ROM_I2C_masterSendMultiByteNextWithTimeout +#else +#define MAP_I2C_masterSendMultiByteNextWithTimeout \ + I2C_masterSendMultiByteNextWithTimeout +#endif +#ifdef ROM_I2C_masterSendMultiByteFinish +#define MAP_I2C_masterSendMultiByteFinish \ + ROM_I2C_masterSendMultiByteFinish +#else +#define MAP_I2C_masterSendMultiByteFinish \ + I2C_masterSendMultiByteFinish +#endif +#ifdef ROM_I2C_masterSendMultiByteFinishWithTimeout +#define MAP_I2C_masterSendMultiByteFinishWithTimeout \ + ROM_I2C_masterSendMultiByteFinishWithTimeout +#else +#define MAP_I2C_masterSendMultiByteFinishWithTimeout \ + I2C_masterSendMultiByteFinishWithTimeout +#endif +#ifdef ROM_I2C_masterSendMultiByteStop +#define MAP_I2C_masterSendMultiByteStop \ + ROM_I2C_masterSendMultiByteStop +#else +#define MAP_I2C_masterSendMultiByteStop \ + I2C_masterSendMultiByteStop +#endif +#ifdef ROM_I2C_masterSendMultiByteStopWithTimeout +#define MAP_I2C_masterSendMultiByteStopWithTimeout \ + ROM_I2C_masterSendMultiByteStopWithTimeout +#else +#define MAP_I2C_masterSendMultiByteStopWithTimeout \ + I2C_masterSendMultiByteStopWithTimeout +#endif +#ifdef ROM_I2C_masterReceiveStart +#define MAP_I2C_masterReceiveStart \ + ROM_I2C_masterReceiveStart +#else +#define MAP_I2C_masterReceiveStart \ + I2C_masterReceiveStart +#endif +#ifdef ROM_I2C_masterReceiveMultiByteNext +#define MAP_I2C_masterReceiveMultiByteNext \ + ROM_I2C_masterReceiveMultiByteNext +#else +#define MAP_I2C_masterReceiveMultiByteNext \ + I2C_masterReceiveMultiByteNext +#endif +#ifdef ROM_I2C_masterReceiveMultiByteFinish +#define MAP_I2C_masterReceiveMultiByteFinish \ + ROM_I2C_masterReceiveMultiByteFinish +#else +#define MAP_I2C_masterReceiveMultiByteFinish \ + I2C_masterReceiveMultiByteFinish +#endif +#ifdef ROM_I2C_masterReceiveMultiByteFinishWithTimeout +#define MAP_I2C_masterReceiveMultiByteFinishWithTimeout \ + ROM_I2C_masterReceiveMultiByteFinishWithTimeout +#else +#define MAP_I2C_masterReceiveMultiByteFinishWithTimeout \ + I2C_masterReceiveMultiByteFinishWithTimeout +#endif +#ifdef ROM_I2C_masterReceiveMultiByteStop +#define MAP_I2C_masterReceiveMultiByteStop \ + ROM_I2C_masterReceiveMultiByteStop +#else +#define MAP_I2C_masterReceiveMultiByteStop \ + I2C_masterReceiveMultiByteStop +#endif +#ifdef ROM_I2C_masterReceiveSingleByte +#define MAP_I2C_masterReceiveSingleByte \ + ROM_I2C_masterReceiveSingleByte +#else +#define MAP_I2C_masterReceiveSingleByte \ + I2C_masterReceiveSingleByte +#endif +#ifdef ROM_I2C_masterReceiveSingle +#define MAP_I2C_masterReceiveSingle \ + ROM_I2C_masterReceiveSingle +#else +#define MAP_I2C_masterReceiveSingle \ + I2C_masterReceiveSingle +#endif +#ifdef ROM_I2C_getReceiveBufferAddressForDMA +#define MAP_I2C_getReceiveBufferAddressForDMA \ + ROM_I2C_getReceiveBufferAddressForDMA +#else +#define MAP_I2C_getReceiveBufferAddressForDMA \ + I2C_getReceiveBufferAddressForDMA +#endif +#ifdef ROM_I2C_getTransmitBufferAddressForDMA +#define MAP_I2C_getTransmitBufferAddressForDMA \ + ROM_I2C_getTransmitBufferAddressForDMA +#else +#define MAP_I2C_getTransmitBufferAddressForDMA \ + I2C_getTransmitBufferAddressForDMA +#endif +#ifdef ROM_I2C_masterIsStopSent +#define MAP_I2C_masterIsStopSent \ + ROM_I2C_masterIsStopSent +#else +#define MAP_I2C_masterIsStopSent \ + I2C_masterIsStopSent +#endif +#ifdef ROM_I2C_masterIsStartSent +#define MAP_I2C_masterIsStartSent \ + ROM_I2C_masterIsStartSent +#else +#define MAP_I2C_masterIsStartSent \ + I2C_masterIsStartSent +#endif +#ifdef ROM_I2C_masterSendStart +#define MAP_I2C_masterSendStart \ + ROM_I2C_masterSendStart +#else +#define MAP_I2C_masterSendStart \ + I2C_masterSendStart +#endif +#ifdef ROM_I2C_enableMultiMasterMode +#define MAP_I2C_enableMultiMasterMode \ + ROM_I2C_enableMultiMasterMode +#else +#define MAP_I2C_enableMultiMasterMode \ + I2C_enableMultiMasterMode +#endif +#ifdef ROM_I2C_disableMultiMasterMode +#define MAP_I2C_disableMultiMasterMode \ + ROM_I2C_disableMultiMasterMode +#else +#define MAP_I2C_disableMultiMasterMode \ + I2C_disableMultiMasterMode +#endif +#ifdef ROM_I2C_enableInterrupt +#define MAP_I2C_enableInterrupt \ + ROM_I2C_enableInterrupt +#else +#define MAP_I2C_enableInterrupt \ + I2C_enableInterrupt +#endif +#ifdef ROM_I2C_disableInterrupt +#define MAP_I2C_disableInterrupt \ + ROM_I2C_disableInterrupt +#else +#define MAP_I2C_disableInterrupt \ + I2C_disableInterrupt +#endif +#ifdef ROM_I2C_clearInterruptFlag +#define MAP_I2C_clearInterruptFlag \ + ROM_I2C_clearInterruptFlag +#else +#define MAP_I2C_clearInterruptFlag \ + I2C_clearInterruptFlag +#endif +#ifdef ROM_I2C_getInterruptStatus +#define MAP_I2C_getInterruptStatus \ + ROM_I2C_getInterruptStatus +#else +#define MAP_I2C_getInterruptStatus \ + I2C_getInterruptStatus +#endif +#ifdef ROM_I2C_getEnabledInterruptStatus +#define MAP_I2C_getEnabledInterruptStatus \ + ROM_I2C_getEnabledInterruptStatus +#else +#define MAP_I2C_getEnabledInterruptStatus \ + I2C_getEnabledInterruptStatus +#endif +#ifdef ROM_I2C_getMode +#define MAP_I2C_getMode \ + ROM_I2C_getMode +#else +#define MAP_I2C_getMode \ + I2C_getMode +#endif +#ifdef ROM_I2C_registerInterrupt +#define MAP_I2C_registerInterrupt \ + ROM_I2C_registerInterrupt +#else +#define MAP_I2C_registerInterrupt \ + I2C_registerInterrupt +#endif +#ifdef ROM_I2C_unregisterInterrupt +#define MAP_I2C_unregisterInterrupt \ + ROM_I2C_unregisterInterrupt +#else +#define MAP_I2C_unregisterInterrupt \ + I2C_unregisterInterrupt +#endif +#ifdef ROM_I2C_slaveSendNAK +#define MAP_I2C_slaveSendNAK \ + ROM_I2C_slaveSendNAK +#else +#define MAP_I2C_slaveSendNAK \ + I2C_slaveSendNAK +#endif + +//***************************************************************************** +// +// Macros for the Interrupt API. +// +//***************************************************************************** +#ifdef ROM_Interrupt_enableMaster +#define MAP_Interrupt_enableMaster \ + ROM_Interrupt_enableMaster +#else +#define MAP_Interrupt_enableMaster \ + Interrupt_enableMaster +#endif +#ifdef ROM_Interrupt_disableMaster +#define MAP_Interrupt_disableMaster \ + ROM_Interrupt_disableMaster +#else +#define MAP_Interrupt_disableMaster \ + Interrupt_disableMaster +#endif +#ifdef ROM_Interrupt_setPriorityGrouping +#define MAP_Interrupt_setPriorityGrouping \ + ROM_Interrupt_setPriorityGrouping +#else +#define MAP_Interrupt_setPriorityGrouping \ + Interrupt_setPriorityGrouping +#endif +#ifdef ROM_Interrupt_getPriorityGrouping +#define MAP_Interrupt_getPriorityGrouping \ + ROM_Interrupt_getPriorityGrouping +#else +#define MAP_Interrupt_getPriorityGrouping \ + Interrupt_getPriorityGrouping +#endif +#ifdef ROM_Interrupt_setPriority +#define MAP_Interrupt_setPriority \ + ROM_Interrupt_setPriority +#else +#define MAP_Interrupt_setPriority \ + Interrupt_setPriority +#endif +#ifdef ROM_Interrupt_getPriority +#define MAP_Interrupt_getPriority \ + ROM_Interrupt_getPriority +#else +#define MAP_Interrupt_getPriority \ + Interrupt_getPriority +#endif +#ifdef ROM_Interrupt_enableInterrupt +#define MAP_Interrupt_enableInterrupt \ + ROM_Interrupt_enableInterrupt +#else +#define MAP_Interrupt_enableInterrupt \ + Interrupt_enableInterrupt +#endif +#ifdef ROM_Interrupt_disableInterrupt +#define MAP_Interrupt_disableInterrupt \ + ROM_Interrupt_disableInterrupt +#else +#define MAP_Interrupt_disableInterrupt \ + Interrupt_disableInterrupt +#endif +#ifdef ROM_Interrupt_isEnabled +#define MAP_Interrupt_isEnabled \ + ROM_Interrupt_isEnabled +#else +#define MAP_Interrupt_isEnabled \ + Interrupt_isEnabled +#endif +#ifdef ROM_Interrupt_pendInterrupt +#define MAP_Interrupt_pendInterrupt \ + ROM_Interrupt_pendInterrupt +#else +#define MAP_Interrupt_pendInterrupt \ + Interrupt_pendInterrupt +#endif +#ifdef ROM_Interrupt_setPriorityMask +#define MAP_Interrupt_setPriorityMask \ + ROM_Interrupt_setPriorityMask +#else +#define MAP_Interrupt_setPriorityMask \ + Interrupt_setPriorityMask +#endif +#ifdef ROM_Interrupt_getPriorityMask +#define MAP_Interrupt_getPriorityMask \ + ROM_Interrupt_getPriorityMask +#else +#define MAP_Interrupt_getPriorityMask \ + Interrupt_getPriorityMask +#endif +#ifdef ROM_Interrupt_setVectorTableAddress +#define MAP_Interrupt_setVectorTableAddress \ + ROM_Interrupt_setVectorTableAddress +#else +#define MAP_Interrupt_setVectorTableAddress \ + Interrupt_setVectorTableAddress +#endif +#ifdef ROM_Interrupt_getVectorTableAddress +#define MAP_Interrupt_getVectorTableAddress \ + ROM_Interrupt_getVectorTableAddress +#else +#define MAP_Interrupt_getVectorTableAddress \ + Interrupt_getVectorTableAddress +#endif +#ifdef ROM_Interrupt_enableSleepOnIsrExit +#define MAP_Interrupt_enableSleepOnIsrExit \ + ROM_Interrupt_enableSleepOnIsrExit +#else +#define MAP_Interrupt_enableSleepOnIsrExit \ + Interrupt_enableSleepOnIsrExit +#endif +#ifdef ROM_Interrupt_disableSleepOnIsrExit +#define MAP_Interrupt_disableSleepOnIsrExit \ + ROM_Interrupt_disableSleepOnIsrExit +#else +#define MAP_Interrupt_disableSleepOnIsrExit \ + Interrupt_disableSleepOnIsrExit +#endif +#ifdef ROM_Interrupt_registerInterrupt +#define MAP_Interrupt_registerInterrupt \ + ROM_Interrupt_registerInterrupt +#else +#define MAP_Interrupt_registerInterrupt \ + Interrupt_registerInterrupt +#endif +#ifdef ROM_Interrupt_unregisterInterrupt +#define MAP_Interrupt_unregisterInterrupt \ + ROM_Interrupt_unregisterInterrupt +#else +#define MAP_Interrupt_unregisterInterrupt \ + Interrupt_unregisterInterrupt +#endif +#ifdef ROM_Interrupt_unpendInterrupt +#define MAP_Interrupt_unpendInterrupt \ + ROM_Interrupt_unpendInterrupt +#else +#define MAP_Interrupt_unpendInterrupt \ + Interrupt_unpendInterrupt +#endif + +//***************************************************************************** +// +// Macros for the MPU API. +// +//***************************************************************************** +#ifdef ROM_MPU_enableModule +#define MAP_MPU_enableModule \ + ROM_MPU_enableModule +#else +#define MAP_MPU_enableModule \ + MPU_enableModule +#endif +#ifdef ROM_MPU_disableModule +#define MAP_MPU_disableModule \ + ROM_MPU_disableModule +#else +#define MAP_MPU_disableModule \ + MPU_disableModule +#endif +#ifdef ROM_MPU_getRegionCount +#define MAP_MPU_getRegionCount \ + ROM_MPU_getRegionCount +#else +#define MAP_MPU_getRegionCount \ + MPU_getRegionCount +#endif +#ifdef ROM_MPU_enableRegion +#define MAP_MPU_enableRegion \ + ROM_MPU_enableRegion +#else +#define MAP_MPU_enableRegion \ + MPU_enableRegion +#endif +#ifdef ROM_MPU_disableRegion +#define MAP_MPU_disableRegion \ + ROM_MPU_disableRegion +#else +#define MAP_MPU_disableRegion \ + MPU_disableRegion +#endif +#ifdef ROM_MPU_setRegion +#define MAP_MPU_setRegion \ + ROM_MPU_setRegion +#else +#define MAP_MPU_setRegion \ + MPU_setRegion +#endif +#ifdef ROM_MPU_getRegion +#define MAP_MPU_getRegion \ + ROM_MPU_getRegion +#else +#define MAP_MPU_getRegion \ + MPU_getRegion +#endif +#ifdef ROM_MPU_enableInterrupt +#define MAP_MPU_enableInterrupt \ + ROM_MPU_enableInterrupt +#else +#define MAP_MPU_enableInterrupt \ + MPU_enableInterrupt +#endif +#ifdef ROM_MPU_disableInterrupt +#define MAP_MPU_disableInterrupt \ + ROM_MPU_disableInterrupt +#else +#define MAP_MPU_disableInterrupt \ + MPU_disableInterrupt +#endif +#ifdef ROM_MPU_registerInterrupt +#define MAP_MPU_registerInterrupt \ + ROM_MPU_registerInterrupt +#else +#define MAP_MPU_registerInterrupt \ + MPU_registerInterrupt +#endif +#ifdef ROM_MPU_unregisterInterrupt +#define MAP_MPU_unregisterInterrupt \ + ROM_MPU_unregisterInterrupt +#else +#define MAP_MPU_unregisterInterrupt \ + MPU_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the PCM API. +// +//***************************************************************************** +#ifdef ROM_PCM_setCoreVoltageLevel +#define MAP_PCM_setCoreVoltageLevel \ + ROM_PCM_setCoreVoltageLevel +#else +#define MAP_PCM_setCoreVoltageLevel \ + PCM_setCoreVoltageLevel +#endif +#ifdef ROM_PCM_getCoreVoltageLevel +#define MAP_PCM_getCoreVoltageLevel \ + ROM_PCM_getCoreVoltageLevel +#else +#define MAP_PCM_getCoreVoltageLevel \ + PCM_getCoreVoltageLevel +#endif +#ifdef ROM_PCM_setCoreVoltageLevelWithTimeout +#define MAP_PCM_setCoreVoltageLevelWithTimeout \ + ROM_PCM_setCoreVoltageLevelWithTimeout +#else +#define MAP_PCM_setCoreVoltageLevelWithTimeout \ + PCM_setCoreVoltageLevelWithTimeout +#endif +#ifdef ROM_PCM_setPowerMode +#define MAP_PCM_setPowerMode \ + ROM_PCM_setPowerMode +#else +#define MAP_PCM_setPowerMode \ + PCM_setPowerMode +#endif +#ifdef ROM_PCM_setPowerModeWithTimeout +#define MAP_PCM_setPowerModeWithTimeout \ + ROM_PCM_setPowerModeWithTimeout +#else +#define MAP_PCM_setPowerModeWithTimeout \ + PCM_setPowerModeWithTimeout +#endif +#ifdef ROM_PCM_getPowerMode +#define MAP_PCM_getPowerMode \ + ROM_PCM_getPowerMode +#else +#define MAP_PCM_getPowerMode \ + PCM_getPowerMode +#endif +#ifdef ROM_PCM_setPowerState +#define MAP_PCM_setPowerState \ + ROM_PCM_setPowerState +#else +#define MAP_PCM_setPowerState \ + PCM_setPowerState +#endif +#ifdef ROM_PCM_setPowerStateWithTimeout +#define MAP_PCM_setPowerStateWithTimeout \ + ROM_PCM_setPowerStateWithTimeout +#else +#define MAP_PCM_setPowerStateWithTimeout \ + PCM_setPowerStateWithTimeout +#endif +#ifdef ROM_PCM_getPowerState +#define MAP_PCM_getPowerState \ + ROM_PCM_getPowerState +#else +#define MAP_PCM_getPowerState \ + PCM_getPowerState +#endif +#ifdef ROM_PCM_shutdownDevice +#define MAP_PCM_shutdownDevice \ + ROM_PCM_shutdownDevice +#else +#define MAP_PCM_shutdownDevice \ + PCM_shutdownDevice +#endif +#ifdef ROM_PCM_gotoLPM0 +#define MAP_PCM_gotoLPM0 \ + ROM_PCM_gotoLPM0 +#else +#define MAP_PCM_gotoLPM0 \ + PCM_gotoLPM0 +#endif +#ifdef ROM_PCM_gotoLPM3 +#define MAP_PCM_gotoLPM3 \ + ROM_PCM_gotoLPM3 +#else +#define MAP_PCM_gotoLPM3 \ + PCM_gotoLPM3 +#endif +#ifdef ROM_PCM_enableInterrupt +#define MAP_PCM_enableInterrupt \ + ROM_PCM_enableInterrupt +#else +#define MAP_PCM_enableInterrupt \ + PCM_enableInterrupt +#endif +#ifdef ROM_PCM_disableInterrupt +#define MAP_PCM_disableInterrupt \ + ROM_PCM_disableInterrupt +#else +#define MAP_PCM_disableInterrupt \ + PCM_disableInterrupt +#endif +#ifdef ROM_PCM_getInterruptStatus +#define MAP_PCM_getInterruptStatus \ + ROM_PCM_getInterruptStatus +#else +#define MAP_PCM_getInterruptStatus \ + PCM_getInterruptStatus +#endif +#ifdef ROM_PCM_getEnabledInterruptStatus +#define MAP_PCM_getEnabledInterruptStatus \ + ROM_PCM_getEnabledInterruptStatus +#else +#define MAP_PCM_getEnabledInterruptStatus \ + PCM_getEnabledInterruptStatus +#endif +#ifdef ROM_PCM_clearInterruptFlag +#define MAP_PCM_clearInterruptFlag \ + ROM_PCM_clearInterruptFlag +#else +#define MAP_PCM_clearInterruptFlag \ + PCM_clearInterruptFlag +#endif +#ifdef ROM_PCM_enableRudeMode +#define MAP_PCM_enableRudeMode \ + ROM_PCM_enableRudeMode +#else +#define MAP_PCM_enableRudeMode \ + PCM_enableRudeMode +#endif +#ifdef ROM_PCM_disableRudeMode +#define MAP_PCM_disableRudeMode \ + ROM_PCM_disableRudeMode +#else +#define MAP_PCM_disableRudeMode \ + PCM_disableRudeMode +#endif +#ifdef ROM_PCM_gotoLPM0InterruptSafe +#define MAP_PCM_gotoLPM0InterruptSafe \ + ROM_PCM_gotoLPM0InterruptSafe +#else +#define MAP_PCM_gotoLPM0InterruptSafe \ + PCM_gotoLPM0InterruptSafe +#endif +#ifdef ROM_PCM_gotoLPM3InterruptSafe +#define MAP_PCM_gotoLPM3InterruptSafe \ + ROM_PCM_gotoLPM3InterruptSafe +#else +#define MAP_PCM_gotoLPM3InterruptSafe \ + PCM_gotoLPM3InterruptSafe +#endif +#ifdef ROM_PCM_registerInterrupt +#define MAP_PCM_registerInterrupt \ + ROM_PCM_registerInterrupt +#else +#define MAP_PCM_registerInterrupt \ + PCM_registerInterrupt +#endif +#ifdef ROM_PCM_unregisterInterrupt +#define MAP_PCM_unregisterInterrupt \ + ROM_PCM_unregisterInterrupt +#else +#define MAP_PCM_unregisterInterrupt \ + PCM_unregisterInterrupt +#endif +#ifdef ROM_PCM_setCoreVoltageLevelNonBlocking +#define MAP_PCM_setCoreVoltageLevelNonBlocking \ + ROM_PCM_setCoreVoltageLevelNonBlocking +#else +#define MAP_PCM_setCoreVoltageLevelNonBlocking \ + PCM_setCoreVoltageLevelNonBlocking +#endif +#ifdef ROM_PCM_setPowerModeNonBlocking +#define MAP_PCM_setPowerModeNonBlocking \ + ROM_PCM_setPowerModeNonBlocking +#else +#define MAP_PCM_setPowerModeNonBlocking \ + PCM_setPowerModeNonBlocking +#endif +#ifdef ROM_PCM_setPowerStateNonBlocking +#define MAP_PCM_setPowerStateNonBlocking \ + ROM_PCM_setPowerStateNonBlocking +#else +#define MAP_PCM_setPowerStateNonBlocking \ + PCM_setPowerStateNonBlocking +#endif +#ifdef ROM_PCM_gotoLPM4 +#define MAP_PCM_gotoLPM4 \ + ROM_PCM_gotoLPM4 +#else +#define MAP_PCM_gotoLPM4 \ + PCM_gotoLPM4 +#endif +#ifdef ROM_PCM_gotoLPM4InterruptSafe +#define MAP_PCM_gotoLPM4InterruptSafe \ + ROM_PCM_gotoLPM4InterruptSafe +#else +#define MAP_PCM_gotoLPM4InterruptSafe \ + PCM_gotoLPM4InterruptSafe +#endif + +//***************************************************************************** +// +// Macros for the PMAP API. +// +//***************************************************************************** +#ifdef ROM_PMAP_configurePorts +#define MAP_PMAP_configurePorts \ + ROM_PMAP_configurePorts +#else +#define MAP_PMAP_configurePorts \ + PMAP_configurePorts +#endif + +//***************************************************************************** +// +// Macros for the PSS API. +// +//***************************************************************************** +#ifdef ROM_PSS_enableHighSidePinToggle +#define MAP_PSS_enableHighSidePinToggle \ + ROM_PSS_enableHighSidePinToggle +#else +#define MAP_PSS_enableHighSidePinToggle \ + PSS_enableHighSidePinToggle +#endif +#ifdef ROM_PSS_disableHighSidePinToggle +#define MAP_PSS_disableHighSidePinToggle \ + ROM_PSS_disableHighSidePinToggle +#else +#define MAP_PSS_disableHighSidePinToggle \ + PSS_disableHighSidePinToggle +#endif +#ifdef ROM_PSS_enableHighSide +#define MAP_PSS_enableHighSide \ + ROM_PSS_enableHighSide +#else +#define MAP_PSS_enableHighSide \ + PSS_enableHighSide +#endif +#ifdef ROM_PSS_disableHighSide +#define MAP_PSS_disableHighSide \ + ROM_PSS_disableHighSide +#else +#define MAP_PSS_disableHighSide \ + PSS_disableHighSide +#endif +#ifdef ROM_PSS_enableLowSide +#define MAP_PSS_enableLowSide \ + ROM_PSS_enableLowSide +#else +#define MAP_PSS_enableLowSide \ + PSS_enableLowSide +#endif +#ifdef ROM_PSS_disableLowSide +#define MAP_PSS_disableLowSide \ + ROM_PSS_disableLowSide +#else +#define MAP_PSS_disableLowSide \ + PSS_disableLowSide +#endif +#ifdef ROM_PSS_setHighSidePerformanceMode +#define MAP_PSS_setHighSidePerformanceMode \ + ROM_PSS_setHighSidePerformanceMode +#else +#define MAP_PSS_setHighSidePerformanceMode \ + PSS_setHighSidePerformanceMode +#endif +#ifdef ROM_PSS_getHighSidePerformanceMode +#define MAP_PSS_getHighSidePerformanceMode \ + ROM_PSS_getHighSidePerformanceMode +#else +#define MAP_PSS_getHighSidePerformanceMode \ + PSS_getHighSidePerformanceMode +#endif +#ifdef ROM_PSS_setLowSidePerformanceMode +#define MAP_PSS_setLowSidePerformanceMode \ + ROM_PSS_setLowSidePerformanceMode +#else +#define MAP_PSS_setLowSidePerformanceMode \ + PSS_setLowSidePerformanceMode +#endif +#ifdef ROM_PSS_getLowSidePerformanceMode +#define MAP_PSS_getLowSidePerformanceMode \ + ROM_PSS_getLowSidePerformanceMode +#else +#define MAP_PSS_getLowSidePerformanceMode \ + PSS_getLowSidePerformanceMode +#endif +#ifdef ROM_PSS_enableHighSideMonitor +#define MAP_PSS_enableHighSideMonitor \ + ROM_PSS_enableHighSideMonitor +#else +#define MAP_PSS_enableHighSideMonitor \ + PSS_enableHighSideMonitor +#endif +#ifdef ROM_PSS_disableHighSideMonitor +#define MAP_PSS_disableHighSideMonitor \ + ROM_PSS_disableHighSideMonitor +#else +#define MAP_PSS_disableHighSideMonitor \ + PSS_disableHighSideMonitor +#endif +#ifdef ROM_PSS_setHighSideVoltageTrigger +#define MAP_PSS_setHighSideVoltageTrigger \ + ROM_PSS_setHighSideVoltageTrigger +#else +#define MAP_PSS_setHighSideVoltageTrigger \ + PSS_setHighSideVoltageTrigger +#endif +#ifdef ROM_PSS_getHighSideVoltageTrigger +#define MAP_PSS_getHighSideVoltageTrigger \ + ROM_PSS_getHighSideVoltageTrigger +#else +#define MAP_PSS_getHighSideVoltageTrigger \ + PSS_getHighSideVoltageTrigger +#endif +#ifdef ROM_PSS_enableInterrupt +#define MAP_PSS_enableInterrupt \ + ROM_PSS_enableInterrupt +#else +#define MAP_PSS_enableInterrupt \ + PSS_enableInterrupt +#endif +#ifdef ROM_PSS_disableInterrupt +#define MAP_PSS_disableInterrupt \ + ROM_PSS_disableInterrupt +#else +#define MAP_PSS_disableInterrupt \ + PSS_disableInterrupt +#endif +#ifdef ROM_PSS_getInterruptStatus +#define MAP_PSS_getInterruptStatus \ + ROM_PSS_getInterruptStatus +#else +#define MAP_PSS_getInterruptStatus \ + PSS_getInterruptStatus +#endif +#ifdef ROM_PSS_clearInterruptFlag +#define MAP_PSS_clearInterruptFlag \ + ROM_PSS_clearInterruptFlag +#else +#define MAP_PSS_clearInterruptFlag \ + PSS_clearInterruptFlag +#endif +#ifdef ROM_PSS_registerInterrupt +#define MAP_PSS_registerInterrupt \ + ROM_PSS_registerInterrupt +#else +#define MAP_PSS_registerInterrupt \ + PSS_registerInterrupt +#endif +#ifdef ROM_PSS_unregisterInterrupt +#define MAP_PSS_unregisterInterrupt \ + ROM_PSS_unregisterInterrupt +#else +#define MAP_PSS_unregisterInterrupt \ + PSS_unregisterInterrupt +#endif +#ifdef ROM_PSS_enableForcedDCDCOperation +#define MAP_PSS_enableForcedDCDCOperation \ + ROM_PSS_enableForcedDCDCOperation +#else +#define MAP_PSS_enableForcedDCDCOperation \ + PSS_enableForcedDCDCOperation +#endif +#ifdef ROM_PSS_disableForcedDCDCOperation +#define MAP_PSS_disableForcedDCDCOperation \ + ROM_PSS_disableForcedDCDCOperation +#else +#define MAP_PSS_disableForcedDCDCOperation \ + PSS_disableForcedDCDCOperation +#endif + +//***************************************************************************** +// +// Macros for the Ref API. +// +//***************************************************************************** +#ifdef ROM_REF_A_setReferenceVoltage +#define MAP_REF_A_setReferenceVoltage \ + ROM_REF_A_setReferenceVoltage +#else +#define MAP_REF_A_setReferenceVoltage \ + REF_A_setReferenceVoltage +#endif +#ifdef ROM_REF_A_disableTempSensor +#define MAP_REF_A_disableTempSensor \ + ROM_REF_A_disableTempSensor +#else +#define MAP_REF_A_disableTempSensor \ + REF_A_disableTempSensor +#endif +#ifdef ROM_REF_A_enableTempSensor +#define MAP_REF_A_enableTempSensor \ + ROM_REF_A_enableTempSensor +#else +#define MAP_REF_A_enableTempSensor \ + REF_A_enableTempSensor +#endif +#ifdef ROM_REF_A_enableReferenceVoltageOutput +#define MAP_REF_A_enableReferenceVoltageOutput \ + ROM_REF_A_enableReferenceVoltageOutput +#else +#define MAP_REF_A_enableReferenceVoltageOutput \ + REF_A_enableReferenceVoltageOutput +#endif +#ifdef ROM_REF_A_disableReferenceVoltageOutput +#define MAP_REF_A_disableReferenceVoltageOutput \ + ROM_REF_A_disableReferenceVoltageOutput +#else +#define MAP_REF_A_disableReferenceVoltageOutput \ + REF_A_disableReferenceVoltageOutput +#endif +#ifdef ROM_REF_A_enableReferenceVoltage +#define MAP_REF_A_enableReferenceVoltage \ + ROM_REF_A_enableReferenceVoltage +#else +#define MAP_REF_A_enableReferenceVoltage \ + REF_A_enableReferenceVoltage +#endif +#ifdef ROM_REF_A_disableReferenceVoltage +#define MAP_REF_A_disableReferenceVoltage \ + ROM_REF_A_disableReferenceVoltage +#else +#define MAP_REF_A_disableReferenceVoltage \ + REF_A_disableReferenceVoltage +#endif +#ifdef ROM_REF_A_getBandgapMode +#define MAP_REF_A_getBandgapMode \ + ROM_REF_A_getBandgapMode +#else +#define MAP_REF_A_getBandgapMode \ + REF_A_getBandgapMode +#endif +#ifdef ROM_REF_A_isBandgapActive +#define MAP_REF_A_isBandgapActive \ + ROM_REF_A_isBandgapActive +#else +#define MAP_REF_A_isBandgapActive \ + REF_A_isBandgapActive +#endif +#ifdef ROM_REF_A_isRefGenBusy +#define MAP_REF_A_isRefGenBusy \ + ROM_REF_A_isRefGenBusy +#else +#define MAP_REF_A_isRefGenBusy \ + REF_A_isRefGenBusy +#endif +#ifdef ROM_REF_A_isRefGenActive +#define MAP_REF_A_isRefGenActive \ + ROM_REF_A_isRefGenActive +#else +#define MAP_REF_A_isRefGenActive \ + REF_A_isRefGenActive +#endif +#ifdef ROM_REF_A_getBufferedBandgapVoltageStatus +#define MAP_REF_A_getBufferedBandgapVoltageStatus \ + ROM_REF_A_getBufferedBandgapVoltageStatus +#else +#define MAP_REF_A_getBufferedBandgapVoltageStatus \ + REF_A_getBufferedBandgapVoltageStatus +#endif +#ifdef ROM_REF_A_getVariableReferenceVoltageStatus +#define MAP_REF_A_getVariableReferenceVoltageStatus \ + ROM_REF_A_getVariableReferenceVoltageStatus +#else +#define MAP_REF_A_getVariableReferenceVoltageStatus \ + REF_A_getVariableReferenceVoltageStatus +#endif +#ifdef ROM_REF_A_setReferenceVoltageOneTimeTrigger +#define MAP_REF_A_setReferenceVoltageOneTimeTrigger \ + ROM_REF_A_setReferenceVoltageOneTimeTrigger +#else +#define MAP_REF_A_setReferenceVoltageOneTimeTrigger \ + REF_A_setReferenceVoltageOneTimeTrigger +#endif +#ifdef ROM_REF_A_setBufferedBandgapVoltageOneTimeTrigger +#define MAP_REF_A_setBufferedBandgapVoltageOneTimeTrigger \ + ROM_REF_A_setBufferedBandgapVoltageOneTimeTrigger +#else +#define MAP_REF_A_setBufferedBandgapVoltageOneTimeTrigger \ + REF_A_setBufferedBandgapVoltageOneTimeTrigger +#endif + +//***************************************************************************** +// +// Macros for the ResetCtl API. +// +//***************************************************************************** +#ifdef ROM_ResetCtl_initiateSoftReset +#define MAP_ResetCtl_initiateSoftReset \ + ROM_ResetCtl_initiateSoftReset +#else +#define MAP_ResetCtl_initiateSoftReset \ + ResetCtl_initiateSoftReset +#endif +#ifdef ROM_ResetCtl_initiateSoftResetWithSource +#define MAP_ResetCtl_initiateSoftResetWithSource \ + ROM_ResetCtl_initiateSoftResetWithSource +#else +#define MAP_ResetCtl_initiateSoftResetWithSource \ + ResetCtl_initiateSoftResetWithSource +#endif +#ifdef ROM_ResetCtl_getSoftResetSource +#define MAP_ResetCtl_getSoftResetSource \ + ROM_ResetCtl_getSoftResetSource +#else +#define MAP_ResetCtl_getSoftResetSource \ + ResetCtl_getSoftResetSource +#endif +#ifdef ROM_ResetCtl_clearSoftResetSource +#define MAP_ResetCtl_clearSoftResetSource \ + ROM_ResetCtl_clearSoftResetSource +#else +#define MAP_ResetCtl_clearSoftResetSource \ + ResetCtl_clearSoftResetSource +#endif +#ifdef ROM_ResetCtl_initiateHardReset +#define MAP_ResetCtl_initiateHardReset \ + ROM_ResetCtl_initiateHardReset +#else +#define MAP_ResetCtl_initiateHardReset \ + ResetCtl_initiateHardReset +#endif +#ifdef ROM_ResetCtl_initiateHardResetWithSource +#define MAP_ResetCtl_initiateHardResetWithSource \ + ROM_ResetCtl_initiateHardResetWithSource +#else +#define MAP_ResetCtl_initiateHardResetWithSource \ + ResetCtl_initiateHardResetWithSource +#endif +#ifdef ROM_ResetCtl_getHardResetSource +#define MAP_ResetCtl_getHardResetSource \ + ROM_ResetCtl_getHardResetSource +#else +#define MAP_ResetCtl_getHardResetSource \ + ResetCtl_getHardResetSource +#endif +#ifdef ROM_ResetCtl_clearHardResetSource +#define MAP_ResetCtl_clearHardResetSource \ + ROM_ResetCtl_clearHardResetSource +#else +#define MAP_ResetCtl_clearHardResetSource \ + ResetCtl_clearHardResetSource +#endif +#ifdef ROM_ResetCtl_getPSSSource +#define MAP_ResetCtl_getPSSSource \ + ROM_ResetCtl_getPSSSource +#else +#define MAP_ResetCtl_getPSSSource \ + ResetCtl_getPSSSource +#endif +#ifdef ROM_ResetCtl_clearPSSFlags +#define MAP_ResetCtl_clearPSSFlags \ + ROM_ResetCtl_clearPSSFlags +#else +#define MAP_ResetCtl_clearPSSFlags \ + ResetCtl_clearPSSFlags +#endif +#ifdef ROM_ResetCtl_getPCMSource +#define MAP_ResetCtl_getPCMSource \ + ROM_ResetCtl_getPCMSource +#else +#define MAP_ResetCtl_getPCMSource \ + ResetCtl_getPCMSource +#endif +#ifdef ROM_ResetCtl_clearPCMFlags +#define MAP_ResetCtl_clearPCMFlags \ + ROM_ResetCtl_clearPCMFlags +#else +#define MAP_ResetCtl_clearPCMFlags \ + ResetCtl_clearPCMFlags +#endif + +//***************************************************************************** +// +// Macros for the RTC API. +// +//***************************************************************************** +#ifdef ROM_RTC_C_startClock +#define MAP_RTC_C_startClock \ + ROM_RTC_C_startClock +#else +#define MAP_RTC_C_startClock \ + RTC_C_startClock +#endif +#ifdef ROM_RTC_C_holdClock +#define MAP_RTC_C_holdClock \ + ROM_RTC_C_holdClock +#else +#define MAP_RTC_C_holdClock \ + RTC_C_holdClock +#endif +#ifdef ROM_RTC_C_setCalibrationFrequency +#define MAP_RTC_C_setCalibrationFrequency \ + ROM_RTC_C_setCalibrationFrequency +#else +#define MAP_RTC_C_setCalibrationFrequency \ + RTC_C_setCalibrationFrequency +#endif +#ifdef ROM_RTC_C_setCalibrationData +#define MAP_RTC_C_setCalibrationData \ + ROM_RTC_C_setCalibrationData +#else +#define MAP_RTC_C_setCalibrationData \ + RTC_C_setCalibrationData +#endif +#ifdef ROM_RTC_C_setTemperatureCompensation +#define MAP_RTC_C_setTemperatureCompensation \ + ROM_RTC_C_setTemperatureCompensation +#else +#define MAP_RTC_C_setTemperatureCompensation \ + RTC_C_setTemperatureCompensation +#endif +#ifdef ROM_RTC_C_initCalendar +#define MAP_RTC_C_initCalendar \ + ROM_RTC_C_initCalendar +#else +#define MAP_RTC_C_initCalendar \ + RTC_C_initCalendar +#endif +#ifdef ROM_RTC_C_getCalendarTime +#define MAP_RTC_C_getCalendarTime \ + ROM_RTC_C_getCalendarTime +#else +#define MAP_RTC_C_getCalendarTime \ + RTC_C_getCalendarTime +#endif +#ifdef ROM_RTC_C_setCalendarAlarm +#define MAP_RTC_C_setCalendarAlarm \ + ROM_RTC_C_setCalendarAlarm +#else +#define MAP_RTC_C_setCalendarAlarm \ + RTC_C_setCalendarAlarm +#endif +#ifdef ROM_RTC_C_setCalendarEvent +#define MAP_RTC_C_setCalendarEvent \ + ROM_RTC_C_setCalendarEvent +#else +#define MAP_RTC_C_setCalendarEvent \ + RTC_C_setCalendarEvent +#endif +#ifdef ROM_RTC_C_definePrescaleEvent +#define MAP_RTC_C_definePrescaleEvent \ + ROM_RTC_C_definePrescaleEvent +#else +#define MAP_RTC_C_definePrescaleEvent \ + RTC_C_definePrescaleEvent +#endif +#ifdef ROM_RTC_C_getPrescaleValue +#define MAP_RTC_C_getPrescaleValue \ + ROM_RTC_C_getPrescaleValue +#else +#define MAP_RTC_C_getPrescaleValue \ + RTC_C_getPrescaleValue +#endif +#ifdef ROM_RTC_C_setPrescaleValue +#define MAP_RTC_C_setPrescaleValue \ + ROM_RTC_C_setPrescaleValue +#else +#define MAP_RTC_C_setPrescaleValue \ + RTC_C_setPrescaleValue +#endif +#ifdef ROM_RTC_C_convertBCDToBinary +#define MAP_RTC_C_convertBCDToBinary \ + ROM_RTC_C_convertBCDToBinary +#else +#define MAP_RTC_C_convertBCDToBinary \ + RTC_C_convertBCDToBinary +#endif +#ifdef ROM_RTC_C_convertBinaryToBCD +#define MAP_RTC_C_convertBinaryToBCD \ + ROM_RTC_C_convertBinaryToBCD +#else +#define MAP_RTC_C_convertBinaryToBCD \ + RTC_C_convertBinaryToBCD +#endif +#ifdef ROM_RTC_C_enableInterrupt +#define MAP_RTC_C_enableInterrupt \ + ROM_RTC_C_enableInterrupt +#else +#define MAP_RTC_C_enableInterrupt \ + RTC_C_enableInterrupt +#endif +#ifdef ROM_RTC_C_disableInterrupt +#define MAP_RTC_C_disableInterrupt \ + ROM_RTC_C_disableInterrupt +#else +#define MAP_RTC_C_disableInterrupt \ + RTC_C_disableInterrupt +#endif +#ifdef ROM_RTC_C_getInterruptStatus +#define MAP_RTC_C_getInterruptStatus \ + ROM_RTC_C_getInterruptStatus +#else +#define MAP_RTC_C_getInterruptStatus \ + RTC_C_getInterruptStatus +#endif +#ifdef ROM_RTC_C_getEnabledInterruptStatus +#define MAP_RTC_C_getEnabledInterruptStatus \ + ROM_RTC_C_getEnabledInterruptStatus +#else +#define MAP_RTC_C_getEnabledInterruptStatus \ + RTC_C_getEnabledInterruptStatus +#endif +#ifdef ROM_RTC_C_clearInterruptFlag +#define MAP_RTC_C_clearInterruptFlag \ + ROM_RTC_C_clearInterruptFlag +#else +#define MAP_RTC_C_clearInterruptFlag \ + RTC_C_clearInterruptFlag +#endif +#ifdef ROM_RTC_C_registerInterrupt +#define MAP_RTC_C_registerInterrupt \ + ROM_RTC_C_registerInterrupt +#else +#define MAP_RTC_C_registerInterrupt \ + RTC_C_registerInterrupt +#endif +#ifdef ROM_RTC_C_unregisterInterrupt +#define MAP_RTC_C_unregisterInterrupt \ + ROM_RTC_C_unregisterInterrupt +#else +#define MAP_RTC_C_unregisterInterrupt \ + RTC_C_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the SPI API. +// +//***************************************************************************** +#ifdef ROM_SPI_initMaster +#define MAP_SPI_initMaster \ + ROM_SPI_initMaster +#else +#define MAP_SPI_initMaster \ + SPI_initMaster +#endif +#ifdef ROM_SPI_selectFourPinFunctionality +#define MAP_SPI_selectFourPinFunctionality \ + ROM_SPI_selectFourPinFunctionality +#else +#define MAP_SPI_selectFourPinFunctionality \ + SPI_selectFourPinFunctionality +#endif +#ifdef ROM_SPI_changeMasterClock +#define MAP_SPI_changeMasterClock \ + ROM_SPI_changeMasterClock +#else +#define MAP_SPI_changeMasterClock \ + SPI_changeMasterClock +#endif +#ifdef ROM_SPI_initSlave +#define MAP_SPI_initSlave \ + ROM_SPI_initSlave +#else +#define MAP_SPI_initSlave \ + SPI_initSlave +#endif +#ifdef ROM_SPI_changeClockPhasePolarity +#define MAP_SPI_changeClockPhasePolarity \ + ROM_SPI_changeClockPhasePolarity +#else +#define MAP_SPI_changeClockPhasePolarity \ + SPI_changeClockPhasePolarity +#endif +#ifdef ROM_SPI_transmitData +#define MAP_SPI_transmitData \ + ROM_SPI_transmitData +#else +#define MAP_SPI_transmitData \ + SPI_transmitData +#endif +#ifdef ROM_SPI_receiveData +#define MAP_SPI_receiveData \ + ROM_SPI_receiveData +#else +#define MAP_SPI_receiveData \ + SPI_receiveData +#endif +#ifdef ROM_SPI_enableModule +#define MAP_SPI_enableModule \ + ROM_SPI_enableModule +#else +#define MAP_SPI_enableModule \ + SPI_enableModule +#endif +#ifdef ROM_SPI_disableModule +#define MAP_SPI_disableModule \ + ROM_SPI_disableModule +#else +#define MAP_SPI_disableModule \ + SPI_disableModule +#endif +#ifdef ROM_SPI_getReceiveBufferAddressForDMA +#define MAP_SPI_getReceiveBufferAddressForDMA \ + ROM_SPI_getReceiveBufferAddressForDMA +#else +#define MAP_SPI_getReceiveBufferAddressForDMA \ + SPI_getReceiveBufferAddressForDMA +#endif +#ifdef ROM_SPI_getTransmitBufferAddressForDMA +#define MAP_SPI_getTransmitBufferAddressForDMA \ + ROM_SPI_getTransmitBufferAddressForDMA +#else +#define MAP_SPI_getTransmitBufferAddressForDMA \ + SPI_getTransmitBufferAddressForDMA +#endif +#ifdef ROM_SPI_isBusy +#define MAP_SPI_isBusy \ + ROM_SPI_isBusy +#else +#define MAP_SPI_isBusy \ + SPI_isBusy +#endif +#ifdef ROM_SPI_enableInterrupt +#define MAP_SPI_enableInterrupt \ + ROM_SPI_enableInterrupt +#else +#define MAP_SPI_enableInterrupt \ + SPI_enableInterrupt +#endif +#ifdef ROM_SPI_disableInterrupt +#define MAP_SPI_disableInterrupt \ + ROM_SPI_disableInterrupt +#else +#define MAP_SPI_disableInterrupt \ + SPI_disableInterrupt +#endif +#ifdef ROM_SPI_getInterruptStatus +#define MAP_SPI_getInterruptStatus \ + ROM_SPI_getInterruptStatus +#else +#define MAP_SPI_getInterruptStatus \ + SPI_getInterruptStatus +#endif +#ifdef ROM_SPI_getEnabledInterruptStatus +#define MAP_SPI_getEnabledInterruptStatus \ + ROM_SPI_getEnabledInterruptStatus +#else +#define MAP_SPI_getEnabledInterruptStatus \ + SPI_getEnabledInterruptStatus +#endif +#ifdef ROM_SPI_clearInterruptFlag +#define MAP_SPI_clearInterruptFlag \ + ROM_SPI_clearInterruptFlag +#else +#define MAP_SPI_clearInterruptFlag \ + SPI_clearInterruptFlag +#endif +#ifdef ROM_SPI_registerInterrupt +#define MAP_SPI_registerInterrupt \ + ROM_SPI_registerInterrupt +#else +#define MAP_SPI_registerInterrupt \ + SPI_registerInterrupt +#endif +#ifdef ROM_SPI_unregisterInterrupt +#define MAP_SPI_unregisterInterrupt \ + ROM_SPI_unregisterInterrupt +#else +#define MAP_SPI_unregisterInterrupt \ + SPI_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the SysCtl API. +// +//***************************************************************************** +#ifdef ROM_SysCtl_getSRAMSize +#define MAP_SysCtl_getSRAMSize \ + ROM_SysCtl_getSRAMSize +#else +#define MAP_SysCtl_getSRAMSize \ + SysCtl_getSRAMSize +#endif +#ifdef ROM_SysCtl_getFlashSize +#define MAP_SysCtl_getFlashSize \ + ROM_SysCtl_getFlashSize +#else +#define MAP_SysCtl_getFlashSize \ + SysCtl_getFlashSize +#endif +#ifdef ROM_SysCtl_rebootDevice +#define MAP_SysCtl_rebootDevice \ + ROM_SysCtl_rebootDevice +#else +#define MAP_SysCtl_rebootDevice \ + SysCtl_rebootDevice +#endif +#ifdef ROM_SysCtl_enableSRAMBank +#define MAP_SysCtl_enableSRAMBank \ + ROM_SysCtl_enableSRAMBank +#else +#define MAP_SysCtl_enableSRAMBank \ + SysCtl_enableSRAMBank +#endif +#ifdef ROM_SysCtl_disableSRAMBank +#define MAP_SysCtl_disableSRAMBank \ + ROM_SysCtl_disableSRAMBank +#else +#define MAP_SysCtl_disableSRAMBank \ + SysCtl_disableSRAMBank +#endif +#ifdef ROM_SysCtl_enableSRAMBankRetention +#define MAP_SysCtl_enableSRAMBankRetention \ + ROM_SysCtl_enableSRAMBankRetention +#else +#define MAP_SysCtl_enableSRAMBankRetention \ + SysCtl_enableSRAMBankRetention +#endif +#ifdef ROM_SysCtl_disableSRAMBankRetention +#define MAP_SysCtl_disableSRAMBankRetention \ + ROM_SysCtl_disableSRAMBankRetention +#else +#define MAP_SysCtl_disableSRAMBankRetention \ + SysCtl_disableSRAMBankRetention +#endif +#ifdef ROM_SysCtl_enablePeripheralAtCPUHalt +#define MAP_SysCtl_enablePeripheralAtCPUHalt \ + ROM_SysCtl_enablePeripheralAtCPUHalt +#else +#define MAP_SysCtl_enablePeripheralAtCPUHalt \ + SysCtl_enablePeripheralAtCPUHalt +#endif +#ifdef ROM_SysCtl_disablePeripheralAtCPUHalt +#define MAP_SysCtl_disablePeripheralAtCPUHalt \ + ROM_SysCtl_disablePeripheralAtCPUHalt +#else +#define MAP_SysCtl_disablePeripheralAtCPUHalt \ + SysCtl_disablePeripheralAtCPUHalt +#endif +#ifdef ROM_SysCtl_setWDTTimeoutResetType +#define MAP_SysCtl_setWDTTimeoutResetType \ + ROM_SysCtl_setWDTTimeoutResetType +#else +#define MAP_SysCtl_setWDTTimeoutResetType \ + SysCtl_setWDTTimeoutResetType +#endif +#ifdef ROM_SysCtl_setWDTPasswordViolationResetType +#define MAP_SysCtl_setWDTPasswordViolationResetType \ + ROM_SysCtl_setWDTPasswordViolationResetType +#else +#define MAP_SysCtl_setWDTPasswordViolationResetType \ + SysCtl_setWDTPasswordViolationResetType +#endif +#ifdef ROM_SysCtl_disableNMISource +#define MAP_SysCtl_disableNMISource \ + ROM_SysCtl_disableNMISource +#else +#define MAP_SysCtl_disableNMISource \ + SysCtl_disableNMISource +#endif +#ifdef ROM_SysCtl_enableNMISource +#define MAP_SysCtl_enableNMISource \ + ROM_SysCtl_enableNMISource +#else +#define MAP_SysCtl_enableNMISource \ + SysCtl_enableNMISource +#endif +#ifdef ROM_SysCtl_getNMISourceStatus +#define MAP_SysCtl_getNMISourceStatus \ + ROM_SysCtl_getNMISourceStatus +#else +#define MAP_SysCtl_getNMISourceStatus \ + SysCtl_getNMISourceStatus +#endif +#ifdef ROM_SysCtl_getTempCalibrationConstant +#define MAP_SysCtl_getTempCalibrationConstant \ + ROM_SysCtl_getTempCalibrationConstant +#else +#define MAP_SysCtl_getTempCalibrationConstant \ + SysCtl_getTempCalibrationConstant +#endif +#ifdef ROM_SysCtl_enableGlitchFilter +#define MAP_SysCtl_enableGlitchFilter \ + ROM_SysCtl_enableGlitchFilter +#else +#define MAP_SysCtl_enableGlitchFilter \ + SysCtl_enableGlitchFilter +#endif +#ifdef ROM_SysCtl_disableGlitchFilter +#define MAP_SysCtl_disableGlitchFilter \ + ROM_SysCtl_disableGlitchFilter +#else +#define MAP_SysCtl_disableGlitchFilter \ + SysCtl_disableGlitchFilter +#endif +#ifdef ROM_SysCtl_getTLVInfo +#define MAP_SysCtl_getTLVInfo \ + ROM_SysCtl_getTLVInfo +#else +#define MAP_SysCtl_getTLVInfo \ + SysCtl_getTLVInfo +#endif + +//***************************************************************************** +// +// Macros for the SysTick API. +// +//***************************************************************************** +#ifdef ROM_SysTick_enableModule +#define MAP_SysTick_enableModule \ + ROM_SysTick_enableModule +#else +#define MAP_SysTick_enableModule \ + SysTick_enableModule +#endif +#ifdef ROM_SysTick_disableModule +#define MAP_SysTick_disableModule \ + ROM_SysTick_disableModule +#else +#define MAP_SysTick_disableModule \ + SysTick_disableModule +#endif +#ifdef ROM_SysTick_enableInterrupt +#define MAP_SysTick_enableInterrupt \ + ROM_SysTick_enableInterrupt +#else +#define MAP_SysTick_enableInterrupt \ + SysTick_enableInterrupt +#endif +#ifdef ROM_SysTick_disableInterrupt +#define MAP_SysTick_disableInterrupt \ + ROM_SysTick_disableInterrupt +#else +#define MAP_SysTick_disableInterrupt \ + SysTick_disableInterrupt +#endif +#ifdef ROM_SysTick_setPeriod +#define MAP_SysTick_setPeriod \ + ROM_SysTick_setPeriod +#else +#define MAP_SysTick_setPeriod \ + SysTick_setPeriod +#endif +#ifdef ROM_SysTick_getPeriod +#define MAP_SysTick_getPeriod \ + ROM_SysTick_getPeriod +#else +#define MAP_SysTick_getPeriod \ + SysTick_getPeriod +#endif +#ifdef ROM_SysTick_getValue +#define MAP_SysTick_getValue \ + ROM_SysTick_getValue +#else +#define MAP_SysTick_getValue \ + SysTick_getValue +#endif +#ifdef ROM_SysTick_registerInterrupt +#define MAP_SysTick_registerInterrupt \ + ROM_SysTick_registerInterrupt +#else +#define MAP_SysTick_registerInterrupt \ + SysTick_registerInterrupt +#endif +#ifdef ROM_SysTick_unregisterInterrupt +#define MAP_SysTick_unregisterInterrupt \ + ROM_SysTick_unregisterInterrupt +#else +#define MAP_SysTick_unregisterInterrupt \ + SysTick_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the Timer_A API. +// +//***************************************************************************** +#ifdef ROM_Timer_A_startCounter +#define MAP_Timer_A_startCounter \ + ROM_Timer_A_startCounter +#else +#define MAP_Timer_A_startCounter \ + Timer_A_startCounter +#endif +#ifdef ROM_Timer_A_configureContinuousMode +#define MAP_Timer_A_configureContinuousMode \ + ROM_Timer_A_configureContinuousMode +#else +#define MAP_Timer_A_configureContinuousMode \ + Timer_A_configureContinuousMode +#endif +#ifdef ROM_Timer_A_configureUpMode +#define MAP_Timer_A_configureUpMode \ + ROM_Timer_A_configureUpMode +#else +#define MAP_Timer_A_configureUpMode \ + Timer_A_configureUpMode +#endif +#ifdef ROM_Timer_A_configureUpDownMode +#define MAP_Timer_A_configureUpDownMode \ + ROM_Timer_A_configureUpDownMode +#else +#define MAP_Timer_A_configureUpDownMode \ + Timer_A_configureUpDownMode +#endif +#ifdef ROM_Timer_A_initCapture +#define MAP_Timer_A_initCapture \ + ROM_Timer_A_initCapture +#else +#define MAP_Timer_A_initCapture \ + Timer_A_initCapture +#endif +#ifdef ROM_Timer_A_initCompare +#define MAP_Timer_A_initCompare \ + ROM_Timer_A_initCompare +#else +#define MAP_Timer_A_initCompare \ + Timer_A_initCompare +#endif +#ifdef ROM_Timer_A_clearTimer +#define MAP_Timer_A_clearTimer \ + ROM_Timer_A_clearTimer +#else +#define MAP_Timer_A_clearTimer \ + Timer_A_clearTimer +#endif +#ifdef ROM_Timer_A_getSynchronizedCaptureCompareInput +#define MAP_Timer_A_getSynchronizedCaptureCompareInput \ + ROM_Timer_A_getSynchronizedCaptureCompareInput +#else +#define MAP_Timer_A_getSynchronizedCaptureCompareInput \ + Timer_A_getSynchronizedCaptureCompareInput +#endif +#ifdef ROM_Timer_A_getOutputForOutputModeOutBitValue +#define MAP_Timer_A_getOutputForOutputModeOutBitValue \ + ROM_Timer_A_getOutputForOutputModeOutBitValue +#else +#define MAP_Timer_A_getOutputForOutputModeOutBitValue \ + Timer_A_getOutputForOutputModeOutBitValue +#endif +#ifdef ROM_Timer_A_getCaptureCompareCount +#define MAP_Timer_A_getCaptureCompareCount \ + ROM_Timer_A_getCaptureCompareCount +#else +#define MAP_Timer_A_getCaptureCompareCount \ + Timer_A_getCaptureCompareCount +#endif +#ifdef ROM_Timer_A_setOutputForOutputModeOutBitValue +#define MAP_Timer_A_setOutputForOutputModeOutBitValue \ + ROM_Timer_A_setOutputForOutputModeOutBitValue +#else +#define MAP_Timer_A_setOutputForOutputModeOutBitValue \ + Timer_A_setOutputForOutputModeOutBitValue +#endif +#ifdef ROM_Timer_A_generatePWM +#define MAP_Timer_A_generatePWM \ + ROM_Timer_A_generatePWM +#else +#define MAP_Timer_A_generatePWM \ + Timer_A_generatePWM +#endif +#ifdef ROM_Timer_A_stopTimer +#define MAP_Timer_A_stopTimer \ + ROM_Timer_A_stopTimer +#else +#define MAP_Timer_A_stopTimer \ + Timer_A_stopTimer +#endif +#ifdef ROM_Timer_A_setCompareValue +#define MAP_Timer_A_setCompareValue \ + ROM_Timer_A_setCompareValue +#else +#define MAP_Timer_A_setCompareValue \ + Timer_A_setCompareValue +#endif +#ifdef ROM_Timer_A_clearInterruptFlag +#define MAP_Timer_A_clearInterruptFlag \ + ROM_Timer_A_clearInterruptFlag +#else +#define MAP_Timer_A_clearInterruptFlag \ + Timer_A_clearInterruptFlag +#endif +#ifdef ROM_Timer_A_clearCaptureCompareInterrupt +#define MAP_Timer_A_clearCaptureCompareInterrupt \ + ROM_Timer_A_clearCaptureCompareInterrupt +#else +#define MAP_Timer_A_clearCaptureCompareInterrupt \ + Timer_A_clearCaptureCompareInterrupt +#endif +#ifdef ROM_Timer_A_enableInterrupt +#define MAP_Timer_A_enableInterrupt \ + ROM_Timer_A_enableInterrupt +#else +#define MAP_Timer_A_enableInterrupt \ + Timer_A_enableInterrupt +#endif +#ifdef ROM_Timer_A_disableInterrupt +#define MAP_Timer_A_disableInterrupt \ + ROM_Timer_A_disableInterrupt +#else +#define MAP_Timer_A_disableInterrupt \ + Timer_A_disableInterrupt +#endif +#ifdef ROM_Timer_A_getInterruptStatus +#define MAP_Timer_A_getInterruptStatus \ + ROM_Timer_A_getInterruptStatus +#else +#define MAP_Timer_A_getInterruptStatus \ + Timer_A_getInterruptStatus +#endif +#ifdef ROM_Timer_A_getEnabledInterruptStatus +#define MAP_Timer_A_getEnabledInterruptStatus \ + ROM_Timer_A_getEnabledInterruptStatus +#else +#define MAP_Timer_A_getEnabledInterruptStatus \ + Timer_A_getEnabledInterruptStatus +#endif +#ifdef ROM_Timer_A_enableCaptureCompareInterrupt +#define MAP_Timer_A_enableCaptureCompareInterrupt \ + ROM_Timer_A_enableCaptureCompareInterrupt +#else +#define MAP_Timer_A_enableCaptureCompareInterrupt \ + Timer_A_enableCaptureCompareInterrupt +#endif +#ifdef ROM_Timer_A_disableCaptureCompareInterrupt +#define MAP_Timer_A_disableCaptureCompareInterrupt \ + ROM_Timer_A_disableCaptureCompareInterrupt +#else +#define MAP_Timer_A_disableCaptureCompareInterrupt \ + Timer_A_disableCaptureCompareInterrupt +#endif +#ifdef ROM_Timer_A_getCaptureCompareInterruptStatus +#define MAP_Timer_A_getCaptureCompareInterruptStatus \ + ROM_Timer_A_getCaptureCompareInterruptStatus +#else +#define MAP_Timer_A_getCaptureCompareInterruptStatus \ + Timer_A_getCaptureCompareInterruptStatus +#endif +#ifdef ROM_Timer_A_getCaptureCompareEnabledInterruptStatus +#define MAP_Timer_A_getCaptureCompareEnabledInterruptStatus \ + ROM_Timer_A_getCaptureCompareEnabledInterruptStatus +#else +#define MAP_Timer_A_getCaptureCompareEnabledInterruptStatus \ + Timer_A_getCaptureCompareEnabledInterruptStatus +#endif +#ifdef ROM_Timer_A_registerInterrupt +#define MAP_Timer_A_registerInterrupt \ + ROM_Timer_A_registerInterrupt +#else +#define MAP_Timer_A_registerInterrupt \ + Timer_A_registerInterrupt +#endif +#ifdef ROM_Timer_A_unregisterInterrupt +#define MAP_Timer_A_unregisterInterrupt \ + ROM_Timer_A_unregisterInterrupt +#else +#define MAP_Timer_A_unregisterInterrupt \ + Timer_A_unregisterInterrupt +#endif +#ifdef ROM_Timer_A_getCounterValue +#define MAP_Timer_A_getCounterValue \ + ROM_Timer_A_getCounterValue +#else +#define MAP_Timer_A_getCounterValue \ + Timer_A_getCounterValue +#endif + +//***************************************************************************** +// +// Macros for the Timer32 API. +// +//***************************************************************************** +#ifdef ROM_Timer32_initModule +#define MAP_Timer32_initModule \ + ROM_Timer32_initModule +#else +#define MAP_Timer32_initModule \ + Timer32_initModule +#endif +#ifdef ROM_Timer32_setCount +#define MAP_Timer32_setCount \ + ROM_Timer32_setCount +#else +#define MAP_Timer32_setCount \ + Timer32_setCount +#endif +#ifdef ROM_Timer32_setCountInBackground +#define MAP_Timer32_setCountInBackground \ + ROM_Timer32_setCountInBackground +#else +#define MAP_Timer32_setCountInBackground \ + Timer32_setCountInBackground +#endif +#ifdef ROM_Timer32_getValue +#define MAP_Timer32_getValue \ + ROM_Timer32_getValue +#else +#define MAP_Timer32_getValue \ + Timer32_getValue +#endif +#ifdef ROM_Timer32_startTimer +#define MAP_Timer32_startTimer \ + ROM_Timer32_startTimer +#else +#define MAP_Timer32_startTimer \ + Timer32_startTimer +#endif +#ifdef ROM_Timer32_haltTimer +#define MAP_Timer32_haltTimer \ + ROM_Timer32_haltTimer +#else +#define MAP_Timer32_haltTimer \ + Timer32_haltTimer +#endif +#ifdef ROM_Timer32_enableInterrupt +#define MAP_Timer32_enableInterrupt \ + ROM_Timer32_enableInterrupt +#else +#define MAP_Timer32_enableInterrupt \ + Timer32_enableInterrupt +#endif +#ifdef ROM_Timer32_disableInterrupt +#define MAP_Timer32_disableInterrupt \ + ROM_Timer32_disableInterrupt +#else +#define MAP_Timer32_disableInterrupt \ + Timer32_disableInterrupt +#endif +#ifdef ROM_Timer32_clearInterruptFlag +#define MAP_Timer32_clearInterruptFlag \ + ROM_Timer32_clearInterruptFlag +#else +#define MAP_Timer32_clearInterruptFlag \ + Timer32_clearInterruptFlag +#endif +#ifdef ROM_Timer32_getInterruptStatus +#define MAP_Timer32_getInterruptStatus \ + ROM_Timer32_getInterruptStatus +#else +#define MAP_Timer32_getInterruptStatus \ + Timer32_getInterruptStatus +#endif +#ifdef ROM_Timer32_registerInterrupt +#define MAP_Timer32_registerInterrupt \ + ROM_Timer32_registerInterrupt +#else +#define MAP_Timer32_registerInterrupt \ + Timer32_registerInterrupt +#endif +#ifdef ROM_Timer32_unregisterInterrupt +#define MAP_Timer32_unregisterInterrupt \ + ROM_Timer32_unregisterInterrupt +#else +#define MAP_Timer32_unregisterInterrupt \ + Timer32_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the UART API. +// +//***************************************************************************** +#ifdef ROM_UART_initModule +#define MAP_UART_initModule \ + ROM_UART_initModule +#else +#define MAP_UART_initModule \ + UART_initModule +#endif +#ifdef ROM_UART_transmitData +#define MAP_UART_transmitData \ + ROM_UART_transmitData +#else +#define MAP_UART_transmitData \ + UART_transmitData +#endif +#ifdef ROM_UART_enableModule +#define MAP_UART_enableModule \ + ROM_UART_enableModule +#else +#define MAP_UART_enableModule \ + UART_enableModule +#endif +#ifdef ROM_UART_disableModule +#define MAP_UART_disableModule \ + ROM_UART_disableModule +#else +#define MAP_UART_disableModule \ + UART_disableModule +#endif +#ifdef ROM_UART_queryStatusFlags +#define MAP_UART_queryStatusFlags \ + ROM_UART_queryStatusFlags +#else +#define MAP_UART_queryStatusFlags \ + UART_queryStatusFlags +#endif +#ifdef ROM_UART_setDormant +#define MAP_UART_setDormant \ + ROM_UART_setDormant +#else +#define MAP_UART_setDormant \ + UART_setDormant +#endif +#ifdef ROM_UART_resetDormant +#define MAP_UART_resetDormant \ + ROM_UART_resetDormant +#else +#define MAP_UART_resetDormant \ + UART_resetDormant +#endif +#ifdef ROM_UART_transmitAddress +#define MAP_UART_transmitAddress \ + ROM_UART_transmitAddress +#else +#define MAP_UART_transmitAddress \ + UART_transmitAddress +#endif +#ifdef ROM_UART_transmitBreak +#define MAP_UART_transmitBreak \ + ROM_UART_transmitBreak +#else +#define MAP_UART_transmitBreak \ + UART_transmitBreak +#endif +#ifdef ROM_UART_getReceiveBufferAddressForDMA +#define MAP_UART_getReceiveBufferAddressForDMA \ + ROM_UART_getReceiveBufferAddressForDMA +#else +#define MAP_UART_getReceiveBufferAddressForDMA \ + UART_getReceiveBufferAddressForDMA +#endif +#ifdef ROM_UART_getTransmitBufferAddressForDMA +#define MAP_UART_getTransmitBufferAddressForDMA \ + ROM_UART_getTransmitBufferAddressForDMA +#else +#define MAP_UART_getTransmitBufferAddressForDMA \ + UART_getTransmitBufferAddressForDMA +#endif +#ifdef ROM_UART_selectDeglitchTime +#define MAP_UART_selectDeglitchTime \ + ROM_UART_selectDeglitchTime +#else +#define MAP_UART_selectDeglitchTime \ + UART_selectDeglitchTime +#endif +#ifdef ROM_UART_enableInterrupt +#define MAP_UART_enableInterrupt \ + ROM_UART_enableInterrupt +#else +#define MAP_UART_enableInterrupt \ + UART_enableInterrupt +#endif +#ifdef ROM_UART_disableInterrupt +#define MAP_UART_disableInterrupt \ + ROM_UART_disableInterrupt +#else +#define MAP_UART_disableInterrupt \ + UART_disableInterrupt +#endif +#ifdef ROM_UART_getInterruptStatus +#define MAP_UART_getInterruptStatus \ + ROM_UART_getInterruptStatus +#else +#define MAP_UART_getInterruptStatus \ + UART_getInterruptStatus +#endif +#ifdef ROM_UART_clearInterruptFlag +#define MAP_UART_clearInterruptFlag \ + ROM_UART_clearInterruptFlag +#else +#define MAP_UART_clearInterruptFlag \ + UART_clearInterruptFlag +#endif +#ifdef ROM_UART_receiveData +#define MAP_UART_receiveData \ + ROM_UART_receiveData +#else +#define MAP_UART_receiveData \ + UART_receiveData +#endif +#ifdef ROM_UART_getEnabledInterruptStatus +#define MAP_UART_getEnabledInterruptStatus \ + ROM_UART_getEnabledInterruptStatus +#else +#define MAP_UART_getEnabledInterruptStatus \ + UART_getEnabledInterruptStatus +#endif +#ifdef ROM_UART_registerInterrupt +#define MAP_UART_registerInterrupt \ + ROM_UART_registerInterrupt +#else +#define MAP_UART_registerInterrupt \ + UART_registerInterrupt +#endif +#ifdef ROM_UART_unregisterInterrupt +#define MAP_UART_unregisterInterrupt \ + ROM_UART_unregisterInterrupt +#else +#define MAP_UART_unregisterInterrupt \ + UART_unregisterInterrupt +#endif + +//***************************************************************************** +// +// Macros for the WDT API. +// +//***************************************************************************** +#ifdef ROM_WDT_A_holdTimer +#define MAP_WDT_A_holdTimer \ + ROM_WDT_A_holdTimer +#else +#define MAP_WDT_A_holdTimer \ + WDT_A_holdTimer +#endif +#ifdef ROM_WDT_A_startTimer +#define MAP_WDT_A_startTimer \ + ROM_WDT_A_startTimer +#else +#define MAP_WDT_A_startTimer \ + WDT_A_startTimer +#endif +#ifdef ROM_WDT_A_clearTimer +#define MAP_WDT_A_clearTimer \ + ROM_WDT_A_clearTimer +#else +#define MAP_WDT_A_clearTimer \ + WDT_A_clearTimer +#endif +#ifdef ROM_WDT_A_initWatchdogTimer +#define MAP_WDT_A_initWatchdogTimer \ + ROM_WDT_A_initWatchdogTimer +#else +#define MAP_WDT_A_initWatchdogTimer \ + WDT_A_initWatchdogTimer +#endif +#ifdef ROM_WDT_A_initIntervalTimer +#define MAP_WDT_A_initIntervalTimer \ + ROM_WDT_A_initIntervalTimer +#else +#define MAP_WDT_A_initIntervalTimer \ + WDT_A_initIntervalTimer +#endif +#ifdef ROM_WDT_A_registerInterrupt +#define MAP_WDT_A_registerInterrupt \ + ROM_WDT_A_registerInterrupt +#else +#define MAP_WDT_A_registerInterrupt \ + WDT_A_registerInterrupt +#endif +#ifdef ROM_WDT_A_unregisterInterrupt +#define MAP_WDT_A_unregisterInterrupt \ + ROM_WDT_A_unregisterInterrupt +#else +#define MAP_WDT_A_unregisterInterrupt \ + WDT_A_unregisterInterrupt +#endif +#ifdef ROM_WDT_A_setPasswordViolationReset +#define MAP_WDT_A_setPasswordViolationReset \ + ROM_WDT_A_setPasswordViolationReset +#else +#define MAP_WDT_A_setPasswordViolationReset \ + WDT_A_setPasswordViolationReset +#endif +#ifdef ROM_WDT_A_setTimeoutReset +#define MAP_WDT_A_setTimeoutReset \ + ROM_WDT_A_setTimeoutReset +#else +#define MAP_WDT_A_setTimeoutReset \ + WDT_A_setTimeoutReset +#endif + +#endif // __ROM_MAP_H__ diff --git a/example/rt_msp432/MSP432P4xx/rtc_c.c b/example/rt_msp432/MSP432P4xx/rtc_c.c new file mode 100644 index 0000000..29ca087 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/rtc_c.c @@ -0,0 +1,338 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include +#include + +void RTC_C_startClock(void) +{ + RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY; + BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_HOLD_OFS) = 0; + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; +} + +void RTC_C_holdClock(void) +{ + RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY; + BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_HOLD_OFS) = 1; + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; +} + +void RTC_C_setCalibrationFrequency(uint_fast16_t frequencySelect) +{ + RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY; + RTC_C->CTL13 = (RTC_C->CTL13 & ~(RTC_C_CTL13_CALF_3)) | frequencySelect; + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; +} + +void RTC_C_setCalibrationData(uint_fast8_t offsetDirection, + uint_fast8_t offsetValue) +{ + RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY; + RTC_C->OCAL = offsetValue + offsetDirection; + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; +} + +bool RTC_C_setTemperatureCompensation(uint_fast16_t offsetDirection, + uint_fast8_t offsetValue) +{ + while (!BITBAND_PERI(RTC_C->TCMP, RTC_C_TCMP_TCRDY_OFS)) + ; + + RTC_C->TCMP = offsetValue + offsetDirection; + + if (BITBAND_PERI(RTC_C->TCMP, RTC_C_TCMP_TCOK_OFS)) + return true; + else + return false; +} + +void RTC_C_initCalendar(const RTC_C_Calendar *calendarTime, + uint_fast16_t formatSelect) +{ + RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY; + + BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_HOLD_OFS) = 1; + + if (formatSelect) + BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_BCD_OFS) = 1; + else + BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_BCD_OFS) = 0; + + RTC_C->TIM0 = (calendarTime->minutes<seconds; + RTC_C->TIM1 = (calendarTime->dayOfWeek<hours; + RTC_C->DATE = (calendarTime->month<dayOfmonth; + RTC_C->YEAR = calendarTime->year; + + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; +} + +RTC_C_Calendar RTC_C_getCalendarTime(void) +{ + RTC_C_Calendar tempCal; + + while (!(BITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_RDY_OFS))) + ; + + tempCal.seconds = RTC_C->TIM0 & RTC_C_TIM0_SEC_MASK; + tempCal.minutes = (RTC_C->TIM0 & RTC_C_TIM0_MIN_MASK)>>RTC_C_TIM0_MIN_OFS; + tempCal.hours = RTC_C->TIM1 & RTC_C_TIM1_HOUR_MASK; + tempCal.dayOfWeek = (RTC_C->TIM1 & RTC_C_TIM1_DOW_MASK)>>RTC_C_TIM1_DOW_OFS; + tempCal.dayOfmonth = RTC_C->DATE & RTC_C_DATE_DAY_MASK; + tempCal.month = (RTC_C->DATE & RTC_C_DATE_MON_MASK)>>RTC_C_DATE_MON_OFS; + tempCal.year = RTC_C->YEAR; + + return (tempCal); +} + +void RTC_C_setCalendarAlarm(uint_fast8_t minutesAlarm, uint_fast8_t hoursAlarm, + uint_fast8_t dayOfWeekAlarm, uint_fast8_t dayOfmonthAlarm) +{ + //Each of these is XORed with 0x80 to turn on if an integer is passed, + //or turn OFF if RTC_ALARM_OFF (0x80) is passed. + RTC_C->AMINHR = ((hoursAlarm ^ 0x80) << 8 )| (minutesAlarm ^ 0x80); + RTC_C->ADOWDAY = ((dayOfmonthAlarm ^ 0x80) << 8 )| (dayOfWeekAlarm ^ 0x80); +} + +void RTC_C_setCalendarEvent(uint_fast16_t eventSelect) +{ + RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY; + RTC_C->CTL13 = (RTC_C->CTL13 & ~(RTC_C_CTL13_TEV_3)) | eventSelect; + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; +} + +void RTC_C_definePrescaleEvent(uint_fast8_t prescaleSelect, + uint_fast8_t prescaleEventDivider) +{ + HWREG8(&RTC_C->PS0CTL + prescaleSelect) &= ~(RTC_C_PS0CTL_RT0IP_7); + HWREG8(&RTC_C->PS0CTL + prescaleSelect) |= + prescaleEventDivider; +} + +uint_fast8_t RTC_C_getPrescaleValue(uint_fast8_t prescaleSelect) +{ + if (RTC_C_PRESCALE_0 == prescaleSelect) + { + return (RTC_C->PS & RTC_C_PS_RT0PS_MASK); + } else if (RTC_C_PRESCALE_1 == prescaleSelect) + { + return (RTC_C->PS & RTC_C_PS_RT1PS_MASK)>>RTC_C_PS_RT1PS_OFS; + } else + { + return (0); + } +} + +void RTC_C_setPrescaleValue(uint_fast8_t prescaleSelect, + uint_fast8_t prescaleCounterValue) +{ + RTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY; + + if (RTC_C_PRESCALE_0 == prescaleSelect) + { + RTC_C->PS = (RTC_C->PS & ~RTC_C_PS_RT0PS_MASK) | prescaleCounterValue; + } else if (RTC_C_PRESCALE_1 == prescaleSelect) + { + RTC_C->PS = (RTC_C->PS & ~RTC_C_PS_RT1PS_MASK) + | (prescaleCounterValue << RTC_C_PS_RT1PS_OFS); + } + + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; +} + +uint16_t RTC_C_convertBCDToBinary(uint16_t valueToConvert) +{ + RTC_C->BCD2BIN = valueToConvert; + return (RTC_C->BCD2BIN); +} + +uint16_t RTC_C_convertBinaryToBCD(uint16_t valueToConvert) +{ + RTC_C->BIN2BCD = valueToConvert; + return (RTC_C->BIN2BCD); +} + +void RTC_C_enableInterrupt(uint8_t interruptMask) +{ + if (interruptMask & (RTC_C_CTL0_OFIE + RTC_C_CTL0_TEVIE + RTC_C_CTL0_AIE + + RTC_C_CTL0_RDYIE)) + { + RTC_C->CTL0 = RTC_C_KEY | (interruptMask + & (RTC_C_CTL0_OFIE + RTC_C_CTL0_TEVIE + RTC_C_CTL0_AIE + + RTC_C_CTL0_RDYIE)); + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; + } + + if (interruptMask & RTC_C_PRESCALE_TIMER0_INTERRUPT) + { + BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIE_OFS) = 1; + } + + if (interruptMask & RTC_C_PRESCALE_TIMER1_INTERRUPT) + { + BITBAND_PERI(RTC_C->PS1CTL,RTC_C_PS1CTL_RT1PSIE_OFS) = 1; + } +} + +void RTC_C_disableInterrupt(uint8_t interruptMask) +{ + if (interruptMask & (RTC_C_CTL0_OFIE + RTC_C_CTL0_TEVIE + RTC_C_CTL0_AIE + + RTC_C_CTL0_RDYIE)) + { + RTC_C->CTL0 = RTC_C_KEY + | (RTC_C->CTL0 & ~((interruptMask | RTC_C_CTL0_KEY_MASK) + & (RTC_C_CTL0_OFIE + RTC_C_CTL0_TEVIE + RTC_C_CTL0_AIE + + RTC_C_CTL0_RDYIE))); + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; + } + + if (interruptMask & RTC_C_PRESCALE_TIMER0_INTERRUPT) + { + BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIE_OFS) = 0; + } + + if (interruptMask & RTC_C_PRESCALE_TIMER1_INTERRUPT) + { + BITBAND_PERI(RTC_C->PS1CTL, RTC_C_PS1CTL_RT1PSIE_OFS) = 0; + } +} + +uint_fast8_t RTC_C_getInterruptStatus(void) +{ + uint_fast8_t tempInterruptFlagMask = 0x00; + uint_fast8_t interruptFlagMask = RTC_C_TIME_EVENT_INTERRUPT + | RTC_C_CLOCK_ALARM_INTERRUPT | RTC_C_CLOCK_READ_READY_INTERRUPT + | RTC_C_PRESCALE_TIMER0_INTERRUPT | RTC_C_PRESCALE_TIMER1_INTERRUPT + | RTC_C_OSCILLATOR_FAULT_INTERRUPT; + + tempInterruptFlagMask |= (RTC_C->CTL0 & (interruptFlagMask >> 4)); + + tempInterruptFlagMask = tempInterruptFlagMask << 4; + + if (interruptFlagMask & RTC_C_PRESCALE_TIMER0_INTERRUPT) + { + if (BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIFG_OFS)) + { + tempInterruptFlagMask |= RTC_C_PRESCALE_TIMER0_INTERRUPT; + } + } + + if (interruptFlagMask & RTC_C_PRESCALE_TIMER1_INTERRUPT) + { + if (BITBAND_PERI(RTC_C->PS1CTL, RTC_C_PS1CTL_RT1PSIFG_OFS)) + { + tempInterruptFlagMask |= RTC_C_PRESCALE_TIMER1_INTERRUPT; + } + } + + return (tempInterruptFlagMask); +} + +uint_fast8_t RTC_C_getEnabledInterruptStatus(void) +{ + + uint32_t intStatus = RTC_C_getInterruptStatus(); + + if (!BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_OFIE_OFS)) + { + intStatus &= ~RTC_C_OSCILLATOR_FAULT_INTERRUPT; + } + + if (!BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_TEVIE_OFS)) + { + intStatus &= ~RTC_C_TIME_EVENT_INTERRUPT; + } + + if (!BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_AIE_OFS)) + { + intStatus &= ~RTC_C_CLOCK_ALARM_INTERRUPT; + } + + if (!BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_RDYIE_OFS)) + { + intStatus &= ~RTC_C_CLOCK_READ_READY_INTERRUPT; + } + + if (!BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIE_OFS)) + { + intStatus &= ~RTC_C_PRESCALE_TIMER0_INTERRUPT; + } + + if (!BITBAND_PERI(RTC_C->PS1CTL, RTC_C_PS1CTL_RT1PSIE_OFS)) + { + intStatus &= ~RTC_C_PRESCALE_TIMER1_INTERRUPT; + } + + return intStatus; +} + +void RTC_C_clearInterruptFlag(uint_fast8_t interruptFlagMask) +{ + if (interruptFlagMask + & (RTC_C_TIME_EVENT_INTERRUPT + RTC_C_CLOCK_ALARM_INTERRUPT + + RTC_C_CLOCK_READ_READY_INTERRUPT + + RTC_C_OSCILLATOR_FAULT_INTERRUPT)) + { + RTC_C->CTL0 = RTC_C_KEY + | (RTC_C->CTL0 & ~((interruptFlagMask >> 4) | RTC_C_CTL0_KEY_MASK)); + BITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0; + } + + if (interruptFlagMask & RTC_C_PRESCALE_TIMER0_INTERRUPT) + { + BITBAND_PERI(RTC_C->PS0CTL, RTC_C_PS0CTL_RT0PSIFG_OFS) = 0; + } + + if (interruptFlagMask & RTC_C_PRESCALE_TIMER1_INTERRUPT) + { + BITBAND_PERI(RTC_C->PS1CTL, RTC_C_PS1CTL_RT1PSIFG_OFS) = 0; + } +} + +void RTC_C_registerInterrupt(void (*intHandler)(void)) +{ + Interrupt_registerInterrupt(INT_RTC_C, intHandler); + Interrupt_enableInterrupt(INT_RTC_C); +} + +void RTC_C_unregisterInterrupt(void) +{ + Interrupt_disableInterrupt(INT_RTC_C); + Interrupt_unregisterInterrupt(INT_RTC_C); +} + diff --git a/example/rt_msp432/MSP432P4xx/rtc_c.h b/example/rt_msp432/MSP432P4xx/rtc_c.h new file mode 100644 index 0000000..ab12598 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/rtc_c.h @@ -0,0 +1,661 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef RTC_C_H_ +#define RTC_C_H_ + +//***************************************************************************** +// +//! \addtogroup rtc_api +//! @{ +// +//***************************************************************************** + + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +//***************************************************************************** +// +//The following is a struct that can be passed to RTC_CalendarInit() in the +//CalendarTime parameter, as well as returned by RTC_getCalendarTime() +// +//***************************************************************************** +typedef struct _RTC_C_Calendar +{ + uint_fast8_t seconds; + uint_fast8_t minutes; + uint_fast8_t hours; + uint_fast8_t dayOfWeek; + uint_fast8_t dayOfmonth; + uint_fast8_t month; + uint_fast16_t year; +} RTC_C_Calendar; + +//***************************************************************************** +// +//The following are values that can be passed to RTC_setCalibrationData() +// +//***************************************************************************** +#define RTC_C_CALIBRATIONFREQ_OFF (RTC_C_CTL13_CALF_0) +#define RTC_C_CALIBRATIONFREQ_512HZ (RTC_C_CTL13_CALF_1) +#define RTC_C_CALIBRATIONFREQ_256HZ (RTC_C_CTL13_CALF_2) +#define RTC_C_CALIBRATIONFREQ_1HZ (RTC_C_CTL13_CALF_3) + +//***************************************************************************** +// +//The following are values that can be passed to RTC_setCalibrationData() +// +//***************************************************************************** +#define RTC_C_CALIBRATION_DOWN1PPM ( !(RTC_C_OCAL_OCALS) ) +#define RTC_C_CALIBRATION_UP1PPM (RTC_C_OCAL_OCALS) + +//***************************************************************************** +// +//The following are values that can be passed to +//RTC_setTemperatureCompensation() +// +//***************************************************************************** +#define RTC_C_COMPENSATION_DOWN1PPM ( !(RTC_C_TCMP_TCMPS) ) +#define RTC_C_COMPENSATION_UP1PPM (RTC_C_TCMP_TCMPS) + +//***************************************************************************** +// +//The following are values that can be passed to RTC_iniRTC_Calendar() +// +//***************************************************************************** +#define RTC_C_FORMAT_BINARY ( !(RTC_C_CTL13_BCD) ) +#define RTC_C_FORMAT_BCD (RTC_C_CTL13_BCD) + +//***************************************************************************** +// +//The following is a value that can be passed to RTC_seRTC_CalendarAlarm() +// +//***************************************************************************** +#define RTC_C_ALARMCONDITION_OFF (0x80) + +//***************************************************************************** +// +//The following are values that can be passed to RTC_seRTC_CalendarEvent() +//in the eventSelect parameter. +// +//***************************************************************************** +#define RTC_C_CALENDAREVENT_MINUTECHANGE (RTC_C_CTL13_TEV_0) +#define RTC_C_CALENDAREVENT_HOURCHANGE (RTC_C_CTL13_TEV_1) +#define RTC_C_CALENDAREVENT_NOON (RTC_C_CTL13_TEV_2) +#define RTC_C_CALENDAREVENT_MIDNIGHT (RTC_C_CTL13_TEV_3) + +//***************************************************************************** +// +//The following are values that can be passed to RTC_definePrescaleEvent() +// +//***************************************************************************** +#define RTC_C_PRESCALE_0 (0x0) +#define RTC_C_PRESCALE_1 (0x1) + +//***************************************************************************** +// +//The following are values that can be passed to RTC_definePrescaleEvent() +//in the prescaleEventDivider parameter. +// +//***************************************************************************** +#define RTC_C_PSEVENTDIVIDER_2 (RTC_C_PS0CTL_RT0IP_0) +#define RTC_C_PSEVENTDIVIDER_4 (RTC_C_PS0CTL_RT0IP_1) +#define RTC_C_PSEVENTDIVIDER_8 (RTC_C_PS0CTL_RT0IP_2) +#define RTC_C_PSEVENTDIVIDER_16 (RTC_C_PS0CTL_RT0IP_3) +#define RTC_C_PSEVENTDIVIDER_32 (RTC_C_PS0CTL_RT0IP_4) +#define RTC_C_PSEVENTDIVIDER_64 (RTC_C_PS0CTL_RT0IP_5) +#define RTC_C_PSEVENTDIVIDER_128 (RTC_C_PS0CTL_RT0IP_6) +#define RTC_C_PSEVENTDIVIDER_256 (RTC_C_PS0CTL_RT0IP_7) + +//***************************************************************************** +// +//The following are values that can be passed to the interrupt functions +// +//***************************************************************************** +#define RTC_C_OSCILLATOR_FAULT_INTERRUPT RTC_C_CTL0_OFIE +#define RTC_C_TIME_EVENT_INTERRUPT RTC_C_CTL0_TEVIE +#define RTC_C_CLOCK_ALARM_INTERRUPT RTC_C_CTL0_AIE +#define RTC_C_CLOCK_READ_READY_INTERRUPT RTC_C_CTL0_RDYIE +#define RTC_C_PRESCALE_TIMER0_INTERRUPT 0x02 +#define RTC_C_PRESCALE_TIMER1_INTERRUPT 0x01 + +//***************************************************************************** +// +//! Starts the RTC. +//! +//! This function clears the RTC main hold bit to allow the RTC to function. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_startClock(void); + +//***************************************************************************** +// +//! Holds the RTC. +//! +//! This function sets the RTC main hold bit to disable RTC functionality. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_holdClock(void); + +//***************************************************************************** +// +//! Allows and Sets the frequency output to RTCLK pin for calibration +//! measurement. +//! +//! \param frequencySelect is the frequency output to RTCLK. +//! Valid values are +//! - \b RTC_C_CALIBRATIONFREQ_OFF - turn off calibration +//! output [Default] +//! - \b RTC_C_CALIBRATIONFREQ_512HZ - output signal at 512Hz +//! for calibration +//! - \b RTC_C_CALIBRATIONFREQ_256HZ - output signal at 256Hz +//! for calibration +//! - \b RTC_C_CALIBRATIONFREQ_1HZ - output signal at 1Hz +//! for calibration +//! +//! This function sets a frequency to measure at the RTCLK output pin. After +//! testing the set frequency, the calibration could be set accordingly. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_setCalibrationFrequency(uint_fast16_t frequencySelect); + +//***************************************************************************** +// +//! Sets the specified calibration for the RTC. +//! +//! \param offsetDirection is the direction that the calibration offset will +//! go. Valid values are +//! - \b RTC_C_CALIBRATION_DOWN1PPM - calibrate at steps of -1 +//! - \b RTC_C_CALIBRATION_UP1PPM - calibrat at steps of +1 +//! \param offsetValue is the value that the offset will be a factor of; a +//! valid value is any integer from 1-240. +//! +//! This function sets the calibration offset to make the RTC as accurate as +//! possible. The offsetDirection can be either +1-ppm or -1-ppm, and the +//! offsetValue should be from 1-240 and is multiplied by the direction setting +//! (i.e. +1-ppm * 8 (offsetValue) = +8-ppm). +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_setCalibrationData(uint_fast8_t offsetDirection, + uint_fast8_t offsetValue); + +//***************************************************************************** +// +//! Sets the specified temperature compensation for the RTC. +//! +//! \param offsetDirection is the direction that the calibration offset will +//! go. Valid values are +//! - \b RTC_C_COMPENSATION_DOWN1PPM - calibrate at steps of -1 +//! - \b RTC_C_COMPENSATION_UP1PPM - calibrate at steps of +1 +//! \param offsetValue is the value that the offset will be a factor of; a +//! value is any integer from 1-240. +//! +//! This function sets the calibration offset to make the RTC as accurate as +//! possible. The offsetDirection can be either +1-ppm or -1-ppm, and the +//! offsetValue should be from 1-240 and is multiplied by the direction setting +//! (i.e. +1-ppm * 8 (offsetValue) = +8-ppm). +//! +//! \return true if calibration was set, false if it could not be set +//! +// +//***************************************************************************** +extern bool RTC_C_setTemperatureCompensation(uint_fast16_t offsetDirection, + uint_fast8_t offsetValue); + +//***************************************************************************** +// +//! Initializes the settings to operate the RTC in Calendar mode. +//! +//! \param calendarTime is the structure containing the values for the Calendar +//! to be initialized to. +//! Valid values should be of type Calendar and should contain the +//! following members and corresponding values: +//! - \b seconds between 0-59 +//! - \b minutes between 0-59 +//! - \b hours between 0-24 +//! - \b dayOfWeek between 0-6 +//! - \b dayOfmonth between 0-31 +//! - \b year between 0-4095 +//! \note Values beyond the ones specified may result in eradic behavior. +//! \param formatSelect is the format for the Calendar registers to use. +//! Valid values are +//! - \b RTC_FORMAT_BINARY [Default] +//! - \b RTC_FORMAT_BCD +//! +//! This function initializes the Calendar mode of the RTC module. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_initCalendar(const RTC_C_Calendar *calendarTime, + uint_fast16_t formatSelect); + +//***************************************************************************** +// +//! Returns the Calendar Time stored in the Calendar registers of the RTC. +//! +//! +//! This function returns the current Calendar time in the form of a Calendar +//! structure. +//! +//! \return A Calendar structure containing the current time. +// +//***************************************************************************** +extern RTC_C_Calendar RTC_C_getCalendarTime(void); + +//***************************************************************************** +// +//! Sets and Enables the desired Calendar Alarm settings. +//! +//! \param minutesAlarm is the alarm condition for the minutes. +//! Valid values are +//! - An integer between 0-59, OR +//! - \b RTC_C_ALARMCONDITION_OFF [Default] +//! \param hoursAlarm is the alarm condition for the hours. +//! Valid values are +//! - An integer between 0-24, OR +//! - \b RTC_C_ALARMCONDITION_OFF [Default] +//! \param dayOfWeekAlarm is the alarm condition for the day of week. +//! Valid values are +//! - An integer between 0-6, OR +//! - \b RTC_C_ALARMCONDITION_OFF [Default] +//! \param dayOfmonthAlarm is the alarm condition for the day of the month. +//! Valid values are +//! - An integer between 0-31, OR +//! - \b RTC_C_ALARMCONDITION_OFF [Default] +//! +//! This function sets a Calendar interrupt condition to assert the RTCAIFG +//! interrupt flag. The condition is a logical and of all of the parameters. +//! For example if the minutes and hours alarm is set, then the interrupt will +//! only assert when the minutes AND the hours change to the specified setting. +//! Use the RTC_ALARM_OFF for any alarm settings that should not be apart of +//! the alarm condition. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_setCalendarAlarm(uint_fast8_t minutesAlarm, + uint_fast8_t hoursAlarm, uint_fast8_t dayOfWeekAlarm, + uint_fast8_t dayOfmonthAlarm); + +//***************************************************************************** +// +//! Sets a single specified Calendar interrupt condition. +//! +//! \param eventSelect is the condition selected. +//! Valid values are +//! - \b RTC_C_CALENDAREVENT_MINUTECHANGE - assert interrupt on every +//! minute +//! - \b RTC_C_CALENDAREVENT_HOURCHANGE - assert interrupt on every hour +//! - \b RTC_C_CALENDAREVENT_NOON - assert interrupt when hour is 12 +//! - \b RTC_C_CALENDAREVENT_MIDNIGHT - assert interrupt when hour is 0 +//! +//! This function sets a specified event to assert the RTCTEVIFG interrupt. This +//! interrupt is independent from the Calendar alarm interrupt. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_setCalendarEvent(uint_fast16_t eventSelect); + +//***************************************************************************** +// +//! Sets up an interrupt condition for the selected Prescaler. +//! +//! \param prescaleSelect is the prescaler to define an interrupt for. +//! Valid values are +//! - \b RTC_C_PRESCALE_0 +//! - \b RTC_C_PRESCALE_1 +//! \param prescaleEventDivider is a divider to specify when an interrupt can +//! occur based on the clock source of the selected prescaler. +//! (Does not affect timer of the selected prescaler). +//! Valid values are +//! - \b RTC_C_PSEVENTDIVIDER_2 [Default] +//! - \b RTC_C_PSEVENTDIVIDER_4 +//! - \b RTC_C_PSEVENTDIVIDER_8 +//! - \b RTC_C_PSEVENTDIVIDER_16 +//! - \b RTC_C_PSEVENTDIVIDER_32 +//! - \b RTC_C_PSEVENTDIVIDER_64 +//! - \b RTC_C_PSEVENTDIVIDER_128 +//! - \b RTC_C_PSEVENTDIVIDER_256 +//! +//! This function sets the condition for an interrupt to assert based on the +//! individual prescalers. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_definePrescaleEvent(uint_fast8_t prescaleSelect, + uint_fast8_t prescaleEventDivider); + +//***************************************************************************** +// +//! Returns the selected Prescaler value. +//! +//! \param prescaleSelect is the prescaler to obtain the value of. +//! Valid values are +//! - \b RTC_C_PRESCALE_0 +//! - \b RTC_C_PRESCALE_1 +//! +//! This function returns the value of the selected prescale counter register. +//! The counter should be held before reading. If in counter mode, the +//! individual prescaler can be held, while in Calendar mode the whole RTC must +//! be held. +//! +//! \return The value of the specified Prescaler count register +// +//***************************************************************************** +extern uint_fast8_t RTC_C_getPrescaleValue(uint_fast8_t prescaleSelect); + +//***************************************************************************** +// +//! Sets the selected Prescaler value. +//! +//! \param prescaleSelect is the prescaler to set the value for. +//! Valid values are +//! - \b RTC_C_PRESCALE_0 +//! - \b RTC_C_PRESCALE_1 +//! \param prescaleCounterValue is the specified value to set the prescaler to; +//! a valid value is any integer from 0-255. +//! +//! This function sets the prescale counter value. Before setting the prescale +//! counter, it should be held. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_setPrescaleValue(uint_fast8_t prescaleSelect, + uint_fast8_t prescaleCounterValue); + +//***************************************************************************** +// +//! Returns the given BCD value in Binary Format +//! +//! \param valueToConvert is the raw value in BCD format to convert to +//! Binary. +//! +//! This function converts BCD values to Binary format. +//! +//! \return The Binary version of the valueToConvert parameter. +// +//***************************************************************************** +extern uint16_t RTC_C_convertBCDToBinary(uint16_t valueToConvert); + +//***************************************************************************** +// +//! Returns the given Binary value in BCD Format +//! + +//! \param valueToConvert is the raw value in Binary format to convert to +//! BCD. +//! +//! This function converts Binary values to BCD format. +//! +//! \return The BCD version of the valueToConvert parameter. +// +//***************************************************************************** +extern uint16_t RTC_C_convertBinaryToBCD(uint16_t valueToConvert); + +//***************************************************************************** +// +//! Enables selected RTC interrupt sources. +//! +//! \param interruptMask is a bit mask of the interrupts to enable. +//! Mask Value is the logical OR of any of the following +//! - \b RTC_C_TIME_EVENT_INTERRUPT - asserts when counter overflows in +//! counter mode or when Calendar event condition defined by +//! defineCalendarEvent() is met. +//! - \b RTC_C_CLOCK_ALARM_INTERRUPT - asserts when alarm condition in +//! Calendar mode is met. +//! - \b RTC_C_CLOCK_READ_READY_INTERRUPT - asserts when Calendar +//! registers are settled. +//! - \b RTC_C_PRESCALE_TIMER0_INTERRUPT - asserts when Prescaler 0 +//! event condition is met. +//! - \b RTC_C_PRESCALE_TIMER1_INTERRUPT - asserts when Prescaler 1 +//! event condition is met. +//! - \b RTC_C_OSCILLATOR_FAULT_INTERRUPT - asserts if there is +//! a problem with the 32kHz oscillator, while the RTC is running. +//! +//! This function enables the selected RTC interrupt source. Only the sources +//! that are enabled can be reflected to the processor interrupt; disabled +//! sources have no effect on the processor. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_enableInterrupt(uint8_t interruptMask); + +//***************************************************************************** +// +//! Disables selected RTC interrupt sources. +//! +//! \param interruptMask is a bit mask of the interrupts to disable. +//! Mask Value is the logical OR of any of the following +//! - \b RTC_C_TIME_EVENT_INTERRUPT - asserts when counter overflows in +//! counter mode or when Calendar event condition defined by +//! defineCalendarEvent() is met. +//! - \b RTC_C_CLOCK_ALARM_INTERRUPT - asserts when alarm condition in +//! Calendar mode is met. +//! - \b RTC_CLOCK_READ_READY_INTERRUPT - asserts when Calendar +//! registers are settled. +//! - \b RTC_C_PRESCALE_TIMER0_INTERRUPT - asserts when Prescaler 0 +//! event condition is met. +//! - \b RTC_C_PRESCALE_TIMER1_INTERRUPT - asserts when Prescaler 1 +//! event condition is met. +//! - \b RTC_C_OSCILLATOR_FAULT_INTERRUPT - asserts if there is a +//! problem with the 32kHz oscillator, while the RTC is running. +//! +//! This function disables the selected RTC interrupt source. Only the sources +//! that are enabled can be reflected to the processor interrupt; disabled +//! sources have no effect on the processor. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_disableInterrupt(uint8_t interruptMask); + +//***************************************************************************** +// +//! Returns the status of the interrupts flags. +//! +//! \return A bit mask of the selected interrupt flag's status. +//! Mask Value is the logical OR of any of the following +//! - \b RTC_C_TIME_EVENT_INTERRUPT - asserts when counter overflows in +//! counter mode or when Calendar event condition defined by +//! defineCalendarEvent() is met. +//! - \b RTC_C_CLOCK_ALARM_INTERRUPT - asserts when alarm condition in +//! Calendar mode is met. +//! - \b RTC_C_CLOCK_READ_READY_INTERRUPT - asserts when Calendar +//! registers are settled. +//! - \b RTC_C_PRESCALE_TIMER0_INTERRUPT - asserts when Prescaler 0 +//! event condition is met. +//! - \b RTC_C_PRESCALE_TIMER1_INTERRUPT - asserts when Prescaler 1 +//! event condition is met. +//! - \b RTC_C_OSCILLATOR_FAULT_INTERRUPT - asserts if there is a +//! problem with the 32kHz oscillator, while the RTC is running. +// +//***************************************************************************** +extern uint_fast8_t RTC_C_getInterruptStatus(void); + +//***************************************************************************** +// +//! Returns the status of the interrupts flags masked with the enabled +//! interrupts. This function is useful to call in ISRs to get a +//! list of pending interrupts that are actually enabled and could have caused +//! the ISR. +//! +//! \return A bit mask of the selected interrupt flag's status. +//! Mask Value is the logical OR of any of the following +//! - \b RTC_TIME_EVENT_INTERRUPT - asserts when counter overflows in +//! counter mode or when Calendar event condition defined by +//! defineCalendarEvent() is met. +//! - \b RTC_CLOCK_ALARM_INTERRUPT - asserts when alarm condition in +//! Calendar mode is met. +//! - \b RTC_CLOCK_READ_READY_INTERRUPT - asserts when Calendar +//! registers are settled. +//! - \b RTC_C_PRESCALE_TIMER0_INTERRUPT - asserts when Prescaler 0 +//! event condition is met. +//! - \b RTC_C_PRESCALE_TIMER1_INTERRUPT - asserts when Prescaler 1 +//! event condition is met. +//! - \b RTC_OSCILLATOR_FAULT_INTERRUPT - asserts if there is a problem +//! with the 32kHz oscillator, while the RTC is running. +// +//***************************************************************************** +extern uint_fast8_t RTC_C_getEnabledInterruptStatus(void); + +//***************************************************************************** +// +//! Clears selected RTC interrupt flags. +//! +//! \param interruptFlagMask is a bit mask of the interrupt flags to be +//! cleared. Mask Value is the logical OR of any of the following +//! - \b RTC_C_TIME_EVENT_INTERRUPT - asserts when counter overflows in +//! counter mode or when Calendar event condition defined by +//! defineCalendarEvent() is met. +//! - \b RTC_C_CLOCK_ALARM_INTERRUPT - asserts when alarm condition in +//! Calendar mode is met. +//! - \b RTC_C_CLOCK_READ_READY_INTERRUPT - asserts when Calendar +//! registers are settled. +//! - \b RTC_C_PRESCALE_TIMER0_INTERRUPT - asserts when Prescaler 0 +//! event condition is met. +//! - \b RTC_C_PRESCALE_TIMER1_INTERRUPT - asserts when Prescaler 1 +//! event condition is met. +//! - \b RTC_C_OSCILLATOR_FAULT_INTERRUPT - asserts if there is +//! a problem with the 32kHz oscillator, while the RTC is running. +//! +//! This function clears the RTC interrupt flag is cleared, so that it no longer +//! asserts. +//! +//! \return None +// +//***************************************************************************** +extern void RTC_C_clearInterruptFlag(uint_fast8_t interruptFlagMask); + +//***************************************************************************** +// +//! Registers an interrupt handler for the RTC interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the +//! RTC interrupt occurs. +//! +//! This function registers the handler to be called when a RTC +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific AES interrupts must be enabled +//! via RTC_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via RTC_clearInterruptFlag(). +//! +//! \return None. +// +//***************************************************************************** +extern void RTC_C_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the RTC interrupt +//! +//! This function unregisters the handler to be called when RTC +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void RTC_C_unregisterInterrupt(void); + +/* Defines for future devices that might have multiple instances */ +#define RTC_C_startClockMultipleInstance(a) RTC_C_startClock() +#define RTC_C_holdClockMultipleInstance(a) RTC_C_holdClock() +#define RTC_C_setCalibrationFrequencyMultipleInstance(a,b) RTC_C_setCalibrationFrequency(b) +#define RTC_C_setCalibrationDataMultipleInstance(a,b,c) RTC_C_setCalibrationData(b,c) +#define RTC_C_setTemperatureCompensationMultipleInstance(a,b,c) RTC_C_setTemperatureCompensation(b,c) +#define RTC_C_initCalendarMultipleInstance(a,b,c) RTC_C_initCalendar(b,c) +#define RTC_C_getCalendarTimeMultipleInstance(a) RTC_C_getCalendarTime() +#define RTC_C_setCalendarAlarmMultipleInstance(a,b,c,d,e) RTC_C_setCalendarAlarm(b,c,d,e) +#define RTC_C_setCalendarEventMultipleInstance(a,b) RTC_C_setCalendarEvent(b) +#define RTC_C_definePrescaleEventMultipleInstance(a,b,c) RTC_C_definePrescaleEvent(b,c) +#define RTC_C_getPrescaleValueMultipleInstance(a,b) RTC_C_getPrescaleValue(b) +#define RTC_C_setPrescaleValueMultipleInstance(a,b,c) RTC_C_setPrescaleValue(b,c) +#define RTC_C_convertBCDToBinaryMultipleInstance(a,b) RTC_C_convertBCDToBinary(b) +#define RTC_C_convertBinaryToBCDMultipleInstance(a,b) RTC_C_convertBinaryToBCD(b) +#define RTC_C_enableInterruptMultipleInstance(a,b) RTC_C_enableInterrupt(b) +#define RTC_C_disableInterruptMultipleInstance(a,b) RTC_C_disableInterrupt(b) +#define RTC_C_getInterruptStatusMultipleInstance(a) RTC_C_getInterruptStatus() +#define RTC_C_getEnabledInterruptStatusMultipleInstance(a) RTC_C_getEnabledInterruptStatus() +#define RTC_C_clearInterruptFlagMultipleInstance(a,b) RTC_C_clearInterruptFlag(b) +#define RTC_C_registerInterruptMultipleInstance(a,b) RTC_C_registerInterrupt(b) +#define RTC_C_unregisterInterruptMultipleInstance(a) RTC_C_unregisterInterrupt() + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif /* RTC_H */ diff --git a/example/rt_msp432/MSP432P4xx/spi.c b/example/rt_msp432/MSP432P4xx/spi.c new file mode 100644 index 0000000..eba38c3 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/spi.c @@ -0,0 +1,1371 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include +#include + +static bool is_A_Module(uint32_t module) +{ + if (module == EUSCI_A0_BASE || module == EUSCI_A1_BASE +#ifdef EUSCI_A2_BASE + || module == EUSCI_A2_BASE +#endif +#ifdef EUSCI_A3_BASE + || module == EUSCI_A3_BASE +#endif + ) + return true; + else + return false; +} + +bool SPI_initMaster(uint32_t moduleInstance, const eUSCI_SPI_MasterConfig *config) +{ + /* Returning false if we are not divisible */ + if((config->clockSourceFrequency + % config->desiredSpiClock) != 0) + { + return false; + } + + if (is_A_Module(moduleInstance)) + { + ASSERT( + (EUSCI_A_SPI_CLOCKSOURCE_ACLK == config->selectClockSource) + || (EUSCI_A_SPI_CLOCKSOURCE_SMCLK + == config->selectClockSource)); + + ASSERT( + (EUSCI_A_SPI_MSB_FIRST == config->msbFirst) + || (EUSCI_A_SPI_LSB_FIRST == config->msbFirst)); + + ASSERT( + (EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT + == config->clockPhase) + || (EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT + == config->clockPhase)); + + ASSERT( + (EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH + == config->clockPolarity) + || (EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW + == config->clockPolarity)); + + ASSERT( + (EUSCI_A_SPI_3PIN == config->spiMode) + || (EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_HIGH + == config->spiMode) + || (EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_LOW + == config->spiMode)); + + //Disable the USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + /* + * Configure as SPI master mode. + * Clock phase select, polarity, msb + * EUSCI_A_CTLW0_MST = Master mode + * EUSCI_A_CTLW0_SYNC = Synchronous mode + * UCMODE_0 = 3-pin SPI + */ + EUSCI_A_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_A_CMSIS(moduleInstance)->CTLW0 + & ~(EUSCI_A_CTLW0_SSEL_MASK + EUSCI_A_CTLW0_CKPH + EUSCI_A_CTLW0_CKPL + EUSCI_A_CTLW0_SEVENBIT + EUSCI_A_CTLW0_MSB + EUSCI_A_CTLW0_MST + + EUSCI_A_CTLW0_MODE_3 + EUSCI_A_CTLW0_SYNC)) + | (config->selectClockSource + config->msbFirst + + config->clockPhase + config->clockPolarity + + EUSCI_A_CTLW0_MST + EUSCI_A_CTLW0_SYNC + config->spiMode); + + EUSCI_A_CMSIS(moduleInstance)->BRW = + (uint16_t) (config->clockSourceFrequency + / config->desiredSpiClock); + + //No modulation + EUSCI_A_CMSIS(moduleInstance)->MCTLW = 0; + + return true; + } else + { + ASSERT( + (EUSCI_B_SPI_CLOCKSOURCE_ACLK == config->selectClockSource) + || (EUSCI_B_SPI_CLOCKSOURCE_SMCLK + == config->selectClockSource)); + + ASSERT( + (EUSCI_B_SPI_MSB_FIRST == config->msbFirst) + || (EUSCI_B_SPI_LSB_FIRST == config->msbFirst)); + + ASSERT( + (EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT + == config->clockPhase) + || (EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT + == config->clockPhase)); + + ASSERT( + (EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH + == config->clockPolarity) + || (EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW + == config->clockPolarity)); + + ASSERT( + (EUSCI_B_SPI_3PIN == config->spiMode) + || (EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_HIGH + == config->spiMode) + || (EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_LOW + == config->spiMode)); + + //Disable the USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + /* + * Configure as SPI master mode. + * Clock phase select, polarity, msb + * EUSCI_A_CTLW0_MST = Master mode + * EUSCI_A_CTLW0_SYNC = Synchronous mode + * UCMODE_0 = 3-pin SPI + */ + EUSCI_B_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_B_CMSIS(moduleInstance)->CTLW0 + & ~(EUSCI_A_CTLW0_SSEL_MASK + EUSCI_A_CTLW0_CKPH + EUSCI_A_CTLW0_CKPL + EUSCI_A_CTLW0_SEVENBIT + EUSCI_A_CTLW0_MSB + EUSCI_A_CTLW0_MST + + EUSCI_A_CTLW0_MODE_3 + EUSCI_A_CTLW0_SYNC)) + | (config->selectClockSource + config->msbFirst + + config->clockPhase + config->clockPolarity + + EUSCI_A_CTLW0_MST + EUSCI_A_CTLW0_SYNC + config->spiMode); + + EUSCI_B_CMSIS(moduleInstance)->BRW = + (uint16_t) (config->clockSourceFrequency + / config->desiredSpiClock); + + return true; + } + +} + +void SPI_selectFourPinFunctionality(uint32_t moduleInstance, + uint_fast8_t select4PinFunctionality) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_select4PinFunctionality(moduleInstance, + select4PinFunctionality); + } else + { + EUSCI_B_SPI_select4PinFunctionality(moduleInstance, + select4PinFunctionality); + } + +} + +void SPI_changeMasterClock(uint32_t moduleInstance, + uint32_t clockSourceFrequency, uint32_t desiredSpiClock) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_masterChangeClock(moduleInstance, clockSourceFrequency, + desiredSpiClock); + } else + { + EUSCI_B_SPI_masterChangeClock(moduleInstance, clockSourceFrequency, + desiredSpiClock); + } + +} + +bool SPI_initSlave(uint32_t moduleInstance, const eUSCI_SPI_SlaveConfig *config) +{ + if (is_A_Module(moduleInstance)) + { + ASSERT( + (EUSCI_A_SPI_MSB_FIRST == config->msbFirst) + || (EUSCI_A_SPI_LSB_FIRST == config->msbFirst)); + + ASSERT( + (EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT + == config->clockPhase) + || (EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT + == config->clockPhase)); + + ASSERT( + (EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH + == config->clockPolarity) + || (EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW + == config->clockPolarity)); + + ASSERT( + (EUSCI_A_SPI_3PIN == config->spiMode) + || (EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_HIGH + == config->spiMode) + || (EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_LOW + == config->spiMode)); + + //Disable USCI Module + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + //Reset OFS_UCAxCTLW0 register + EUSCI_A_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_A_CMSIS(moduleInstance)->CTLW0 + & ~(EUSCI_A_CTLW0_MSB + EUSCI_A_CTLW0_SEVENBIT + EUSCI_A_CTLW0_MST + EUSCI_A_CTLW0_CKPL + EUSCI_A_CTLW0_CKPH + EUSCI_A_CTLW0_MODE_3)) + | (config->clockPhase + config->clockPolarity + + config->msbFirst + EUSCI_A_CTLW0_SYNC + config->spiMode); + + return true; + } else + { + ASSERT( + (EUSCI_B_SPI_MSB_FIRST == config->msbFirst) + || (EUSCI_B_SPI_LSB_FIRST == config->msbFirst)); + + ASSERT( + (EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT + == config->clockPhase) + || (EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT + == config->clockPhase)); + + ASSERT( + (EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH + == config->clockPolarity) + || (EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW + == config->clockPolarity)); + + ASSERT( + (EUSCI_B_SPI_3PIN == config->spiMode) + || (EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_HIGH + == config->spiMode) + || (EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_LOW + == config->spiMode)); + + //Disable USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + //Reset OFS_UCBxCTLW0 register + EUSCI_B_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_B_CMSIS(moduleInstance)->CTLW0 + & ~(EUSCI_A_CTLW0_MSB + EUSCI_A_CTLW0_SEVENBIT + EUSCI_A_CTLW0_MST + EUSCI_A_CTLW0_CKPL + EUSCI_A_CTLW0_CKPH + EUSCI_A_CTLW0_MODE_3)) + | (config->clockPhase + config->clockPolarity + + config->msbFirst + EUSCI_A_CTLW0_SYNC + config->spiMode); + + return true; + } + +} + +void SPI_changeClockPhasePolarity(uint32_t moduleInstance, + uint_fast16_t clockPhase, uint_fast16_t clockPolarity) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_changeClockPhasePolarity(moduleInstance, clockPhase, + clockPolarity); + } else + { + EUSCI_B_SPI_changeClockPhasePolarity(moduleInstance, clockPhase, + clockPolarity); + } + +} + +void SPI_transmitData(uint32_t moduleInstance, uint_fast8_t transmitData) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_transmitData(moduleInstance, transmitData); + } else + { + EUSCI_B_SPI_transmitData(moduleInstance, transmitData); + } + +} + +uint8_t SPI_receiveData(uint32_t moduleInstance) +{ + if (is_A_Module(moduleInstance)) + { + return EUSCI_A_SPI_receiveData(moduleInstance); + } else + { + return EUSCI_B_SPI_receiveData(moduleInstance); + } + +} + +void SPI_enableModule(uint32_t moduleInstance) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_enable(moduleInstance); + } else + { + EUSCI_B_SPI_enable(moduleInstance); + } + +} + +void SPI_disableModule(uint32_t moduleInstance) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_disable(moduleInstance); + } else + { + EUSCI_B_SPI_disable(moduleInstance); + } + +} + +uint32_t SPI_getReceiveBufferAddressForDMA(uint32_t moduleInstance) +{ + if (is_A_Module(moduleInstance)) + { + return EUSCI_A_SPI_getReceiveBufferAddressForDMA(moduleInstance); + } else + { + return EUSCI_B_SPI_getReceiveBufferAddressForDMA(moduleInstance); + } + +} + +uint32_t SPI_getTransmitBufferAddressForDMA(uint32_t moduleInstance) +{ + if (is_A_Module(moduleInstance)) + { + return EUSCI_A_SPI_getTransmitBufferAddressForDMA(moduleInstance); + } else + { + return EUSCI_B_SPI_getTransmitBufferAddressForDMA(moduleInstance); + } + +} + +uint_fast8_t SPI_isBusy(uint32_t moduleInstance) +{ + if (is_A_Module(moduleInstance)) + { + return EUSCI_A_SPI_isBusy(moduleInstance); + } else + { + return EUSCI_B_SPI_isBusy(moduleInstance); + } + +} + +void SPI_enableInterrupt(uint32_t moduleInstance, uint_fast8_t mask) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_enableInterrupt(moduleInstance, mask); + } else + { + EUSCI_B_SPI_enableInterrupt(moduleInstance, mask); + } + +} + +void SPI_disableInterrupt(uint32_t moduleInstance, uint_fast8_t mask) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_disableInterrupt(moduleInstance, mask); + } else + { + EUSCI_B_SPI_disableInterrupt(moduleInstance, mask); + } + +} + +uint_fast8_t SPI_getInterruptStatus(uint32_t moduleInstance, uint16_t mask) +{ + if (is_A_Module(moduleInstance)) + { + return EUSCI_A_SPI_getInterruptStatus(moduleInstance, mask); + } else + { + return EUSCI_B_SPI_getInterruptStatus(moduleInstance, mask); + } + +} + +uint_fast8_t SPI_getEnabledInterruptStatus(uint32_t moduleInstance) +{ + if (is_A_Module(moduleInstance)) + { + return SPI_getInterruptStatus(moduleInstance, + EUSCI_SPI_TRANSMIT_INTERRUPT | EUSCI_SPI_RECEIVE_INTERRUPT) + & EUSCI_A_CMSIS(moduleInstance)->IE; + + } else + { + return SPI_getInterruptStatus(moduleInstance, + EUSCI_SPI_TRANSMIT_INTERRUPT | EUSCI_SPI_RECEIVE_INTERRUPT) + & EUSCI_B_CMSIS(moduleInstance)->IE; + + } +} + +void SPI_clearInterruptFlag(uint32_t moduleInstance, uint_fast8_t mask) +{ + if (is_A_Module(moduleInstance)) + { + EUSCI_A_SPI_clearInterruptFlag(moduleInstance, mask); + } else + { + EUSCI_B_SPI_clearInterruptFlag(moduleInstance, mask); + } + +} + +void SPI_registerInterrupt(uint32_t moduleInstance, void (*intHandler)(void)) +{ + switch (moduleInstance) + { + case EUSCI_A0_BASE: + Interrupt_registerInterrupt(INT_EUSCIA0, intHandler); + Interrupt_enableInterrupt(INT_EUSCIA0); + break; + case EUSCI_A1_BASE: + Interrupt_registerInterrupt(INT_EUSCIA1, intHandler); + Interrupt_enableInterrupt(INT_EUSCIA1); + break; +#ifdef EUSCI_A2_BASE + case EUSCI_A2_BASE: + Interrupt_registerInterrupt(INT_EUSCIA2, intHandler); + Interrupt_enableInterrupt(INT_EUSCIA2); + break; +#endif +#ifdef EUSCI_A3_BASE + case EUSCI_A3_BASE: + Interrupt_registerInterrupt(INT_EUSCIA3, intHandler); + Interrupt_enableInterrupt(INT_EUSCIA3); + break; +#endif + case EUSCI_B0_BASE: + Interrupt_registerInterrupt(INT_EUSCIB0, intHandler); + Interrupt_enableInterrupt(INT_EUSCIB0); + break; + case EUSCI_B1_BASE: + Interrupt_registerInterrupt(INT_EUSCIB1, intHandler); + Interrupt_enableInterrupt(INT_EUSCIB1); + break; +#ifdef EUSCI_B2_BASE + case EUSCI_B2_BASE: + Interrupt_registerInterrupt(INT_EUSCIB2, intHandler); + Interrupt_enableInterrupt(INT_EUSCIB2); + break; +#endif +#ifdef EUSCI_B3_BASE + case EUSCI_B3_BASE: + Interrupt_registerInterrupt(INT_EUSCIB3, intHandler); + Interrupt_enableInterrupt(INT_EUSCIB3); + break; +#endif + default: + ASSERT(false); + } +} + +void SPI_unregisterInterrupt(uint32_t moduleInstance) +{ + switch (moduleInstance) + { + case EUSCI_A0_BASE: + Interrupt_disableInterrupt(INT_EUSCIA0); + Interrupt_unregisterInterrupt(INT_EUSCIA0); + break; + case EUSCI_A1_BASE: + Interrupt_disableInterrupt(INT_EUSCIA1); + Interrupt_unregisterInterrupt(INT_EUSCIA1); + break; +#ifdef EUSCI_A2_BASE + case EUSCI_A2_BASE: + Interrupt_disableInterrupt(INT_EUSCIA2); + Interrupt_unregisterInterrupt(INT_EUSCIA2); + break; +#endif +#ifdef EUSCI_A3_BASE + case EUSCI_A3_BASE: + Interrupt_disableInterrupt(INT_EUSCIA3); + Interrupt_unregisterInterrupt(INT_EUSCIA3); + break; +#endif + case EUSCI_B0_BASE: + Interrupt_disableInterrupt(INT_EUSCIB0); + Interrupt_unregisterInterrupt(INT_EUSCIB0); + break; + case EUSCI_B1_BASE: + Interrupt_disableInterrupt(INT_EUSCIB1); + Interrupt_unregisterInterrupt(INT_EUSCIB1); + break; +#ifdef EUSCI_B2_BASE + case EUSCI_B2_BASE: + Interrupt_disableInterrupt(INT_EUSCIB2); + Interrupt_unregisterInterrupt(INT_EUSCIB2); + break; +#endif +#ifdef EUSCI_B3_BASE + case EUSCI_B3_BASE: + Interrupt_disableInterrupt(INT_EUSCIB3); + Interrupt_unregisterInterrupt(INT_EUSCIB3); + break; +#endif + default: + ASSERT(false); + } + +} + +/* Backwards Compatibility Layer */ + +//***************************************************************************** +// +//! \brief Selects 4Pin Functionality +//! +//! This function should be invoked only in 4-wire mode. Invoking this function +//! has no effect in 3-wire mode. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! \param select4PinFunctionality selects 4 pin functionality +//! Valid values are: +//! - \b EUSCI_B_SPI_PREVENT_CONFLICTS_WITH_OTHER_MASTERS +//! - \b EUSCI_B_SPI_ENABLE_SIGNAL_FOR_4WIRE_SLAVE +//! +//! Modified bits are \b UCSTEM of \b UCAxCTLW0 register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_select4PinFunctionality(uint32_t baseAddress, + uint8_t select4PinFunctionality) +{ + ASSERT( + (EUSCI_B_SPI_PREVENT_CONFLICTS_WITH_OTHER_MASTERS + == select4PinFunctionality) + || (EUSCI_B_SPI_ENABLE_SIGNAL_FOR_4WIRE_SLAVE + == select4PinFunctionality)); + + EUSCI_B_CMSIS(baseAddress)->CTLW0 = (EUSCI_B_CMSIS(baseAddress)->CTLW0 + & ~EUSCI_B_CTLW0_STEM) | select4PinFunctionality; +} + +//***************************************************************************** +// +//! \brief Initializes the SPI Master clock. At the end of this function call, +//! SPI module is left enabled. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! \param clockSourceFrequency is the frequency of the slected clock source +//! \param desiredSpiClock is the desired clock rate for SPI communication +//! +//! Modified bits are \b UCSWRST of \b UCAxCTLW0 register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_masterChangeClock(uint32_t baseAddress, + uint32_t clockSourceFrequency, uint32_t desiredSpiClock) +{ + //Disable the USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + EUSCI_B_CMSIS(baseAddress)->BRW = (uint16_t) (clockSourceFrequency + / desiredSpiClock); + + //Reset the UCSWRST bit to enable the USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 0; +} + +//***************************************************************************** +// +//! \brief Initializes the SPI Slave block. +//! +//! Upon successful initialization of the SPI slave block, this function will +//! have initailized the slave block, but the SPI Slave block still remains +//! disabled and must be enabled with EUSCI_B_SPI_enable() +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI Slave module. +//! \param msbFirst controls the direction of the receive and transmit shift +//! register. +//! Valid values are: +//! - \b EUSCI_B_SPI_MSB_FIRST +//! - \b EUSCI_B_SPI_LSB_FIRST [Default] +//! \param clockPhase is clock phase select. +//! Valid values are: +//! - \b EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT +//! [Default] +//! - \b EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT +//! \param clockPolarity is clock polarity select +//! Valid values are: +//! - \b EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH +//! - \b EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default] +//! \param spiMode is SPI mode select +//! Valid values are: +//! - \b EUSCI_B_SPI_3PIN +//! - \b EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_HIGH +//! - \b EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_LOW +//! +//! Modified bits are \b EUSCI_A_CTLW0_MSB, \b EUSCI_A_CTLW0_MST, \b EUSCI_A_CTLW0_SEVENBIT, \b EUSCI_A_CTLW0_CKPL, \b EUSCI_A_CTLW0_CKPH, \b +//! UCMODE and \b UCSWRST of \b UCAxCTLW0 register. +//! +//! \return STATUS_SUCCESS +// +//***************************************************************************** +bool EUSCI_B_SPI_slaveInit(uint32_t baseAddress, uint16_t msbFirst, + uint16_t clockPhase, uint16_t clockPolarity, uint16_t spiMode) +{ + ASSERT( + (EUSCI_B_SPI_MSB_FIRST == msbFirst) + || (EUSCI_B_SPI_LSB_FIRST == msbFirst)); + + ASSERT( + (EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT + == clockPhase) + || (EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT + == clockPhase)); + + ASSERT( + (EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH == clockPolarity) + || (EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW + == clockPolarity)); + + ASSERT( + (EUSCI_B_SPI_3PIN == spiMode) + || (EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_HIGH == spiMode) + || (EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_LOW == spiMode)); + + //Disable USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + //Reset OFS_UCBxCTLW0 register + EUSCI_B_CMSIS(baseAddress)->CTLW0 = (EUSCI_B_CMSIS(baseAddress)->CTLW0 + & ~(EUSCI_A_CTLW0_MSB + EUSCI_A_CTLW0_SEVENBIT + EUSCI_A_CTLW0_MST + EUSCI_A_CTLW0_CKPL + EUSCI_A_CTLW0_CKPH + EUSCI_A_CTLW0_MODE_3)) + | (clockPhase + clockPolarity + msbFirst + EUSCI_A_CTLW0_SYNC + spiMode); + + return true; +} + +//***************************************************************************** +// +//! \brief Changes the SPI colock phase and polarity. At the end of this +//! function call, SPI module is left enabled. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! \param clockPhase is clock phase select. +//! Valid values are: +//! - \b EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT +//! [Default] +//! - \b EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT +//! \param clockPolarity is clock polarity select +//! Valid values are: +//! - \b EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH +//! - \b EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default] +//! +//! Modified bits are \b EUSCI_A_CTLW0_CKPL, \b EUSCI_A_CTLW0_CKPH and \b UCSWRST of \b UCAxCTLW0 +//! register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_changeClockPhasePolarity(uint32_t baseAddress, + uint16_t clockPhase, uint16_t clockPolarity) +{ + + ASSERT( + (EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH == clockPolarity) + || (EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW + == clockPolarity)); + + ASSERT( + (EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT + == clockPhase) + || (EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT + == clockPhase)); + + //Disable the USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + EUSCI_B_CMSIS(baseAddress)->CTLW0 = (EUSCI_B_CMSIS(baseAddress)->CTLW0 + & ~(EUSCI_A_CTLW0_CKPH + EUSCI_A_CTLW0_CKPL)) | (clockPhase + clockPolarity); + + //Reset the UCSWRST bit to enable the USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 0; +} + +//***************************************************************************** +// +//! \brief Transmits a byte from the SPI Module. +//! +//! This function will place the supplied data into SPI trasmit data register +//! to start transmission. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! \param transmitData data to be transmitted from the SPI module +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_transmitData(uint32_t baseAddress, uint8_t transmitData) +{ + EUSCI_B_CMSIS(baseAddress)->TXBUF = transmitData; +} + +//***************************************************************************** +// +//! \brief Receives a byte that has been sent to the SPI Module. +//! +//! This function reads a byte of data from the SPI receive data Register. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! +//! \return Returns the byte received from by the SPI module, cast as an +//! uint8_t. +// +//***************************************************************************** +uint8_t EUSCI_B_SPI_receiveData(uint32_t baseAddress) +{ + return EUSCI_B_CMSIS(baseAddress)->RXBUF; +} + +//***************************************************************************** +// +//! \brief Enables individual SPI interrupt sources. +//! +//! Enables the indicated SPI interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. Does not clear interrupt flags. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! \param mask is the bit mask of the interrupt sources to be enabled. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_B_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_B_SPI_RECEIVE_INTERRUPT +//! +//! Modified bits of \b UCAxIFG register and bits of \b UCAxIE register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_enableInterrupt(uint32_t baseAddress, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_B_SPI_RECEIVE_INTERRUPT + | EUSCI_B_SPI_TRANSMIT_INTERRUPT))); + + EUSCI_B_CMSIS(baseAddress)->IE |= mask; +} + +//***************************************************************************** +// +//! \brief Disables individual SPI interrupt sources. +//! +//! Disables the indicated SPI interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! \param mask is the bit mask of the interrupt sources to be disabled. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_B_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_B_SPI_RECEIVE_INTERRUPT +//! +//! Modified bits of \b UCAxIE register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_disableInterrupt(uint32_t baseAddress, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_B_SPI_RECEIVE_INTERRUPT + | EUSCI_B_SPI_TRANSMIT_INTERRUPT))); + + EUSCI_B_CMSIS(baseAddress)->IE &= ~mask; +} + +//***************************************************************************** +// +//! \brief Gets the current SPI interrupt status. +//! +//! This returns the interrupt status for the SPI module based on which flag is +//! passed. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! \param mask is the masked interrupt flag status to be returned. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_B_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_B_SPI_RECEIVE_INTERRUPT +//! +//! \return Logical OR of any of the following: +//! - \b EUSCI_B_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_B_SPI_RECEIVE_INTERRUPT +//! \n indicating the status of the masked interrupts +// +//***************************************************************************** +uint8_t EUSCI_B_SPI_getInterruptStatus(uint32_t baseAddress, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_B_SPI_RECEIVE_INTERRUPT + | EUSCI_B_SPI_TRANSMIT_INTERRUPT))); + + return EUSCI_B_CMSIS(baseAddress)->IFG & mask; +} + +//***************************************************************************** +// +//! \brief Clears the selected SPI interrupt status flag. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! \param mask is the masked interrupt flag to be cleared. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_B_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_B_SPI_RECEIVE_INTERRUPT +//! +//! Modified bits of \b UCAxIFG register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_clearInterruptFlag(uint32_t baseAddress, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_B_SPI_RECEIVE_INTERRUPT + | EUSCI_B_SPI_TRANSMIT_INTERRUPT))); + + EUSCI_B_CMSIS(baseAddress)->IFG &= ~mask; +} + +//***************************************************************************** +// +//! \brief Enables the SPI block. +//! +//! This will enable operation of the SPI block. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! +//! Modified bits are \b UCSWRST of \b UCBxCTLW0 register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_enable(uint32_t baseAddress) +{ + //Reset the UCSWRST bit to enable the USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 0; +} + +//***************************************************************************** +// +//! \brief Disables the SPI block. +//! +//! This will disable operation of the SPI block. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! +//! Modified bits are \b UCSWRST of \b UCBxCTLW0 register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_B_SPI_disable(uint32_t baseAddress) +{ + //Set the UCSWRST bit to disable the USCI Module + BITBAND_PERI(EUSCI_B_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; +} + +//***************************************************************************** +// +//! \brief Returns the address of the RX Buffer of the SPI for the DMA module. +//! +//! Returns the address of the SPI RX Buffer. This can be used in conjunction +//! with the DMA to store the received data directly to memory. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! +//! \return the address of the RX Buffer +// +//***************************************************************************** +uint32_t EUSCI_B_SPI_getReceiveBufferAddressForDMA(uint32_t baseAddress) +{ + return ((uint32_t)(&EUSCI_B_CMSIS(baseAddress)->RXBUF)); +} + +//***************************************************************************** +// +//! \brief Returns the address of the TX Buffer of the SPI for the DMA module. +//! +//! Returns the address of the SPI TX Buffer. This can be used in conjunction +//! with the DMA to obtain transmitted data directly from memory. +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! +//! \return the address of the TX Buffer +// +//***************************************************************************** +uint32_t EUSCI_B_SPI_getTransmitBufferAddressForDMA(uint32_t baseAddress) +{ + return ((uint32_t)(&EUSCI_B_CMSIS(baseAddress)->TXBUF)); +} + +//***************************************************************************** +// +//! \brief Indicates whether or not the SPI bus is busy. +//! +//! This function returns an indication of whether or not the SPI bus is +//! busy.This function checks the status of the bus via UCBBUSY bit +//! +//! \param baseAddress is the base address of the EUSCI_B_SPI module. +//! +//! \return true if busy, false otherwise +// +//***************************************************************************** +bool EUSCI_B_SPI_isBusy(uint32_t baseAddress) +{ + //Return the bus busy status. + return BITBAND_PERI(EUSCI_B_CMSIS(baseAddress)->STATW, EUSCI_B_STATW_BBUSY_OFS); +} + +//***************************************************************************** +// +//! \brief Selects 4Pin Functionality +//! +//! This function should be invoked only in 4-wire mode. Invoking this function +//! has no effect in 3-wire mode. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! \param select4PinFunctionality selects 4 pin functionality +//! Valid values are: +//! - \b EUSCI_A_SPI_PREVENT_CONFLICTS_WITH_OTHER_MASTERS +//! - \b EUSCI_A_SPI_ENABLE_SIGNAL_FOR_4WIRE_SLAVE +//! +//! Modified bits are \b UCSTEM of \b UCAxCTLW0 register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_select4PinFunctionality(uint32_t baseAddress, + uint8_t select4PinFunctionality) +{ + ASSERT( + (EUSCI_A_SPI_PREVENT_CONFLICTS_WITH_OTHER_MASTERS + == select4PinFunctionality) + || (EUSCI_A_SPI_ENABLE_SIGNAL_FOR_4WIRE_SLAVE + == select4PinFunctionality)); + + EUSCI_A_CMSIS(baseAddress)->CTLW0 = (EUSCI_A_CMSIS(baseAddress)->CTLW0 + & ~EUSCI_A_CTLW0_STEM) | select4PinFunctionality; +} + +//***************************************************************************** +// +//! \brief Initializes the SPI Master clock. At the end of this function call, +//! SPI module is left enabled. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! \param clockSourceFrequency is the frequency of the slected clock source +//! \param desiredSpiClock is the desired clock rate for SPI communication +//! +//! Modified bits are \b UCSWRST of \b UCAxCTLW0 register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_masterChangeClock(uint32_t baseAddress, + uint32_t clockSourceFrequency, uint32_t desiredSpiClock) +{ + //Disable the USCI Module + BITBAND_PERI(EUSCI_A_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + EUSCI_A_CMSIS(baseAddress)->BRW = (uint16_t) (clockSourceFrequency + / desiredSpiClock); + + //Reset the UCSWRST bit to enable the USCI Module + BITBAND_PERI(EUSCI_A_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 0; +} + +//***************************************************************************** +// +//! \brief Initializes the SPI Slave block. +//! +//! Upon successful initialization of the SPI slave block, this function will +//! have initailized the slave block, but the SPI Slave block still remains +//! disabled and must be enabled with EUSCI_A_SPI_enable() +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI Slave module. +//! \param msbFirst controls the direction of the receive and transmit shift +//! register. +//! Valid values are: +//! - \b EUSCI_A_SPI_MSB_FIRST +//! - \b EUSCI_A_SPI_LSB_FIRST [Default] +//! \param clockPhase is clock phase select. +//! Valid values are: +//! - \b EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT +//! [Default] +//! - \b EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT +//! \param clockPolarity is clock polarity select +//! Valid values are: +//! - \b EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH +//! - \b EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default] +//! \param spiMode is SPI mode select +//! Valid values are: +//! - \b EUSCI_A_SPI_3PIN +//! - \b EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_HIGH +//! - \b EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_LOW +//! +//! Modified bits are \b EUSCI_A_CTLW0_MSB, \b EUSCI_A_CTLW0_MST, \b EUSCI_A_CTLW0_SEVENBIT, \b EUSCI_A_CTLW0_CKPL, \b EUSCI_A_CTLW0_CKPH, \b +//! UCMODE and \b UCSWRST of \b UCAxCTLW0 register. +//! +//! \return STATUS_SUCCESS +// +//***************************************************************************** +bool EUSCI_A_SPI_slaveInit(uint32_t baseAddress, uint16_t msbFirst, + uint16_t clockPhase, uint16_t clockPolarity, uint16_t spiMode) +{ + ASSERT( + (EUSCI_A_SPI_MSB_FIRST == msbFirst) + || (EUSCI_A_SPI_LSB_FIRST == msbFirst)); + + ASSERT( + (EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT + == clockPhase) + || (EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT + == clockPhase)); + + ASSERT( + (EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH == clockPolarity) + || (EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW + == clockPolarity)); + + ASSERT( + (EUSCI_A_SPI_3PIN == spiMode) + || (EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_HIGH == spiMode) + || (EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_LOW == spiMode)); + + //Disable USCI Module + BITBAND_PERI(EUSCI_A_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + //Reset OFS_UCAxCTLW0 register + EUSCI_A_CMSIS(baseAddress)->CTLW0 = (EUSCI_A_CMSIS(baseAddress)->CTLW0 + & ~(EUSCI_A_CTLW0_MSB + EUSCI_A_CTLW0_SEVENBIT + EUSCI_A_CTLW0_MST + EUSCI_A_CTLW0_CKPL + EUSCI_A_CTLW0_CKPH + EUSCI_A_CTLW0_MODE_3)) + | (clockPhase + clockPolarity + msbFirst + EUSCI_A_CTLW0_SYNC + spiMode); + + return true; +} + +//***************************************************************************** +// +//! \brief Changes the SPI colock phase and polarity. At the end of this +//! function call, SPI module is left enabled. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! \param clockPhase is clock phase select. +//! Valid values are: +//! - \b EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT +//! [Default] +//! - \b EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT +//! \param clockPolarity is clock polarity select +//! Valid values are: +//! - \b EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH +//! - \b EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default] +//! +//! Modified bits are \b EUSCI_A_CTLW0_CKPL, \b EUSCI_A_CTLW0_CKPH and \b UCSWRST of \b UCAxCTLW0 +//! register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_changeClockPhasePolarity(uint32_t baseAddress, + uint16_t clockPhase, uint16_t clockPolarity) +{ + + ASSERT( + (EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH == clockPolarity) + || (EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW + == clockPolarity)); + + ASSERT( + (EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT + == clockPhase) + || (EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT + == clockPhase)); + + //Disable the USCI Module + BITBAND_PERI(EUSCI_A_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + EUSCI_A_CMSIS(baseAddress)->CTLW0 = (EUSCI_A_CMSIS(baseAddress)->CTLW0 + & ~(EUSCI_A_CTLW0_CKPH + EUSCI_A_CTLW0_CKPL)) | (clockPhase + clockPolarity); + + //Reset the UCSWRST bit to enable the USCI Module + BITBAND_PERI(EUSCI_A_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 0; +} + +//***************************************************************************** +// +//! \brief Transmits a byte from the SPI Module. +//! +//! This function will place the supplied data into SPI trasmit data register +//! to start transmission. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! \param transmitData data to be transmitted from the SPI module +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_transmitData(uint32_t baseAddress, uint8_t transmitData) +{ + EUSCI_A_CMSIS(baseAddress)->TXBUF = transmitData; +} + +//***************************************************************************** +// +//! \brief Receives a byte that has been sent to the SPI Module. +//! +//! This function reads a byte of data from the SPI receive data Register. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! +//! \return Returns the byte received from by the SPI module, cast as an +//! uint8_t. +// +//***************************************************************************** +uint8_t EUSCI_A_SPI_receiveData(uint32_t baseAddress) +{ + return EUSCI_A_CMSIS(baseAddress)->RXBUF; +} + +//***************************************************************************** +// +//! \brief Enables individual SPI interrupt sources. +//! +//! Enables the indicated SPI interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. Does not clear interrupt flags. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! \param mask is the bit mask of the interrupt sources to be enabled. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_A_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_A_SPI_RECEIVE_INTERRUPT +//! +//! Modified bits of \b UCAxIFG register and bits of \b UCAxIE register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_enableInterrupt(uint32_t baseAddress, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_A_SPI_RECEIVE_INTERRUPT + | EUSCI_A_SPI_TRANSMIT_INTERRUPT))); + + EUSCI_A_CMSIS(baseAddress)->IE |= mask; +} + +//***************************************************************************** +// +//! \brief Disables individual SPI interrupt sources. +//! +//! Disables the indicated SPI interrupt sources. Only the sources that are +//! enabled can be reflected to the processor interrupt; disabled sources have +//! no effect on the processor. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! \param mask is the bit mask of the interrupt sources to be disabled. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_A_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_A_SPI_RECEIVE_INTERRUPT +//! +//! Modified bits of \b UCAxIE register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_disableInterrupt(uint32_t baseAddress, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_A_SPI_RECEIVE_INTERRUPT + | EUSCI_A_SPI_TRANSMIT_INTERRUPT))); + + EUSCI_A_CMSIS(baseAddress)->IE &= ~mask; +} + +//***************************************************************************** +// +//! \brief Gets the current SPI interrupt status. +//! +//! This returns the interrupt status for the SPI module based on which flag is +//! passed. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! \param mask is the masked interrupt flag status to be returned. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_A_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_A_SPI_RECEIVE_INTERRUPT +//! +//! \return Logical OR of any of the following: +//! - \b EUSCI_A_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_A_SPI_RECEIVE_INTERRUPT +//! \n indicating the status of the masked interrupts +// +//***************************************************************************** +uint8_t EUSCI_A_SPI_getInterruptStatus(uint32_t baseAddress, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_A_SPI_RECEIVE_INTERRUPT + | EUSCI_A_SPI_TRANSMIT_INTERRUPT))); + + return EUSCI_A_CMSIS(baseAddress)->IFG & mask; +} + +//***************************************************************************** +// +//! \brief Clears the selected SPI interrupt status flag. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! \param mask is the masked interrupt flag to be cleared. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_A_SPI_TRANSMIT_INTERRUPT +//! - \b EUSCI_A_SPI_RECEIVE_INTERRUPT +//! +//! Modified bits of \b UCAxIFG register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_clearInterruptFlag(uint32_t baseAddress, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_A_SPI_RECEIVE_INTERRUPT + | EUSCI_A_SPI_TRANSMIT_INTERRUPT))); + + EUSCI_A_CMSIS(baseAddress)->IFG &= ~mask; +} + +//***************************************************************************** +// +//! \brief Enables the SPI block. +//! +//! This will enable operation of the SPI block. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! +//! Modified bits are \b UCSWRST of \b UCAxCTLW0 register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_enable(uint32_t baseAddress) +{ + //Reset the UCSWRST bit to enable the USCI Module + BITBAND_PERI(EUSCI_A_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 0; +} + +//***************************************************************************** +// +//! \brief Disables the SPI block. +//! +//! This will disable operation of the SPI block. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! +//! Modified bits are \b UCSWRST of \b UCAxCTLW0 register. +//! +//! \return None +// +//***************************************************************************** +void EUSCI_A_SPI_disable(uint32_t baseAddress) +{ + //Set the UCSWRST bit to disable the USCI Module + BITBAND_PERI(EUSCI_A_CMSIS(baseAddress)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; +} + +//***************************************************************************** +// +//! \brief Returns the address of the RX Buffer of the SPI for the DMA module. +//! +//! Returns the address of the SPI RX Buffer. This can be used in conjunction +//! with the DMA to store the received data directly to memory. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! +//! \return the address of the RX Buffer +// +//***************************************************************************** +uint32_t EUSCI_A_SPI_getReceiveBufferAddressForDMA(uint32_t baseAddress) +{ + return (uint32_t)&EUSCI_A_CMSIS(baseAddress)->RXBUF; +} + +//***************************************************************************** +// +//! \brief Returns the address of the TX Buffer of the SPI for the DMA module. +//! +//! Returns the address of the SPI TX Buffer. This can be used in conjunction +//! with the DMA to obtain transmitted data directly from memory. +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! +//! \return the address of the TX Buffer +// +//***************************************************************************** +uint32_t EUSCI_A_SPI_getTransmitBufferAddressForDMA(uint32_t baseAddress) +{ + return (uint32_t)&EUSCI_A_CMSIS(baseAddress)->TXBUF; +} + +//***************************************************************************** +// +//! \brief Indicates whether or not the SPI bus is busy. +//! +//! This function returns an indication of whether or not the SPI bus is +//! busy.This function checks the status of the bus via UCBBUSY bit +//! +//! \param baseAddress is the base address of the EUSCI_A_SPI module. +//! +//! \return true if busy, false otherwise +//***************************************************************************** +bool EUSCI_A_SPI_isBusy(uint32_t baseAddress) +{ + //Return the bus busy status. + return BITBAND_PERI(EUSCI_A_CMSIS(baseAddress)->STATW, EUSCI_B_STATW_BBUSY_OFS); +} diff --git a/example/rt_msp432/MSP432P4xx/spi.h b/example/rt_msp432/MSP432P4xx/spi.h new file mode 100644 index 0000000..eb0fa7b --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/spi.h @@ -0,0 +1,822 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef SPI_H_ +#define SPI_H_ + +//***************************************************************************** +// +//! \addtogroup spi_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include "eusci.h" + +/* Configuration Defines */ +#define EUSCI_SPI_CLOCKSOURCE_ACLK EUSCI_B_CTLW0_SSEL__ACLK +#define EUSCI_SPI_CLOCKSOURCE_SMCLK EUSCI_B_CTLW0_SSEL__SMCLK + +#define EUSCI_SPI_MSB_FIRST EUSCI_B_CTLW0_MSB +#define EUSCI_SPI_LSB_FIRST 0x00 + +#define EUSCI_SPI_BUSY EUSCI_A_STATW_BUSY +#define EUSCI_SPI_NOT_BUSY 0x00 + +#define EUSCI_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT 0x00 +#define EUSCI_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT EUSCI_B_CTLW0_CKPH + +#define EUSCI_SPI_3PIN EUSCI_B_CTLW0_MODE_0 +#define EUSCI_SPI_4PIN_UCxSTE_ACTIVE_HIGH EUSCI_B_CTLW0_MODE_1 +#define EUSCI_SPI_4PIN_UCxSTE_ACTIVE_LOW EUSCI_B_CTLW0_MODE_2 + +#define EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_HIGH EUSCI_B_CTLW0_CKPL +#define EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_LOW 0x00 + +#define EUSCI_SPI_TRANSMIT_INTERRUPT EUSCI_B__TXIE +#define EUSCI_SPI_RECEIVE_INTERRUPT EUSCI_B__RXIE + +#define EUSCI_SPI_ENABLE_SIGNAL_FOR_4WIRE_SLAVE EUSCI_B_CTLW0_STEM +#define EUSCI_SPI_PREVENT_CONFLICTS_WITH_OTHER_MASTERS 0x00 + +//***************************************************************************** +// +//! ypedef eUSCI_SPI_MasterConfig +//! \brief Type definition for \link _eUSCI_SPI_MasterConfig \endlink structure +//! +//! \struct _eUSCI_SPI_MasterConfig +//! \brief Configuration structure for master mode in the \b SPI module. See +//! \link SPI_initMaster \endlink for parameter documentation. +// +//***************************************************************************** +typedef struct _eUSCI_SPI_MasterConfig +{ + uint_fast8_t selectClockSource; + uint32_t clockSourceFrequency; + uint32_t desiredSpiClock; + uint_fast16_t msbFirst; + uint_fast16_t clockPhase; + uint_fast16_t clockPolarity; + uint_fast16_t spiMode; +} eUSCI_SPI_MasterConfig; + +//***************************************************************************** +// +//! ypedef eUSCI_SPI_SlaveConfig +//! \brief Type definition for \link _eUSCI_SPI_SlaveConfig \endlink structure +//! +//! \struct _eUSCI_SPI_SlaveConfig +//! \brief Configuration structure for slave mode in the \b SPI module. See +//! \link SPI_initSlave \endlink for parameter documentation. +// +//***************************************************************************** +typedef struct _eUSCI_SPI_SlaveConfig +{ + uint_fast16_t msbFirst; + uint_fast16_t clockPhase; + uint_fast16_t clockPolarity; + uint_fast16_t spiMode; +} eUSCI_SPI_SlaveConfig; + +//***************************************************************************** +// +//! Initializes the SPI Master block. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! \param config Configuration structure for SPI master mode +//! +//!
+//! Configuration options for \link eUSCI_SPI_MasterConfig \endlink structure. +//!
+//! +//! \param selectClockSource selects clock source. Valid values are +//! - \b EUSCI_SPI_CLOCKSOURCE_ACLK +//! - \b EUSCI_SPI_CLOCKSOURCE_SMCLK +//! \param clockSourceFrequency is the frequency of the selected clock source +//! \param desiredSpiClock is the desired clock rate for SPI communication +//! \param msbFirst controls the direction of the receive and transmit shift +//! register. Valid values are +//! - \b EUSCI_SPI_MSB_FIRST +//! - \b EUSCI_SPI_LSB_FIRST [Default Value] +//! \param clockPhase is clock phase select. +//! Valid values are +//! - \b EUSCI_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT +//! [Default Value] +//! - \b EUSCI_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT +//! \param clockPolarity is clock polarity select. +//! Valid values are +//! - \b EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_HIGH +//! - \b EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default Value] +//! \param spiMode is SPI mode select. +//! Valid values are +//! - \b EUSCI_SPI_3PIN [Default Value] +//! - \b EUSCI_SPI_4PIN_UCxSTE_ACTIVE_HIGH +//! - \b EUSCI_SPI_4PIN_UCxSTE_ACTIVE_LOW +//! Upon successful initialization of the SPI master block, this function +//! will have set the bus speed for the master, but the SPI Master block +//! still remains disabled and must be enabled with SPI_enableModule() +//! +//! Modified bits are \b UCCKPH, \b UCCKPL, \b UC7BIT, \b UCMSB,\b UCSSELx, +//! \b UCSWRST bits of \b UCAxCTLW0 register +//! +//! \return true +// +//***************************************************************************** +extern bool SPI_initMaster(uint32_t moduleInstance, + const eUSCI_SPI_MasterConfig *config); + +//***************************************************************************** +// +//! Selects 4Pin Functionality +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! \param select4PinFunctionality selects Clock source. Valid values are +//! - \b EUSCI_SPI_PREVENT_CONFLICTS_WITH_OTHER_MASTERS +//! - \b EUSCI_SPI_ENABLE_SIGNAL_FOR_4WIRE_SLAVE +//! This function should be invoked only in 4-wire mode. Invoking this function +//! has no effect in 3-wire mode. +//! +//! Modified bits are \b UCSTEM bit of \b UCAxCTLW0 register +//! +//! \return true +// +//***************************************************************************** +extern void SPI_selectFourPinFunctionality(uint32_t moduleInstance, + uint_fast8_t select4PinFunctionality); + +//***************************************************************************** +// +//! Initializes the SPI Master clock.At the end of this function call, SPI +//! module is left enabled. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! \param clockSourceFrequency is the frequency of the selected clock source +//! \param desiredSpiClock is the desired clock rate for SPI communication. +//! +//! Modified bits are \b UCSWRST bit of \b UCAxCTLW0 register and +//! \b UCAxBRW register +//! +//! \return None +// +//***************************************************************************** +extern void SPI_changeMasterClock(uint32_t moduleInstance, + uint32_t clockSourceFrequency, uint32_t desiredSpiClock); + +//***************************************************************************** +// +//! Initializes the SPI Slave block. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! \param config Configuration structure for SPI slave mode +//! +//!
+//! Configuration options for \link eUSCI_SPI_SlaveConfig \endlink structure. +//!
+//! +//! \param msbFirst controls the direction of the receive and transmit shift +//! register. Valid values are +//! - \b EUSCI_SPI_MSB_FIRST +//! - \b EUSCI_SPI_LSB_FIRST [Default Value] +//! \param clockPhase is clock phase select. +//! Valid values are +//! - \b EUSCI_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT +//! [Default Value] +//! - \b EUSCI_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT +//! \param clockPolarity is clock polarity select. +//! Valid values are +//! - \b EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_HIGH +//! - \b EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default Value] +//! \param spiMode is SPI mode select. +//! Valid values are +//! - \b EUSCI_SPI_3PIN [Default Value] +//! - \b EUSCI_SPI_4PIN_UCxSTE_ACTIVE_HIGH +//! - \b EUSCI_SPI_4PIN_UCxSTE_ACTIVE_LOW +//! Upon successful initialization of the SPI slave block, this function +//! will have initialized the slave block, but the SPI Slave block +//! still remains disabled and must be enabled with SPI_enableModule() +//! +//! Modified bits are \b UCMSB, \b UC7BIT, \b UCMST, \b UCCKPL, \b UCCKPH, +//! \b UCMODE, \b UCSWRST bits of \b UCAxCTLW0 +//! +//! \return true +//***************************************************************************** +extern bool SPI_initSlave(uint32_t moduleInstance, + const eUSCI_SPI_SlaveConfig *config); + +//***************************************************************************** +// +//! Changes the SPI clock phase and polarity.At the end of this function call, +//! SPI module is left enabled. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! \param clockPhase is clock phase select. +//! Valid values are: +//! - \b EUSCI_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT +//! [Default Value] +//! - \b EUSCI_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT +//! \param clockPolarity is clock polarity select. +//! Valid values are: +//! - \b EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_HIGH +//! - \b EUSCI_SPI_CLOCKPOLARITY_INACTIVITY_LOW [Default Value] +//! +//! Modified bits are \b UCSWRST, \b UCCKPH, \b UCCKPL, \b UCSWRST bits of +//! \b UCAxCTLW0 +//! +//! \return None +// +//***************************************************************************** +extern void SPI_changeClockPhasePolarity(uint32_t moduleInstance, + uint_fast16_t clockPhase, uint_fast16_t clockPolarity); + +//***************************************************************************** +// +//! Transmits a byte from the SPI Module. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! \param transmitData data to be transmitted from the SPI module +//! +//! This function will place the supplied data into SPI transmit data register +//! to start transmission +//! +//! Modified register is \b UCAxTXBUF +//! +//! \return None. +// +//***************************************************************************** +extern void SPI_transmitData(uint32_t moduleInstance, + uint_fast8_t transmitData); + +//***************************************************************************** +// +//! Receives a byte that has been sent to the SPI Module. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! +//! This function reads a byte of data from the SPI receive data Register. +//! +//! \return Returns the byte received from by the SPI module, cast as an +//! uint8_t. +// +//***************************************************************************** +extern uint8_t SPI_receiveData(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Enables the SPI block. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! +//! This will enable operation of the SPI block. +//! Modified bits are \b UCSWRST bit of \b UCAxCTLW0 register. +//! +//! \return None. +// +//***************************************************************************** +extern void SPI_enableModule(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Disables the SPI block. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! +//! This will disable operation of the SPI block. +//! +//! Modified bits are \b UCSWRST bit of \b UCAxCTLW0 register. +//! +//! \return None. +// +//***************************************************************************** +extern void SPI_disableModule(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Returns the address of the RX Buffer of the SPI for the DMA module. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! +//! Returns the address of the SPI RX Buffer. This can be used in conjunction +//! with the DMA to store the received data directly to memory. +//! +//! \return NONE +// +//***************************************************************************** +extern uint32_t SPI_getReceiveBufferAddressForDMA(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Returns the address of the TX Buffer of the SPI for the DMA module. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! +//! Returns the address of the SPI TX Buffer. This can be used in conjunction +//! with the DMA to obtain transmitted data directly from memory. +//! +//! \return NONE +// +//***************************************************************************** +extern uint32_t SPI_getTransmitBufferAddressForDMA(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Indicates whether or not the SPI bus is busy. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! +//! This function returns an indication of whether or not the SPI bus is +//! busy.This function checks the status of the bus via UCBBUSY bit +//! +//! \return EUSCI_SPI_BUSY if the SPI module transmitting or receiving +//! is busy; otherwise, returns EUSCI_SPI_NOT_BUSY. +// +//***************************************************************************** +extern uint_fast8_t SPI_isBusy(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Enables individual SPI interrupt sources. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! \param mask is the bit mask of the interrupt sources to be enabled. +//! +//! Enables the indicated SPI interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. +//! +//! The mask parameter is the logical OR of any of the following: +//! - \b EUSCI_SPI_RECEIVE_INTERRUPT Receive interrupt +//! - \b EUSCI_SPI_TRANSMIT_INTERRUPT Transmit interrupt +//! +//! Modified registers are \b UCAxIFG and \b UCAxIE +//! +//! \return None. +// +//***************************************************************************** +extern void SPI_enableInterrupt(uint32_t moduleInstance, uint_fast8_t mask); + +//***************************************************************************** +// +//! Disables individual SPI interrupt sources. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! \param mask is the bit mask of the interrupt sources to be +//! disabled. +//! +//! Disables the indicated SPI interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. +//! +//! The mask parameter is the logical OR of any of the following: +//! - \b EUSCI_SPI_RECEIVE_INTERRUPT Receive interrupt +//! - \b EUSCI_SPI_TRANSMIT_INTERRUPT Transmit interrupt +//! +//! Modified register is \b UCAxIE +//! +//! \return None. +// +//***************************************************************************** +extern void SPI_disableInterrupt(uint32_t moduleInstance, uint_fast8_t mask); + +//***************************************************************************** +// +//! Gets the current SPI interrupt status. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! \param mask Mask of interrupt to filter. This can include: +//! - \b EUSCI_SPI_RECEIVE_INTERRUPT -Receive interrupt +//! - \b EUSCI_SPI_TRANSMIT_INTERRUPT - Transmit interrupt +//! +//! Modified registers are \b UCAxIFG. +//! +//! \return The current interrupt status as the mask of the set flags +//! Mask parameter can be either any of the following selection: +//! - \b EUSCI_SPI_RECEIVE_INTERRUPT -Receive interrupt +//! - \b EUSCI_SPI_TRANSMIT_INTERRUPT - Transmit interrupt +// +//***************************************************************************** +extern uint_fast8_t SPI_getInterruptStatus(uint32_t moduleInstance, + uint16_t mask); + +//***************************************************************************** +// +//! Gets the current SPI interrupt status masked with the enabled interrupts. +//! This function is useful to call in ISRs to get a list of pending +//! interrupts that are actually enabled and could have caused +//! the ISR. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! Modified registers are \b UCAxIFG. +//! +//! \return The current interrupt status as the mask of the set flags +//! Mask parameter can be either any of the following selection: +//! - \b EUSCI_SPI_RECEIVE_INTERRUPT -Receive interrupt +//! - \b EUSCI_SPI_TRANSMIT_INTERRUPT - Transmit interrupt +// +//***************************************************************************** +extern uint_fast8_t SPI_getEnabledInterruptStatus(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Clears the selected SPI interrupt status flag. +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! \param mask is the masked interrupt flag to be cleared. +//! +//! The mask parameter is the logical OR of any of the following: +//! - \b EUSCI_SPI_RECEIVE_INTERRUPT -Receive interrupt +//! - \b EUSCI_SPI_TRANSMIT_INTERRUPT - Transmit interrupt +//! Modified registers are \b UCAxIFG. +//! +//! \return None +// +//***************************************************************************** +extern void SPI_clearInterruptFlag(uint32_t moduleInstance, uint_fast8_t mask); + +//***************************************************************************** +// +//! Registers an interrupt handler for the timer capture compare interrupt. +//! +//! \param moduleInstance is the instance of the eUSCI (SPI) module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! It is important to note that for eUSCI modules, only "B" modules such as +//! EUSCI_B0 can be used. "A" modules such as EUSCI_A0 do not support the +//! I2C mode. +//! +//! \param intHandler is a pointer to the function to be called when the +//! timer capture compare interrupt occurs. +//! +//! This function registers the handler to be called when a timer +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific SPI interrupts must be enabled +//! via SPI_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via SPI_clearInterruptFlag(). +//! +//! \return None. +// +//***************************************************************************** +extern void SPI_registerInterrupt(uint32_t moduleInstance, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the timer +//! +//! \param moduleInstance is the instance of the eUSCI A/B module. Valid +//! parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! - \b EUSCI_B0_BASE +//! - \b EUSCI_B1_BASE +//! - \b EUSCI_B2_BASE +//! - \b EUSCI_B3_BASE +//! +//! This function unregisters the handler to be called when timer +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void SPI_unregisterInterrupt(uint32_t moduleInstance); + +/* Backwards Compatibility Layer */ +#define EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT 0x00 +#define EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT UCCKPH + +#define EUSCI_B_SPI_MSB_FIRST UCMSB +#define EUSCI_B_SPI_LSB_FIRST 0x00 + +#define EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH UCCKPL +#define EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW 0x00 + +#define EUSCI_B_SPI_CLOCKSOURCE_ACLK UCSSEL__ACLK +#define EUSCI_B_SPI_CLOCKSOURCE_SMCLK UCSSEL__SMCLK + +#define EUSCI_B_SPI_3PIN UCMODE_0 +#define EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_HIGH UCMODE_1 +#define EUSCI_B_SPI_4PIN_UCxSTE_ACTIVE_LOW UCMODE_2 + +#define EUSCI_B_SPI_PREVENT_CONFLICTS_WITH_OTHER_MASTERS 0x00 +#define EUSCI_B_SPI_ENABLE_SIGNAL_FOR_4WIRE_SLAVE UCSTEM + +#define EUSCI_B_SPI_TRANSMIT_INTERRUPT UCTXIE +#define EUSCI_B_SPI_RECEIVE_INTERRUPT UCRXIE + +#define EUSCI_B_SPI_BUSY UCBUSY +#define EUSCI_B_SPI_NOT_BUSY 0x00 + +#define EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT 0x00 +#define EUSCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT UCCKPH + +#define EUSCI_A_SPI_MSB_FIRST UCMSB +#define EUSCI_A_SPI_LSB_FIRST 0x00 + +#define EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_HIGH UCCKPL +#define EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW 0x00 + +#define EUSCI_A_SPI_CLOCKSOURCE_ACLK UCSSEL__ACLK +#define EUSCI_A_SPI_CLOCKSOURCE_SMCLK UCSSEL__SMCLK + +#define EUSCI_A_SPI_3PIN UCMODE_0 +#define EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_HIGH UCMODE_1 +#define EUSCI_A_SPI_4PIN_UCxSTE_ACTIVE_LOW UCMODE_2 + +#define EUSCI_A_SPI_PREVENT_CONFLICTS_WITH_OTHER_MASTERS 0x00 +#define EUSCI_A_SPI_ENABLE_SIGNAL_FOR_4WIRE_SLAVE UCSTEM + +#define EUSCI_A_SPI_TRANSMIT_INTERRUPT UCTXIE +#define EUSCI_A_SPI_RECEIVE_INTERRUPT UCRXIE + +#define EUSCI_A_SPI_BUSY UCBUSY +#define EUSCI_A_SPI_NOT_BUSY 0x00 + +extern void EUSCI_A_SPI_select4PinFunctionality(uint32_t baseAddress, + uint8_t select4PinFunctionality); +extern void EUSCI_A_SPI_masterChangeClock(uint32_t baseAddress, + uint32_t clockSourceFrequency, uint32_t desiredSpiClock); +extern bool EUSCI_A_SPI_slaveInit(uint32_t baseAddress, uint16_t msbFirst, + uint16_t clockPhase, uint16_t clockPolarity, uint16_t spiMode); +extern void EUSCI_A_SPI_changeClockPhasePolarity(uint32_t baseAddress, + uint16_t clockPhase, uint16_t clockPolarity); +extern void EUSCI_A_SPI_transmitData(uint32_t baseAddress, + uint8_t transmitData); +extern uint8_t EUSCI_A_SPI_receiveData(uint32_t baseAddress); +extern void EUSCI_A_SPI_enableInterrupt(uint32_t baseAddress, uint8_t mask); +extern void EUSCI_A_SPI_disableInterrupt(uint32_t baseAddress, uint8_t mask); +extern uint8_t EUSCI_A_SPI_getInterruptStatus(uint32_t baseAddress, + uint8_t mask); +extern void EUSCI_A_SPI_clearInterruptFlag(uint32_t baseAddress, uint8_t mask); +extern void EUSCI_A_SPI_enable(uint32_t baseAddress); +extern void EUSCI_A_SPI_disable(uint32_t baseAddress); +extern uint32_t EUSCI_A_SPI_getReceiveBufferAddressForDMA(uint32_t baseAddress); +extern uint32_t EUSCI_A_SPI_getTransmitBufferAddressForDMA( + uint32_t baseAddress); +extern bool EUSCI_A_SPI_isBusy(uint32_t baseAddress); +extern void EUSCI_B_SPI_select4PinFunctionality(uint32_t baseAddress, + uint8_t select4PinFunctionality); +extern void EUSCI_B_SPI_masterChangeClock(uint32_t baseAddress, + uint32_t clockSourceFrequency, uint32_t desiredSpiClock); +extern bool EUSCI_B_SPI_slaveInit(uint32_t baseAddress, uint16_t msbFirst, + uint16_t clockPhase, uint16_t clockPolarity, uint16_t spiMode); +extern void EUSCI_B_SPI_changeClockPhasePolarity(uint32_t baseAddress, + uint16_t clockPhase, uint16_t clockPolarity); +extern void EUSCI_B_SPI_transmitData(uint32_t baseAddress, + uint8_t transmitData); +extern uint8_t EUSCI_B_SPI_receiveData(uint32_t baseAddress); +extern void EUSCI_B_SPI_enableInterrupt(uint32_t baseAddress, uint8_t mask); +extern void EUSCI_B_SPI_disableInterrupt(uint32_t baseAddress, uint8_t mask); +extern uint8_t EUSCI_B_SPI_getInterruptStatus(uint32_t baseAddress, + uint8_t mask); +extern void EUSCI_B_SPI_clearInterruptFlag(uint32_t baseAddress, uint8_t mask); +extern void EUSCI_B_SPI_enable(uint32_t baseAddress); +extern void EUSCI_B_SPI_disable(uint32_t baseAddress); +extern uint32_t EUSCI_B_SPI_getReceiveBufferAddressForDMA(uint32_t baseAddress); +extern uint32_t EUSCI_B_SPI_getTransmitBufferAddressForDMA( + uint32_t baseAddress); +extern bool EUSCI_B_SPI_isBusy(uint32_t baseAddress); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif /* SPI_H_ */ + diff --git a/example/rt_msp432/MSP432P4xx/sysctl.c b/example/rt_msp432/MSP432P4xx/sysctl.c new file mode 100644 index 0000000..5ffe6b8 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/sysctl.c @@ -0,0 +1,280 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include +#include + +/* DriverLib Includes */ +#include +#include + +#ifdef DEBUG + +static bool SysCtlSRAMBankValid(uint8_t sramBank) +{ + return( + sramBank == SYSCTL_SRAM_BANK7 || + sramBank == SYSCTL_SRAM_BANK6 || + sramBank == SYSCTL_SRAM_BANK5 || + sramBank == SYSCTL_SRAM_BANK4 || + sramBank == SYSCTL_SRAM_BANK3 || + sramBank == SYSCTL_SRAM_BANK2 || + sramBank == SYSCTL_SRAM_BANK1 + ); +} + +static bool SysCtlSRAMBankValidRet(uint8_t sramBank) +{ + sramBank &= ~(SYSCTL_SRAM_BANK7 & SYSCTL_SRAM_BANK6 & + SYSCTL_SRAM_BANK5 & SYSCTL_SRAM_BANK4 & + SYSCTL_SRAM_BANK3 & SYSCTL_SRAM_BANK2 & + SYSCTL_SRAM_BANK1); + + return (sramBank == 0); +} + +static bool SysCtlPeripheralIsValid (uint16_t hwPeripheral) +{ + hwPeripheral &= ~(SYSCTL_PERIPH_DMA & SYSCTL_PERIPH_WDT & + SYSCTL_PERIPH_ADC & SYSCTL_PERIPH_EUSCIB3 & + SYSCTL_PERIPH_EUSCIB2 & SYSCTL_PERIPH_EUSCIB1 & + SYSCTL_PERIPH_EUSCIB0 & SYSCTL_PERIPH_EUSCIA3 & + SYSCTL_PERIPH_EUSCIA2 & SYSCTL_PERIPH_EUSCIA1 & + SYSCTL_PERIPH_EUSCIA0 & SYSCTL_PERIPH_TIMER32_0_MODULE & + SYSCTL_PERIPH_TIMER16_3 & SYSCTL_PERIPH_TIMER16_2 & + SYSCTL_PERIPH_TIMER16_2 & SYSCTL_PERIPH_TIMER16_1 & + SYSCTL_PERIPH_TIMER16_0); + + return (hwPeripheral == 0); +} +#endif + +void SysCtl_getTLVInfo(uint_fast8_t tag, uint_fast8_t instance, + uint_fast8_t *length, uint32_t **data_address) +{ + /* TLV Structure Start Address */ + uint32_t *TLV_address = (uint32_t *) TLV_START; + + while (((*TLV_address != tag)) // check for tag and instance + && (*TLV_address != TLV_TAGEND)) // do range check first + { + if (*TLV_address == tag) + { + if(instance == 0) + { + break; + } + + /* Repeat until requested instance is reached */ + instance--; + } + + TLV_address += (*(TLV_address + 1)) + 2; + } + + /* Check if Tag match happened... */ + if (*TLV_address == tag) + { + /* Return length = Address + 1 */ + *length = (*(TLV_address + 1))*4; + /* Return address of first data/value info = Address + 2 */ + *data_address = (uint32_t *) (TLV_address + 2); + } + // If there was no tag match and the end of TLV structure was reached.. + else + { + // Return 0 for TAG not found + *length = 0; + // Return 0 for TAG not found + *data_address = 0; + } +} + +uint_least32_t SysCtl_getSRAMSize(void) +{ + return SYSCTL->SRAM_SIZE; +} + +uint_least32_t SysCtl_getFlashSize(void) +{ + return SYSCTL->FLASH_SIZE; +} + +void SysCtl_disableNMISource(uint_fast8_t flags) +{ + SYSCTL->NMI_CTLSTAT &= ~(flags); +} + +void SysCtl_enableNMISource(uint_fast8_t flags) +{ + SYSCTL->NMI_CTLSTAT |= flags; +} + +uint_fast8_t SysCtl_getNMISourceStatus(void) +{ + return SYSCTL->NMI_CTLSTAT; +} + +void SysCtl_enableSRAMBank(uint_fast8_t sramBank) +{ + ASSERT(SysCtlSRAMBankValid(sramBank)); + + /* Waiting for SRAM Ready Bit to be set */ + while (!(SYSCTL->SRAM_BANKEN & SYSCTL_SRAM_BANKEN_SRAM_RDY)) + ; + + SYSCTL->SRAM_BANKEN = (sramBank | SYSCTL_SRAM_BANKEN_BNK0_EN); +} + +void SysCtl_disableSRAMBank(uint_fast8_t sramBank) +{ + ASSERT(SysCtlSRAMBankValid(sramBank)); + + /* Waiting for SRAM Ready Bit to be set */ + while (!(SYSCTL->SRAM_BANKEN & SYSCTL_SRAM_BANKEN_SRAM_RDY)) + ; + + switch (sramBank) + { + case SYSCTL_SRAM_BANK7: + sramBank = SYSCTL_SRAM_BANK6 + SYSCTL_SRAM_BANK5 + SYSCTL_SRAM_BANK4 + + SYSCTL_SRAM_BANK3 + SYSCTL_SRAM_BANK2 + + SYSCTL_SRAM_BANK1; + break; + case SYSCTL_SRAM_BANK6: + sramBank = SYSCTL_SRAM_BANK5 + SYSCTL_SRAM_BANK4 + + SYSCTL_SRAM_BANK3 + SYSCTL_SRAM_BANK2 + + SYSCTL_SRAM_BANK1; + break; + case SYSCTL_SRAM_BANK5: + sramBank = SYSCTL_SRAM_BANK4 + SYSCTL_SRAM_BANK3 + + SYSCTL_SRAM_BANK2 + SYSCTL_SRAM_BANK1; + break; + case SYSCTL_SRAM_BANK4: + sramBank = SYSCTL_SRAM_BANK3 + SYSCTL_SRAM_BANK2 + + SYSCTL_SRAM_BANK1; + break; + case SYSCTL_SRAM_BANK3: + sramBank = SYSCTL_SRAM_BANK2 + SYSCTL_SRAM_BANK1; + break; + case SYSCTL_SRAM_BANK2: + sramBank = SYSCTL_SRAM_BANK1; + break; + case SYSCTL_SRAM_BANK1: + sramBank = 0; + break; + default: + return; + } + + SYSCTL->SRAM_BANKEN = (sramBank | SYSCTL_SRAM_BANKEN_BNK0_EN); +} + +void SysCtl_enableSRAMBankRetention(uint_fast8_t sramBank) +{ + ASSERT(SysCtlSRAMBankValidRet(sramBank)); + + /* Waiting for SRAM Ready Bit to be set */ + while (!(SYSCTL->SRAM_BANKRET & SYSCTL_SRAM_BANKRET_SRAM_RDY)) + ; + + SYSCTL->SRAM_BANKRET |= sramBank; +} + +void SysCtl_disableSRAMBankRetention(uint_fast8_t sramBank) +{ + ASSERT(SysCtlSRAMBankValidRet(sramBank)); + + /* Waiting for SRAM Ready Bit to be set */ + while (!(SYSCTL->SRAM_BANKRET & SYSCTL_SRAM_BANKRET_SRAM_RDY)) + ; + + SYSCTL->SRAM_BANKRET &= ~sramBank; +} + +void SysCtl_rebootDevice(void) +{ + SYSCTL->REBOOT_CTL = (SYSCTL_REBOOT_CTL_REBOOT | SYSCTL_REBOOT_KEY); +} + +void SysCtl_enablePeripheralAtCPUHalt(uint_fast16_t devices) +{ + ASSERT(SysCtlPeripheralIsValid(devices)); + SYSCTL->PERIHALT_CTL &= ~devices; +} + +void SysCtl_disablePeripheralAtCPUHalt(uint_fast16_t devices) +{ + ASSERT(SysCtlPeripheralIsValid(devices)); + SYSCTL->PERIHALT_CTL |= devices; +} + +void SysCtl_setWDTTimeoutResetType(uint_fast8_t resetType) +{ + if (resetType) + SYSCTL->WDTRESET_CTL |= + SYSCTL_WDTRESET_CTL_TIMEOUT; + else + SYSCTL->WDTRESET_CTL &= ~SYSCTL_WDTRESET_CTL_TIMEOUT; +} + +void SysCtl_setWDTPasswordViolationResetType(uint_fast8_t resetType) +{ + ASSERT(resetType <= SYSCTL_HARD_RESET); + + if (resetType) + SYSCTL->WDTRESET_CTL |= + SYSCTL_WDTRESET_CTL_VIOLATION; + else + SYSCTL->WDTRESET_CTL &= ~SYSCTL_WDTRESET_CTL_VIOLATION; +} + +void SysCtl_enableGlitchFilter(void) +{ + SYSCTL->DIO_GLTFLT_CTL |= SYSCTL_DIO_GLTFLT_CTL_GLTCH_EN; +} + +void SysCtl_disableGlitchFilter(void) +{ + SYSCTL->DIO_GLTFLT_CTL &= ~SYSCTL_DIO_GLTFLT_CTL_GLTCH_EN; +} + +uint_fast16_t SysCtl_getTempCalibrationConstant(uint32_t refVoltage, + uint32_t temperature) +{ + return HWREG16(TLV_BASE + refVoltage + temperature); +} diff --git a/example/rt_msp432/MSP432P4xx/sysctl.h b/example/rt_msp432/MSP432P4xx/sysctl.h new file mode 100644 index 0000000..b08d62a --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/sysctl.h @@ -0,0 +1,544 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __SYSCTL_H__ +#define __SYSCTL_H__ + +//***************************************************************************** +// +//! \addtogroup sysctl_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +//***************************************************************************** +// +// Control specific variables +// +//***************************************************************************** +#define SYSCTL_SRAM_BANK7 SYSCTL_SRAM_BANKEN_BNK7_EN +#define SYSCTL_SRAM_BANK6 SYSCTL_SRAM_BANKEN_BNK6_EN +#define SYSCTL_SRAM_BANK5 SYSCTL_SRAM_BANKEN_BNK5_EN +#define SYSCTL_SRAM_BANK4 SYSCTL_SRAM_BANKEN_BNK4_EN +#define SYSCTL_SRAM_BANK3 SYSCTL_SRAM_BANKEN_BNK3_EN +#define SYSCTL_SRAM_BANK2 SYSCTL_SRAM_BANKEN_BNK2_EN +#define SYSCTL_SRAM_BANK1 SYSCTL_SRAM_BANKEN_BNK1_EN + +#define SYSCTL_HARD_RESET 1 +#define SYSCTL_SOFT_RESET 0 + +#define SYSCTL_PERIPH_DMA SYSCTL_PERIHALT_CTL_HALT_DMA +#define SYSCTL_PERIPH_WDT SYSCTL_PERIHALT_CTL_HALT_WDT +#define SYSCTL_PERIPH_ADC SYSCTL_PERIHALT_CTL_HALT_ADC +#define SYSCTL_PERIPH_EUSCIB3 SYSCTL_PERIHALT_CTL_HALT_EUB3 +#define SYSCTL_PERIPH_EUSCIB2 SYSCTL_PERIHALT_CTL_HALT_EUB2 +#define SYSCTL_PERIPH_EUSCIB1 SYSCTL_PERIHALT_CTL_HALT_EUB1 +#define SYSCTL_PERIPH_EUSCIB0 SYSCTL_PERIHALT_CTL_HALT_EUB0 +#define SYSCTL_PERIPH_EUSCIA3 SYSCTL_PERIHALT_CTL_HALT_EUA3 +#define SYSCTL_PERIPH_EUSCIA2 SYSCTL_PERIHALT_CTL_HALT_EUA2 +#define SYSCTL_PERIPH_EUSCIA1 SYSCTL_PERIHALT_CTL_HALT_EUA1 +#define SYSCTL_PERIPH_EUSCIA0 SYSCTL_PERIHALT_CTL_HALT_EUA0 +#define SYSCTL_PERIPH_TIMER32_0_MODULE SYSCTL_PERIHALT_CTL_HALT_T32_0 +#define SYSCTL_PERIPH_TIMER16_3 SYSCTL_PERIHALT_CTL_HALT_T16_3 +#define SYSCTL_PERIPH_TIMER16_2 SYSCTL_PERIHALT_CTL_HALT_T16_2 +#define SYSCTL_PERIPH_TIMER16_1 SYSCTL_PERIHALT_CTL_HALT_T16_1 +#define SYSCTL_PERIPH_TIMER16_0 SYSCTL_PERIHALT_CTL_HALT_T16_0 + +#define SYSCTL_NMIPIN_SRC SYSCTL_NMI_CTLSTAT_PIN_SRC +#define SYSCTL_PCM_SRC SYSCTL_NMI_CTLSTAT_PCM_SRC +#define SYSCTL_PSS_SRC SYSCTL_NMI_CTLSTAT_PSS_SRC +#define SYSCTL_CS_SRC SYSCTL_NMI_CTLSTAT_CS_SRC + +#define SYSCTL_REBOOT_KEY 0x6900 + +#define SYSCTL_1_2V_REF (uint32_t)&TLV->ADC14_REF1P2V_TS30C - (uint32_t)TLV_BASE +#define SYSCTL_1_45V_REF (uint32_t)&TLV->ADC14_REF1P45V_TS30C - (uint32_t)TLV_BASE +#define SYSCTL_2_5V_REF (uint32_t)&TLV->ADC14_REF2P5V_TS30C - (uint32_t)TLV_BASE + +#define SYSCTL_85_DEGREES_C 4 +#define SYSCTL_30_DEGREES_C 0 + + +#define TLV_START 0x00201004 +#define TLV_TAG_RESERVED1 1 +#define TLV_TAG_RESERVED2 2 +#define TLV_TAG_CS 3 +#define TLV_TAG_FLASHCTL 4 +#define TLV_TAG_ADC14 5 +#define TLV_TAG_RESERVED6 6 +#define TLV_TAG_RESERVED7 7 +#define TLV_TAG_REF 8 +#define TLV_TAG_RESERVED9 9 +#define TLV_TAG_RESERVED10 10 +#define TLV_TAG_DEVINFO 11 +#define TLV_TAG_DIEREC 12 +#define TLV_TAG_RANDNUM 13 +#define TLV_TAG_RESERVED14 14 +#define TLV_TAG_BSL 15 +#define TLV_TAGEND 0x0BD0E11D + +//***************************************************************************** +// +// Structures for TLV definitions +// +//***************************************************************************** +typedef struct +{ + uint32_t maxProgramPulses; + uint32_t maxErasePulses; +} SysCtl_FlashTLV_Info; + +typedef struct +{ + uint32_t rDCOIR_FCAL_RSEL04; + uint32_t rDCOIR_FCAL_RSEL5; + uint32_t rDCOIR_MAXPOSTUNE_RSEL04; + uint32_t rDCOIR_MAXNEGTUNE_RSEL04; + uint32_t rDCOIR_MAXPOSTUNE_RSEL5; + uint32_t rDCOIR_MAXNEGTUNE_RSEL5; + uint32_t rDCOIR_CONSTK_RSEL04; + uint32_t rDCOIR_CONSTK_RSEL5; + uint32_t rDCOER_FCAL_RSEL04; + uint32_t rDCOER_FCAL_RSEL5; + uint32_t rDCOER_MAXPOSTUNE_RSEL04; + uint32_t rDCOER_MAXNEGTUNE_RSEL04; + uint32_t rDCOER_MAXPOSTUNE_RSEL5; + uint32_t rDCOER_MAXNEGTUNE_RSEL5; + uint32_t rDCOER_CONSTK_RSEL04; + uint32_t rDCOER_CONSTK_RSEL5; + +} SysCtl_CSCalTLV_Info; + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! Gets the size of the SRAM. +//! +//! \return The total number of bytes of SRAM. +// +//***************************************************************************** +extern uint_least32_t SysCtl_getSRAMSize(void); + +//***************************************************************************** +// +//! Gets the size of the flash. +//! +//! \return The total number of bytes of flash. +// +//***************************************************************************** +extern uint_least32_t SysCtl_getFlashSize(void); + +//***************************************************************************** +// +//! Reboots the device and causes the device to re-initialize itself. +//! +//! \return This function does not return. +// +//***************************************************************************** +extern void SysCtl_rebootDevice(void); + +//***************************************************************************** +// +//! The TLV structure uses a tag or base address to identify segments of the +//! table where information is stored. Some examples of TLV tags are Peripheral +//! Descriptor, Interrupts, Info Block and Die Record. This function retrieves +//! the value of a tag and the length of the tag. +//! +//! \param tag represents the tag for which the information needs to be +//! retrieved. +//! Valid values are: +//! - \b TLV_TAG_RESERVED1 +//! - \b TLV_TAG_RESERVED2 +//! - \b TLV_TAG_CS +//! - \b TLV_TAG_FLASHCTL +//! - \b TLV_TAG_ADC14 +//! - \b TLV_TAG_RESERVED6 +//! - \b TLV_TAG_RESERVED7 +//! - \b TLV_TAG_REF +//! - \b TLV_TAG_RESERVED9 +//! - \b TLV_TAG_RESERVED10 +//! - \b TLV_TAG_DEVINFO +//! - \b TLV_TAG_DIEREC +//! - \b TLV_TAG_RANDNUM +//! - \b TLV_TAG_RESERVED14 +//! \param instance In some cases a specific tag may have more than one +//! instance. For example there may be multiple instances of timer +//! calibration data present under a single Timer Cal tag. This variable +//! specifies the instance for which information is to be retrieved (0, +//! 1, etc.). When only one instance exists; 0 is passed. +//! \param length Acts as a return through indirect reference. The function +//! retrieves the value of the TLV tag length. This value is pointed to +//! by *length and can be used by the application level once the +//! function is called. If the specified tag is not found then the +//! pointer is null 0. +//! \param data_address acts as a return through indirect reference. Once the +//! function is called data_address points to the pointer that holds the +//! value retrieved from the specified TLV tag. If the specified tag is +//! not found then the pointer is null 0. +//! +//! \return None +// +//***************************************************************************** +extern void SysCtl_getTLVInfo(uint_fast8_t tag, uint_fast8_t instance, + uint_fast8_t *length, uint32_t **data_address); + +//***************************************************************************** +// +//! Enables a set of banks in the SRAM. This can be used to optimize power +//! consumption when every SRAM bank isn't needed. It is important to note +//! that when a higher bank is enabled, all of the SRAM banks below that bank +//! are also enabled. For example, if the user enables SYSCTL_SRAM_BANK7, +//! the banks SYSCTL_SRAM_BANK1 through SYSCTL_SRAM_BANK7 will be enabled +//! (SRAM_BANK0 is reserved and always enabled). +//! +//! \param sramBank The SRAM bank tier to enable. +//! Must be only one of the following values: +//! - \b SYSCTL_SRAM_BANK1, +//! - \b SYSCTL_SRAM_BANK2, +//! - \b SYSCTL_SRAM_BANK3, +//! - \b SYSCTL_SRAM_BANK4, +//! - \b SYSCTL_SRAM_BANK5, +//! - \b SYSCTL_SRAM_BANK6, +//! - \b SYSCTL_SRAM_BANK7 +//! +//! \note \b SYSCTL_SRAM_BANK0 is reserved and always enabled. +//! +//! \return None. +// +//***************************************************************************** +extern void SysCtl_enableSRAMBank(uint_fast8_t sramBank); + +//***************************************************************************** +// +//! Disables a set of banks in the SRAM. This can be used to optimize power +//! consumption when every SRAM bank isn't needed. It is important to note +//! that when a higher bank is disabled, all of the SRAM banks above that bank +//! are also disabled. For example, if the user disables SYSCTL_SRAM_BANK5, +//! the banks SYSCTL_SRAM_BANK6 through SYSCTL_SRAM_BANK7 will be disabled. +//! +//! \param sramBank The SRAM bank tier to disable. +//! Must be only one of the following values: +//! - \b SYSCTL_SRAM_BANK1, +//! - \b SYSCTL_SRAM_BANK2, +//! - \b SYSCTL_SRAM_BANK3, +//! - \b SYSCTL_SRAM_BANK4, +//! - \b SYSCTL_SRAM_BANK5, +//! - \b SYSCTL_SRAM_BANK6, +//! - \b SYSCTL_SRAM_BANK7 +//! +//! \note \b SYSCTL_SRAM_BANK0 is reserved and always enabled. +//! +//! \return None. +// +//***************************************************************************** +extern void SysCtl_disableSRAMBank(uint_fast8_t sramBank); + +//***************************************************************************** +// +//! Enables retention of the specified SRAM bank register when the device goes +//! into LPM3 mode. When the system is placed in LPM3 mode, the SRAM +//! banks specified with this function will be placed into retention mode. By +//! default, retention of every SRAM bank except SYSCTL_SRAM_BANK0 (reserved) is +//! disabled. Retention of individual banks can be set without the restrictions +//! of the enable/disable functions. +//! +//! \param sramBank The SRAM banks to enable retention +//! Can be a bitwise OR of the following values: +//! - \b SYSCTL_SRAM_BANK1, +//! - \b SYSCTL_SRAM_BANK2, +//! - \b SYSCTL_SRAM_BANK3, +//! - \b SYSCTL_SRAM_BANK4, +//! - \b SYSCTL_SRAM_BANK5, +//! - \b SYSCTL_SRAM_BANK6, +//! - \b SYSCTL_SRAM_BANK7 +//! \note \b SYSCTL_SRAM_BANK0 is reserved and retention is always enabled. +//! +//! +//! \return None. +// +//***************************************************************************** +extern void SysCtl_enableSRAMBankRetention(uint_fast8_t sramBank); + +//***************************************************************************** +// +//! Disables retention of the specified SRAM bank register when the device goes +//! into LPM3 mode. When the system is placed in LPM3 mode, the SRAM +//! banks specified with this function will not be placed into retention mode. +//! By default, retention of every SRAM bank except SYSCTL_SRAM_BANK0 (reserved) +//! is disabled. Retention of individual banks can be set without the +//! restrictions of the enable/disable SRAM bank functions. +//! +//! \param sramBank The SRAM banks to disable retention +//! Can be a bitwise OR of the following values: +//! - \b SYSCTL_SRAM_BANK1, +//! - \b SYSCTL_SRAM_BANK2, +//! - \b SYSCTL_SRAM_BANK3, +//! - \b SYSCTL_SRAM_BANK4, +//! - \b SYSCTL_SRAM_BANK5, +//! - \b SYSCTL_SRAM_BANK6, +//! - \b SYSCTL_SRAM_BANK7 +//! \note \b SYSCTL_SRAM_BANK0 is reserved and retention is always enabled. +//! +//! \return None. +// +// +//***************************************************************************** +extern void SysCtl_disableSRAMBankRetention(uint_fast8_t sramBank); + +//***************************************************************************** +// +//! Makes it so that the provided peripherals will either halt execution after +//! a CPU HALT. Parameters in this function can be combined to account for +//! multiple peripherals. By default, all peripherals keep running after a +//! CPU HALT. +//! +//! \param devices The peripherals to continue running after a CPU HALT +//! This can be a bitwise OR of the following values: +//! - \b SYSCTL_PERIPH_DMA, +//! - \b SYSCTL_PERIPH_WDT, +//! - \b SYSCTL_PERIPH_ADC, +//! - \b SYSCTL_PERIPH_EUSCIB3, +//! - \b SYSCTL_PERIPH_EUSCIB2, +//! - \b SYSCTL_PERIPH_EUSCIB1 +//! - \b SYSCTL_PERIPH_EUSCIB0, +//! - \b SYSCTL_PERIPH_EUSCIA3, +//! - \b SYSCTL_PERIPH_EUSCIA2 +//! - \b SYSCTL_PERIPH_EUSCIA1, +//! - \b SYSCTL_PERIPH_EUSCIA0, +//! - \b SYSCTL_PERIPH_TIMER32_0_MODULE, +//! - \b SYSCTL_PERIPH_TIMER16_3, +//! - \b SYSCTL_PERIPH_TIMER16_2, +//! - \b SYSCTL_PERIPH_TIMER16_1, +//! - \b SYSCTL_PERIPH_TIMER16_0 +//! +//! \return None. +// +// +//***************************************************************************** +extern void SysCtl_enablePeripheralAtCPUHalt(uint_fast16_t devices); + +//***************************************************************************** +// +//! Makes it so that the provided peripherals will either halt execution after +//! a CPU HALT. Parameters in this function can be combined to account for +//! multiple peripherals. By default, all peripherals keep running after a +//! CPU HALT. +//! +//! \param devices The peripherals to disable after a CPU HALT +//! +//! The \e devices parameter can be a bitwise OR of the following values: +//! This can be a bitwise OR of the following values: +//! - \b SYSCTL_PERIPH_DMA, +//! - \b SYSCTL_PERIPH_WDT, +//! - \b SYSCTL_PERIPH_ADC, +//! - \b SYSCTL_PERIPH_EUSCIB3, +//! - \b SYSCTL_PERIPH_EUSCIB2, +//! - \b SYSCTL_PERIPH_EUSCIB1 +//! - \b SYSCTL_PERIPH_EUSCIB0, +//! - \b SYSCTL_PERIPH_EUSCIA3, +//! - \b SYSCTL_PERIPH_EUSCIA2 +//! - \b SYSCTL_PERIPH_EUSCIA1, +//! - \b SYSCTL_PERIPH_EUSCIA0, +//! - \b SYSCTL_PERIPH_TIMER32_0_MODULE, +//! - \b SYSCTL_PERIPH_TIMER16_3, +//! - \b SYSCTL_PERIPH_TIMER16_2, +//! - \b SYSCTL_PERIPH_TIMER16_1, +//! - \b SYSCTL_PERIPH_TIMER16_0 +//! +//! \return None. +// +// +//***************************************************************************** +extern void SysCtl_disablePeripheralAtCPUHalt(uint_fast16_t devices); + +//***************************************************************************** +// +//! Sets the type of RESET that happens when a watchdog timeout occurs. +//! +//! \param resetType The type of reset to set +//! +//! The \e resetType parameter must be only one of the following values: +//! - \b SYSCTL_HARD_RESET, +//! - \b SYSCTL_SOFT_RESET +//! +//! \return None. +// +// +//***************************************************************************** +extern void SysCtl_setWDTTimeoutResetType(uint_fast8_t resetType); + +//***************************************************************************** +// +//! Sets the type of RESET that happens when a watchdog password violation +//! occurs. +//! +//! \param resetType The type of reset to set +//! +//! The \e resetType parameter must be only one of the following values: +//! - \b SYSCTL_HARD_RESET, +//! - \b SYSCTL_SOFT_RESET +//! +//! \return None. +// +// +//***************************************************************************** +extern void SysCtl_setWDTPasswordViolationResetType(uint_fast8_t resetType); + +//***************************************************************************** +// +//! Disables NMIs for the provided modules. When disabled, a NMI flag will not +//! occur when a fault condition comes from the corresponding modules. +//! +//! \param flags The NMI sources to disable +//! Can be a bitwise OR of the following parameters: +//! - \b SYSCTL_NMIPIN_SRC, +//! - \b SYSCTL_PCM_SRC, +//! - \b SYSCTL_PSS_SRC, +//! - \b SYSCTL_CS_SRC +//! +// +//***************************************************************************** +extern void SysCtl_disableNMISource(uint_fast8_t flags); + +//***************************************************************************** +// +//! Enables NMIs for the provided modules. When enabled, a NMI flag will +//! occur when a fault condition comes from the corresponding modules. +//! +//! \param flags The NMI sources to enable +//! Can be a bitwise OR of the following parameters: +//! - \b SYSCTL_NMIPIN_SRC, +//! - \b SYSCTL_PCM_SRC, +//! - \b SYSCTL_PSS_SRC, +//! - \b SYSCTL_CS_SRC +//! +// +//***************************************************************************** +extern void SysCtl_enableNMISource(uint_fast8_t flags); + +//***************************************************************************** +// +//! Returns the current sources of NMIs that are enabled +//! +//! \return Bitwise OR of NMI flags that are enabled +// +//***************************************************************************** +extern uint_fast8_t SysCtl_getNMISourceStatus(void); + +//***************************************************************************** +// +//! Enables glitch suppression on the reset pin of the device. Refer to the +//! device data sheet for specific information about glitch suppression +//! +//! \return None. +// +// +//***************************************************************************** +extern void SysCtl_enableGlitchFilter(void); + +//***************************************************************************** +// +//! Disables glitch suppression on the reset pin of the device. Refer to the +//! device data sheet for specific information about glitch suppression +//! +//! \return None. +// +// +//***************************************************************************** +extern void SysCtl_disableGlitchFilter(void); + +//***************************************************************************** +// +//! Retrieves the calibration constant of the temperature sensor to be used +//! in temperature calculation. +//! +//! \param refVoltage Reference voltage being used. +//! +//! The \e refVoltage parameter must be only one of the following values: +//! - \b SYSCTL_1_2V_REF +//! - \b SYSCTL_1_45V_REF +//! - \b SYSCTL_2_5V_REF +//! +//! \param temperature is the calibration temperature that the user wants to be +//! returned. +//! +//! The \e temperature parameter must be only one of the following values: +//! - \b SYSCTL_30_DEGREES_C +//! - \b SYSCTL_85_DEGREES_C +//! +//! \return None. +// +// +//***************************************************************************** +extern uint_fast16_t SysCtl_getTempCalibrationConstant(uint32_t refVoltage, + uint32_t temperature); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __SYSCTL_H__ diff --git a/example/rt_msp432/MSP432P4xx/systick.c b/example/rt_msp432/MSP432P4xx/systick.c new file mode 100644 index 0000000..209e53a --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/systick.c @@ -0,0 +1,118 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include + +void SysTick_enableModule(void) +{ + // + // Enable SysTick. + // + SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; +} + +void SysTick_disableModule(void) +{ + // + // Disable SysTick. + // + SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk); +} + +void SysTick_registerInterrupt(void (*intHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + Interrupt_registerInterrupt(FAULT_SYSTICK, intHandler); + +} + +void SysTick_unregisterInterrupt(void) +{ + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(FAULT_SYSTICK); +} + +void SysTick_enableInterrupt(void) +{ + // + // Enable the SysTick interrupt. + // + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; +} + +void SysTick_disableInterrupt(void) +{ + // + // Disable the SysTick interrupt. + // + SysTick->CTRL &= ~(SysTick_CTRL_TICKINT_Msk); +} + +void SysTick_setPeriod(uint32_t period) +{ + // + // Check the arguments. + // + ASSERT((period > 0) && (period <= 16777216)); + + // + // Set the period of the SysTick counter. + // + SysTick->LOAD = period - 1; +} + +uint32_t SysTick_getPeriod(void) +{ + // + // Return the period of the SysTick counter. + // + return (SysTick->LOAD + 1); +} + +uint32_t SysTick_getValue(void) +{ + // + // Return the current value of the SysTick counter. + // + return (SysTick->VAL); +} diff --git a/example/rt_msp432/MSP432P4xx/systick.h b/example/rt_msp432/MSP432P4xx/systick.h new file mode 100644 index 0000000..27b9c73 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/systick.h @@ -0,0 +1,219 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __SYSTICK_H__ +#define __SYSTICK_H__ + +//***************************************************************************** +// +//! \addtogroup systick_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif +#include + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! Enables the SysTick counter. +//! +//! This function starts the SysTick counter. If an interrupt handler has been +//! registered, it is called when the SysTick counter rolls over. +//! +//! \note Calling this function causes the SysTick counter to (re)commence +//! counting from its current value. The counter is not automatically reloaded +//! with the period as specified in a previous call to SysTick_setPeriod(). If +//! an immediate reload is required, the \b NVIC_ST_CURRENT register must be +//! written to force the reload. Any write to this register clears the SysTick +//! counter to 0 and causes a reload with the supplied period on the next +//! clock. +//! +//! \return None. +// +//***************************************************************************** +extern void SysTick_enableModule(void); + +//***************************************************************************** +// +//! Disables the SysTick counter. +//! +//! This function stops the SysTick counter. If an interrupt handler has been +//! registered, it is not called until SysTick is restarted. +//! +//! \return None. +// +//***************************************************************************** +extern void SysTick_disableModule(void); + +//***************************************************************************** +// +//! Registers an interrupt handler for the SysTick interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the +//! SysTick interrupt occurs. +//! +//! This function registers the handler to be called when a SysTick interrupt +//! occurs. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void SysTick_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the SysTick interrupt. +//! +//! This function unregisters the handler to be called when a SysTick interrupt +//! occurs. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void SysTick_unregisterInterrupt(void); + +//***************************************************************************** +// +//! Enables the SysTick interrupt. +//! +//! This function enables the SysTick interrupt, allowing it to be +//! reflected to the processor. +//! +//! \note The SysTick interrupt handler is not required to clear the SysTick +//! interrupt source because it is cleared automatically by the NVIC when the +//! interrupt handler is called. +//! +//! \return None. +// +//***************************************************************************** +extern void SysTick_enableInterrupt(void); + +//***************************************************************************** +// +//! Disables the SysTick interrupt. +//! +//! This function disables the SysTick interrupt, preventing it from being +//! reflected to the processor. +//! +//! \return None. +// +//***************************************************************************** +extern void SysTick_disableInterrupt(void); + +//***************************************************************************** +// +//! Sets the period of the SysTick counter. +//! +//! \param period is the number of clock ticks in each period of the SysTick +//! counter and must be between 1 and 16,777,216, inclusive. +//! +//! This function sets the rate at which the SysTick counter wraps, which +//! equates to the number of processor clocks between interrupts. +//! +//! \note Calling this function does not cause the SysTick counter to reload +//! immediately. If an immediate reload is required, the \b NVIC_ST_CURRENT +//! register must be written. Any write to this register clears the SysTick +//! counter to 0 and causes a reload with the \e period supplied here on +//! the next clock after SysTick is enabled. +//! +//! \return None. +// +//***************************************************************************** +extern void SysTick_setPeriod(uint32_t period); + +//***************************************************************************** +// +//! Gets the period of the SysTick counter. +//! +//! This function returns the rate at which the SysTick counter wraps, which +//! equates to the number of processor clocks between interrupts. +//! +//! \return Returns the period of the SysTick counter. +// +//***************************************************************************** +extern uint32_t SysTick_getPeriod(void); + +//***************************************************************************** +// +//! Gets the current value of the SysTick counter. +//! +//! This function returns the current value of the SysTick counter, which is +//! a value between the period - 1 and zero, inclusive. +//! +//! \return Returns the current value of the SysTick counter. +// +//***************************************************************************** +extern uint32_t SysTick_getValue(void); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __SYSTICK_H__ diff --git a/example/rt_msp432/MSP432P4xx/timer32.c b/example/rt_msp432/MSP432P4xx/timer32.c new file mode 100644 index 0000000..d7011ed --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/timer32.c @@ -0,0 +1,151 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include + +void Timer32_initModule(uint32_t timer, uint32_t preScaler, uint32_t resolution, + uint32_t mode) +{ + /* Setting up one shot or continuous mode */ + if (mode == TIMER32_PERIODIC_MODE) + BITBAND_PERI(TIMER32_CMSIS(timer)->CONTROL, TIMER32_CONTROL_MODE_OFS) + = 1; + else if (mode == TIMER32_FREE_RUN_MODE) + BITBAND_PERI(TIMER32_CMSIS(timer)->CONTROL, TIMER32_CONTROL_MODE_OFS) + = 0; + else + ASSERT(false); + + /* Setting the resolution of the timer */ + if (resolution == TIMER32_16BIT) + BITBAND_PERI(TIMER32_CMSIS(timer)->CONTROL, TIMER32_CONTROL_SIZE_OFS) + = 0; + else if (resolution == TIMER32_32BIT) + BITBAND_PERI(TIMER32_CMSIS(timer)->CONTROL, TIMER32_CONTROL_SIZE_OFS) + = 1; + else + ASSERT(false); + + /* Setting the PreScaler */ + ASSERT( + resolution == TIMER32_PRESCALER_1 + || resolution == TIMER32_PRESCALER_16 + || resolution == TIMER32_PRESCALER_256); + + TIMER32_CMSIS(timer)->CONTROL = TIMER32_CMSIS(timer)->CONTROL + & (~TIMER32_CONTROL_PRESCALE_MASK) | preScaler; + +} + +void Timer32_setCount(uint32_t timer, uint32_t count) +{ + if (!BITBAND_PERI(TIMER32_CMSIS(timer)->CONTROL, TIMER32_CONTROL_SIZE_OFS) + && (count > UINT16_MAX)) + TIMER32_CMSIS(timer)->LOAD = UINT16_MAX; + else + TIMER32_CMSIS(timer)->LOAD = count; +} + +void Timer32_setCountInBackground(uint32_t timer, uint32_t count) +{ + if (!BITBAND_PERI(TIMER32_CMSIS(timer)->CONTROL, TIMER32_CONTROL_SIZE_OFS) + && (count > UINT16_MAX)) + TIMER32_CMSIS(timer)->BGLOAD = UINT16_MAX; + else + TIMER32_CMSIS(timer)->BGLOAD = count; +} + +uint32_t Timer32_getValue(uint32_t timer) +{ + return TIMER32_CMSIS(timer)->VALUE; +} + +void Timer32_startTimer(uint32_t timer, bool oneShot) +{ + ASSERT(timer == TIMER32_0_MODULE || timer == TIMER32_1_MODULE); + + if (oneShot) + BITBAND_PERI(TIMER32_CMSIS(timer)->CONTROL, TIMER32_CONTROL_ONESHOT_OFS) + = 1; + else + BITBAND_PERI(TIMER32_CMSIS(timer)->CONTROL, TIMER32_CONTROL_ONESHOT_OFS) + = 0; + + TIMER32_CMSIS(timer)->CONTROL |= TIMER32_CONTROL_ENABLE; +} + +void Timer32_haltTimer(uint32_t timer) +{ + ASSERT(timer == TIMER32_0_MODULE || timer == TIMER32_1_MODULE); + + TIMER32_CMSIS(timer)->CONTROL &= ~TIMER32_CONTROL_ENABLE; +} + +void Timer32_enableInterrupt(uint32_t timer) +{ + TIMER32_CMSIS(timer)->CONTROL |= TIMER32_CONTROL_IE; +} + +void Timer32_disableInterrupt(uint32_t timer) +{ + TIMER32_CMSIS(timer)->CONTROL &= ~TIMER32_CONTROL_IE; +} + +void Timer32_clearInterruptFlag(uint32_t timer) +{ + TIMER32_CMSIS(timer)->INTCLR |= 0x01; +} + +uint32_t Timer32_getInterruptStatus(uint32_t timer) +{ + return TIMER32_CMSIS(timer)->MIS; +} + +void Timer32_registerInterrupt(uint32_t timerInterrupt, + void (*intHandler)(void)) +{ + Interrupt_registerInterrupt(timerInterrupt, intHandler); + Interrupt_enableInterrupt(timerInterrupt); +} + +void Timer32_unregisterInterrupt(uint32_t timerInterrupt) +{ + Interrupt_disableInterrupt(timerInterrupt); + Interrupt_unregisterInterrupt(timerInterrupt); +} + diff --git a/example/rt_msp432/MSP432P4xx/timer32.h b/example/rt_msp432/MSP432P4xx/timer32.h new file mode 100644 index 0000000..0d67440 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/timer32.h @@ -0,0 +1,361 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef TIMER32_H_ +#define TIMER32_H_ + +//***************************************************************************** +// +//! \addtogroup timer32_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include +#include + +//***************************************************************************** +// +// Control specific variables +// +//***************************************************************************** +#define TIMER32_CMSIS(x) ((Timer32_Type *) x) + +#define TIMER_OFFSET 0x020 + +#define TIMER32_0_BASE (uint32_t)TIMER32_1 +#define TIMER32_1_BASE (uint32_t)TIMER32_2 + +#define TIMER32_0_INTERRUPT INT_T32_INT1 +#define TIMER32_1_INTERRUPT INT_T32_INT2 +#define TIMER32_COMBINED_INTERRUPT INT_T32_INTC + +#define TIMER32_16BIT 0x00 +#define TIMER32_32BIT 0x01 + +#define TIMER32_PRESCALER_1 0x00 +#define TIMER32_PRESCALER_16 0x04 +#define TIMER32_PRESCALER_256 0x08 + +#define TIMER32_FREE_RUN_MODE 0x00 +#define TIMER32_PERIODIC_MODE 0x01 + +//***************************************************************************** +// +// API Function prototypes +// +//***************************************************************************** + +//***************************************************************************** +// +//! Initializes the Timer32 module +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! +//! \param preScaler is the prescaler (or divider) to apply to the clock +//! source given to the Timer32 module. +//! Valid values are +//! - \b TIMER32_PRESCALER_1 [DEFAULT] +//! - \b TIMER32_PRESCALER_16 +//! - \b TIMER32_PRESCALER_256 +//! \param resolution is the bit resolution of the Timer32 module. +//! Valid values are +//! - \b TIMER32_16BIT [DEFAULT] +//! - \b TIMER32_32BIT +//! \param mode selects between free run and periodic mode. In free run +//! mode, the value of the timer is reset to UINT16_MAX (for 16-bit mode) or +//! UINT32_MAX (for 16-bit mode) when the timer reaches zero. In periodic mode, +//! the timer is reset to the value set by the Timer32_setCount function. +//! Valid values are +//! - \b TIMER32_FREE_RUN_MODE [DEFAULT] +//! - \b TIMER32_PERIODIC_MODE +//! +//! +//! \return None. +// +//***************************************************************************** +extern void Timer32_initModule(uint32_t timer, uint32_t preScaler, + uint32_t resolution, uint32_t mode); + +//***************************************************************************** +// +//! Sets the count of the timer and resets the current value to the value +//! passed. This value is set on the next rising edge of the clock provided to +//! the timer module +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! \param count Value of the timer to set. Note that +//! if the timer is in 16-bit mode and a value is passed in that exceeds +//! UINT16_MAX, the value will be truncated to UINT16_MAX. +//! +//! Also note that if the timer is operating in periodic mode, the value passed +//! into this function will represent the new period of the timer (the value +//! which is reloaded into the timer each time it reaches a zero value). +//! +//! \return None +// +//***************************************************************************** +extern void Timer32_setCount(uint32_t timer, uint32_t count); + +//***************************************************************************** +// +//! Sets the count of the timer without resetting the current value. When the +//! current value of the timer reaches zero, the value passed into this function +//! will be set as the new count value. +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! \param count Value of the timer to set in the background. Note that +//! if the timer is in 16-bit mode and a value is passed in that exceeds +//! UINT16_MAX, the value will be truncated to UINT16_MAX. +//! +//! Also note that if the timer is operating in periodic mode, the value passed +//! into this function will represent the new period of the timer (the value +//! which is reloaded into the timer each time it reaches a zero value). +//! +//! \return None +// +//***************************************************************************** +extern void Timer32_setCountInBackground(uint32_t timer, uint32_t count); + +//***************************************************************************** +// +//! Returns the current value of the timer. +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! +//! \return The current count of the timer. +// +//***************************************************************************** +extern uint32_t Timer32_getValue(uint32_t timer); + +//***************************************************************************** +// +//! Starts the timer. The Timer32_initModule function should be called (in +//! conjunction with Timer32_setCount if periodic mode is desired) prior to +// starting the timer. +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! +//! \param oneShot sets whether the Timer32 module operates in one shot +//! or continuous mode. In one shot mode, the timer will halt when a zero is +//! reached and stay halted until either: +//! - The user calls the Timer32PeriodSet function +//! - The Timer32_initModule is called to reinitialize the timer with one-shot +//! mode disabled. +//! +//! A true value will cause the timer to operate in one shot mode while a false +//! value will cause the timer to operate in continuous mode +//! +//! \return None +// +//***************************************************************************** +extern void Timer32_startTimer(uint32_t timer, bool oneShot); + +//***************************************************************************** +// +//! Halts the timer. Current count and setting values are preserved. +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! +//! \return None +// +//***************************************************************************** +extern void Timer32_haltTimer(uint32_t timer); + +//***************************************************************************** +// +//! Enables a Timer32 interrupt source. +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! +//! Enables the indicated Timer32 interrupt source. +//! +//! \return None. +// +//***************************************************************************** +extern void Timer32_enableInterrupt(uint32_t timer); + +//***************************************************************************** +// +//! Disables a Timer32 interrupt source. +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! +//! Disables the indicated Timer32 interrupt source. +//! +//! \return None. +// +//***************************************************************************** +extern void Timer32_disableInterrupt(uint32_t timer); + +//***************************************************************************** +// +//! Clears Timer32 interrupt source. +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! +//! The Timer32 interrupt source is cleared, so that it no longer asserts. +//! +//! \return None. +// +//***************************************************************************** +extern void Timer32_clearInterruptFlag(uint32_t timer); + +//***************************************************************************** +// +//! Gets the current Timer32 interrupt status. +//! +//! \param timer is the instance of the Timer32 module. +//! Valid parameters must be one of the following values: +//! - \b TIMER32_0_BASE +//! - \b TIMER32_1_BASE +//! +//! This returns the interrupt status for the Timer32 module. A positive value +//! will indicate that an interrupt is pending while a zero value will indicate +//! that no interrupt is pending. +//! +//! \return The current interrupt status +// +//***************************************************************************** +extern uint32_t Timer32_getInterruptStatus(uint32_t timer); + +//***************************************************************************** +// +//! Registers an interrupt handler for Timer32 interrupts. +//! +//! \param timerInterrupt is the specific interrupt to register. For the +//! Timer32 module, there are a total of three different interrupts: one +//! interrupt for each two Timer32 modules, and a "combined" interrupt which +//! is a logical OR of each individual Timer32 interrupt. +//! - \b TIMER32_0_INTERRUPT +//! - \b TIMER32_1_INTERRUPT +//! - \b TIMER32_COMBINED_INTERRUPT +//! +//! \param intHandler is a pointer to the function to be called when the +//! Timer32 interrupt occurs. +//! +//! This function registers the handler to be called when an Timer32 +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific Timer32 interrupts must be enabled +//! via Timer32_enableInterrupt(). It is the interrupt handler's +//! responsibility to clear the interrupt source +//! via Timer32_clearInterruptFlag(). +//! +//! \return None. +// +//***************************************************************************** +extern void Timer32_registerInterrupt(uint32_t timerInterrupt, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the Timer32 interrupt. +//! +//! \param timerInterrupt is the specific interrupt to register. For the +//! Timer32 module, there are a total of three different interrupts: one +//! interrupt for each two Timer32 modules, and a "combined" interrupt which +//! is a logical OR of each individual Timer32 interrupt. +//! - \b TIMER32_0_INTERRUPT +//! - \b TIMER32_1_INTERRUPT +//! - \b TIMER32_COMBINED_INTERRUPT +//! +//! This function unregisters the handler to be called when a Timer32 +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void Timer32_unregisterInterrupt(uint32_t timerInterrupt); + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif /* TIMER32_H_ */ diff --git a/example/rt_msp432/MSP432P4xx/timer_a.c b/example/rt_msp432/MSP432P4xx/timer_a.c new file mode 100644 index 0000000..0b80447 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/timer_a.c @@ -0,0 +1,812 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include + +static void privateTimer_AProcessClockSourceDivider(uint32_t timer, + uint16_t clockSourceDivider) +{ + TIMER_A_CMSIS(timer)->CTL &= ~TIMER_A_CTL_ID__8; + TIMER_A_CMSIS(timer)->EX0 &= ~TIMER_A_EX0_IDEX_MASK; + + switch (clockSourceDivider) + { + case TIMER_A_CLOCKSOURCE_DIVIDER_1: + case TIMER_A_CLOCKSOURCE_DIVIDER_2: + TIMER_A_CMSIS(timer)->CTL |= ((clockSourceDivider - 1) << 6); + TIMER_A_CMSIS(timer)->EX0 = TIMER_A_EX0_TAIDEX_0; + break; + case TIMER_A_CLOCKSOURCE_DIVIDER_4: + TIMER_A_CMSIS(timer)->CTL |= TIMER_A_CTL_ID__4; + TIMER_A_CMSIS(timer)->EX0 = TIMER_A_EX0_TAIDEX_0; + break; + case TIMER_A_CLOCKSOURCE_DIVIDER_8: + TIMER_A_CMSIS(timer)->CTL |= TIMER_A_CTL_ID__8; + TIMER_A_CMSIS(timer)->EX0 = TIMER_A_EX0_TAIDEX_0; + break; + case TIMER_A_CLOCKSOURCE_DIVIDER_3: + case TIMER_A_CLOCKSOURCE_DIVIDER_5: + case TIMER_A_CLOCKSOURCE_DIVIDER_6: + case TIMER_A_CLOCKSOURCE_DIVIDER_7: + TIMER_A_CMSIS(timer)->CTL |= TIMER_A_CTL_ID__1; + TIMER_A_CMSIS(timer)->EX0 = (clockSourceDivider - 1); + break; + + case TIMER_A_CLOCKSOURCE_DIVIDER_10: + case TIMER_A_CLOCKSOURCE_DIVIDER_12: + case TIMER_A_CLOCKSOURCE_DIVIDER_14: + case TIMER_A_CLOCKSOURCE_DIVIDER_16: + TIMER_A_CMSIS(timer)->CTL |= TIMER_A_CTL_ID__2; + TIMER_A_CMSIS(timer)->EX0 = (clockSourceDivider / 2 - 1); + break; + + case TIMER_A_CLOCKSOURCE_DIVIDER_20: + case TIMER_A_CLOCKSOURCE_DIVIDER_24: + case TIMER_A_CLOCKSOURCE_DIVIDER_28: + case TIMER_A_CLOCKSOURCE_DIVIDER_32: + TIMER_A_CMSIS(timer)->CTL |= TIMER_A_CTL_ID__4; + TIMER_A_CMSIS(timer)->EX0 = (clockSourceDivider / 4 - 1); + break; + case TIMER_A_CLOCKSOURCE_DIVIDER_40: + case TIMER_A_CLOCKSOURCE_DIVIDER_48: + case TIMER_A_CLOCKSOURCE_DIVIDER_56: + case TIMER_A_CLOCKSOURCE_DIVIDER_64: + TIMER_A_CMSIS(timer)->CTL |= TIMER_A_CTL_ID__8; + TIMER_A_CMSIS(timer)->EX0 = (clockSourceDivider / 8 - 1); + break; + } +} + +void Timer_A_startCounter(uint32_t timer, uint_fast16_t timerMode) +{ + ASSERT( + (TIMER_A_UPDOWN_MODE == timerMode) + || (TIMER_A_CONTINUOUS_MODE == timerMode) + || (TIMER_A_UP_MODE == timerMode)); + + TIMER_A_CMSIS(timer)->CTL |= timerMode; +} + +void Timer_A_configureContinuousMode(uint32_t timer, + const Timer_A_ContinuousModeConfig *config) +{ + ASSERT( + (TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_ACLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_SMCLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK + == config->clockSource)); + + ASSERT( + (TIMER_A_DO_CLEAR == config->timerClear) + || (TIMER_A_SKIP_CLEAR == config->timerClear)); + + ASSERT( + (TIMER_A_TAIE_INTERRUPT_ENABLE == config->timerInterruptEnable_TAIE) + || (TIMER_A_TAIE_INTERRUPT_DISABLE + == config->timerInterruptEnable_TAIE)); + + ASSERT( + (TIMER_A_CLOCKSOURCE_DIVIDER_1 == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_2 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_4 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_8 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_3 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_5 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_6 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_7 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_10 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_12 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_14 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_16 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_20 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_24 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_28 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_32 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_40 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_48 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_56 + == config->clockSourceDivider) + || (TIMER_A_CLOCKSOURCE_DIVIDER_64 + == config->clockSourceDivider)); + + privateTimer_AProcessClockSourceDivider(timer, config->clockSourceDivider); + + TIMER_A_CMSIS(timer)->CTL = (TIMER_A_CMSIS(timer)->CTL + & ~(TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK + + TIMER_A_UPDOWN_MODE + TIMER_A_DO_CLEAR + + TIMER_A_TAIE_INTERRUPT_ENABLE)) + | (config->clockSource + config->timerClear + + config->timerInterruptEnable_TAIE); +} + +void Timer_A_configureUpMode(uint32_t timer, const Timer_A_UpModeConfig *config) +{ + ASSERT( + (TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_ACLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_SMCLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK + == config->clockSource)); + + ASSERT( + (TIMER_A_DO_CLEAR == config->timerClear) + || (TIMER_A_SKIP_CLEAR == config->timerClear)); + + ASSERT( + (TIMER_A_DO_CLEAR == config->timerClear) + || (TIMER_A_SKIP_CLEAR == config->timerClear)); + + privateTimer_AProcessClockSourceDivider(timer, config->clockSourceDivider); + + TIMER_A_CMSIS(timer)->CTL &= + ~(TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK + TIMER_A_UPDOWN_MODE + + TIMER_A_DO_CLEAR + TIMER_A_TAIE_INTERRUPT_ENABLE); + + TIMER_A_CMSIS(timer)->CTL |= (config->clockSource + config->timerClear + + config->timerInterruptEnable_TAIE); + + if (TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE + == config->captureCompareInterruptEnable_CCR0_CCIE) + BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[0],TIMER_A_CCTLN_CCIE_OFS) = 1; + else + BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[0],TIMER_A_CCTLN_CCIE_OFS) = 0; + + TIMER_A_CMSIS(timer)->CCR[0] = config->timerPeriod; +} + +void Timer_A_configureUpDownMode(uint32_t timer, + const Timer_A_UpDownModeConfig *config) +{ + ASSERT( + (TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_ACLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_SMCLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK + == config->clockSource)); + + ASSERT( + (TIMER_A_DO_CLEAR == config->timerClear) + || (TIMER_A_SKIP_CLEAR == config->timerClear)); + + ASSERT( + (TIMER_A_DO_CLEAR == config->timerClear) + || (TIMER_A_SKIP_CLEAR == config->timerClear)); + + privateTimer_AProcessClockSourceDivider(timer, config->clockSourceDivider); + + TIMER_A_CMSIS(timer)->CTL &= + ~(TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK + TIMER_A_UPDOWN_MODE + + TIMER_A_DO_CLEAR + TIMER_A_TAIE_INTERRUPT_ENABLE); + + TIMER_A_CMSIS(timer)->CTL |= (config->clockSource + TIMER_A_STOP_MODE + + config->timerClear + config->timerInterruptEnable_TAIE); + if (TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE + == config->captureCompareInterruptEnable_CCR0_CCIE) + BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[0],TIMER_A_CCTLN_CCIE_OFS) = 1; + else + BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[0],TIMER_A_CCTLN_CCIE_OFS) = 0; + + TIMER_A_CMSIS(timer)->CCR[0] = config->timerPeriod; +} + +void Timer_A_initCapture(uint32_t timer, + const Timer_A_CaptureModeConfig *config) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == config->captureRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == config->captureRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == config->captureRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == config->captureRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == config->captureRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == config->captureRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == config->captureRegister)); + + ASSERT( + (TIMER_A_CAPTUREMODE_NO_CAPTURE == config->captureMode) + || (TIMER_A_CAPTUREMODE_RISING_EDGE == config->captureMode) + || (TIMER_A_CAPTUREMODE_FALLING_EDGE == config->captureMode) + || (TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE + == config->captureMode)); + + ASSERT( + (TIMER_A_CAPTURE_INPUTSELECT_CCIxA == config->captureInputSelect) + || (TIMER_A_CAPTURE_INPUTSELECT_CCIxB + == config->captureInputSelect) + || (TIMER_A_CAPTURE_INPUTSELECT_GND + == config->captureInputSelect) + || (TIMER_A_CAPTURE_INPUTSELECT_Vcc + == config->captureInputSelect)); + + ASSERT( + (TIMER_A_CAPTURE_ASYNCHRONOUS == config->synchronizeCaptureSource) + || (TIMER_A_CAPTURE_SYNCHRONOUS + == config->synchronizeCaptureSource)); + + ASSERT( + (TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE + == config->captureInterruptEnable) + || (TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE + == config->captureInterruptEnable)); + + ASSERT( + (TIMER_A_OUTPUTMODE_OUTBITVALUE == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_SET == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE_RESET + == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_SET_RESET + == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_RESET == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE_SET + == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_RESET_SET + == config->captureOutputMode)); + + if (TIMER_A_CAPTURECOMPARE_REGISTER_0 == config->captureRegister) + { + //CaptureCompare register 0 only supports certain modes + ASSERT( + (TIMER_A_OUTPUTMODE_OUTBITVALUE == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_SET == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE + == config->captureOutputMode) + || (TIMER_A_OUTPUTMODE_RESET + == config->captureOutputMode)); + } + uint8_t idx = (config->captureRegister>>1)-1; + TIMER_A_CMSIS(timer)->CCTL[idx] = + (TIMER_A_CMSIS(timer)->CCTL[idx] + & ~(TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE + | TIMER_A_CAPTURE_INPUTSELECT_Vcc + | TIMER_A_CAPTURE_SYNCHRONOUS | TIMER_A_DO_CLEAR + | TIMER_A_TAIE_INTERRUPT_ENABLE | TIMER_A_CCTLN_CM_3)) + | (config->captureMode | config->captureInputSelect + | config->synchronizeCaptureSource + | config->captureInterruptEnable + | config->captureOutputMode | TIMER_A_CCTLN_CAP); + +} + +void Timer_A_initCompare(uint32_t timer, + const Timer_A_CompareModeConfig *config) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == config->compareRegister)); + + ASSERT( + (TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE + == config->compareInterruptEnable) + || (TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE + == config->compareInterruptEnable)); + + ASSERT( + (TIMER_A_OUTPUTMODE_OUTBITVALUE == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_SET == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE_RESET + == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_SET_RESET + == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_RESET == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE_SET + == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_RESET_SET + == config->compareOutputMode)); + + if (TIMER_A_CAPTURECOMPARE_REGISTER_0 == config->compareRegister) + { + //CaptureCompare register 0 only supports certain modes + ASSERT( + (TIMER_A_OUTPUTMODE_OUTBITVALUE == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_SET == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE + == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_RESET + == config->compareOutputMode)); + } + + uint8_t idx = (config->compareRegister>>1)-1; + TIMER_A_CMSIS(timer)->CCTL[idx] = + (TIMER_A_CMSIS(timer)->CCTL[idx] + & ~(TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE + | TIMER_A_OUTPUTMODE_RESET_SET | TIMER_A_CCTLN_CAP)) + | (config->compareInterruptEnable + config->compareOutputMode); + + TIMER_A_CMSIS(timer)->CCR[idx] = config->compareValue; + +} + +uint16_t Timer_A_getCounterValue(uint32_t timer) +{ + uint_fast16_t voteOne, voteTwo, res; + + voteTwo = TIMER_A_CMSIS(timer)->R; + + do + { + voteOne = voteTwo; + voteTwo = TIMER_A_CMSIS(timer)->R; + + if (voteTwo > voteOne) + res = voteTwo - voteOne; + else if (voteOne > voteTwo) + res = voteOne - voteTwo; + else + res = 0; + + } while (res > TIMER_A_THRESHOLD); + + return voteTwo; + +} + +void Timer_A_clearTimer(uint32_t timer) +{ + BITBAND_PERI(TIMER_A_CMSIS(timer)->CTL , TIMER_A_CTL_CLR_OFS) = 1; +} + +uint_fast8_t Timer_A_getSynchronizedCaptureCompareInput(uint32_t timer, + uint_fast16_t captureCompareRegister, uint_fast16_t synchronizedSetting) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == captureCompareRegister)); + + ASSERT( + (TIMER_A_READ_CAPTURE_COMPARE_INPUT == synchronizedSetting) + || (TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT + == synchronizedSetting)); + + uint8_t idx = (captureCompareRegister>>1) - 1; + if (TIMER_A_CMSIS(timer)->CCTL[idx] & synchronizedSetting) + return TIMER_A_CAPTURECOMPARE_INPUT_HIGH; + else + return TIMER_A_CAPTURECOMPARE_INPUT_LOW; +} + +uint_fast8_t Timer_A_getOutputForOutputModeOutBitValue(uint32_t timer, + uint_fast16_t captureCompareRegister) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == captureCompareRegister)); + + uint8_t idx = (captureCompareRegister>>1) - 1; + if (BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[idx],TIMER_A_CCTLN_OUT_OFS)) + return TIMER_A_OUTPUTMODE_OUTBITVALUE_HIGH; + else + return TIMER_A_OUTPUTMODE_OUTBITVALUE_LOW; +} + +uint_fast16_t Timer_A_getCaptureCompareCount(uint32_t timer, + uint_fast16_t captureCompareRegister) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == captureCompareRegister)); + + uint8_t idx = (captureCompareRegister>>1) - 1; + return (TIMER_A_CMSIS(timer)->CCR[idx]); +} + +void Timer_A_setOutputForOutputModeOutBitValue(uint32_t timer, + uint_fast16_t captureCompareRegister, + uint_fast8_t outputModeOutBitValue) +{ + uint8_t idx = (captureCompareRegister>>1) - 1; + TIMER_A_CMSIS(timer)->CCTL[idx] = + ((TIMER_A_CMSIS(timer)->CCTL[idx]) + & ~(TIMER_A_OUTPUTMODE_RESET_SET)) + | (outputModeOutBitValue); +} + +void Timer_A_generatePWM(uint32_t timer, const Timer_A_PWMConfig *config) +{ + ASSERT( + (TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_ACLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_SMCLK == config->clockSource) + || (TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK + == config->clockSource)); + + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == config->compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == config->compareRegister)); + + ASSERT( + (TIMER_A_OUTPUTMODE_OUTBITVALUE == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_SET == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE_RESET + == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_SET_RESET + == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_RESET == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_TOGGLE_SET + == config->compareOutputMode) + || (TIMER_A_OUTPUTMODE_RESET_SET + == config->compareOutputMode)); + + privateTimer_AProcessClockSourceDivider(timer, config->clockSourceDivider); + + TIMER_A_CMSIS(timer)->CTL &= + ~(TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK + TIMER_A_UPDOWN_MODE + + TIMER_A_DO_CLEAR + TIMER_A_TAIE_INTERRUPT_ENABLE); + + TIMER_A_CMSIS(timer)->CTL |= (config->clockSource + TIMER_A_UP_MODE + + TIMER_A_DO_CLEAR); + + TIMER_A_CMSIS(timer)->CCR[0] = config->timerPeriod; + + TIMER_A_CMSIS(timer)->CCTL[0] &= ~(TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE + + TIMER_A_OUTPUTMODE_RESET_SET); + + uint8_t idx = (config->compareRegister>>1) - 1; + TIMER_A_CMSIS(timer)->CCTL[idx] |= config->compareOutputMode; + TIMER_A_CMSIS(timer)->CCR[idx] = config->dutyCycle; +} + +void Timer_A_stopTimer(uint32_t timer) +{ + TIMER_A_CMSIS(timer)->CTL &= ~TIMER_A_CTL_MC_3; +} + +void Timer_A_setCompareValue(uint32_t timer, uint_fast16_t compareRegister, + uint_fast16_t compareValue) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 == compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 == compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 == compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 == compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 == compareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 == compareRegister)); + + uint8_t idx = (compareRegister>>1) - 1; + TIMER_A_CMSIS(timer)->CCR[idx] = compareValue; +} + +void Timer_A_clearInterruptFlag(uint32_t timer) +{ + BITBAND_PERI(TIMER_A_CMSIS(timer)->CTL,TIMER_A_CTL_IFG_OFS) = 0; +} + +void Timer_A_clearCaptureCompareInterrupt(uint32_t timer, + uint_fast16_t captureCompareRegister) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == captureCompareRegister)); + + uint8_t idx = (captureCompareRegister>>1) - 1; + BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[idx],TIMER_A_CCTLN_CCIFG_OFS) = 0; +} + +void Timer_A_enableInterrupt(uint32_t timer) +{ + BITBAND_PERI(TIMER_A_CMSIS(timer)->CTL,TIMER_A_CTL_IE_OFS) = 1; +} + +void Timer_A_disableInterrupt(uint32_t timer) +{ + BITBAND_PERI(TIMER_A_CMSIS(timer)->CTL,TIMER_A_CTL_IE_OFS) = 0; +} + +uint32_t Timer_A_getInterruptStatus(uint32_t timer) +{ + return (TIMER_A_CMSIS(timer)->CTL) & TIMER_A_CTL_IFG; +} + +void Timer_A_enableCaptureCompareInterrupt(uint32_t timer, + uint_fast16_t captureCompareRegister) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == captureCompareRegister)); + + uint8_t idx = (captureCompareRegister>>1) - 1; + BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[idx],TIMER_A_CCTLN_CCIE_OFS) = 1; +} + +void Timer_A_disableCaptureCompareInterrupt(uint32_t timer, + uint_fast16_t captureCompareRegister) +{ + ASSERT( + (TIMER_A_CAPTURECOMPARE_REGISTER_0 == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_1 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_2 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_3 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_4 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_5 + == captureCompareRegister) + || (TIMER_A_CAPTURECOMPARE_REGISTER_6 + == captureCompareRegister)); + + uint8_t idx = (captureCompareRegister>>1) - 1; + BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[idx],TIMER_A_CCTLN_CCIE_OFS) = 0; + +} + +uint32_t Timer_A_getCaptureCompareInterruptStatus(uint32_t timer, + uint_fast16_t captureCompareRegister, uint_fast16_t mask) +{ + uint8_t idx = (captureCompareRegister>>1) - 1; + return (TIMER_A_CMSIS(timer)->CCTL[idx]) & mask; +} + +uint32_t Timer_A_getEnabledInterruptStatus(uint32_t timer) +{ + if (TIMER_A_CMSIS(timer)->CTL & TIMER_A_CTL_IE) + { + return Timer_A_getInterruptStatus(timer); + } else + { + return 0; + } + +} + +uint32_t Timer_A_getCaptureCompareEnabledInterruptStatus(uint32_t timer, + uint_fast16_t captureCompareRegister) +{ + uint8_t idx = (captureCompareRegister>>1) - 1; + if (BITBAND_PERI(TIMER_A_CMSIS(timer)->CCTL[idx],TIMER_A_CCTLN_CCIE_OFS)) + return Timer_A_getCaptureCompareInterruptStatus(timer, + captureCompareRegister, + TIMER_A_CAPTURE_OVERFLOW | + TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG); + else + return 0; +} + +void Timer_A_registerInterrupt(uint32_t timer, uint_fast8_t interruptSelect, + void (*intHandler)(void)) +{ + if (interruptSelect == TIMER_A_CCR0_INTERRUPT) + { + switch (timer) + { + case TIMER_A0_BASE: + Interrupt_registerInterrupt(INT_TA0_0, intHandler); + Interrupt_enableInterrupt(INT_TA0_0); + break; + case TIMER_A1_BASE: + Interrupt_registerInterrupt(INT_TA1_0, intHandler); + Interrupt_enableInterrupt(INT_TA1_0); + break; + case TIMER_A2_BASE: + Interrupt_registerInterrupt(INT_TA2_0, intHandler); + Interrupt_enableInterrupt(INT_TA2_0); + break; + case TIMER_A3_BASE: + Interrupt_registerInterrupt(INT_TA3_0, intHandler); + Interrupt_enableInterrupt(INT_TA3_0); + break; + default: + ASSERT(false); + } + } else if (interruptSelect == TIMER_A_CCRX_AND_OVERFLOW_INTERRUPT) + { + switch (timer) + { + case TIMER_A0_BASE: + Interrupt_registerInterrupt(INT_TA0_N, intHandler); + Interrupt_enableInterrupt(INT_TA0_N); + break; + case TIMER_A1_BASE: + Interrupt_registerInterrupt(INT_TA1_N, intHandler); + Interrupt_enableInterrupt(INT_TA1_N); + break; + case TIMER_A2_BASE: + Interrupt_registerInterrupt(INT_TA2_N, intHandler); + Interrupt_enableInterrupt(INT_TA2_N); + break; + case TIMER_A3_BASE: + Interrupt_registerInterrupt(INT_TA3_N, intHandler); + Interrupt_enableInterrupt(INT_TA3_N); + break; + default: + ASSERT(false); + } + } else + { + ASSERT(false); + } +} + +void Timer_A_unregisterInterrupt(uint32_t timer, uint_fast8_t interruptSelect) +{ + if (interruptSelect == TIMER_A_CCR0_INTERRUPT) + { + switch (timer) + { + case TIMER_A0_BASE: + Interrupt_disableInterrupt(INT_TA0_0); + Interrupt_unregisterInterrupt(INT_TA0_0); + break; + case TIMER_A1_BASE: + Interrupt_disableInterrupt(INT_TA1_0); + Interrupt_unregisterInterrupt(INT_TA1_0); + break; + case TIMER_A2_BASE: + Interrupt_disableInterrupt(INT_TA2_0); + Interrupt_unregisterInterrupt(INT_TA2_0); + break; + case TIMER_A3_BASE: + Interrupt_disableInterrupt(INT_TA3_0); + Interrupt_unregisterInterrupt(INT_TA3_0); + break; + default: + ASSERT(false); + } + } else if (interruptSelect == TIMER_A_CCRX_AND_OVERFLOW_INTERRUPT) + { + switch (timer) + { + case TIMER_A0_BASE: + Interrupt_disableInterrupt(INT_TA0_N); + Interrupt_unregisterInterrupt(INT_TA0_N); + break; + case TIMER_A1_BASE: + Interrupt_disableInterrupt(INT_TA1_N); + Interrupt_unregisterInterrupt(INT_TA1_N); + break; + case TIMER_A2_BASE: + Interrupt_disableInterrupt(INT_TA2_N); + Interrupt_unregisterInterrupt(INT_TA2_N); + break; + case TIMER_A3_BASE: + Interrupt_disableInterrupt(INT_TA3_N); + Interrupt_unregisterInterrupt(INT_TA3_N); + break; + default: + ASSERT(false); + } + } else + { + ASSERT(false); + } +} + diff --git a/example/rt_msp432/MSP432P4xx/timer_a.h b/example/rt_msp432/MSP432P4xx/timer_a.h new file mode 100644 index 0000000..2ad62b4 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/timer_a.h @@ -0,0 +1,1299 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef TIMERA_H_ +#define TIMERA_H_ + +//***************************************************************************** +// +//! \addtogroup timera_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include +#include + +//***************************************************************************** +// +// Timer_A Specific Parameters +// +//***************************************************************************** +#define TIMER_A_CMSIS(x) ((Timer_A_Type *) x) + +#define TIMER_A_CCR0_INTERRUPT 0x00 +#define TIMER_A_CCRX_AND_OVERFLOW_INTERRUPT 0x01 + +//***************************************************************************** +// +//! ypedef Timer_A_ContinuousModeConfig +//! \brief Type definition for \link _Timer_A_ContinuousModeConfig \endlink +//! structure +//! +//! \struct _Timer_A_ContinuousModeConfig +//! \brief Configuration structure for continuous mode in the \b Timer_A module. +//! See \link Timer_A_configureContinuousMode \endlink for parameter +//! documentation. +// +//***************************************************************************** +typedef struct _Timer_A_ContinuousModeConfig +{ + uint_fast16_t clockSource; + uint_fast16_t clockSourceDivider; + uint_fast16_t timerInterruptEnable_TAIE; + uint_fast16_t timerClear; +} Timer_A_ContinuousModeConfig; + +//***************************************************************************** +// +//! ypedef Timer_A_UpModeConfig +//! \brief Type definition for \link _Timer_A_UpModeConfig \endlink +//! structure +//! +//! \struct _Timer_A_UpModeConfig +//! \brief Configuration structure for Up mode in the \b Timer_A module. See +//! \link Timer_A_configureUpMode \endlink for parameter +//! documentation. +// +//***************************************************************************** +typedef struct _Timer_A_UpModeConfig +{ + uint_fast16_t clockSource; + uint_fast16_t clockSourceDivider; + uint_fast16_t timerPeriod; + uint_fast16_t timerInterruptEnable_TAIE; + uint_fast16_t captureCompareInterruptEnable_CCR0_CCIE; + uint_fast16_t timerClear; +} Timer_A_UpModeConfig; + +//***************************************************************************** +// +//! ypedef Timer_A_UpDownModeConfig +//! \brief Type definition for \link _Timer_A_UpDownModeConfig \endlink +//! structure +//! +//! \struct _Timer_A_UpDownModeConfig +//! \brief Configuration structure for UpDown mode in the \b Timer_A module. See +//! \link Timer_A_configureUpDownMode \endlink for parameter +//! documentation. +// +//***************************************************************************** +typedef struct _Timer_A_UpDownModeConfig +{ + uint_fast16_t clockSource; + uint_fast16_t clockSourceDivider; + uint_fast16_t timerPeriod; + uint_fast16_t timerInterruptEnable_TAIE; + uint_fast16_t captureCompareInterruptEnable_CCR0_CCIE; + uint_fast16_t timerClear; +} Timer_A_UpDownModeConfig; + +//***************************************************************************** +// +//! ypedef Timer_A_CaptureModeConfig +//! \brief Type definition for \link _Timer_A_CaptureModeConfig \endlink +//! structure +//! +//! \struct _Timer_A_CaptureModeConfig +//! \brief Configuration structure for capture mode in the \b Timer_A module. +//! See \link Timer_A_initCapture \endlink for parameter +//! documentation. +// +//***************************************************************************** +typedef struct _Timer_A_CaptureModeConfig +{ + uint_fast16_t captureRegister; + uint_fast16_t captureMode; + uint_fast16_t captureInputSelect; + uint_fast16_t synchronizeCaptureSource; + uint_fast8_t captureInterruptEnable; + uint_fast16_t captureOutputMode; +} Timer_A_CaptureModeConfig; + +//***************************************************************************** +// +//! ypedef Timer_A_CompareModeConfig +//! \brief Type definition for \link _Timer_A_CompareModeConfig \endlink +//! structure +//! +//! \struct _Timer_A_CompareModeConfig +//! \brief Configuration structure for compare mode in the \b Timer_A module. +//! See \link Timer_A_initCompare \endlink for parameter +//! documentation. +// +//***************************************************************************** +typedef struct _Timer_A_CompareModeConfig +{ + uint_fast16_t compareRegister; + uint_fast16_t compareInterruptEnable; + uint_fast16_t compareOutputMode; + uint_fast16_t compareValue; +} Timer_A_CompareModeConfig; + +//***************************************************************************** +// +//! ypedef Timer_A_PWMConfig +//! \brief Type definition for \link _Timer_A_PWMConfig \endlink +//! structure +//! +//! \struct _Timer_A_PWMConfig +//! \brief Configuration structure for PWM mode in the \b Timer_A module. See +//! \link Timer_A_generatePWM \endlink for parameter +//! documentation. +// +//***************************************************************************** +typedef struct _Timer_A_PWMConfig +{ + uint_fast16_t clockSource; + uint_fast16_t clockSourceDivider; + uint_fast16_t timerPeriod; + uint_fast16_t compareRegister; + uint_fast16_t compareOutputMode; + uint_fast16_t dutyCycle; +} Timer_A_PWMConfig; + + +//***************************************************************************** +// +// The following is a parameter determines the maximum difference in counts of +// the TAxR register for a majority vote +// +//***************************************************************************** +#define TIMER_A_THRESHOLD 50 + +//***************************************************************************** +// +// The following are values that can be passed to the clockSourceDivider +// parameter +// +//***************************************************************************** +#define TIMER_A_CLOCKSOURCE_DIVIDER_1 0x01 +#define TIMER_A_CLOCKSOURCE_DIVIDER_2 0x02 +#define TIMER_A_CLOCKSOURCE_DIVIDER_4 0x04 +#define TIMER_A_CLOCKSOURCE_DIVIDER_8 0x08 +#define TIMER_A_CLOCKSOURCE_DIVIDER_3 0x03 +#define TIMER_A_CLOCKSOURCE_DIVIDER_5 0x05 +#define TIMER_A_CLOCKSOURCE_DIVIDER_6 0x06 +#define TIMER_A_CLOCKSOURCE_DIVIDER_7 0x07 +#define TIMER_A_CLOCKSOURCE_DIVIDER_10 0x0A +#define TIMER_A_CLOCKSOURCE_DIVIDER_12 0x0C +#define TIMER_A_CLOCKSOURCE_DIVIDER_14 0x0E +#define TIMER_A_CLOCKSOURCE_DIVIDER_16 0x10 +#define TIMER_A_CLOCKSOURCE_DIVIDER_20 0x14 +#define TIMER_A_CLOCKSOURCE_DIVIDER_24 0x18 +#define TIMER_A_CLOCKSOURCE_DIVIDER_28 0x1C +#define TIMER_A_CLOCKSOURCE_DIVIDER_32 0x20 +#define TIMER_A_CLOCKSOURCE_DIVIDER_40 0x28 +#define TIMER_A_CLOCKSOURCE_DIVIDER_48 0x30 +#define TIMER_A_CLOCKSOURCE_DIVIDER_56 0x38 +#define TIMER_A_CLOCKSOURCE_DIVIDER_64 0x40 + +//***************************************************************************** +// +// The following are values that can be passed to the timerMode parameter +// +//***************************************************************************** +#define TIMER_A_STOP_MODE TIMER_A_CTL_MC_0 +#define TIMER_A_UP_MODE TIMER_A_CTL_MC_1 +#define TIMER_A_CONTINUOUS_MODE TIMER_A_CTL_MC_2 +#define TIMER_A_UPDOWN_MODE TIMER_A_CTL_MC_3 + +//***************************************************************************** +// +// The following are values that can be passed to the timerClear parameter +// +//***************************************************************************** +#define TIMER_A_DO_CLEAR TIMER_A_CTL_CLR +#define TIMER_A_SKIP_CLEAR 0x00 + +//***************************************************************************** +// +// The following are values that can be passed to the clockSource parameter +// +//***************************************************************************** +#define TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK TIMER_A_CTL_SSEL__TACLK +#define TIMER_A_CLOCKSOURCE_ACLK TIMER_A_CTL_SSEL__ACLK +#define TIMER_A_CLOCKSOURCE_SMCLK TIMER_A_CTL_SSEL__SMCLK +#define TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK TIMER_A_CTL_SSEL__INCLK + +//***************************************************************************** +// +// The following are values that can be passed to the timerInterruptEnable_TAIE +// parameter +// +//***************************************************************************** +#define TIMER_A_TAIE_INTERRUPT_ENABLE TIMER_A_CTL_IE +#define TIMER_A_TAIE_INTERRUPT_DISABLE 0x00 + +//***************************************************************************** +// +// The following are values that can be passed to the +// captureCompareInterruptEnable_CCR0_CCIE parameter +// +//***************************************************************************** +#define TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE TIMER_A_CCTLN_CCIE +#define TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE 0x00 + +//***************************************************************************** +// +// The following are values that can be passed to the captureInterruptEnable +// parameter +// +//***************************************************************************** +#define TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE 0x00 +#define TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE TIMER_A_CCTLN_CCIE + +//***************************************************************************** +// +// The following are values that can be passed to the captureInputSelect +// parameter +// +//***************************************************************************** +#define TIMER_A_CAPTURE_INPUTSELECT_CCIxA TIMER_A_CCTLN_CCIS_0 +#define TIMER_A_CAPTURE_INPUTSELECT_CCIxB TIMER_A_CCTLN_CCIS_1 +#define TIMER_A_CAPTURE_INPUTSELECT_GND TIMER_A_CCTLN_CCIS_2 +#define TIMER_A_CAPTURE_INPUTSELECT_Vcc TIMER_A_CCTLN_CCIS_3 + +//***************************************************************************** +// +// The following are values that can be passed to the compareOutputMode +// parameter +// +//***************************************************************************** +#define TIMER_A_OUTPUTMODE_OUTBITVALUE TIMER_A_CCTLN_OUTMOD_0 +#define TIMER_A_OUTPUTMODE_SET TIMER_A_CCTLN_OUTMOD_1 +#define TIMER_A_OUTPUTMODE_TOGGLE_RESET TIMER_A_CCTLN_OUTMOD_2 +#define TIMER_A_OUTPUTMODE_SET_RESET TIMER_A_CCTLN_OUTMOD_3 +#define TIMER_A_OUTPUTMODE_TOGGLE TIMER_A_CCTLN_OUTMOD_4 +#define TIMER_A_OUTPUTMODE_RESET TIMER_A_CCTLN_OUTMOD_5 +#define TIMER_A_OUTPUTMODE_TOGGLE_SET TIMER_A_CCTLN_OUTMOD_6 +#define TIMER_A_OUTPUTMODE_RESET_SET TIMER_A_CCTLN_OUTMOD_7 + +//***************************************************************************** +// +// The following are values that can be passed to the compareRegister parameter +// +//***************************************************************************** +#define TIMER_A_CAPTURECOMPARE_REGISTER_0 0x02 +#define TIMER_A_CAPTURECOMPARE_REGISTER_1 0x04 +#define TIMER_A_CAPTURECOMPARE_REGISTER_2 0x06 +#define TIMER_A_CAPTURECOMPARE_REGISTER_3 0x08 +#define TIMER_A_CAPTURECOMPARE_REGISTER_4 0x0A +#define TIMER_A_CAPTURECOMPARE_REGISTER_5 0x0C +#define TIMER_A_CAPTURECOMPARE_REGISTER_6 0x0E + +//***************************************************************************** +// +// The following are values that can be passed to the captureMode parameter +// +//***************************************************************************** +#define TIMER_A_CAPTUREMODE_NO_CAPTURE TIMER_A_CCTLN_CM_0 +#define TIMER_A_CAPTUREMODE_RISING_EDGE TIMER_A_CCTLN_CM_1 +#define TIMER_A_CAPTUREMODE_FALLING_EDGE TIMER_A_CCTLN_CM_2 +#define TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE TIMER_A_CCTLN_CM_3 + +//***************************************************************************** +// +// The following are values that can be passed to the synchronizeCaptureSource +// parameter +// +//***************************************************************************** +#define TIMER_A_CAPTURE_ASYNCHRONOUS 0x00 +#define TIMER_A_CAPTURE_SYNCHRONOUS TIMER_A_CCTLN_SCS + +//***************************************************************************** +// +// The following are values that can be passed to the mask parameter +// +//***************************************************************************** +#define TIMER_A_CAPTURE_OVERFLOW TIMER_A_CCTLN_COV +#define TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG TIMER_A_CCTLN_CCIFG + +//***************************************************************************** +// +// The following are values that can be passed to the synchronized parameter +// +//***************************************************************************** +#define TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT TIMER_A_CCTLN_SCCI +#define TIMER_A_READ_CAPTURE_COMPARE_INPUT TIMER_A_CCTLN_CCI + + +#define TIMER_A_CAPTURECOMPARE_INPUT_HIGH 0x01 +#define TIMER_A_CAPTURECOMPARE_INPUT_LOW 0x00 + +//***************************************************************************** +// +// The following are values that can be passed to the outputModeOutBitValue +// parameter +// +//***************************************************************************** +#define TIMER_A_OUTPUTMODE_OUTBITVALUE_HIGH TIMER_A_CCTLN_OUT +#define TIMER_A_OUTPUTMODE_OUTBITVALUE_LOW 0x00 + +//***************************************************************************** +// +// The following are values that can be passed toThe following are values that +// can be returned by the interrupt functions +// +//***************************************************************************** +#define TIMER_A_INTERRUPT_NOT_PENDING 0x00 +#define TIMER_A_INTERRUPT_PENDING 0x01 + + +/* Convenience function for setting the PWM Duty Cycle */ +#define Timer_A_setDutyCycle(timer,dutyCycle) \ + Timer_A_setCompareValue(timer,dutyCycle) + +//***************************************************************************** +// +//Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! Starts Timer_A counter +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param timerMode selects Clock source. Valid values are +//! - \b TIMER_A_CONTINUOUS_MODE [Default value] +//! - \b TIMER_A_UPDOWN_MODE +//! - \b TIMER_A_UP_MODE +//! +//! \note This function assumes that the timer has been previously configured +//! using Timer_A_configureContinuousMode, Timer_A_configureUpMode or +//! Timer_A_configureUpDownMode. +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_startCounter(uint32_t timer, uint_fast16_t timerMode); + +//***************************************************************************** +// +//! Configures Timer_A in continuous mode. +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param config Configuration structure for Timer_A continuous mode +//! +//!
+//! Configuration options for \link Timer_A_ContinuousModeConfig \endlink +//! structure. +//!
+//! +//! \param clockSource selects Clock source. Valid values are +//! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default value] +//! - \b TIMER_A_CLOCKSOURCE_ACLK +//! - \b TIMER_A_CLOCKSOURCE_SMCLK +//! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK +//! \param timerInterruptEnable_TAIE is the divider for Clock source. +//! Valid values are: +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default value] +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64 +//! \param timerInterruptEnable_TAIE is to enable or disable Timer_A +//! interrupt. Valid values are +//! - \b TIMER_A_TAIE_INTERRUPT_ENABLE +//! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default value] +//! \param timerClear decides if Timer_A clock divider, count direction, +//! count need to be reset. Valid values are +//! - \b TIMER_A_DO_CLEAR +//! - \b TIMER_A_SKIP_CLEAR [Default value] +//! +//! \note This API does not start the timer. Timer needs to be started when +//! required using the Timer_A_startCounter API. +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_configureContinuousMode(uint32_t timer, + const Timer_A_ContinuousModeConfig *config); + +//***************************************************************************** +// +//! Configures Timer_A in up mode. +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param config Configuration structure for Timer_A Up mode +//! +//!
+//! Configuration options for \link Timer_A_UpModeConfig \endlink +//! structure. +//!
+//! \param clockSource selects Clock source. Valid values are +//! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default value] +//! - \b TIMER_A_CLOCKSOURCE_ACLK +//! - \b TIMER_A_CLOCKSOURCE_SMCLK +//! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK +//! \param clockSourceDivider is the divider for Clock source. Valid values +//! are: +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default value] +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64 +//! \param timerPeriod is the specified Timer_A period. This is the value +//! that gets written into the CCR0. Limited to 16 bits[uint16_t] +//! \param timerInterruptEnable_TAIE is to enable or disable Timer_A +//! interrupt. Valid values are: +//! - \b TIMER_A_TAIE_INTERRUPT_ENABLE and +//! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default value] +//! \param captureCompareInterruptEnable_CCR0_CCIE is to enable or disable +//! Timer_A CCR0 captureComapre interrupt. Valid values are +//! - \b TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE and +//! - \b TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE [Default value] +//! \param timerClear decides if Timer_A clock divider, count direction, +//! count need to be reset. Valid values are +//! - \b TIMER_A_DO_CLEAR +//! - \b TIMER_A_SKIP_CLEAR [Default value] +//! +//!\note This API does not start the timer. Timer needs to be started when +//!required using the Timer_A_startCounter API. +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_configureUpMode(uint32_t timer, + const Timer_A_UpModeConfig *config); + +//***************************************************************************** +// +//! Configures Timer_A in up down mode. +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param config Configuration structure for Timer_A UpDown mode +//! +//!
+//! Configuration options for \link Timer_A_UpDownModeConfig \endlink +//! structure. +//!
+//! \param clockSource selects Clock source. Valid values are +//! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK [Default value] +//! - \b TIMER_A_CLOCKSOURCE_ACLK +//! - \b TIMER_A_CLOCKSOURCE_SMCLK +//! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK +//! \param clockSourceDivider is the divider for Clock source. Valid values +//! are: +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 [Default value] +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64 +//! \param timerPeriod is the specified Timer_A period +//! \param timerInterruptEnable_TAIE is to enable or disable Timer_A +//! interrupt. +//! Valid values are +//! - \b TIMER_A_TAIE_INTERRUPT_ENABLE +//! - \b TIMER_A_TAIE_INTERRUPT_DISABLE [Default value] +//! \param captureCompareInterruptEnable_CCR0_CCIE is to enable or disable +//! Timer_A CCR0 captureComapre interrupt. Valid values are +//! - \b TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE and +//! - \b TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE [Default value] +//! \param timerClear decides if Timer_A clock divider, count direction, count +//! need to be reset. Valid values are +//! - \b TIMER_A_DO_CLEAR +//! - \b TIMER_A_SKIP_CLEAR [Default value] +//! +//!This API does not start the timer. Timer needs to be started when required +//!using the Timer_A_startCounter API. +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_configureUpDownMode(uint32_t timer, + const Timer_A_UpDownModeConfig *config); + +//***************************************************************************** +// +//! Initializes Capture Mode +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param config Configuration structure for Timer_A capture mode +//! +//!
+//! Configuration options for \link Timer_A_CaptureModeConfig \endlink +//! structure. +//!
+//! \param captureRegister selects the Capture register being used. Valid +//! values are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//! \n Refer to datasheet to ensure the device has the capture compare +//! register being used +//! \param captureMode is the capture mode selected. Valid values are +//! - \b TIMER_A_CAPTUREMODE_NO_CAPTURE [Default value] +//! - \b TIMER_A_CAPTUREMODE_RISING_EDGE +//! - \b TIMER_A_CAPTUREMODE_FALLING_EDGE +//! - \b TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE +//! \param captureInputSelect decides the Input Select +//! - \b TIMER_A_CAPTURE_INPUTSELECT_CCIxA [Default value] +//! - \b TIMER_A_CAPTURE_INPUTSELECT_CCIxB +//! - \b TIMER_A_CAPTURE_INPUTSELECT_GND +//! - \b TIMER_A_CAPTURE_INPUTSELECT_Vcc +//! \param synchronizeCaptureSource decides if capture source should be +//! synchronized with timer clock +//! Valid values are +//! - \b TIMER_A_CAPTURE_ASYNCHRONOUS [Default value] +//! - \b TIMER_A_CAPTURE_SYNCHRONOUS +//! \param captureInterruptEnable is to enable or disable +//! timer captureComapre interrupt. Valid values are +//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE [Default value] +//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE +//! \param captureOutputMode specifies the ouput mode. Valid values are +//! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE [Default value], +//! - \b TIMER_A_OUTPUTMODE_SET, +//! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET, +//! - \b TIMER_A_OUTPUTMODE_SET_RESET +//! - \b TIMER_A_OUTPUTMODE_TOGGLE, +//! - \b TIMER_A_OUTPUTMODE_RESET, +//! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET, +//! - \b TIMER_A_OUTPUTMODE_RESET_SET +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_initCapture(uint32_t timer, + const Timer_A_CaptureModeConfig *config); + +//***************************************************************************** +// +//! Initializes Compare Mode +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param config Configuration structure for Timer_A compare mode +//! +//!
+//! Configuration options for \link Timer_A_CompareModeConfig \endlink +//! structure. +//!
+//! \param compareRegister selects the Capture register being used. Valid +//! values are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//! \n Refer to datasheet to ensure the device has the capture compare +//! register being used +//! \param compareInterruptEnable is to enable or disable +//! timer captureComapre interrupt. Valid values are +//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE and +//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE [Default value] +//! \param compareOutputMode specifies the output mode. Valid values are +//! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE [Default value], +//! - \b TIMER_A_OUTPUTMODE_SET, +//! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET, +//! - \b TIMER_A_OUTPUTMODE_SET_RESET +//! - \b TIMER_A_OUTPUTMODE_TOGGLE, +//! - \b TIMER_A_OUTPUTMODE_RESET, +//! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET, +//! - \b TIMER_A_OUTPUTMODE_RESET_SET +//! \param compareValue is the count to be compared with in compare mode +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_initCompare(uint32_t timer, + const Timer_A_CompareModeConfig *config); + +//***************************************************************************** +// +//! Reset/Clear the timer clock divider, count direction, count +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \returns None +// +//***************************************************************************** +extern void Timer_A_clearTimer(uint32_t timer); + +//***************************************************************************** +// +//! Get synchronized capture compare input +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister selects the Capture register being used. +//! Valid values are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//! \n Refer to datasheet to ensure the device has the capture compare +//! register being used +//! \param synchronizedSetting is to select type of capture compare input. +//! Valid values are +//! - \b TIMER_A_READ_CAPTURE_COMPARE_INPUT +//! - \b TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT +//! +//! \return \b TIMER_A_CAPTURECOMPARE_INPUT_HIGH or +//! - \b TIMER_A_CAPTURECOMPARE_INPUT_LOW +// +//***************************************************************************** +extern uint_fast8_t Timer_A_getSynchronizedCaptureCompareInput(uint32_t timer, + uint_fast16_t captureCompareRegister, + uint_fast16_t synchronizedSetting); + +//***************************************************************************** +// +//! Get ouput bit for output mode +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister selects the Capture register being used. +//! Valid values are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//! \n Refer to datasheet to ensure the device has the capture compare +//! register being used +//! +//! \return \b TIMER_A_OUTPUTMODE_OUTBITVALUE_HIGH or +//! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE_LOW +// +//***************************************************************************** +extern uint_fast8_t Timer_A_getOutputForOutputModeOutBitValue(uint32_t timer, + uint_fast16_t captureCompareRegister); + +//***************************************************************************** +// +//! Get current capture compare count +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister selects the Capture register being used. +//! Valid values are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//! \n Refer to datasheet to ensure the device has the capture compare +//! register being used +//! +//! \return current count as uint16_t +// +//***************************************************************************** +extern uint_fast16_t Timer_A_getCaptureCompareCount(uint32_t timer, + uint_fast16_t captureCompareRegister); + +//***************************************************************************** +// +//! Set ouput bit for output mode +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister selects the Capture register being used. +//! are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//! \n Refer to datasheet to ensure the device has the capture compare +//! register being used +//! \param outputModeOutBitValue the value to be set for out bit. +//! Valid values are: +//! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE_HIGH +//! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE_LOW +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_setOutputForOutputModeOutBitValue(uint32_t timer, + uint_fast16_t captureCompareRegister, + uint_fast8_t outputModeOutBitValue); + +//***************************************************************************** +// +//! Generate a PWM with timer running in up mode +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param config Configuration structure for Timer_A PWM mode +//! +//!
+//! Configuration options for \link Timer_A_PWMConfig \endlink +//! structure. +//!
+//! \param clockSource selects Clock source. Valid values are +//! - \b TIMER_A_CLOCKSOURCE_EXTERNAL_TXCLK +//! - \b TIMER_A_CLOCKSOURCE_ACLK +//! - \b TIMER_A_CLOCKSOURCE_SMCLK +//! - \b TIMER_A_CLOCKSOURCE_INVERTED_EXTERNAL_TXCLK +//! \param clockSourceDivider is the divider for Clock source. Valid values +//! are +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_1 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_2 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_4 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_8 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_3 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_5 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_6 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_7 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_10 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_12 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_14 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_16 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_20 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_24 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_28 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_32 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_40 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_48 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_56 +//! - \b TIMER_A_CLOCKSOURCE_DIVIDER_64 +//! \param timerPeriod selects the desired timer period +//! \param compareRegister selects the compare register being used. +//! Valid values are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//!
\n Refer to datasheet to ensure the device has the capture compare +//! register being used +//! \param compareOutputMode specifies the ouput mode. Valid values are: +//! - \b TIMER_A_OUTPUTMODE_OUTBITVALUE, +//! - \b TIMER_A_OUTPUTMODE_SET, +//! - \b TIMER_A_OUTPUTMODE_TOGGLE_RESET, +//! - \b TIMER_A_OUTPUTMODE_SET_RESET +//! - \b TIMER_A_OUTPUTMODE_TOGGLE, +//! - \b TIMER_A_OUTPUTMODE_RESET, +//! - \b TIMER_A_OUTPUTMODE_TOGGLE_SET, +//! - \b TIMER_A_OUTPUTMODE_RESET_SET +//! \param dutyCycle specifies the dutycycle for the generated waveform +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_generatePWM(uint32_t timer, + const Timer_A_PWMConfig *config); + +//***************************************************************************** +// +//! Stops the timer +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \returns None +// +//***************************************************************************** +extern void Timer_A_stopTimer(uint32_t timer); + +//***************************************************************************** +// +//! Sets the value of the capture-compare register +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param compareRegister selects the Capture register being used. Valid +//! values are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//!
\n Refer to datasheet to ensure the device has the capture compare +//! register being used +//! \param compareValue is the count to be compared with in compare mode +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_setCompareValue(uint32_t timer, + uint_fast16_t compareRegister, uint_fast16_t compareValue); + +//***************************************************************************** +// +//! Returns the current value of the specified timer. Note that according to +//! the Timer A user guide, reading the value of the counter is unreliable +//! if the system clock is asynchronous from the timer clock. The API addresses +//! this concern by reading the timer count register twice and then determining +//! the integrity of the value. If the two values are within 10 timer counts +//! of each other, the value is deemed safe and returned. If not, the process +//! is repeated until a reliable timer value is determined. +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \returns The value of the specified timer +// +//***************************************************************************** +extern uint16_t Timer_A_getCounterValue(uint32_t timer); + +//***************************************************************************** +// +//! Clears the Timer TAIFG interrupt flag +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_clearInterruptFlag(uint32_t timer); + +//***************************************************************************** +// +//! Clears the capture-compare interrupt flag +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister selects the Capture-compare register being +//! used. Valid values are +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_0 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_1 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_2 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_3 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_4 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_5 +//! - \b TIMER_A_CAPTURECOMPARE_REGISTER_6 +//!
Refer to the datasheet to ensure the device has the capture compare +//! register being used +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_clearCaptureCompareInterrupt(uint32_t timer, + uint_fast16_t captureCompareRegister); + +//***************************************************************************** +// +//! Enable timer interrupt +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_enableInterrupt(uint32_t timer); + +//***************************************************************************** +// +//! Disable timer interrupt +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_disableInterrupt(uint32_t timer); + +//***************************************************************************** +// +//! Get timer interrupt status +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \return uint32_t. Return interrupt status. Valid values are +//! - \b TIMER_A_INTERRUPT_PENDING +//! - \b TIMER_A_INTERRUPT_NOT_PENDING +// +//***************************************************************************** +extern uint32_t Timer_A_getInterruptStatus(uint32_t timer); + +//***************************************************************************** +// +//! Get timer interrupt status masked with the enabled interrupts. +//! This function is useful to call in ISRs to get a list of pending +//! interrupts that are actually enabled and could have caused +//! the ISR. +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \return uint32_t. Return interrupt status. Valid values are +//! - \b TIMER_A_INTERRUPT_PENDING +//! - \b TIMER_A_INTERRUPT_NOT_PENDING +// +//***************************************************************************** +extern uint32_t Timer_A_getEnabledInterruptStatus(uint32_t timer); + +//***************************************************************************** +// +//! Enable capture compare interrupt +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister is the selected capture compare register +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_enableCaptureCompareInterrupt(uint32_t timer, + uint_fast16_t captureCompareRegister); + +//***************************************************************************** +// +//! Disable capture compare interrupt +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister is the selected capture compare register +//! +//! \return None +// +//***************************************************************************** +extern void Timer_A_disableCaptureCompareInterrupt(uint32_t timer, + uint_fast16_t captureCompareRegister); + +//***************************************************************************** +// +//! Return capture compare interrupt status +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister is the selected capture compare register +//! +//! \param mask is the mask for the interrupt status +//! Mask value is the logical OR of any of the following: +//! - \b TIMER_A_CAPTURE_OVERFLOW +//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG +//! +//! \returns uint32_t. The mask of the set flags. +//! Valid values is an OR of +//! - \b TIMER_A_CAPTURE_OVERFLOW, +//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG +// +//***************************************************************************** +extern uint32_t Timer_A_getCaptureCompareInterruptStatus(uint32_t timer, + uint_fast16_t captureCompareRegister, uint_fast16_t mask); + +//***************************************************************************** +// +//! Return capture compare interrupt status masked with the enabled interrupts. +//! This function is useful to call in ISRs to get a list of pending +//! interrupts that are actually enabled and could have caused +//! the ISR. +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! \param captureCompareRegister is the selected capture compare register +//! +//! \returns uint32_t. The mask of the set flags. +//! Valid values is an OR of +//! - \b TIMER_A_CAPTURE_OVERFLOW, +//! - \b TIMER_A_CAPTURECOMPARE_INTERRUPT_FLAG +// +//***************************************************************************** +extern uint32_t Timer_A_getCaptureCompareEnabledInterruptStatus(uint32_t timer, + uint_fast16_t captureCompareRegister); + +//***************************************************************************** +// +//! Registers an interrupt handler for the timer capture compare interrupt. +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \param interruptSelect Selects which timer interrupt handler to +//! register. For the timer module, there are two separate interrupt handlers +//! that can be registered: +//! - \b TIMER_A_CCR0_INTERRUPT Corresponds to the interrupt for CCR0 +//! - \b TIMER_A_CCRX_AND_OVERFLOW_INTERRUPT Corresponds to the +//! interrupt for CCR1-6, as well as the overflow interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the +//! timer capture compare interrupt occurs. +//! +//! This function registers the handler to be called when a timer +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific Timer_Ainterrupts must be enabled +//! via Timer_A_enableInterrupt(). It is the interrupt handler's +//! responsibility to clear the interrupt source +//! via Timer_A_clearCaptureCompareInterrupt(). +//! +//! \return None. +// +//***************************************************************************** +extern void Timer_A_registerInterrupt(uint32_t timer, + uint_fast8_t interruptSelect, void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the timer +//! +//! \param timer is the instance of the Timer_A module. Valid parameters +//! vary from part to part, but can include: +//! - \b TIMER_A0_BASE +//! - \b TIMER_A1_BASE +//! - \b TIMER_A2_BASE +//! - \b TIMER_A3_BASE +//! +//! \param interruptSelect Selects which timer interrupt handler to +//! register. For the timer module, there are two separate interrupt handlers +//! that can be registered: +//! - \b TIMER_A_CCR0_INTERRUPT Corresponds to the interrupt for CCR0 +//! - \b TIMER_A_CCRX_AND_OVERFLOW_INTERRUPT Corresponds to the +//! interrupt for CCR1-6, as well as the overflow interrupt. +//! +//! This function unregisters the handler to be called when timer +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void Timer_A_unregisterInterrupt(uint32_t timer, + uint_fast8_t interruptSelect); + +/* Backwards Compatibility Layer */ +#define Timer_A_clearTimerInterrupt Timer_A_clearInterruptFlag +#define Timer_A_clear Timer_A_clearTimer +#define Timer_A_initCaptureMode Timer_A_initCapture +#define Timer_A_initCompareMode Timer_A_initCompare +#define Timer_A_initContinuousMode Timer_A_configureContinuousMode +#define Timer_A_initUpDownMode Timer_A_configureUpDownMode +#define Timer_A_initUpMode Timer_A_configureUpMode +#define Timer_A_outputPWM Timer_A_generatePWM +#define Timer_A_stop Timer_A_stopTimer + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif /* TIMERA_H_ */ diff --git a/example/rt_msp432/MSP432P4xx/uart.c b/example/rt_msp432/MSP432P4xx/uart.c new file mode 100644 index 0000000..2b9e6ab --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/uart.c @@ -0,0 +1,396 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#include +#include +#include +#include + +bool UART_initModule(uint32_t moduleInstance, const eUSCI_UART_Config *config) +{ + bool retVal = true; + + ASSERT( + (EUSCI_A_UART_MODE == config->uartMode) + || (EUSCI_A_UART_IDLE_LINE_MULTI_PROCESSOR_MODE + == config->uartMode) + || (EUSCI_A_UART_ADDRESS_BIT_MULTI_PROCESSOR_MODE + == config->uartMode) + || (EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE + == config->uartMode)); + + ASSERT( + (EUSCI_A_UART_CLOCKSOURCE_ACLK == config->selectClockSource) + || (EUSCI_A_UART_CLOCKSOURCE_SMCLK + == config->selectClockSource)); + + ASSERT( + (EUSCI_A_UART_MSB_FIRST == config->msborLsbFirst) + || (EUSCI_A_UART_LSB_FIRST == config->msborLsbFirst)); + + ASSERT( + (EUSCI_A_UART_ONE_STOP_BIT == config->numberofStopBits) + || (EUSCI_A_UART_TWO_STOP_BITS == config->numberofStopBits)); + + ASSERT( + (EUSCI_A_UART_NO_PARITY == config->parity) + || (EUSCI_A_UART_ODD_PARITY == config->parity) + || (EUSCI_A_UART_EVEN_PARITY == config->parity)); + + /* Disable the USCI Module */ + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; + + /* Clock source select */ + EUSCI_A_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_A_CMSIS(moduleInstance)->CTLW0 & ~EUSCI_A_CTLW0_SSEL_MASK) + | config->selectClockSource; + + /* MSB, LSB select */ + if (config->msborLsbFirst) + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_MSB_OFS) = 1; + else + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_MSB_OFS) = 0; + + /* UCSPB = 0(1 stop bit) OR 1(2 stop bits) */ + if (config->numberofStopBits) + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SPB_OFS) = 1; + else + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SPB_OFS) = 0; + + /* Parity */ + switch (config->parity) + { + case EUSCI_A_UART_NO_PARITY: + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PEN_OFS) = 0; + break; + case EUSCI_A_UART_ODD_PARITY: + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PEN_OFS) = 1; + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PAR_OFS) = 0; + break; + case EUSCI_A_UART_EVEN_PARITY: + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PEN_OFS) = 1; + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_PAR_OFS) = 1; + break; + } + + /* BaudRate Control Register */ + EUSCI_A_CMSIS(moduleInstance)->BRW = config->clockPrescalar; + EUSCI_A_CMSIS(moduleInstance)->MCTLW = ((config->secondModReg << 8) + + (config->firstModReg << 4) + config->overSampling); + + /* Asynchronous mode & 8 bit character select & clear mode */ + EUSCI_A_CMSIS(moduleInstance)->CTLW0 = + (EUSCI_A_CMSIS(moduleInstance)->CTLW0 + & ~(EUSCI_A_CTLW0_SYNC | EUSCI_A_CTLW0_SEVENBIT | EUSCI_A_CTLW0_MODE_3 | EUSCI_A_CTLW0_RXEIE | EUSCI_A_CTLW0_BRKIE | EUSCI_A_CTLW0_DORM + | EUSCI_A_CTLW0_TXADDR | EUSCI_A_CTLW0_TXBRK)) | config->uartMode; + + return retVal; +} + +void UART_transmitData(uint32_t moduleInstance, uint_fast8_t transmitData) +{ + /* If interrupts are not used, poll for flags */ + if (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IE, EUSCI_A__TXIE_OFS)) + while (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IFG, EUSCI_A_IFG_TXIFG_OFS)) + ; + + EUSCI_A_CMSIS(moduleInstance)->TXBUF = transmitData; +} + +uint8_t UART_receiveData(uint32_t moduleInstance) +{ + /* If interrupts are not used, poll for flags */ + if (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IE, EUSCI_A__RXIE_OFS)) + while (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IFG, EUSCI_A_IFG_RXIFG_OFS)) + ; + + return EUSCI_A_CMSIS(moduleInstance)->RXBUF; +} + +void UART_enableModule(uint32_t moduleInstance) +{ + /* Reset the UCSWRST bit to enable the USCI Module */ + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 0; +} + +void UART_disableModule(uint32_t moduleInstance) +{ + /* Set the UCSWRST bit to disable the USCI Module */ + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_SWRST_OFS) = 1; +} + +uint_fast8_t UART_queryStatusFlags(uint32_t moduleInstance, uint_fast8_t mask) +{ + ASSERT( + 0x00 != mask + && (EUSCI_A_UART_LISTEN_ENABLE + EUSCI_A_UART_FRAMING_ERROR + + EUSCI_A_UART_OVERRUN_ERROR + + EUSCI_A_UART_PARITY_ERROR + + EUSCI_A_UART_BREAK_DETECT + + EUSCI_A_UART_RECEIVE_ERROR + + EUSCI_A_UART_ADDRESS_RECEIVED + + EUSCI_A_UART_IDLELINE + EUSCI_A_UART_BUSY)); + + return EUSCI_A_CMSIS(moduleInstance)->STATW & mask; +} + +void UART_setDormant(uint32_t moduleInstance) +{ + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_DORM_OFS) = 1; +} + +void UART_resetDormant(uint32_t moduleInstance) +{ + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_DORM_OFS) = 0; +} + +void UART_transmitAddress(uint32_t moduleInstance, uint_fast8_t transmitAddress) +{ + /* Set UCTXADDR bit */ + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_TXADDR_OFS) = 1; + + /* Place next byte to be sent into the transmit buffer */ + EUSCI_A_CMSIS(moduleInstance)->TXBUF = transmitAddress; +} + +void UART_transmitBreak(uint32_t moduleInstance) +{ + /* Set UCTXADDR bit */ + BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->CTLW0, EUSCI_A_CTLW0_TXBRK_OFS) = 1; + + /* If current mode is automatic baud-rate detection */ + if (EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE + == (EUSCI_A_CMSIS(moduleInstance)->CTLW0 + & EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE)) + EUSCI_A_CMSIS(moduleInstance)->TXBUF = + EUSCI_A_UART_AUTOMATICBAUDRATE_SYNC; + else + EUSCI_A_CMSIS(moduleInstance)->TXBUF = DEFAULT_SYNC; + + /* If interrupts are not used, poll for flags */ + if (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IE, EUSCI_A__TXIE_OFS)) + while (!BITBAND_PERI(EUSCI_A_CMSIS(moduleInstance)->IFG, EUSCI_A_IFG_TXIFG_OFS)) + ; +} + +uint32_t UART_getReceiveBufferAddressForDMA(uint32_t moduleInstance) +{ + return (uint32_t)&EUSCI_A_CMSIS(moduleInstance)->RXBUF; +} + +uint32_t UART_getTransmitBufferAddressForDMA(uint32_t moduleInstance) +{ + return (uint32_t)&EUSCI_B_CMSIS(moduleInstance)->TXBUF; +} + +void UART_selectDeglitchTime(uint32_t moduleInstance, uint32_t deglitchTime) +{ + ASSERT( + (EUSCI_A_UART_DEGLITCH_TIME_2ns == deglitchTime) + || (EUSCI_A_UART_DEGLITCH_TIME_50ns == deglitchTime) + || (EUSCI_A_UART_DEGLITCH_TIME_100ns == deglitchTime) + || (EUSCI_A_UART_DEGLITCH_TIME_200ns == deglitchTime)); + + EUSCI_A_CMSIS(moduleInstance)->CTLW1 = + (EUSCI_A_CMSIS(moduleInstance)->CTLW1 & ~(EUSCI_A_CTLW1_GLIT_MASK)) + | deglitchTime; + +} + +void UART_enableInterrupt(uint32_t moduleInstance, uint_fast8_t mask) +{ + uint_fast8_t locMask; + + ASSERT( + !(mask + & ~(EUSCI_A_UART_RECEIVE_INTERRUPT + | EUSCI_A_UART_TRANSMIT_INTERRUPT + | EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT + | EUSCI_A_UART_BREAKCHAR_INTERRUPT + | EUSCI_A_UART_STARTBIT_INTERRUPT + | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT))); + + locMask = (mask + & (EUSCI_A_UART_RECEIVE_INTERRUPT | EUSCI_A_UART_TRANSMIT_INTERRUPT + | EUSCI_A_UART_STARTBIT_INTERRUPT + | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT)); + + EUSCI_A_CMSIS(moduleInstance)->IE |= locMask; + + locMask = (mask + & (EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT + | EUSCI_A_UART_BREAKCHAR_INTERRUPT)); + EUSCI_A_CMSIS(moduleInstance)->CTLW0 |= locMask; +} + +void UART_disableInterrupt(uint32_t moduleInstance, uint_fast8_t mask) +{ + uint_fast8_t locMask; + + ASSERT( + !(mask + & ~(EUSCI_A_UART_RECEIVE_INTERRUPT + | EUSCI_A_UART_TRANSMIT_INTERRUPT + | EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT + | EUSCI_A_UART_BREAKCHAR_INTERRUPT + | EUSCI_A_UART_STARTBIT_INTERRUPT + | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT))); + + locMask = (mask + & (EUSCI_A_UART_RECEIVE_INTERRUPT | EUSCI_A_UART_TRANSMIT_INTERRUPT + | EUSCI_A_UART_STARTBIT_INTERRUPT + | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT)); + EUSCI_A_CMSIS(moduleInstance)->IE &= ~locMask; + + locMask = (mask + & (EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT + | EUSCI_A_UART_BREAKCHAR_INTERRUPT)); + EUSCI_A_CMSIS(moduleInstance)->CTLW0 &= ~locMask; +} + +uint_fast8_t UART_getInterruptStatus(uint32_t moduleInstance, uint8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG + | EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG + | EUSCI_A_UART_STARTBIT_INTERRUPT_FLAG + | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG))); + + return EUSCI_A_CMSIS(moduleInstance)->IFG & mask; +} + +uint_fast8_t UART_getEnabledInterruptStatus(uint32_t moduleInstance) +{ + uint_fast8_t intStatus = UART_getInterruptStatus(moduleInstance, + EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG | EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG); + uint_fast8_t intEnabled = EUSCI_A_CMSIS(moduleInstance)->IE; + + if (!(intEnabled & EUSCI_A_UART_RECEIVE_INTERRUPT)) + { + intStatus &= ~EUSCI_A_UART_RECEIVE_INTERRUPT; + } + + if (!(intEnabled & EUSCI_A_UART_TRANSMIT_INTERRUPT)) + { + intStatus &= ~EUSCI_A_UART_TRANSMIT_INTERRUPT; + } + + intEnabled = EUSCI_A_CMSIS(moduleInstance)->CTLW0; + + if (!(intEnabled & EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT)) + { + intStatus &= ~EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT; + } + + if (!(intEnabled & EUSCI_A_UART_BREAKCHAR_INTERRUPT)) + { + intStatus &= ~EUSCI_A_UART_BREAKCHAR_INTERRUPT; + } + + return intStatus; +} + +void UART_clearInterruptFlag(uint32_t moduleInstance, uint_fast8_t mask) +{ + ASSERT( + !(mask + & ~(EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG + | EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG + | EUSCI_A_UART_STARTBIT_INTERRUPT_FLAG + | EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG))); + + //Clear the UART interrupt source. + EUSCI_A_CMSIS(moduleInstance)->IFG &= ~(mask); +} + +void UART_registerInterrupt(uint32_t moduleInstance, void (*intHandler)(void)) +{ + switch (moduleInstance) + { + case EUSCI_A0_BASE: + Interrupt_registerInterrupt(INT_EUSCIA0, intHandler); + Interrupt_enableInterrupt(INT_EUSCIA0); + break; + case EUSCI_A1_BASE: + Interrupt_registerInterrupt(INT_EUSCIA1, intHandler); + Interrupt_enableInterrupt(INT_EUSCIA1); + break; +#ifdef EUSCI_A2_BASE + case EUSCI_A2_BASE: + Interrupt_registerInterrupt(INT_EUSCIA2, intHandler); + Interrupt_enableInterrupt(INT_EUSCIA2); + break; +#endif +#ifdef EUSCI_A3_BASE + case EUSCI_A3_BASE: + Interrupt_registerInterrupt(INT_EUSCIA3, intHandler); + Interrupt_enableInterrupt(INT_EUSCIA3); + break; +#endif + default: + ASSERT(false); + } +} + +void UART_unregisterInterrupt(uint32_t moduleInstance) +{ + switch (moduleInstance) + { + case EUSCI_A0_BASE: + Interrupt_disableInterrupt(INT_EUSCIA0); + Interrupt_unregisterInterrupt(INT_EUSCIA0); + break; + case EUSCI_A1_BASE: + Interrupt_disableInterrupt(INT_EUSCIA1); + Interrupt_unregisterInterrupt(INT_EUSCIA1); + break; +#ifdef EUSCI_A2_BASE + case EUSCI_A2_BASE: + Interrupt_disableInterrupt(INT_EUSCIA2); + Interrupt_unregisterInterrupt(INT_EUSCIA2); + break; +#endif +#ifdef EUSCI_A3_BASE + case EUSCI_A3_BASE: + Interrupt_disableInterrupt(INT_EUSCIA3); + Interrupt_unregisterInterrupt(INT_EUSCIA3); + break; +#endif + default: + ASSERT(false); + } +} diff --git a/example/rt_msp432/MSP432P4xx/uart.h b/example/rt_msp432/MSP432P4xx/uart.h new file mode 100644 index 0000000..1db85f9 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/uart.h @@ -0,0 +1,760 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef UART_H_ +#define UART_H_ + +//***************************************************************************** +// +//! \addtogroup uart_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +#include +#include "eusci.h" + +#define DEFAULT_SYNC 0x00 +#define EUSCI_A_UART_AUTOMATICBAUDRATE_SYNC 0x55 + +#define EUSCI_A_UART_NO_PARITY 0x00 +#define EUSCI_A_UART_ODD_PARITY 0x01 +#define EUSCI_A_UART_EVEN_PARITY 0x02 + +#define EUSCI_A_UART_MSB_FIRST EUSCI_A_CTLW0_MSB +#define EUSCI_A_UART_LSB_FIRST 0x00 + +#define EUSCI_A_UART_MODE EUSCI_A_CTLW0_MODE_0 +#define EUSCI_A_UART_IDLE_LINE_MULTI_PROCESSOR_MODE EUSCI_A_CTLW0_MODE_1 +#define EUSCI_A_UART_ADDRESS_BIT_MULTI_PROCESSOR_MODE EUSCI_A_CTLW0_MODE_2 +#define EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE EUSCI_A_CTLW0_MODE_3 + +#define EUSCI_A_UART_CLOCKSOURCE_SMCLK EUSCI_A_CTLW0_SSEL__SMCLK +#define EUSCI_A_UART_CLOCKSOURCE_ACLK EUSCI_A_CTLW0_SSEL__ACLK + +#define EUSCI_A_UART_ONE_STOP_BIT 0x00 +#define EUSCI_A_UART_TWO_STOP_BITS EUSCI_A_CTLW0_SPB + +#define EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION 0x01 +#define EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION 0x00 + +#define EUSCI_A_UART_RECEIVE_INTERRUPT EUSCI_A_IE_RXIE +#define EUSCI_A_UART_TRANSMIT_INTERRUPT EUSCI_A_IE_TXIE +#define EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT EUSCI_A_CTLW0_RXEIE +#define EUSCI_A_UART_BREAKCHAR_INTERRUPT EUSCI_A_CTLW0_BRKIE +#define EUSCI_A_UART_STARTBIT_INTERRUPT EUSCI_A_IE_STTIE +#define EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT EUSCI_B_IE_STPIE + +#define EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG EUSCI_A_IFG_RXIFG +#define EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG EUSCI_A_IFG_TXIFG +#define EUSCI_A_UART_STARTBIT_INTERRUPT_FLAG EUSCI_A_IFG_STTIFG +#define EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG EUSCI_A_IFG_TXCPTIFG + +#define EUSCI_A_UART_LISTEN_ENABLE EUSCI_A_STATW_LISTEN +#define EUSCI_A_UART_FRAMING_ERROR EUSCI_A_STATW_FE +#define EUSCI_A_UART_OVERRUN_ERROR EUSCI_A_STATW_OE +#define EUSCI_A_UART_PARITY_ERROR EUSCI_A_STATW_PE +#define EUSCI_A_UART_BREAK_DETECT EUSCI_A_STATW_BRK +#define EUSCI_A_UART_RECEIVE_ERROR EUSCI_A_STATW_RXERR +#define EUSCI_A_UART_ADDRESS_RECEIVED EUSCI_A_STATW_ADDR_IDLE +#define EUSCI_A_UART_IDLELINE EUSCI_A_STATW_ADDR_IDLE +#define EUSCI_A_UART_BUSY EUSCI_A_STATW_BUSY + +#define EUSCI_A_UART_DEGLITCH_TIME_2ns 0x00 +#define EUSCI_A_UART_DEGLITCH_TIME_50ns 0x0001 +#define EUSCI_A_UART_DEGLITCH_TIME_100ns 0x0002 +#define EUSCI_A_UART_DEGLITCH_TIME_200ns (0x0001 + 0x0002) + +//***************************************************************************** +// +//! ypedef eUSCI_eUSCI_UART_Config +//! \brief Type definition for \link _eUSCI_UART_Config \endlink +//! structure +//! +//! \struct _eUSCI_eUSCI_UART_Config +//! \brief Configuration structure for compare mode in the \b UART module. See +//! \link UART_initModule \endlink for parameter +//! documentation. +// +//***************************************************************************** +typedef struct _eUSCI_eUSCI_UART_Config +{ + uint_fast8_t selectClockSource; + uint_fast16_t clockPrescalar; + uint_fast8_t firstModReg; + uint_fast8_t secondModReg; + uint_fast8_t parity; + uint_fast16_t msborLsbFirst; + uint_fast16_t numberofStopBits; + uint_fast16_t uartMode; + uint_fast8_t overSampling; +} eUSCI_UART_Config; + +//***************************************************************************** +// +//! Initialization routine for the UART block. The values to be written +//! into the UCAxBRW and UCAxMCTLW registers should be pre-computed and passed +//! into the initialization function +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//! \param config Configuration structure for the UART module +//! +//!
+//! Configuration options for \link eUSCI_UART_Config \endlink +//! structure. +//!
+//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode. +//! \param selectClockSource selects Clock source. Valid values are +//! - \b EUSCI_A_UART_CLOCKSOURCE_SMCLK +//! - \b EUSCI_A_UART_CLOCKSOURCE_ACLK +//! \param clockPrescalar is the value to be written into UCBRx bits +//! \param firstModReg is First modulation stage register setting. This +//! value is a pre-calculated value which can be obtained from the Device +//! User Guide.This value is written into UCBRFx bits of UCAxMCTLW. +//! \param secondModReg is Second modulation stage register setting. +//! This value is a pre-calculated value which can be obtained from the +//! Device User Guide. This value is written into UCBRSx bits of +//! UCAxMCTLW. +//! \param parity is the desired parity. Valid values are +//! - \b EUSCI_A_UART_NO_PARITY [Default Value], +//! - \b EUSCI_A_UART_ODD_PARITY, +//! - \b EUSCI_A_UART_EVEN_PARITY +//! \param msborLsbFirst controls direction of receive and transmit shift +//! register. Valid values are +//! - \b EUSCI_A_UART_MSB_FIRST +//! - \b EUSCI_A_UART_LSB_FIRST [Default Value] +//! \param numberofStopBits indicates one/two STOP bits +//! Valid values are +//! - \b EUSCI_A_UART_ONE_STOP_BIT [Default Value] +//! - \b EUSCI_A_UART_TWO_STOP_BITS +//! \param uartMode selects the mode of operation +//! Valid values are +//! - \b EUSCI_A_UART_MODE [Default Value], +//! - \b EUSCI_A_UART_IDLE_LINE_MULTI_PROCESSOR_MODE, +//! - \b EUSCI_A_UART_ADDRESS_BIT_MULTI_PROCESSOR_MODE, +//! - \b EUSCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODE +//! \param overSampling indicates low frequency or oversampling baud +//! generation +//! Valid values are +//! - \b EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION +//! - \b EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION +//! +//! Upon successful initialization of the UART block, this function +//! will have initialized the module, but the UART block still remains +//! disabled and must be enabled with UART_enableModule() +//! +//! Refer to +//! +//! this calculator for help on calculating values for the parameters. +//! +//! Modified bits are \b UCPEN, \b UCPAR, \b UCMSB, \b UC7BIT, \b UCSPB, +//! \b UCMODEx, \b UCSYNC bits of \b UCAxCTL0 and \b UCSSELx, +//! \b UCSWRST bits of \b UCAxCTL1 +//! +//! \return true or +//! STATUS_FAIL of the initialization process +// +//***************************************************************************** +extern bool UART_initModule(uint32_t moduleInstance, + const eUSCI_UART_Config *config); + +//***************************************************************************** +// +//! Transmits a byte from the UART Module. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! \param transmitData data to be transmitted from the UART module +//! +//! This function will place the supplied data into UART transmit data register +//! to start transmission +//! +//! Modified register is \b UCAxTXBUF +//! \return None. +// +//***************************************************************************** +extern void UART_transmitData(uint32_t moduleInstance, + uint_fast8_t transmitData); + +//***************************************************************************** +// +//! Receives a byte that has been sent to the UART Module. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! This function reads a byte of data from the UART receive data Register. +//! +//! Modified register is \b UCAxRXBUF +//! +//! \return Returns the byte received from by the UART module, cast as an +//! uint8_t. +// +//***************************************************************************** +extern uint8_t UART_receiveData(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Enables the UART block. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! This will enable operation of the UART block. +//! +//! Modified register is \b UCAxCTL1 +//! +//! \return None. +// +//***************************************************************************** +extern void UART_enableModule(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Disables the UART block. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! This will disable operation of the UART block. +//! +//! Modified register is \b UCAxCTL1 +//! +//! \return None. +// +//***************************************************************************** +extern void UART_disableModule(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Gets the current UART status flags. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! \param mask is the masked interrupt flag status to be returned. +//! +//! This returns the status for the UART module based on which +//! flag is passed. mask parameter can be either any of the following +//! selection. +//! - \b EUSCI_A_UART_LISTEN_ENABLE +//! - \b EUSCI_A_UART_FRAMING_ERROR +//! - \b EUSCI_A_UART_OVERRUN_ERROR +//! - \b EUSCI_A_UART_PARITY_ERROR +//! - \b eUARTBREAK_DETECT +//! - \b EUSCI_A_UART_RECEIVE_ERROR +//! - \b EUSCI_A_UART_ADDRESS_RECEIVED +//! - \b EUSCI_A_UART_IDLELINE +//! - \b EUSCI_A_UART_BUSY +//! +//! Modified register is \b UCAxSTAT +//! +//! \return the masked status flag +// +//***************************************************************************** +extern uint_fast8_t UART_queryStatusFlags(uint32_t moduleInstance, + uint_fast8_t mask); + +//***************************************************************************** +// +//! Sets the UART module in dormant mode +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! Puts USCI in sleep mode +//! Only characters that are preceded by an idle-line or with address bit set +//! UCRXIFG. In UART mode with automatic baud-rate detection, only the +//! combination of a break and synch field sets UCRXIFG. +//! +//! Modified register is \b UCAxCTL1 +//! +//! \return None. +// +//***************************************************************************** +extern void UART_setDormant(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Re-enables UART module from dormant mode +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! Not dormant. All received characters set UCRXIFG. +//! +//! Modified bits are \b UCDORM of \b UCAxCTL1 register. +//! +//! \return None. +// +//***************************************************************************** +extern void UART_resetDormant(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Transmits the next byte to be transmitted marked as address depending on +//! selected multiprocessor mode +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! \param transmitAddress is the next byte to be transmitted +//! +//! Modified register is \b UCAxCTL1, \b UCAxTXBUF +//! +//! \return None. +// +//***************************************************************************** +extern void UART_transmitAddress(uint32_t moduleInstance, + uint_fast8_t transmitAddress); + +//***************************************************************************** +// +//! Transmit break. Transmits a break with the next write to the transmit +//! buffer. In UART mode with automatic baud-rate detection, +//! EUSCI_A_UART_AUTOMATICBAUDRATE_SYNC(0x55) must be written into UCAxTXBUF to +//! generate the required break/synch fields. +//! Otherwise, DEFAULT_SYNC(0x00) must be written into the transmit buffer. +//! Also ensures module is ready for transmitting the next data +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! asEUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! Modified register is \b UCAxCTL1, \b UCAxTXBUF +//! +//! \return None. +// +//***************************************************************************** +extern void UART_transmitBreak(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Returns the address of the RX Buffer of the UART for the DMA module. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! Returns the address of the UART RX Buffer. This can be used in conjunction +//! with the DMA to store the received data directly to memory. +//! +//! \return None +// +//***************************************************************************** +extern uint32_t UART_getReceiveBufferAddressForDMA(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Returns the address of the TX Buffer of the UART for the DMA module. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! Returns the address of the UART TX Buffer. This can be used in conjunction +//! with the DMA to obtain transmitted data directly from memory. +//! +//! \return None +// +//***************************************************************************** +extern uint32_t UART_getTransmitBufferAddressForDMA(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Sets the deglitch time +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! \param deglitchTime is the selected deglitch time +//! Valid values are +//! - \b EUSCI_A_UART_DEGLITCH_TIME_2ns +//! - \b EUSCI_A_UART_DEGLITCH_TIME_50ns +//! - \b EUSCI_A_UART_DEGLITCH_TIME_100ns +//! - \b EUSCI_A_UART_DEGLITCH_TIME_200ns +//! +//! +//! Returns the address of the UART TX Buffer. This can be used in conjunction +//! with the DMA to obtain transmitted data directly from memory. +//! +//! \return None +// +//***************************************************************************** +extern void UART_selectDeglitchTime(uint32_t moduleInstance, + uint32_t deglitchTime); + +//***************************************************************************** +// +//! Enables individual UART interrupt sources. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! \param mask is the bit mask of the interrupt sources to be enabled. +//! +//! Enables the indicated UART interrupt sources. The interrupt flag is first +//! and then the corresponding interrupt is enabled. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. +//! +//! The mask parameter is the logical OR of any of the following: +//! - \b EUSCI_A_UART_RECEIVE_INTERRUPT -Receive interrupt +//! - \b EUSCI_A_UART_TRANSMIT_INTERRUPT - Transmit interrupt +//! - \b EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT - Receive +//! erroneous-character interrupt enable +//! - \b EUSCI_A_UART_BREAKCHAR_INTERRUPT - Receive break character interrupt +//! enable +//! +//! Modified register is \b UCAxIFG, \b UCAxIE and \b UCAxCTL1 +//! +//! \return None. +// +//***************************************************************************** +extern void UART_enableInterrupt(uint32_t moduleInstance, uint_fast8_t mask); + +//***************************************************************************** +// +//! Disables individual UART interrupt sources. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! \param mask is the bit mask of the interrupt sources to be +//! disabled. +//! +//! Disables the indicated UART interrupt sources. Only the sources that +//! are enabled can be reflected to the processor interrupt; disabled sources +//! have no effect on the processor. +//! +//! The mask parameter is the logical OR of any of the following: +//! - \b EUSCI_A_UART_RECEIVE_INTERRUPT -Receive interrupt +//! - \b EUSCI_A_UART_TRANSMIT_INTERRUPT - Transmit interrupt +//! - \b EUSCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT - Receive +//! erroneous-character interrupt enable +//! - \b EUSCI_A_UART_BREAKCHAR_INTERRUPT - Receive break character interrupt +//! enable +//! +//! Modified register is \b UCAxIFG, \b UCAxIE and \b UCAxCTL1 +//! \return None. +// +//***************************************************************************** +extern void UART_disableInterrupt(uint32_t moduleInstance, uint_fast8_t mask); + +//***************************************************************************** +// +//! Gets the current UART interrupt status. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! \param mask is the masked interrupt flag status to be returned. +//! Mask value is the logical OR of any of the following: +//! - \b EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG +//! - \b EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG +//! - \b EUSCI_A_UART_STARTBIT_INTERRUPT_FLAG +//! - \b EUSCI_A_UART_TRANSMIT_COMPLETE_INTERRUPT_FLAG +//! +//! +//! \return The current interrupt status as an ORed bit mask: +//! - \b EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG -Receive interrupt flag +//! - \b EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG - Transmit interrupt flag +// +//***************************************************************************** +extern uint_fast8_t UART_getInterruptStatus(uint32_t moduleInstance, + uint8_t mask); + +//***************************************************************************** +// +//! Gets the current UART interrupt status masked with the enabled interrupts. +//! This function is useful to call in ISRs to get a list of pending +//! interrupts that are actually enabled and could have caused +//! the ISR. + +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! +//! \return The current interrupt status as an ORed bit mask: +//! - \b EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG -Receive interrupt flag +//! - \b EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG - Transmit interrupt flag +// +//***************************************************************************** +extern uint_fast8_t UART_getEnabledInterruptStatus(uint32_t moduleInstance); + +//***************************************************************************** +// +//! Clears UART interrupt sources. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode +//! \param mask is a bit mask of the interrupt sources to be cleared. +//! +//! The UART interrupt source is cleared, so that it no longer asserts. +//! The highest interrupt flag is automatically cleared when an interrupt vector +//! generator is used. +//! +//! The mask parameter has the same definition as the mask parameter to +//! EUSCI_A_UART_enableInterrupt(). +//! +//! Modified register is \b UCAxIFG +//! +//! \return None. +// +//***************************************************************************** +extern void UART_clearInterruptFlag(uint32_t moduleInstance, uint_fast8_t mask); + +//***************************************************************************** +// +//! Registers an interrupt handler for UART interrupts. +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode. +//! +//! \param intHandler is a pointer to the function to be called when the +//! timer capture compare interrupt occurs. +//! +//! This function registers the handler to be called when an UART +//! interrupt occurs. This function enables the global interrupt in the +//! interrupt controller; specific UART interrupts must be enabled +//! via UART_enableInterrupt(). It is the interrupt handler's responsibility to +//! clear the interrupt source via UART_clearInterruptFlag(). +//! +//! \return None. +// +//***************************************************************************** +extern void UART_registerInterrupt(uint32_t moduleInstance, + void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the UART module +//! +//! \param moduleInstance is the instance of the eUSCI A (UART) module. +//! Valid parameters vary from part to part, but can include: +//! - \b EUSCI_A0_BASE +//! - \b EUSCI_A1_BASE +//! - \b EUSCI_A2_BASE +//! - \b EUSCI_A3_BASE +//!
It is important to note that for eUSCI modules, only "A" modules such +//! as EUSCI_A0 can be used. "B" modules such as EUSCI_B0 do not support the +//! UART mode. +//! +//! This function unregisters the handler to be called when timer +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void UART_unregisterInterrupt(uint32_t moduleInstance); + +/* Backwards Compatibility Layer */ +#define EUSCI_A_UART_transmitData UART_transmitData +#define EUSCI_A_UART_receiveData UART_receiveData +#define EUSCI_A_UART_enableInterrupt UART_enableInterrupt +#define EUSCI_A_UART_disableInterrupt UART_disableInterrupt +#define EUSCI_A_UART_getInterruptStatus UART_getInterruptStatus +#define EUSCI_A_UART_clearInterruptFlag UART_clearInterruptFlag +#define EUSCI_A_UART_enable UART_enableModule +#define EUSCI_A_UART_disable UART_disableModule +#define EUSCI_A_UART_queryStatusFlags UART_queryStatusFlags +#define EUSCI_A_UART_setDormant UART_setDormant +#define EUSCI_A_UART_resetDormant UART_resetDormant +#define EUSCI_A_UART_transmitAddress UART_transmitAddress +#define EUSCI_A_UART_transmitBreak UART_transmitBreak +#define EUSCI_A_UART_getReceiveBufferAddressForDMA UART_getReceiveBufferAddressForDMA +#define EUSCI_A_UART_getTransmitBufferAddressForDMA UART_getTransmitBufferAddressForDMA +#define EUSCI_A_UART_selectDeglitchTime UART_selectDeglitchTime + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif /* UART_H_ */ diff --git a/example/rt_msp432/MSP432P4xx/wdt_a.c b/example/rt_msp432/MSP432P4xx/wdt_a.c new file mode 100644 index 0000000..f6cd39c --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/wdt_a.c @@ -0,0 +1,119 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +/* Standard Includes */ +#include + +/* DriverLib Includes */ +#include +#include +#include + +void WDT_A_holdTimer(void) +{ + //Set Hold bit + uint8_t newWDTStatus = (WDT_A->CTL | WDT_A_CTL_HOLD); + + WDT_A->CTL = WDT_A_CTL_PW + newWDTStatus; +} + +void WDT_A_startTimer(void) +{ + //Reset Hold bit + uint8_t newWDTStatus = (WDT_A->CTL & ~(WDT_A_CTL_HOLD)); + + WDT_A->CTL = WDT_A_CTL_PW + newWDTStatus; +} + +void WDT_A_clearTimer(void) +{ + //Set Counter Clear bit + uint8_t newWDTStatus = (WDT_A->CTL | WDT_A_CTL_CNTCL); + + WDT_A->CTL = WDT_A_CTL_PW + newWDTStatus; +} + +void WDT_A_initWatchdogTimer(uint_fast8_t clockSelect, + uint_fast8_t clockIterations) +{ + WDT_A->CTL = WDT_A_CTL_PW + WDT_A_CTL_CNTCL + WDT_A_CTL_HOLD + + clockSelect + clockIterations; +} + +void WDT_A_initIntervalTimer(uint_fast8_t clockSelect, + uint_fast8_t clockIterations) +{ + + WDT_A->CTL = WDT_A_CTL_PW + WDT_A_CTL_CNTCL + WDT_A_CTL_HOLD + WDT_A_CTL_TMSEL + + clockSelect + clockIterations; +} + +void WDT_A_setPasswordViolationReset(uint_fast8_t resetType) +{ + SysCtl_setWDTPasswordViolationResetType(resetType); +} + +void WDT_A_setTimeoutReset(uint_fast8_t resetType) +{ + SysCtl_setWDTTimeoutResetType(resetType); +} + +void WDT_A_registerInterrupt(void (*intHandler)(void)) +{ + // + // Register the interrupt handler, returning an error if an error occurs. + // + Interrupt_registerInterrupt(INT_WDT_A, intHandler); + + // + // Enable the system control interrupt. + // + Interrupt_enableInterrupt (INT_WDT_A); +} + +void WDT_A_unregisterInterrupt(void) +{ + // + // Disable the interrupt. + // + Interrupt_disableInterrupt (INT_WDT_A); + + // + // Unregister the interrupt handler. + // + Interrupt_unregisterInterrupt(INT_WDT_A); +} + diff --git a/example/rt_msp432/MSP432P4xx/wdt_a.h b/example/rt_msp432/MSP432P4xx/wdt_a.h new file mode 100644 index 0000000..8891990 --- /dev/null +++ b/example/rt_msp432/MSP432P4xx/wdt_a.h @@ -0,0 +1,297 @@ +/* + * ------------------------------------------- + * MSP432 DriverLib - v3_21_00_05 + * ------------------------------------------- + * + * --COPYRIGHT--,BSD,BSD + * Copyright (c) 2016, Texas Instruments Incorporated + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * --/COPYRIGHT--*/ +#ifndef __WATCHDOG_H__ +#define __WATCHDOG_H__ + +//***************************************************************************** +// +//! \addtogroup wdt_api +//! @{ +// +//***************************************************************************** + +//***************************************************************************** +// +// If building with a C++ compiler, make all of the definitions in this header +// have a C binding. +// +//***************************************************************************** +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include "sysctl.h" + +#define WDT_A_HARD_RESET SYSCTL_HARD_RESET +#define WDT_A_SOFT_RESET SYSCTL_SOFT_RESET + +//***************************************************************************** +// +// The following are values that can be passed to the clockSelect parameter for +// functions: WDT_A_watchdogTimerInit(), and WDT_A_intervalTimerInit(). +// +//***************************************************************************** +#define WDT_A_CLOCKSOURCE_SMCLK (WDT_A_CTL_SSEL_0) +#define WDT_A_CLOCKSOURCE_ACLK (WDT_A_CTL_SSEL_1) +#define WDT_A_CLOCKSOURCE_VLOCLK (WDT_A_CTL_SSEL_2) +#define WDT_A_CLOCKSOURCE_XCLK (WDT_A_CTL_SSEL_3) +#define WDT_A_CLOCKSOURCE_BCLK (WDT_A_CTL_SSEL_4) + +//***************************************************************************** +// +// The following are values that can be passed to the clockDivider parameter +// for functions: WDT_A_watchdogTimerInit(), and WDT_A_intervalTimerInit(). +// +//***************************************************************************** +#define WDT_A_CLOCKDIVIDER_2G (WDT_A_CTL_IS_0) +#define WDT_A_CLOCKDIVIDER_128M (WDT_A_CTL_IS_1) +#define WDT_A_CLOCKDIVIDER_8192K (WDT_A_CTL_IS_2) +#define WDT_A_CLOCKDIVIDER_512K (WDT_A_CTL_IS_3) +#define WDT_A_CLOCKDIVIDER_32K (WDT_A_CTL_IS_4) +#define WDT_A_CLOCKDIVIDER_8192 (WDT_A_CTL_IS_5) +#define WDT_A_CLOCKDIVIDER_512 (WDT_A_CTL_IS_6) +#define WDT_A_CLOCKDIVIDER_64 (WDT_A_CTL_IS_7) +#define WDT_A_CLOCKITERATIONS_2G WDT_A_CLOCKDIVIDER_2G +#define WDT_A_CLOCKITERATIONS_128M WDT_A_CLOCKDIVIDER_128M +#define WDT_A_CLOCKITERATIONS_8192K WDT_A_CLOCKDIVIDER_8192K +#define WDT_A_CLOCKITERATIONS_512K WDT_A_CLOCKDIVIDER_512K +#define WDT_A_CLOCKITERATIONS_32K WDT_A_CLOCKDIVIDER_32K +#define WDT_A_CLOCKITERATIONS_8192 WDT_A_CLOCKDIVIDER_8192 +#define WDT_A_CLOCKITERATIONS_512 WDT_A_CLOCKDIVIDER_512 +#define WDT_A_CLOCKITERATIONS_64 WDT_A_CLOCKDIVIDER_64 + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +//***************************************************************************** +// +//! Holds the Watchdog Timer. +//! +//! This function stops the watchdog timer from running. This way no interrupt +//! or PUC is asserted. +//! +//! \return None +// +//***************************************************************************** +extern void WDT_A_holdTimer(void); + +//***************************************************************************** +// +//! Starts the Watchdog Timer. +//! +//! This function starts the watchdog timer functionality to start counting. +//! +//! \return None +// +//***************************************************************************** +extern void WDT_A_startTimer(void); + +//***************************************************************************** +// +//! Clears the timer counter of the Watchdog Timer. +//! +//! This function clears the watchdog timer count to 0x0000h. This function +//! is used to "service the dog" when operating in watchdog mode. +//! +//! \return None +// +//***************************************************************************** +extern void WDT_A_clearTimer(void); + +//***************************************************************************** +// +//! Sets the clock source for the Watchdog Timer in watchdog mode. +//! +//! \param clockSelect is the clock source that the watchdog timer will use. +//! Valid values are +//! - \b WDT_A_CLOCKSOURCE_SMCLK [Default] +//! - \b WDT_A_CLOCKSOURCE_ACLK +//! - \b WDT_A_CLOCKSOURCE_VLOCLK +//! - \b WDT_A_CLOCKSOURCE_BCLK +//! \param clockIterations is the number of clock iterations for a watchdog +//! timeout. +//! Valid values are +//! - \b WDT_A_CLOCKITERATIONS_2G [Default] +//! - \b WDT_A_CLOCKITERATIONS_128M +//! - \b WDT_A_CLOCKITERATIONS_8192K +//! - \b WDT_A_CLOCKITERATIONS_512K +//! - \b WDT_A_CLOCKITERATIONS_32K +//! - \b WDT_A_CLOCKITERATIONS_8192 +//! - \b WDT_A_CLOCKITERATIONS_512 +//! - \b WDT_A_CLOCKITERATIONS_64 +//! +//! This function sets the watchdog timer in watchdog mode, which will cause a +//! PUC when the timer overflows. When in the mode, a PUC can be avoided with a +//! call to WDT_A_resetTimer() before the timer runs out. +//! +//! \return None +// +//***************************************************************************** +extern void WDT_A_initWatchdogTimer(uint_fast8_t clockSelect, + uint_fast8_t clockDivider); + +//***************************************************************************** +// +//! Sets the clock source for the Watchdog Timer in timer interval mode. +//! +//! \param clockSelect is the clock source that the watchdog timer will use. +//! Valid values are +//! - \b WDT_A_CLOCKSOURCE_SMCLK [Default] +//! - \b WDT_A_CLOCKSOURCE_ACLK +//! - \b WDT_A_CLOCKSOURCE_VLOCLK +//! - \b WDT_A_CLOCKSOURCE_BCLK +//! \param clockIterations is the number of clock iterations for a watchdog +//! interval. +//! Valid values are +//! - \b WDT_A_CLOCKITERATIONS_2G [Default] +//! - \b WDT_A_CLOCKITERATIONS_128M +//! - \b WDT_A_CLOCKITERATIONS_8192K +//! - \b WDT_A_CLOCKITERATIONS_512K +//! - \b WDT_A_CLOCKITERATIONS_32K +//! - \b WDT_A_CLOCKITERATIONS_8192 +//! - \b WDT_A_CLOCKITERATIONS_512 +//! - \b WDT_A_CLOCKITERATIONS_64 +//! +//! This function sets the watchdog timer as timer interval mode, which will +//! assert an interrupt without causing a PUC. +//! +//! \return None +// +//***************************************************************************** +extern void WDT_A_initIntervalTimer(uint_fast8_t clockSelect, + uint_fast8_t clockDivider); + +//***************************************************************************** +// +//! Registers an interrupt handler for the watchdog interrupt. +//! +//! \param intHandler is a pointer to the function to be called when the +//! watchdog interrupt occurs. +//! +//! \return None. +// +//***************************************************************************** +extern void WDT_A_registerInterrupt(void (*intHandler)(void)); + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the watchdog. +//! +//! This function unregisters the handler to be called when a watchdog +//! interrupt occurs. This function also masks off the interrupt in the +//! interrupt controller so that the interrupt handler no longer is called. +//! +//! \sa Interrupt_registerInterrupt() for important information about +//! registering interrupt handlers. +//! +//! \return None. +// +//***************************************************************************** +extern void WDT_A_unregisterInterrupt(void); + +//***************************************************************************** +// +//! Sets the type of RESET that happens when a watchdog password violation +//! occurs. +//! +//! \param resetType The type of reset to set +//! +//! The \e resetType parameter must be only one of the following values: +//! - \b WDT_A_HARD_RESET +//! - \b WDT_A_SOFT_RESET +//! +//! \return None. +// +// +//***************************************************************************** +extern void WDT_A_setPasswordViolationReset(uint_fast8_t resetType); + +//***************************************************************************** +// +//! Sets the type of RESET that happens when a watchdog timeout occurs. +//! +//! \param resetType The type of reset to set +//! +//! The \e resetType parameter must be only one of the following values: +//! - \b WDT_A_HARD_RESET +//! - \b WDT_A_SOFT_RESET +//! +//! \return None. +// +// +//***************************************************************************** +extern void WDT_A_setTimeoutReset(uint_fast8_t resetType); + +/* Defines for future devices that might have multiple instances */ +#define WDT_A_holdTimerMultipleTimer(a) WDT_A_holdTimer() +#define WDT_A_startTimerMultipleTimer(a) WDT_A_startTimer() +#define WDT_A_resetTimerMultipleTimer(a) WDT_A_clearTimer() +#define WDT_A_initWatchdogTimerMultipleTimer(a,b,c) WDT_A_initWatchdogTimer(b,c) +#define WDT_A_initIntervalTimerMultipleTimer(a,b,c) WDT_A_initIntervalTimer(b,c) +#define WDT_A_registerInterruptMultipleTimer(a,b) WDT_A_registerInterrupt(b) +#define WDT_A_unregisterInterruptMultipleTimer(a) WDT_A_unregisterInterrupt() + +/* Backwards compatibility layer */ +#define WDT_A_hold WDT_A_holdTimerMultipleTimer +#define WDT_A_start WDT_A_startTimerMultipleTimer +#define WDT_A_resetTimer WDT_A_resetTimerMultipleTimer +#define WDT_A_watchdogTimerInit WDT_A_initWatchdogTimerMultipleTimer +#define WDT_A_intervalTimerInit WDT_A_initIntervalTimerMultipleTimer + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + +#endif // __WATCHDOG_H__ diff --git a/include/cadmium/core/simulation/abs_simulator.hpp b/include/cadmium/core/simulation/abs_simulator.hpp deleted file mode 100644 index ccf5602..0000000 --- a/include/cadmium/core/simulation/abs_simulator.hpp +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Abstract simulator. - * Copyright (C) 2021 Román Cárdenas Rodríguez - * ARSLab - Carleton University - * GreenLSI - Polytechnic University of Madrid - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef CADMIUM_CORE_SIMULATION_ABS_SIMULATOR_HPP_ -#define CADMIUM_CORE_SIMULATION_ABS_SIMULATOR_HPP_ - -#include -#include -#include "../logger/logger.hpp" -#include "../modeling/component.hpp" - -namespace cadmium { - //! Abstract simulator class. - class AbstractSimulator { - protected: - long modelId; //!< Model identification number. - double timeLast; //!< Last simulation time. - double timeNext; //!< Next simulation time. - public: - /** - * Constructor function. - * @param time initial simulation time. - */ - AbstractSimulator(double time): modelId(), timeLast(time), timeNext(std::numeric_limits::infinity()) {} - - //! default destructor function. - virtual ~AbstractSimulator() = default; - - //! @return last simulation time. - [[nodiscard]] double getTimeLast() const { - return timeLast; - } - - //! @return next simulation time. - [[nodiscard]] double getTimeNext() const { - return timeNext; - } - - //! @return pointer to the component corresponding to the abstract simulator. - [[nodiscard]] virtual std::shared_ptr getComponent() const = 0; - - /** - * Sets the model number ID. - * @param next corresponding model ID number. - * @return the next model ID number. - */ - virtual long setModelId(long next) = 0; - - /** - * Sets a logger (atomic states and output messages). - * @param log pointer to the logger. - */ - virtual void setLogger(const std::shared_ptr& log) = 0; - - /** - * It performs all the tasks needed before the simulation. - * @param time initial simulation time. - */ - virtual void start(double time) = 0; - - /** - * It performs all the tasks needed after the simulation. - * @param time last simulation time. - */ - virtual void stop(double time) = 0; - - /** - * It executes the model collection function. - * @param time simulation time. - */ - virtual void collection(double time) = 0; - - /** - * It executes the model transition function. - * @param time - */ - virtual void transition(double time) = 0; - - //! it clears the input and output ports of the model. - virtual void clear() = 0; - }; -} - -#endif //CADMIUM_CORE_SIMULATION_ABS_SIMULATOR_HPP_ diff --git a/include/cadmium/core/simulation/coordinator.hpp b/include/cadmium/core/simulation/coordinator.hpp deleted file mode 100644 index e3a4600..0000000 --- a/include/cadmium/core/simulation/coordinator.hpp +++ /dev/null @@ -1,156 +0,0 @@ -/** - * DEVS Coordinator class. - * Copyright (C) 2021 Román Cárdenas Rodríguez - * ARSLab - Carleton University - * GreenLSI - Polytechnic University of Madrid - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef CADMIUM_CORE_SIMULATION_COORDINATOR_HPP_ -#define CADMIUM_CORE_SIMULATION_COORDINATOR_HPP_ - -#include -#include -#include -#include "abs_simulator.hpp" -#include "simulator.hpp" -#include "../modeling/atomic.hpp" -#include "../modeling/coupled.hpp" -#include "../modeling/component.hpp" - -namespace cadmium { - //! DEVS sequential coordinator class. - class Coordinator: public AbstractSimulator { - private: - std::shared_ptr model; //!< Pointer to coupled model of the coordinator. - std::vector> simulators; //!< Vector of child simulators. - public: - /** - * Constructor function. - * @param model pointer to the coordinator coupled model. - * @param time initial simulation time. - * @param parallel if true, simulators will use mutexes for logging. - */ - Coordinator(std::shared_ptr model, double time): AbstractSimulator(time), model(std::move(model)) { - if (this->model == nullptr) { - throw CadmiumSimulationException("no coupled model provided"); - } - timeLast = time; - for (auto& [componentId, component]: this->model->getComponents()) { - std::shared_ptr simulator; - auto coupled = std::dynamic_pointer_cast(component); - if (coupled != nullptr) { - simulator = std::make_shared(coupled, time); - } else { - auto atomic = std::dynamic_pointer_cast(component); - if (atomic == nullptr) { - throw CadmiumSimulationException("component is not a coupled nor atomic model"); - } - simulator = std::make_shared(atomic, time); - } - simulators.push_back(simulator); - timeNext = std::min(timeNext, simulator->getTimeNext()); - } - } - - //! @return pointer to the coupled model of the coordinator. - [[nodiscard]] std::shared_ptr getComponent() const override { - return model; - } - - //! @return pointer to the coupled model of the coordinator without upcasting it to an abstract Component. - [[nodiscard]] std::shared_ptr getCoupled() const { - return model; - } - - //! @return pointer to subcomponents. - [[nodiscard]] const std::vector>& getSubcomponents() { - return simulators; - } - - /** - * Sets the model ID of its coupled model and all the models of its child simulators. - * @param next next available model ID. - * @return next available model ID after assiging the ID to all the child models. - */ - long setModelId(long next) override { - modelId = next++; - for (auto& simulator: simulators) { - next = simulator->setModelId(next); - } - return next; - } - - //! It updates the initial simulation time and calls to the start method of all its child simulators. - void start(double time) override { - timeLast = time; - std::for_each(simulators.begin(), simulators.end(), [time](auto& s) { s->start(time); }); - } - - //! It updates the final simulation time and calls to the stop method of all its child simulators. - void stop(double time) override { - timeLast = time; - std::for_each(simulators.begin(), simulators.end(), [time](auto& s) { s->stop(time); }); - } - - /** - * It collects all the output messages and propagates them according to the ICs and EOCs. - * @param time new simulation time. - */ - void collection(double time) override { - if (time >= timeNext) { - std::for_each(simulators.begin(), simulators.end(), [time](auto& s) { s->collection(time); }); - for (auto& [portFrom, portTo]: model->getSerialICs()) { - portTo->propagate(portFrom); - } - for (auto& [portFrom, portTo]: model->getSerialEOCs()) { - portTo->propagate(portFrom); - } - } - } - - /** - * It propagates input messages according to the EICs and triggers the state transition function of child components. - * @param time new simulation time. - */ - void transition(double time) override { - for (auto& [portFrom, portTo]: model->getSerialEICs()) { - portTo->propagate(portFrom); - } - timeLast = time; - timeNext = std::numeric_limits::infinity(); - for (auto& simulator: simulators) { - simulator->transition(time); - timeNext = std::min(timeNext, simulator->getTimeNext()); - } - } - - //! It clears the messages from all the ports of child components. - void clear() override { - std::for_each(simulators.begin(), simulators.end(), [](auto& s) { s->clear(); }); - model->clearPorts(); - } - - /** - * It sets the logger to all the child components. - * @param log pointer to the new logger. - */ - void setLogger(const std::shared_ptr& log) override { - std::for_each(simulators.begin(), simulators.end(), [log](auto& s) { s->setLogger(log); }); - } - }; -} - -#endif //CADMIUM_CORE_SIMULATION_COORDINATOR_HPP_ diff --git a/include/cadmium/core/simulation/root_coordinator.hpp b/include/cadmium/core/simulation/root_coordinator.hpp deleted file mode 100644 index e573662..0000000 --- a/include/cadmium/core/simulation/root_coordinator.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/** - * - * Copyright (C) 2021 Román Cárdenas Rodríguez - * ARSLab - Carleton University - * GreenLSI - Polytechnic University of Madrid - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef CADMIUM_CORE_SIMULATION_ROOT_COORDINATOR_HPP_ -#define CADMIUM_CORE_SIMULATION_ROOT_COORDINATOR_HPP_ - -#include -#include -#include -#include -#include "coordinator.hpp" -#include "../logger/logger.hpp" - -namespace cadmium { - //! Root coordinator class. - class RootCoordinator { - protected: - std::shared_ptr topCoordinator; //!< Pointer to top coordinator. - std::shared_ptr logger; //!< Pointer to simulation logger. - - void simulationAdvance(double timeNext) { - if (logger != nullptr) { - logger->lock(); // TODO are locks necessary here? In theory, you should be the only one executing here - logger->logTime(timeNext); - logger->unlock(); - } - topCoordinator->collection(timeNext); - topCoordinator->transition(timeNext); - topCoordinator->clear(); - } - - public: - RootCoordinator(std::shared_ptr model, double time): - topCoordinator(std::make_shared(std::move(model), time)), logger() {} - explicit RootCoordinator(std::shared_ptr model): RootCoordinator(std::move(model), 0) {} - - void setLogger(const std::shared_ptr& log) { - logger = log; - topCoordinator->setLogger(log); - } - - std::shared_ptr getLogger() { - return logger; - } - - std::shared_ptr getTopCoordinator() { - return topCoordinator; - } - - void start() { - if (logger != nullptr) { - logger->start(); - } - topCoordinator->setModelId(0); - topCoordinator->start(topCoordinator->getTimeLast()); - } - - void stop() { - topCoordinator->stop(topCoordinator->getTimeLast()); - if (logger != nullptr) { - logger->stop(); - } - } - - [[maybe_unused]] void simulate(long nIterations) { - // Firsts, we make sure that Mutexes are not activated - if (logger != nullptr) { - logger->removeMutex(); - } - double timeNext = topCoordinator->getTimeNext(); - while (nIterations-- > 0 && timeNext < std::numeric_limits::infinity()) { - simulationAdvance(timeNext); - timeNext = topCoordinator->getTimeNext(); - } - } - - [[maybe_unused]] void simulate(double timeInterval) { - // Firsts, we make sure that Mutexes are not activated - if (logger != nullptr) { - logger->removeMutex(); - } - double timeNext = topCoordinator->getTimeNext(); - double timeFinal = topCoordinator->getTimeLast()+timeInterval; - while(timeNext < timeFinal) { - simulationAdvance(timeNext); - timeNext = topCoordinator->getTimeNext(); - } - } - }; -} - -#endif //CADMIUM_CORE_SIMULATION_ROOT_COORDINATOR_HPP_ diff --git a/include/cadmium/core/exception.hpp b/include/cadmium/exception.hpp similarity index 81% rename from include/cadmium/core/exception.hpp rename to include/cadmium/exception.hpp index 6d12c42..7833bb9 100644 --- a/include/cadmium/core/exception.hpp +++ b/include/cadmium/exception.hpp @@ -18,10 +18,11 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CORE_EXCEPTION_HPP_ -#define CADMIUM_CORE_EXCEPTION_HPP_ +#ifndef CADMIUM_EXCEPTION_HPP_ +#define CADMIUM_EXCEPTION_HPP_ #include +#include namespace cadmium { //! Base class for exceptions thrown by Cadmium. @@ -60,6 +61,16 @@ namespace cadmium { */ explicit CadmiumSimulationException(std::string message): CadmiumException(std::move(message)) {} }; + + //! Exceptions thrown due to an error in a real-time clock. + class CadmiumRTClockException: public CadmiumException { + public: + /** + * Constructor function + * @param message information about the simulation error. + */ + explicit CadmiumRTClockException(std::string message): CadmiumException(std::move(message)) {} + }; } -#endif //CADMIUM_CORE_EXCEPTION_HPP_ +#endif //CADMIUM_EXCEPTION_HPP_ diff --git a/include/cadmium/lib/iestream.hpp b/include/cadmium/lib/iestream.hpp index d50eaed..43d9fcb 100644 --- a/include/cadmium/lib/iestream.hpp +++ b/include/cadmium/lib/iestream.hpp @@ -20,10 +20,11 @@ #ifndef CADMIUM_LIB_IESTREAM_HPP_ #define CADMIUM_LIB_IESTREAM_HPP_ +#include #include #include -#include "../core/modeling/atomic.hpp" -#include "../core/exception.hpp" +#include "../modeling/devs/atomic.hpp" +#include "../exception.hpp" namespace cadmium::lib { /** diff --git a/include/cadmium/celldevs/asymm/cell.hpp b/include/cadmium/modeling/celldevs/asymm/cell.hpp similarity index 91% rename from include/cadmium/celldevs/asymm/cell.hpp rename to include/cadmium/modeling/celldevs/asymm/cell.hpp index 432b91a..b02ab0e 100644 --- a/include/cadmium/celldevs/asymm/cell.hpp +++ b/include/cadmium/modeling/celldevs/asymm/cell.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_ASYMM_CELL_HPP_ -#define CADMIUM_CELLDEVS_ASYMM_CELL_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_ASYMM_CELL_HPP_ +#define CADMIUM_MODELING_CELLDEVS_ASYMM_CELL_HPP_ #include #include "../core/cell.hpp" @@ -43,4 +43,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_ASYMM_CELL_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_ASYMM_CELL_HPP_ diff --git a/include/cadmium/celldevs/asymm/config.hpp b/include/cadmium/modeling/celldevs/asymm/config.hpp similarity index 93% rename from include/cadmium/celldevs/asymm/config.hpp rename to include/cadmium/modeling/celldevs/asymm/config.hpp index d02c18c..7f4f7c4 100644 --- a/include/cadmium/celldevs/asymm/config.hpp +++ b/include/cadmium/modeling/celldevs/asymm/config.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_ASYMM_CONFIG_HPP_ -#define CADMIUM_CELLDEVS_ASYMM_CONFIG_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_ASYMM_CONFIG_HPP_ +#define CADMIUM_MODELING_CELLDEVS_ASYMM_CONFIG_HPP_ #include #include @@ -56,4 +56,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_ASYMM_CONFIG_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_ASYMM_CONFIG_HPP_ diff --git a/include/cadmium/celldevs/asymm/coupled.hpp b/include/cadmium/modeling/celldevs/asymm/coupled.hpp similarity index 94% rename from include/cadmium/celldevs/asymm/coupled.hpp rename to include/cadmium/modeling/celldevs/asymm/coupled.hpp index 87035c1..066e268 100644 --- a/include/cadmium/celldevs/asymm/coupled.hpp +++ b/include/cadmium/modeling/celldevs/asymm/coupled.hpp @@ -18,15 +18,15 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_ASYMM_COUPLED_HPP_ -#define CADMIUM_CELLDEVS_ASYMM_COUPLED_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_ASYMM_COUPLED_HPP_ +#define CADMIUM_MODELING_CELLDEVS_ASYMM_COUPLED_HPP_ #include #include #include #include "cell.hpp" #include "../core/coupled.hpp" -#include "../../core/exception.hpp" +#include "../../../exception.hpp" namespace cadmium::celldevs { @@ -77,4 +77,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_ASYMM_COUPLED_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_ASYMM_COUPLED_HPP_ diff --git a/include/cadmium/celldevs/core/cell.hpp b/include/cadmium/modeling/celldevs/core/cell.hpp similarity index 97% rename from include/cadmium/celldevs/core/cell.hpp rename to include/cadmium/modeling/celldevs/core/cell.hpp index 6ac8c41..faefcfa 100644 --- a/include/cadmium/celldevs/core/cell.hpp +++ b/include/cadmium/modeling/celldevs/core/cell.hpp @@ -18,14 +18,14 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_CELL_HPP_ -#define CADMIUM_CELLDEVS_CORE_CELL_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_CELL_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_CELL_HPP_ #include #include #include #include -#include "../../core/modeling/atomic.hpp" +#include "../../devs/atomic.hpp" #include "config.hpp" #include "msg.hpp" #include "queue/queue.hpp" @@ -154,4 +154,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_CELL_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_CELL_HPP_ diff --git a/include/cadmium/celldevs/core/config.hpp b/include/cadmium/modeling/celldevs/core/config.hpp similarity index 96% rename from include/cadmium/celldevs/core/config.hpp rename to include/cadmium/modeling/celldevs/core/config.hpp index a47fe08..10e0064 100644 --- a/include/cadmium/celldevs/core/config.hpp +++ b/include/cadmium/modeling/celldevs/core/config.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_CONFIG_HPP_ -#define CADMIUM_CELLDEVS_CORE_CONFIG_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_CONFIG_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_CONFIG_HPP_ #include #include @@ -82,4 +82,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_CONFIG_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_CONFIG_HPP_ diff --git a/include/cadmium/celldevs/core/coupled.hpp b/include/cadmium/modeling/celldevs/core/coupled.hpp similarity index 96% rename from include/cadmium/celldevs/core/coupled.hpp rename to include/cadmium/modeling/celldevs/core/coupled.hpp index 1cb3015..63290e4 100644 --- a/include/cadmium/celldevs/core/coupled.hpp +++ b/include/cadmium/modeling/celldevs/core/coupled.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_COUPLED_HPP_ -#define CADMIUM_CELLDEVS_CORE_COUPLED_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_COUPLED_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_COUPLED_HPP_ #include #include @@ -30,8 +30,8 @@ #include #include "cell.hpp" #include "config.hpp" -#include "../../core/modeling/coupled.hpp" -#include "../../core/exception.hpp" +#include "../../devs/coupled.hpp" +#include "../../../exception.hpp" namespace cadmium::celldevs { /** @@ -147,4 +147,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_COUPLED_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_COUPLED_HPP_ diff --git a/include/cadmium/celldevs/core/msg.hpp b/include/cadmium/modeling/celldevs/core/msg.hpp similarity index 93% rename from include/cadmium/celldevs/core/msg.hpp rename to include/cadmium/modeling/celldevs/core/msg.hpp index eecd32f..cf66c54 100644 --- a/include/cadmium/celldevs/core/msg.hpp +++ b/include/cadmium/modeling/celldevs/core/msg.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_MSG_HPP_ -#define CADMIUM_CELLDEVS_CORE_MSG_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_MSG_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_MSG_HPP_ #include #include @@ -58,4 +58,4 @@ namespace cadmium::celldevs { } } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_MSG_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_MSG_HPP_ diff --git a/include/cadmium/celldevs/core/queue/hybrid.hpp b/include/cadmium/modeling/celldevs/core/queue/hybrid.hpp similarity index 93% rename from include/cadmium/celldevs/core/queue/hybrid.hpp rename to include/cadmium/modeling/celldevs/core/queue/hybrid.hpp index 5cfdb66..8c88028 100644 --- a/include/cadmium/celldevs/core/queue/hybrid.hpp +++ b/include/cadmium/modeling/celldevs/core/queue/hybrid.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_QUEUE_HYBRID_HPP_ -#define CADMIUM_CELLDEVS_CORE_QUEUE_HYBRID_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_HYBRID_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_HYBRID_HPP_ #include #include @@ -74,4 +74,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_QUEUE_HYBRID_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_HYBRID_HPP_ diff --git a/include/cadmium/celldevs/core/queue/inertial.hpp b/include/cadmium/modeling/celldevs/core/queue/inertial.hpp similarity index 93% rename from include/cadmium/celldevs/core/queue/inertial.hpp rename to include/cadmium/modeling/celldevs/core/queue/inertial.hpp index e192c02..d448099 100644 --- a/include/cadmium/celldevs/core/queue/inertial.hpp +++ b/include/cadmium/modeling/celldevs/core/queue/inertial.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_QUEUE_INERTIAL_HPP_ -#define CADMIUM_CELLDEVS_CORE_QUEUE_INERTIAL_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_INERTIAL_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_INERTIAL_HPP_ #include #include @@ -71,4 +71,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_QUEUE_INERTIAL_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_INERTIAL_HPP_ diff --git a/include/cadmium/celldevs/core/queue/queue.hpp b/include/cadmium/modeling/celldevs/core/queue/queue.hpp similarity index 93% rename from include/cadmium/celldevs/core/queue/queue.hpp rename to include/cadmium/modeling/celldevs/core/queue/queue.hpp index 66e097f..47eecae 100644 --- a/include/cadmium/celldevs/core/queue/queue.hpp +++ b/include/cadmium/modeling/celldevs/core/queue/queue.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_QUEUE_HPP_ -#define CADMIUM_CELLDEVS_CORE_QUEUE_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_HPP_ #include #include @@ -27,7 +27,7 @@ #include "inertial.hpp" #include "transport.hpp" #include "hybrid.hpp" -#include "../../../core/exception.hpp" +#include "../../../../exception.hpp" namespace cadmium::celldevs { /** @@ -77,4 +77,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_QUEUE_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_HPP_ diff --git a/include/cadmium/celldevs/core/queue/transport.hpp b/include/cadmium/modeling/celldevs/core/queue/transport.hpp similarity index 93% rename from include/cadmium/celldevs/core/queue/transport.hpp rename to include/cadmium/modeling/celldevs/core/queue/transport.hpp index 7b8244f..1c5d9b9 100644 --- a/include/cadmium/celldevs/core/queue/transport.hpp +++ b/include/cadmium/modeling/celldevs/core/queue/transport.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_QUEUE_TRANSPORT_HPP_ -#define CADMIUM_CELLDEVS_CORE_QUEUE_TRANSPORT_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_TRANSPORT_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_TRANSPORT_HPP_ #include #include @@ -80,4 +80,4 @@ namespace cadmium::celldevs { }; } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_QUEUE_TRANSPORT_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_QUEUE_TRANSPORT_HPP_ diff --git a/include/cadmium/celldevs/core/utility.hpp b/include/cadmium/modeling/celldevs/core/utility.hpp similarity index 93% rename from include/cadmium/celldevs/core/utility.hpp rename to include/cadmium/modeling/celldevs/core/utility.hpp index 376a825..1db2612 100644 --- a/include/cadmium/celldevs/core/utility.hpp +++ b/include/cadmium/modeling/celldevs/core/utility.hpp @@ -18,11 +18,11 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_CORE_UTILITY_HPP_ -#define CADMIUM_CELLDEVS_CORE_UTILITY_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_CORE_UTILITY_HPP_ +#define CADMIUM_MODELING_CELLDEVS_CORE_UTILITY_HPP_ -#include #include +#include #include #include "../grid/utility.hpp" @@ -61,4 +61,4 @@ namespace cadmium::celldevs { } } // namespace cadmium::celldevs -#endif // CADMIUM_CELLDEVS_CORE_UTILITY_HPP_ +#endif // CADMIUM_MODELING_CELLDEVS_CORE_UTILITY_HPP_ diff --git a/include/cadmium/celldevs/grid/cell.hpp b/include/cadmium/modeling/celldevs/grid/cell.hpp similarity index 97% rename from include/cadmium/celldevs/grid/cell.hpp rename to include/cadmium/modeling/celldevs/grid/cell.hpp index 1a6f5f8..104e5cc 100644 --- a/include/cadmium/celldevs/grid/cell.hpp +++ b/include/cadmium/modeling/celldevs/grid/cell.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_GRID_CELL_HPP_ -#define CADMIUM_CELLDEVS_GRID_CELL_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_GRID_CELL_HPP_ +#define CADMIUM_MODELING_CELLDEVS_GRID_CELL_HPP_ #include #include @@ -125,4 +125,4 @@ namespace cadmium::celldevs { }; } -#endif //CADMIUM_CELLDEVS_GRID_CELL_HPP_ +#endif //CADMIUM_MODELING_CELLDEVS_GRID_CELL_HPP_ diff --git a/include/cadmium/celldevs/grid/config.hpp b/include/cadmium/modeling/celldevs/grid/config.hpp similarity index 96% rename from include/cadmium/celldevs/grid/config.hpp rename to include/cadmium/modeling/celldevs/grid/config.hpp index 2181bd2..2f23806 100644 --- a/include/cadmium/celldevs/grid/config.hpp +++ b/include/cadmium/modeling/celldevs/grid/config.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_GRID_CONFIG_HPP_ -#define CADMIUM_CELLDEVS_GRID_CONFIG_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_GRID_CONFIG_HPP_ +#define CADMIUM_MODELING_CELLDEVS_GRID_CONFIG_HPP_ #include #include @@ -29,7 +29,7 @@ #include "scenario.hpp" #include "utility.hpp" #include "../core/config.hpp" -#include "../../core/exception.hpp" +#include "../../../exception.hpp" namespace cadmium::celldevs { /** @@ -139,4 +139,4 @@ namespace cadmium::celldevs { }; } -#endif //CADMIUM_CELLDEVS_GRID_CONFIG_HPP_ +#endif //CADMIUM_MODELING_CELLDEVS_GRID_CONFIG_HPP_ diff --git a/include/cadmium/celldevs/grid/coupled.hpp b/include/cadmium/modeling/celldevs/grid/coupled.hpp similarity index 95% rename from include/cadmium/celldevs/grid/coupled.hpp rename to include/cadmium/modeling/celldevs/grid/coupled.hpp index 5109d29..79f9e49 100644 --- a/include/cadmium/celldevs/grid/coupled.hpp +++ b/include/cadmium/modeling/celldevs/grid/coupled.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CELLDEVS_GRID_COUPLED_HPP_ -#define CADMIUM_CELLDEVS_GRID_COUPLED_HPP_ +#ifndef CADMIUM_MODELING_CELLDEVS_GRID_COUPLED_HPP_ +#define CADMIUM_MODELING_CELLDEVS_GRID_COUPLED_HPP_ #include #include @@ -28,7 +28,7 @@ #include "scenario.hpp" #include "utility.hpp" #include "../core/coupled.hpp" -#include "../../core/exception.hpp" +#include "../../../exception.hpp" namespace cadmium::celldevs { @@ -106,4 +106,4 @@ namespace cadmium::celldevs { }; } -#endif //CADMIUM_CELLDEVS_GRID_COUPLED_HPP_ +#endif //CADMIUM_MODELING_CELLDEVS_GRID_COUPLED_HPP_ diff --git a/include/cadmium/celldevs/grid/scenario.hpp b/include/cadmium/modeling/celldevs/grid/scenario.hpp similarity index 99% rename from include/cadmium/celldevs/grid/scenario.hpp rename to include/cadmium/modeling/celldevs/grid/scenario.hpp index 2dc71d4..33a4477 100644 --- a/include/cadmium/celldevs/grid/scenario.hpp +++ b/include/cadmium/modeling/celldevs/grid/scenario.hpp @@ -27,7 +27,7 @@ #include #include #include "utility.hpp" -#include "../../core/exception.hpp" +#include "../../../exception.hpp" namespace cadmium::celldevs { /** diff --git a/include/cadmium/celldevs/grid/utility.hpp b/include/cadmium/modeling/celldevs/grid/utility.hpp similarity index 100% rename from include/cadmium/celldevs/grid/utility.hpp rename to include/cadmium/modeling/celldevs/grid/utility.hpp diff --git a/include/cadmium/core/modeling/atomic.hpp b/include/cadmium/modeling/devs/atomic.hpp similarity index 96% rename from include/cadmium/core/modeling/atomic.hpp rename to include/cadmium/modeling/devs/atomic.hpp index b133c5f..1ab50fe 100644 --- a/include/cadmium/core/modeling/atomic.hpp +++ b/include/cadmium/modeling/devs/atomic.hpp @@ -18,11 +18,13 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CORE_MODELING_ATOMIC_HPP_ -#define CADMIUM_CORE_MODELING_ATOMIC_HPP_ +#ifndef CADMIUM_MODELING_DEVS_ATOMIC_HPP_ +#define CADMIUM_MODELING_DEVS_ATOMIC_HPP_ #include -#include +#ifndef NO_LOGGING + #include +#endif #include #include #include @@ -72,11 +74,13 @@ namespace cadmium { */ [[nodiscard]] virtual double timeAdvance() const = 0; + #ifndef NO_LOGGING /** * Virtual method to log the atomic model's current state. * @return string representing the current state of the atomic model. */ [[nodiscard]] virtual std::string logState() const = 0; + #endif }; /** @@ -156,13 +160,15 @@ namespace cadmium { return this->timeAdvance(state); } + #ifndef NO_LOGGING //! @return a string representation of the model state. S must implement the insertion (<<) operator. [[nodiscard]] std::string logState() const override { std::stringstream ss; ss << state; return ss.str(); } + #endif }; } -#endif //CADMIUM_CORE_MODELING_ATOMIC_HPP_ +#endif //CADMIUM_MODELING_DEVS_ATOMIC_HPP_ diff --git a/include/cadmium/core/modeling/component.hpp b/include/cadmium/modeling/devs/component.hpp similarity index 92% rename from include/cadmium/core/modeling/component.hpp rename to include/cadmium/modeling/devs/component.hpp index da5409c..9793626 100644 --- a/include/cadmium/core/modeling/component.hpp +++ b/include/cadmium/modeling/devs/component.hpp @@ -18,18 +18,20 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CORE_MODELING_COMPONENT_HPP_ -#define CADMIUM_CORE_MODELING_COMPONENT_HPP_ +#ifndef CADMIUM_MODELING_DEVS_COMPONENT_HPP_ +#define CADMIUM_MODELING_DEVS_COMPONENT_HPP_ #include #include -#include +#ifndef NO_LOGGING + #include +#endif #include #include #include #include #include "port.hpp" -#include "../exception.hpp" +#include "../../exception.hpp" namespace cadmium { @@ -109,11 +111,13 @@ namespace cadmium { * @throws CadmiumModelException if there is no input port with the provided ID. */ [[nodiscard]] std::shared_ptr getInPort(const std::string& id) const { - try { - return inPorts.at(id); - } catch (std::out_of_range& _) { - throw CadmiumModelException("port not found"); - } + if(inPorts.find(id)==inPorts.end()) throw CadmiumModelException("port not found"); + return inPorts.find(id)->second; + // try { + // return inPorts.at(id); + // } catch (...) { + // throw CadmiumModelException("port not found"); + // } } /** @@ -139,11 +143,13 @@ namespace cadmium { * @throws CadmiumModelException if there is no output port with the provided ID. */ [[nodiscard]] std::shared_ptr getOutPort(const std::string& id) const { - try { - return outPorts.at(id); - } catch (std::out_of_range& _) { - throw CadmiumModelException("port not found"); - } + if(outPorts.find(id)==outPorts.end()) throw CadmiumModelException("port not found"); + return outPorts.find(id)->second; + // try { + // return outPorts.at(id); + // } catch (...) { + // throw CadmiumModelException("port not found"); + // } } /** @@ -270,4 +276,4 @@ namespace cadmium { }; } -#endif //CADMIUM_CORE_MODELING_COMPONENT_HPP_ +#endif //CADMIUM_MODELING_DEVS_COMPONENT_HPP_ diff --git a/include/cadmium/core/modeling/coupled.hpp b/include/cadmium/modeling/devs/coupled.hpp similarity index 96% rename from include/cadmium/core/modeling/coupled.hpp rename to include/cadmium/modeling/devs/coupled.hpp index 2cc9657..a97cd31 100644 --- a/include/cadmium/core/modeling/coupled.hpp +++ b/include/cadmium/modeling/devs/coupled.hpp @@ -18,22 +18,24 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CORE_MODELING_COUPLED_HPP_ -#define CADMIUM_CORE_MODELING_COUPLED_HPP_ +#ifndef CADMIUM_MODELING_DEVS_COUPLED_HPP_ +#define CADMIUM_MODELING_DEVS_COUPLED_HPP_ -#include #include +#ifndef NO_LOGGING + #include +#endif +#include #include #include #include +#include #include #include #include #include "component.hpp" #include "port.hpp" -#include "../exception.hpp" - -#include +#include "../../exception.hpp" namespace cadmium { //! Couplings are unordered maps {portTo: [portFrom1, portFrom2, ...]}. @@ -116,11 +118,13 @@ namespace cadmium { * @throw CadmiumModelException if the component is not found. */ [[nodiscard]] std::shared_ptr getComponent(const std::string& id) const { - try { - return components.at(id); - } catch (std::out_of_range& _) { - throw CadmiumModelException("component not found"); - } + if(components.find(id)==components.end()) throw CadmiumModelException("component not found"); + return components.find(id)->second; + // try { + // return components.at(id); + // } catch (std::out_of_range& _) { + // throw CadmiumModelException("component not found"); + // } } /** @@ -145,6 +149,7 @@ namespace cadmium { */ template std::shared_ptr addComponent(Args&&... args) { + static_assert(std::is_base_of::value, "T must inherit cadmium::Component"); auto component = std::make_shared(std::forward(args)...); addComponent(component); return component; @@ -443,4 +448,4 @@ namespace cadmium { }; } -#endif //CADMIUM_CORE_MODELING_COUPLED_HPP_ +#endif //CADMIUM_MODELING_DEVS_COUPLED_HPP_ diff --git a/include/cadmium/core/modeling/port.hpp b/include/cadmium/modeling/devs/port.hpp similarity index 97% rename from include/cadmium/core/modeling/port.hpp rename to include/cadmium/modeling/devs/port.hpp index 5174bf7..4ae686d 100644 --- a/include/cadmium/core/modeling/port.hpp +++ b/include/cadmium/modeling/devs/port.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CORE_MODELING_PORT_HPP_ -#define CADMIUM_CORE_MODELING_PORT_HPP_ +#ifndef CADMIUM_MODELING_DEVS_PORT_HPP_ +#define CADMIUM_MODELING_DEVS_PORT_HPP_ #include #include @@ -29,7 +29,7 @@ #include #include #include "component.hpp" -#include "../exception.hpp" +#include "../../exception.hpp" namespace cadmium { class Component; @@ -97,12 +97,14 @@ namespace cadmium { */ virtual void propagate(const std::shared_ptr& portFrom) = 0; + #ifndef NO_LOGGING /** * It logs a single message of the port bag. * @param i index in the bag of the message to be logged. * @return a string representation of the ith message in the port bag. */ [[nodiscard]] virtual std::string logMessage(std::size_t i) const = 0; // TODO change to lazy iterator + #endif }; /** @@ -183,6 +185,7 @@ namespace cadmium { bag.insert(bag.end(), typedPort->bag.begin(), typedPort->bag.end()); } + #ifndef NO_LOGGING /** * It logs a given message of the bag. * @param i index in the bag of the message to be logged. @@ -193,6 +196,7 @@ namespace cadmium { ss << bag.at(i); return ss.str(); } + #endif }; //! Type alias to work with shared pointers pointing to _Port objects with less boilerplate code. @@ -235,6 +239,7 @@ namespace cadmium { bag.push_back(std::make_shared(std::forward(args)...)); } + #ifndef NO_LOGGING /** * It logs a single message of the bag. * @param i index in the bag of the message to be logged. @@ -245,6 +250,7 @@ namespace cadmium { ss << *bag.at(i); return ss.str(); } + #endif }; //! Type alias to work with shared pointers pointing to _BigPort objects with less boilerplate code. @@ -252,4 +258,4 @@ namespace cadmium { using BigPort = std::shared_ptr<_BigPort>; } -#endif //CADMIUM_CORE_MODELING_PORT_HPP_ +#endif //CADMIUM_MODELING_DEVS_PORT_HPP_ diff --git a/include/cadmium/simulation/core/abs_simulator.hpp b/include/cadmium/simulation/core/abs_simulator.hpp new file mode 100644 index 0000000..fbb2d0e --- /dev/null +++ b/include/cadmium/simulation/core/abs_simulator.hpp @@ -0,0 +1,105 @@ +/** + * Abstract simulator. + * Copyright (C) 2021 Román Cárdenas Rodríguez + * ARSLab - Carleton University + * GreenLSI - Polytechnic University of Madrid + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_CORE_ABS_SIMULATOR_HPP_ +#define CADMIUM_SIMULATION_CORE_ABS_SIMULATOR_HPP_ + +#include +#include +#ifndef NO_LOGGING + #include "../logger/logger.hpp" +#endif +#include "../../modeling/devs/component.hpp" + +namespace cadmium { + //! Abstract simulator class. + class AbstractSimulator { + protected: + long modelId; //!< Model identification number. + double timeLast; //!< Last simulation time. + double timeNext; //!< Next simulation time. + public: + /** + * Constructor function. + * @param time initial simulation time. + */ + explicit AbstractSimulator(double time): modelId(), timeLast(time), timeNext(std::numeric_limits::infinity()) {} + + //! default destructor function. + virtual ~AbstractSimulator() = default; + + //! @return last simulation time. + [[nodiscard]] double getTimeLast() const { + return timeLast; + } + + //! @return next simulation time. + [[nodiscard]] double getTimeNext() const { + return timeNext; + } + + //! @return pointer to the component corresponding to the abstract simulator. + [[nodiscard]] virtual std::shared_ptr getComponent() const = 0; + + /** + * Sets the model number ID. + * @param next corresponding model ID number. + * @return the next model ID number. + */ + virtual long setModelId(long next) = 0; + + #ifndef NO_LOGGING + /** + * Sets a logger (atomic states and output messages). + * @param newLogger pointer to the new logger. + */ + virtual void setLogger(const std::shared_ptr& newLogger) = 0; + #endif + + /** + * It performs all the tasks needed before the simulation. + * @param time initial simulation time. + */ + virtual void start(double time) = 0; + + /** + * It performs all the tasks needed after the simulation. + * @param time last simulation time. + */ + virtual void stop(double time) = 0; + + /** + * It executes the model collection function. + * @param time simulation time. + */ + virtual void collection(double time) = 0; + + /** + * It executes the model transition function. + * @param time + */ + virtual void transition(double time) = 0; + + //! it clears the input and output ports of the model. + virtual void clear() = 0; + }; +} + +#endif // CADMIUM_SIMULATION_CORE_ABS_SIMULATOR_HPP_ diff --git a/include/cadmium/simulation/core/coordinator.hpp b/include/cadmium/simulation/core/coordinator.hpp new file mode 100644 index 0000000..28cbd55 --- /dev/null +++ b/include/cadmium/simulation/core/coordinator.hpp @@ -0,0 +1,158 @@ +/** + * DEVS Coordinator class. + * Copyright (C) 2021 Román Cárdenas Rodríguez + * ARSLab - Carleton University + * GreenLSI - Polytechnic University of Madrid + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_CORE_COORDINATOR_HPP_ +#define CADMIUM_SIMULATION_CORE_COORDINATOR_HPP_ + +#include +#include +#include +#include "abs_simulator.hpp" +#include "simulator.hpp" +#include "../../modeling/devs/atomic.hpp" +#include "../../modeling/devs/coupled.hpp" +#include "../../modeling/devs/component.hpp" + +namespace cadmium { + //! DEVS sequential coordinator class. + class Coordinator: public AbstractSimulator { + private: + std::shared_ptr model; //!< Pointer to coupled model of the coordinator. + std::vector> simulators; //!< Vector of child simulators. + public: + /** + * Constructor function. + * @param model pointer to the coordinator coupled model. + * @param time initial simulation time. + * @param parallel if true, simulators will use mutexes for logging. + */ + Coordinator(std::shared_ptr model, double time): AbstractSimulator(time), model(std::move(model)) { + if (this->model == nullptr) { + throw CadmiumSimulationException("no coupled model provided"); + } + timeLast = time; + for (auto& [componentId, component]: this->model->getComponents()) { + std::shared_ptr simulator; + auto coupled = std::dynamic_pointer_cast(component); + if (coupled != nullptr) { + simulator = std::make_shared(coupled, time); + } else { + auto atomic = std::dynamic_pointer_cast(component); + if (atomic == nullptr) { + throw CadmiumSimulationException("component is not a coupled nor atomic model"); + } + simulator = std::make_shared(atomic, time); + } + simulators.push_back(simulator); + timeNext = std::min(timeNext, simulator->getTimeNext()); + } + } + + //! @return pointer to the coupled model of the coordinator. + [[nodiscard]] std::shared_ptr getComponent() const override { + return model; + } + + //! @return pointer to the coupled model of the coordinator without upcasting it to an abstract Component. + [[nodiscard]] std::shared_ptr getCoupled() const { + return model; + } + + //! @return pointer to subcomponents. + [[nodiscard]] const std::vector>& getSubcomponents() { + return simulators; + } + + /** + * Sets the model ID of its coupled model and all the models of its child simulators. + * @param next next available model ID. + * @return next available model ID after assiging the ID to all the child models. + */ + long setModelId(long next) override { + modelId = next++; + for (auto& simulator: simulators) { + next = simulator->setModelId(next); + } + return next; + } + + //! It updates the initial simulation time and calls to the start method of all its child simulators. + void start(double time) override { + timeLast = time; + std::for_each(simulators.begin(), simulators.end(), [time](auto& s) { s->start(time); }); + } + + //! It updates the final simulation time and calls to the stop method of all its child simulators. + void stop(double time) override { + timeLast = time; + std::for_each(simulators.begin(), simulators.end(), [time](auto& s) { s->stop(time); }); + } + + /** + * It collects all the output messages and propagates them according to the ICs and EOCs. + * @param time new simulation time. + */ + void collection(double time) override { + if (time >= timeNext) { + std::for_each(simulators.begin(), simulators.end(), [time](auto& s) { s->collection(time); }); + for (auto& [portFrom, portTo]: model->getSerialICs()) { + portTo->propagate(portFrom); + } + for (auto& [portFrom, portTo]: model->getSerialEOCs()) { + portTo->propagate(portFrom); + } + } + } + + /** + * It propagates input messages according to the EICs and triggers the state transition function of child components. + * @param time new simulation time. + */ + void transition(double time) override { + for (auto& [portFrom, portTo]: model->getSerialEICs()) { + portTo->propagate(portFrom); + } + timeLast = time; + timeNext = std::numeric_limits::infinity(); + for (auto& simulator: simulators) { + simulator->transition(time); + timeNext = std::min(timeNext, simulator->getTimeNext()); + } + } + + //! It clears the messages from all the ports of child components. + void clear() override { + std::for_each(simulators.begin(), simulators.end(), [](auto& s) { s->clear(); }); + model->clearPorts(); + } + + #ifndef NO_LOGGING + /** + * It sets the logger to all the child components. + * @param log pointer to the new logger. + */ + void setLogger(const std::shared_ptr& log) override { + std::for_each(simulators.begin(), simulators.end(), [log](auto& s) { s->setLogger(log); }); + } + #endif + }; +} + +#endif // CADMIUM_SIMULATION_CORE_COORDINATOR_HPP_ \ No newline at end of file diff --git a/include/cadmium/core/simulation/simulator.hpp b/include/cadmium/simulation/core/simulator.hpp similarity index 76% rename from include/cadmium/core/simulation/simulator.hpp rename to include/cadmium/simulation/core/simulator.hpp index c581cde..754bde9 100644 --- a/include/cadmium/core/simulation/simulator.hpp +++ b/include/cadmium/simulation/core/simulator.hpp @@ -18,23 +18,28 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CORE_SIMULATION_SIMULATOR_HPP_ -#define CADMIUM_CORE_SIMULATION_SIMULATOR_HPP_ +#ifndef CADMIUM_SIMULATION_CORE_SIMULATOR_HPP_ +#define CADMIUM_SIMULATION_CORE_SIMULATOR_HPP_ #include #include #include "abs_simulator.hpp" -#include "../exception.hpp" -#include "../logger/logger.hpp" -#include "../modeling/atomic.hpp" +#include "../../exception.hpp" +#ifndef NO_LOGGING + #include "../logger/logger.hpp" +#endif +#include "../../modeling/devs/atomic.hpp" namespace cadmium { //! DEVS simulator. class Simulator: public AbstractSimulator { private: std::shared_ptr model; //!< Pointer to the corresponding atomic DEVS model. - std::shared_ptr logger; //!< Pointer to logger (for output messages and state). + #ifndef NO_LOGGING + std::shared_ptr logger; + #endif public: + #ifndef NO_LOGGING /** * Constructor function. * @param model pointer to the atomic model. @@ -46,6 +51,19 @@ namespace cadmium { } timeNext = timeLast + this->model->timeAdvance(); } + #else + /** + * Constructor function. + * @param model pointer to the atomic model. + * @param time initial simulation time. + */ + Simulator(std::shared_ptr model, double time): AbstractSimulator(time), model(std::move(model)) { + if (this->model == nullptr) { + throw CadmiumSimulationException("no atomic model provided"); + } + timeNext = timeLast + this->model->timeAdvance(); + } + #endif //! @return pointer to the corresponding atomic DEVS model. [[nodiscard]] std::shared_ptr getComponent() const override { @@ -62,13 +80,15 @@ namespace cadmium { return next + 1; } + #ifndef NO_LOGGING /** * Sets a new logger. * @param log pointer to the logger. */ - void setLogger(const std::shared_ptr& log) override { - logger = log; + void setLogger(const std::shared_ptr& newLogger) override { + logger = newLogger; } + #endif /** * It performs all the operations before running a simulation. @@ -76,11 +96,11 @@ namespace cadmium { */ void start(double time) override { timeLast = time; + #ifndef NO_LOGGING if (logger != nullptr) { - logger->lock(); logger->logState(timeLast, modelId, model->getId(), model->logState()); - logger->unlock(); } + #endif }; /** @@ -89,11 +109,11 @@ namespace cadmium { */ void stop(double time) override { timeLast = time; + #ifndef NO_LOGGING if (logger != nullptr) { - logger->lock(); logger->logState(timeLast, modelId, model->getId(), model->logState()); - logger->unlock(); } + #endif } /** @@ -121,18 +141,11 @@ namespace cadmium { auto e = time - timeLast; (time < timeNext) ? model->externalTransition(e) : model->confluentTransition(e); } + #ifndef NO_LOGGING if (logger != nullptr) { - logger->lock(); // TODO leave lock/unlock calls only for parallel execution - if (time >= timeNext) { - for (const auto& outPort: model->getOutPorts()) { - for (std::size_t i = 0; i < outPort->size(); ++i) { - logger->logOutput(time, modelId, model->getId(), outPort->getId(), outPort->logMessage(i)); - } - } - } - logger->logState(time, modelId, model->getId(), model->logState()); - logger->unlock(); // TODO leave lock/unlock calls only for parallel execution + logger->logModel(time, modelId, model, time >= timeNext); } + #endif timeLast = time; timeNext = time + model->timeAdvance(); } @@ -144,4 +157,4 @@ namespace cadmium { }; } -#endif //CADMIUM_CORE_SIMULATION_SIMULATOR_HPP_ +#endif // CADMIUM_SIMULATION_CORE_SIMULATOR_HPP_ diff --git a/include/cadmium/core/logger/csv.hpp b/include/cadmium/simulation/logger/csv.hpp similarity index 94% rename from include/cadmium/core/logger/csv.hpp rename to include/cadmium/simulation/logger/csv.hpp index 1373867..06b135b 100644 --- a/include/cadmium/core/logger/csv.hpp +++ b/include/cadmium/simulation/logger/csv.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CORE_LOGGER_CSV_LOGGER_HPP_ -#define CADMIUM_CORE_LOGGER_CSV_LOGGER_HPP_ +#ifndef CADMIUM_SIMULATION_LOGGER_CSV_HPP_ +#define CADMIUM_SIMULATION_LOGGER_CSV_HPP_ #include #include @@ -50,6 +50,7 @@ namespace cadmium { //! It starts the output file stream and prints the CSV header. void start() override { file.open(filepath); + file << "sep=" << sep << std::endl; //. */ -#ifndef CADMIUM_CORE_LOGGER_LOGGER_HPP_ -#define CADMIUM_CORE_LOGGER_LOGGER_HPP_ +#ifndef CADMIUM_SIMULATION_LOGGER_LOGGER_HPP_ +#define CADMIUM_SIMULATION_LOGGER_LOGGER_HPP_ -#include -#include #include +#include "../../modeling/devs/atomic.hpp" namespace cadmium { //! Cadmium Logger abstract class. class Logger { private: - std::optional mutex; //!< Mutex for enabling a good parallel execution. + //std::optional mutex; //!< Mutex for enabling a good parallel execution. public: //! Constructor function. - Logger(): mutex() {} + Logger() {} //! Destructor function. virtual ~Logger() = default; - //! Creates a new mutex for parallel execution. - void createMutex() { - mutex.emplace(); - } - - //! Removes a mutex for sequential execution. - void removeMutex() { - mutex.reset(); - } - - //! It locks the logger mutex (if needed). - inline void lock() { - if (mutex.has_value()) { - mutex->lock(); - } - } - - //! It unlocks the logger mutex (if needed). - inline void unlock() { - if (mutex.has_value()) { - mutex->unlock(); - } - } - //! Virtual method to execute any task prior to the simulation required by the logger. virtual void start() = 0; @@ -81,7 +56,11 @@ namespace cadmium { * @param portName name of the model port in which the output message was created. * @param output string representation of the output message. */ - virtual void logOutput(double time, long modelId, const std::string& modelName, const std::string& portName, const std::string& output) = 0; + virtual void logOutput(double time, + long modelId, + const std::string& modelName, + const std::string& portName, + const std::string& output) = 0; /** * Virtual method to log atomic models' states. @@ -91,7 +70,28 @@ namespace cadmium { * @param state string representation of the state. */ virtual void logState(double time, long modelId, const std::string& modelName, const std::string& state) = 0; + + /** + * method for logging the state of an atomic model after executing its output and/or transition functions. + * @param time current simulation time. + * @param modelId ID of the model that generated the output message. + * @param modelName name of the model that generated the output message. + * @param logOutput if true, it will print the output messages of the model. + */ + virtual void logModel(double time, + long modelId, + const std::shared_ptr& model, + bool logOutput) { + if (logOutput) { + for (const auto& outPort: model->getOutPorts()) { + for (std::size_t i = 0; i < outPort->size(); ++i) { + this->logOutput(time, modelId, model->getId(), outPort->getId(), outPort->logMessage(i)); + } + } + } + this->logState(time, modelId, model->getId(), model->logState()); + } }; } -#endif //CADMIUM_CORE_LOGGER_LOGGER_HPP_ +#endif // CADMIUM_SIMULATION_LOGGER_LOGGER_HPP_ diff --git a/include/cadmium/simulation/logger/mutex.hpp b/include/cadmium/simulation/logger/mutex.hpp new file mode 100644 index 0000000..6d8c29e --- /dev/null +++ b/include/cadmium/simulation/logger/mutex.hpp @@ -0,0 +1,114 @@ +/** + * Coordinator for executing simulations in parallel. + * Copyright (C) 2021 Román Cárdenas Rodríguez + * ARSLab - Carleton University + * GreenLSI - Polytechnic University of Madrid + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_LOGGER_MUTEX_HPP_ +#define CADMIUM_SIMULATION_LOGGER_MUTEX_HPP_ + +#include +#include +#include "logger.hpp" + +namespace cadmium { + //! Cadmium logger guarded by a mutex. It is necessary for parallel execution. + template + class MutexLogger : public Logger { + static_assert(std::is_base_of::value, "T must inherit cadmium::Logger"); + private: + T logger; + std::mutex mutex; //!< Mutex for synchronizing parallel logging. + public: + //! Constructor function. + explicit MutexLogger(T logger) : Logger(), logger(std::move(logger)), mutex() { + } + + //! Virtual method to execute any task prior to the simulation required by the logger. + void start() override { + mutex.lock(); + logger.start(); + mutex.unlock(); + }; + + //! Virtual method to execute any task after the simulation required by the logger. + void stop() override { + mutex.lock(); + logger.stop(); + mutex.unlock(); + }; + + /** + * Virtual method to log the simulation time after a simulation step. By default, it does nothing. + * @param time new simulation time. + */ + void logTime(double time) override { + mutex.lock(); + logger.logTime(time); + mutex.unlock(); + } + + /** + * Virtual method to log atomic models' output messages. + * @param time current simulation time. + * @param modelId ID of the model that generated the output message. + * @param modelName name of the model that generated the output message. + * @param portName name of the model port in which the output message was created. + * @param output string representation of the output message. + */ + void logOutput(double time, + long modelId, + const std::string& modelName, + const std::string& portName, + const std::string& output) override { + mutex.lock(); + logger.logOutput(time, modelId, modelName, portName, output); + mutex.unlock(); + } + + /** + * Virtual method to log atomic models' states. + * @param time current simulation time. + * @param modelId ID of the model that generated the output message. + * @param modelName name of the model that generated the output message. + * @param state string representation of the state. + */ + void logState(double time, long modelId, const std::string& modelName, const std::string& state) override { + mutex.lock(); + logger.logState(time, modelId, modelName, state); + mutex.unlock(); + } + + /** + * method for logging the state of an atomic model after executing its output and/or transition functions. + * @param time current simulation time. + * @param modelId ID of the model that generated the output message. + * @param modelName name of the model that generated the output message. + * @param logOutput if true, it will print the output messages of the model. + */ + void logModel(double time, + long modelId, + const std::shared_ptr& model, + bool logOutput) override { + mutex.lock(); + logger.logModel(time, modelId, model, logOutput); + mutex.unlock(); + } + }; +} + +#endif //CADMIUM_SIMULATION_LOGGER_MUTEX_HPP_ diff --git a/include/cadmium/simulation/logger/stdout.hpp b/include/cadmium/simulation/logger/stdout.hpp new file mode 100644 index 0000000..930d6be --- /dev/null +++ b/include/cadmium/simulation/logger/stdout.hpp @@ -0,0 +1,102 @@ +/** + * STDOUT logger. + * Copyright (C) 2023 Ezequiel Pecker Marcosig + * ARSLab - Carleton University + * SEDLab - University of Buenos Aires + * Modified by: Sasisekhar Govind + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PASTDOUTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_CORE_LOGGER_STDOUT_LOGGER_HPP_ +#define CADMIUM_CORE_LOGGER_STDOUT_LOGGER_HPP_ + +#include +#include +#include +#include "logger.hpp" + +namespace cadmium { + //! Cadmium STDOUT logger class. + class STDOUTLogger: public Logger { + private: + std::string sep; //!< String used as column separation. + // std::ostream& sink; //!< output stream. + public: + /** + * Constructor function. + * @param sep string used as column separation. + */ + STDOUTLogger(std::string sep): Logger(), sep(std::move(sep)){} + + /** + * Constructor function. Separation is set to ",". + */ + explicit STDOUTLogger(): STDOUTLogger(",") {} + + //! It starts the output file stream and prints the header in standard output. + void start() override { + std::cout << "time" << sep << "model_id" << sep << "model_name" << sep << "port_name" << sep << "data" << std::endl; + } + + //! It does nothing after the simulation. + void stop() override { + } + + /** + * Virtual method to log atomic models' output messages. + * @param time current simulation time. + * @param modelId ID of the model that generated the output message. + * @param modelName name of the model that generated the output message. + * @param portName name of the model port in which the output message was created. + * @param output string representation of the output message. + */ + void logOutput(double time, long modelId, const std::string& modelName, const std::string& portName, const std::string& output) override { + std::cout << "\x1B[32m" << time << sep << modelId << sep << modelName << sep << portName << sep << output << "\033[0m" << std::endl; + } + + /** + * Virtual method to log atomic models' states. + * @param time current simulation time. + * @param modelId ID of the model that generated the output message. + * @param modelName name of the model that generated the output message. + * @param state string representation of the state. + */ + void logState(double time, long modelId, const std::string& modelName, const std::string& state) override { + +#ifndef NO_LOG_STATE //!< if you do not want to log the state transitions, define this macro + std::cout << "\x1B[33m" << time << sep << modelId << sep << modelName << sep << sep << state << "\033[0m" << std::endl; +#endif + } + +#ifdef LOG_INPUT //!< if you want to log inputs, define this macro + void logModel(double time, + long modelId, + const std::shared_ptr& model, + bool logOutput) override { + + for (const auto& inPort: model->getInPorts()) { + for (std::size_t i = 0; i < inPort->size(); ++i) { + this->logOutput(time, modelId, model->getId(), inPort->getId(), inPort->logMessage(i)); + } + } + + Logger::logModel(time, modelId, model, logOutput); + } +#endif + + }; +} + +#endif //CADMIUM_CORE_LOGGER_STDOUT_LOGGER_HPP_ diff --git a/include/cadmium/core/simulation/parallel_root_coordinator.hpp b/include/cadmium/simulation/parallel_root_coordinator.hpp similarity index 74% rename from include/cadmium/core/simulation/parallel_root_coordinator.hpp rename to include/cadmium/simulation/parallel_root_coordinator.hpp index 7006e6f..c1faf94 100644 --- a/include/cadmium/core/simulation/parallel_root_coordinator.hpp +++ b/include/cadmium/simulation/parallel_root_coordinator.hpp @@ -18,8 +18,8 @@ * along with this program. If not, see . */ -#ifndef CADMIUM_CORE_SIMULATION_PARALLEL_ROOT_COORDINATOR_HPP_ -#define CADMIUM_CORE_SIMULATION_PARALLEL_ROOT_COORDINATOR_HPP_ +#ifndef CADMIUM_SIMULATION_PARALLEL_ROOT_COORDINATOR_HPP_ +#define CADMIUM_SIMULATION_PARALLEL_ROOT_COORDINATOR_HPP_ #include #include @@ -28,15 +28,16 @@ #include #include #include "root_coordinator.hpp" -#include "../logger/logger.hpp" - -#include +#ifndef NO_LOGGING + #include "logger/logger.hpp" + #include "logger/mutex.hpp" +#endif namespace cadmium { //! Parallel Root coordinator class. class ParallelRootCoordinator { private: - std::shared_ptr rootCoordinator; + std::shared_ptr rootCoordinator; //! It serializes the IC couplings in pairs to parallelize message propagation. std::vector, std::vector>>> stackedIC; public: @@ -49,27 +50,27 @@ namespace cadmium { } explicit ParallelRootCoordinator(std::shared_ptr model): ParallelRootCoordinator(std::move(model), 0) {} - void setLogger(const std::shared_ptr& log) { - rootCoordinator->setLogger(log); - } + + #ifndef NO_LOGGING + template + void setLogger(Args&&... args) { + T logger = T(std::forward(args)...); + rootCoordinator->setLogger>(std::move(logger)); + } + #endif void start() { - rootCoordinator->start(); - } + rootCoordinator->start(); + } - void stop() { - rootCoordinator->stop(); - } + void stop() { + rootCoordinator->stop(); + } void simulate(long nIterations, size_t thread_number = std::thread::hardware_concurrency()) { - // First, we make sure that Mutexes are activated - if (rootCoordinator->getLogger()) { - rootCoordinator->getLogger()->createMutex(); - } double timeNext = rootCoordinator->getTopCoordinator()->getTimeNext(); - // Threads created - #pragma omp parallel default(none) num_threads(thread_number) shared(timeNext, nIterations) +#pragma omp parallel default(none) num_threads(thread_number) shared(timeNext, nIterations) { //each thread get its if within the group size_t tid = omp_get_thread_num(); @@ -81,52 +82,52 @@ namespace cadmium { while (nIterations-- > 0 && timeNext < std::numeric_limits::infinity()) { // Step 1: execute output functions - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 0; i < nSubcomponents; i++) { subcomponents.at(i)->collection(timeNext); } - #pragma omp barrier +#pragma omp barrier //end Step 1 - // Step 2: route messages - #pragma omp for schedule(static) + // Step 2: route messages +#pragma omp for schedule(static) for (size_t i = 0; i < nICs; i++) { // We only parallelize by destination port, right? - for (auto& portFrom: stackedIC[i].second) { + for (auto& portFrom: stackedIC[i].second) { stackedIC.at(i).first->propagate(portFrom); - } + } } - #pragma omp barrier +#pragma omp barrier // end Step 2 // Step 3: state transitions - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 0; i < nSubcomponents; i++) { subcomponents.at(i)->transition(timeNext); subcomponents.at(i)->clear(); } - #pragma omp barrier +#pragma omp barrier // end Step 3 // Step 4: time for next events localNext = subcomponents[0]->getTimeNext(); // Potential bug: what if model is empty? I'd initialize this to infinity and iterate from 0 - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 1; i < nSubcomponents; i++){ if (subcomponents[i]->getTimeNext() < localNext) { localNext = subcomponents[i]->getTimeNext(); } } - #pragma omp single +#pragma omp single { timeNext = localNext; } - #pragma omp barrier - #pragma omp critical +#pragma omp barrier +#pragma omp critical { if (localNext < timeNext) { timeNext = localNext; } } - #pragma omp barrier +#pragma omp barrier //end Step 4 }//end simulation loop @@ -134,15 +135,11 @@ namespace cadmium { } void simulate(double timeInterval, size_t thread_number = std::thread::hardware_concurrency()) { - // First, we make sure that Mutexes are activated - if (rootCoordinator->getLogger()) { - rootCoordinator->getLogger()->createMutex(); - } - double timeNext = rootCoordinator->getTopCoordinator()->getTimeNext(); + double timeNext = rootCoordinator->getTopCoordinator()->getTimeNext(); double timeFinal = rootCoordinator->getTopCoordinator()->getTimeLast()+timeInterval; //threads created - #pragma omp parallel default(none) num_threads(thread_number) shared(timeNext, timeFinal, rootCoordinator) +#pragma omp parallel default(none) num_threads(thread_number) shared(timeNext, timeFinal, rootCoordinator) { //each thread get its if within the group size_t tid = omp_get_thread_num(); @@ -154,52 +151,52 @@ namespace cadmium { while(timeNext < timeFinal) { // Step 1: execute output functions - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 0; i < nSubcomponents; i++) { - subcomponents.at(i)->collection(timeNext); + subcomponents.at(i)->collection(timeNext); } - #pragma omp barrier +#pragma omp barrier //end Step 1 - // Step 2: route messages - #pragma omp for schedule(static) + // Step 2: route messages +#pragma omp for schedule(static) for (size_t i = 0; i < nICs; i++) { - for (auto& portFrom: stackedIC[i].second){ + for (auto& portFrom: stackedIC[i].second){ stackedIC.at(i).first->propagate(portFrom); - } + } } - #pragma omp barrier +#pragma omp barrier // end Step 2 // Step 3: state transitions - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 0; i < nSubcomponents; i++){ subcomponents.at(i)->transition(timeNext); subcomponents.at(i)->clear(); } - #pragma omp barrier +#pragma omp barrier // end Step 3 // Step 4: time for next events localNext = subcomponents[0]->getTimeNext(); - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 1; i < nSubcomponents; i++){ if (subcomponents[i]->getTimeNext() < localNext){ localNext = subcomponents[i]->getTimeNext(); } } - #pragma omp single +#pragma omp single { timeNext = localNext; } - #pragma omp barrier - #pragma omp critical +#pragma omp barrier +#pragma omp critical { if (localNext < timeNext) { timeNext = localNext; } } - #pragma omp barrier +#pragma omp barrier //end Step 4 }//end simulation loop @@ -207,15 +204,11 @@ namespace cadmium { } void simulateSerialCollection(double timeInterval, size_t thread_number = std::thread::hardware_concurrency()) { - // Firsts, we make sure that Mutexes are activated - if(rootCoordinator->getLogger()) { - rootCoordinator->getLogger()->createMutex(); - } - double timeNext = rootCoordinator->getTopCoordinator()->getTimeNext(); + double timeNext = rootCoordinator->getTopCoordinator()->getTimeNext(); double timeFinal = rootCoordinator->getTopCoordinator()->getTimeLast() + timeInterval; //threads created - #pragma omp parallel default(none) num_threads(thread_number) shared(timeNext, timeFinal, rootCoordinator) +#pragma omp parallel default(none) num_threads(thread_number) shared(timeNext, timeFinal, rootCoordinator) { //each thread get its if within the group size_t tid = omp_get_thread_num(); @@ -227,11 +220,11 @@ namespace cadmium { while (timeNext < timeFinal) { // Step 1: execute output functions - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 0; i < nSubcomponents; i++){ - subcomponents.at(i)->collection(timeNext); + subcomponents.at(i)->collection(timeNext); } - #pragma omp barrier +#pragma omp barrier //end Step 1 // Step 2: route messages (in sequential) @@ -243,34 +236,34 @@ namespace cadmium { // end Step 2 // Step 3: state transitions - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 0; i < nSubcomponents; i++) { subcomponents.at(i)->transition(timeNext); subcomponents.at(i)->clear(); } - #pragma omp barrier +#pragma omp barrier // end Step 3 // Step 4: time for next events localNext = subcomponents[0]->getTimeNext(); - #pragma omp for schedule(static) +#pragma omp for schedule(static) for (size_t i = 1; i < nSubcomponents; i++){ if (subcomponents[i]->getTimeNext() < localNext) { localNext = subcomponents[i]->getTimeNext(); } } - #pragma omp single +#pragma omp single { timeNext = localNext; } - #pragma omp barrier - #pragma omp critical +#pragma omp barrier +#pragma omp critical { if (localNext < timeNext) { timeNext = localNext; } } - #pragma omp barrier +#pragma omp barrier //end Step 4 }//end simulation loop @@ -279,4 +272,4 @@ namespace cadmium { }; } -#endif //CADMIUM_CORE_SIMULATION_PARALLEL_ROOT_COORDINATOR_HPP_ +#endif // CADMIUM_SIMULATION_PARALLEL_ROOT_COORDINATOR_HPP_ diff --git a/include/cadmium/simulation/root_coordinator.hpp b/include/cadmium/simulation/root_coordinator.hpp new file mode 100644 index 0000000..ffcddca --- /dev/null +++ b/include/cadmium/simulation/root_coordinator.hpp @@ -0,0 +1,121 @@ +/** + * Root coordinator for sequential simulation. + * Copyright (C) 2021 Román Cárdenas Rodríguez + * ARSLab - Carleton University + * GreenLSI - Polytechnic University of Madrid + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_ROOT_COORDINATOR_HPP_ +#define CADMIUM_SIMULATION_ROOT_COORDINATOR_HPP_ + +#include +#include +#include +#include +#include +#include "core/coordinator.hpp" +#ifndef NO_LOGGING + #include "logger/logger.hpp" +#endif + +namespace cadmium { + //! Root coordinator class. + class RootCoordinator { + protected: + std::shared_ptr topCoordinator; //!< Pointer to top coordinator. + #ifndef NO_LOGGING + std::shared_ptr logger; //!< Pointer to simulation logger. + #endif + + virtual void simulationAdvance(double timeNext) { + #ifndef NO_LOGGING + if (logger != nullptr) { + logger->logTime(timeNext); + } + #endif + topCoordinator->collection(timeNext); + topCoordinator->transition(timeNext); + topCoordinator->clear(); + } + + public: + #ifndef NO_LOGGING + RootCoordinator(std::shared_ptr model, double time): + topCoordinator(std::make_shared(std::move(model), time)), logger() {} + explicit RootCoordinator(std::shared_ptr model): RootCoordinator(std::move(model), 0) {} + #else + RootCoordinator(std::shared_ptr model, double time): + topCoordinator(std::make_shared(std::move(model), time)) {} + explicit RootCoordinator(std::shared_ptr model): RootCoordinator(std::move(model), 0) {} + #endif + virtual ~RootCoordinator() = default; + + #ifndef NO_LOGGING + template + void setLogger(Args&&... args) { + static_assert(std::is_base_of::value, "T must inherit cadmium::Logger"); + logger = std::make_shared(std::forward(args)...); + topCoordinator->setLogger(logger); + } + + std::shared_ptr getLogger() { + return logger; + } + #endif + + std::shared_ptr getTopCoordinator() { + return topCoordinator; + } + + virtual void start() { + #ifndef NO_LOGGING + if (logger != nullptr) { + logger->start(); + } + #endif + topCoordinator->setModelId(0); + topCoordinator->start(topCoordinator->getTimeLast()); + } + + virtual void stop() { + topCoordinator->stop(topCoordinator->getTimeLast()); + #ifndef NO_LOGGING + if (logger != nullptr) { + logger->stop(); + } + #endif + } + + [[maybe_unused]] void simulate(long nIterations) { + double timeNext = topCoordinator->getTimeNext(); + while (nIterations-- > 0 && timeNext < std::numeric_limits::infinity()) { + this->simulationAdvance(timeNext); + timeNext = topCoordinator->getTimeNext(); + } + } + + [[maybe_unused]] virtual void simulate(double timeInterval) { + double timeNext = topCoordinator->getTimeNext(); + double timeFinal = topCoordinator->getTimeLast() + timeInterval; + while(timeNext < timeFinal) { + this->simulationAdvance(timeNext); + timeNext = topCoordinator->getTimeNext(); + } + } + }; +} + +#endif // CADMIUM_SIMULATION_SEQUENTIAL_ROOT_COORDINATOR_HPP_ diff --git a/include/cadmium/simulation/rt_clock/ESPclock.hpp b/include/cadmium/simulation/rt_clock/ESPclock.hpp new file mode 100644 index 0000000..cd2b72f --- /dev/null +++ b/include/cadmium/simulation/rt_clock/ESPclock.hpp @@ -0,0 +1,184 @@ +/** + * Real-time clock based for the ESP32. + * Copyright (C) 2023 Sasisekhar Mangalam Govind + * ARSLab - Carleton University + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_RT_CLOCK_ESP_HPP +#define CADMIUM_SIMULATION_RT_CLOCK_ESP_HPP + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "driver/gptimer.h" +#include "esp_log.h" +#include "rt_clock.hpp" +#include "../../exception.hpp" +#include "interrupt_handler.hpp" +#include + +namespace cadmium { + /** + * Real-time clock based on the std::chrono library. It is suitable for Linux, MacOS, and Windows. + * @tparam T Internal clock type. By default, it uses the std::chrono::steady_clock + */ + template> + class ESPclock : RealTimeClock { + private: + gptimer_handle_t executionTimer; + double rTimeLast; + std::shared_ptr top_model; + std::shared_ptr> ISR_handle; + bool IE; + + void initTimer() { + gptimer_config_t timer_config1 = { + .clk_src = GPTIMER_CLK_SRC_DEFAULT, + .direction = GPTIMER_COUNT_UP, + .resolution_hz = 40 * 1000 * 1000, // 10MHz, 1 tick=100ns + .intr_priority = 0, + .flags = { + .intr_shared = true, + .allow_pd = false, + + .backup_before_sleep = false //*!< @deprecated, but quiets warnings + } + + }; + ESP_ERROR_CHECK(gptimer_new_timer(&timer_config1, &executionTimer)); + + ESP_ERROR_CHECK(gptimer_enable(executionTimer)); + gptimer_set_raw_count(executionTimer, 0); + gptimer_start(executionTimer); + } + + public: + + //! The empty constructor does not check the accumulated delay jitter. + ESPclock() : RealTimeClock() { + initTimer(); + this->top_model = NULL; + IE = false; + } + + [[maybe_unused]] ESPclock(std::shared_ptr model, std::shared_ptr> handler = nullptr) : RealTimeClock() { + initTimer(); + + IE = (handler != nullptr); //!< Enable interrupts if the handler is provided. + + this->top_model = model; + this->ISR_handle = handler; //!< Set the interrupt handler. + } + + /** + * Starts the real-time clock. + * @param timeLast initial simulation time. + */ + void start(double timeLast) override { + RealTimeClock::start(timeLast); + uint64_t count = 0; + uint32_t res = 0; + gptimer_get_resolution(executionTimer, &res); + gptimer_get_raw_count(executionTimer, &count); + rTimeLast = (double)count / (double)res; + } + + /** + * Stops the real-time clock. + * @param timeLast last simulation time. + */ + void stop(double timeLast) override { + uint64_t count = 0; + uint32_t res = 0; + gptimer_get_resolution(executionTimer, &res); + gptimer_get_raw_count(executionTimer, &count); + rTimeLast = (double)count / (double)res; + RealTimeClock::stop(timeLast); + } + + /** + * Waits until the next simulation time or until an external event happens. + * + * @param timeNext next simulation time (in seconds) for an internal transition. + * @return next simulation time (in seconds). Return value must be less than or equal to timeNext. + * */ + double waitUntil(double timeNext) override { + auto duration = timeNext - vTimeLast; + rTimeLast += duration; + + uint64_t count = 0; + uint32_t res = 0; + + gptimer_get_resolution(executionTimer, &res); + gptimer_get_raw_count(executionTimer, &count); + double timeNow = (double)count / (double)res; + + while(timeNow < rTimeLast) { + gptimer_get_resolution(executionTimer, &res); + gptimer_get_raw_count(executionTimer, &count); + timeNow = (double)count / (double)res; + + if(IE){ + if (ISR_handle->ISRcb()) { + auto data = ISR_handle->decodeISR(); + // Use std::visit to handle the variant type + std::visit([&](auto&& value) { + using ActualType = std::decay_t; + + bool isBigPort = std::dynamic_pointer_cast<_BigPort>(top_model->getInPort(data.second)) != nullptr; + + if(isBigPort){ + cadmium::BigPort out; + cadmium::Component IC("Interrupt Component"); + out = IC.addOutBigPort("out"); + out->addMessage(value); + + if (top_model->getInPort(data.second)->compatible(out)){ + top_model->getInPort(data.second)->propagate(out); + } else { + std::cerr << "[Interrupt Component] Incompatible ports!!" << std::endl; + } + } else { + cadmium::Port out; + cadmium::Component IC("Interrupt Component"); + out = IC.addOutPort("out"); + out->addMessage(value); + + if (top_model->getInPort(data.second)->compatible(out)){ + top_model->getInPort(data.second)->propagate(out); + } else { + std::cerr << "[Interrupt Component] Incompatible ports!!" << std::endl; + } + } + + }, data.first); + rTimeLast = timeNow; + break; + } + } + + } + + +#ifdef DEBUG_DELAY + ESP_LOGI("ESPclock", "[DELAY] %f us", (timeNow - rTimeLast) * 1000 * 1000); +#endif + return RealTimeClock::waitUntil(std::min(timeNext, timeNow)); + } + }; +} + +#endif // CADMIUM_SIMULATION_RT_ESP_CLOCK_HPP diff --git a/include/cadmium/simulation/rt_clock/chrono.hpp b/include/cadmium/simulation/rt_clock/chrono.hpp new file mode 100644 index 0000000..e5eb97f --- /dev/null +++ b/include/cadmium/simulation/rt_clock/chrono.hpp @@ -0,0 +1,180 @@ +/** + * Real-time clock based on the chrono standard library. + * Copyright (C) 2023 Román Cárdenas Rodríguez + * ARSLab - Carleton University + * GreenLSI - Polytechnic University of Madrid + * 2025 Sasisekhar Mangalam Govind + * ARSLab - Carleton University + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_RT_CLOCK_CHRONO_HPP +#define CADMIUM_SIMULATION_RT_CLOCK_CHRONO_HPP + +#include +#include +#include +#include +#include +#include "rt_clock.hpp" +#include "../../exception.hpp" + +#include "../../modeling/devs/component.hpp" //for the interrupt +#include "../../modeling/devs/coupled.hpp" //for the interrupt + +#include "interrupt_handler.hpp" + +namespace cadmium { + /** + * Real-time clock based on the std::chrono library. It is suitable for Linux, MacOS, and Windows. + * @tparam T Internal clock type. By default, it uses the std::chrono::steady_clock + */ + template> + class ChronoClock : RealTimeClock { + protected: + std::chrono::time_point rTimeLast; + std::shared_ptr top_model; + std::shared_ptr> ISR_handle; + bool IE; + double startTime; + std::optional maxJitter; //!< Maximum allowed delay jitter. This parameter is optional. + + public: + + //! The empty constructor does not check the accumulated delay jitter. + ChronoClock() : RealTimeClock(), rTimeLast(T::now()) { + this->top_model = NULL; + IE = false; + startTime = std::chrono::duration(T::now().time_since_epoch()).count(); + } + + //! Constructor accepting both a top model and an interrupt handler. + //! This constructor initializes the real-time clock with a model and a handler for asynchronous inputs. + //! If no handler is provided, it defaults to nullptr, and interrupts will be disabled. + //! @param model Pointer to the coupled top model. + //! @param handler Shared pointer to the interrupt handler. Defaults to nullptr. + [[maybe_unused]] explicit ChronoClock(std::shared_ptr model, std::shared_ptr> handler = nullptr) + : ChronoClock() { + IE = (handler != nullptr); //!< Enable interrupts if the handler is provided. + + this->top_model = model; + this->ISR_handle = handler; //!< Set the interrupt handler. + } + + [[maybe_unused]] explicit ChronoClock(typename T::duration maxJitter) : ChronoClock() { + this->top_model = NULL; + IE = false; + startTime = std::chrono::duration(T::now().time_since_epoch()).count(); + this->maxJitter.emplace(maxJitter); + } + + /** + * Starts the real-time clock. + * @param timeLast initial simulation time. + */ + void start(double timeLast) override { + RealTimeClock::start(timeLast); + rTimeLast = T::now(); + } + + /** + * Stops the real-time clock. + * @param timeLast last simulation time. + */ + void stop(double timeLast) override { + rTimeLast = T::now(); + RealTimeClock::stop(timeLast); + } + + /** + * Waits until the next simulation time or until an external event happens. + * + * @param nextTime next simulation time (in seconds) for an internal transition. + * @return next simulation time (in seconds). Return value must be less than or equal to nextTime. + * */ + double waitUntil(double timeNext) override { + auto duration = + std::chrono::duration_cast(std::chrono::duration(timeNext - vTimeLast)); + rTimeLast += duration; + + while(T::now() < rTimeLast || timeNext == std::numeric_limits::infinity()) { + if(IE){ + if (ISR_handle->ISRcb()) { + auto data = ISR_handle->decodeISR(); + + auto epoch = T::now().time_since_epoch(); + double time_now = std::chrono::duration(epoch).count(); + + // Use std::visit to handle the variant type + std::visit([&](auto&& value) { + using ActualType = std::decay_t; + + bool isBigPort = std::dynamic_pointer_cast<_BigPort>(top_model->getInPort(data.second)) != nullptr; + + if(isBigPort){ + cadmium::BigPort out; + cadmium::Component IC("Interrupt Component"); + out = IC.addOutBigPort("out"); + out->addMessage(value); + + if (top_model->getInPort(data.second)->compatible(out)){ + top_model->getInPort(data.second)->propagate(out); + } else { + std::cerr << "[Interrupt Component] Incompatible ports!!" << std::endl; + } + } else { + cadmium::Port out; + cadmium::Component IC("Interrupt Component"); + out = IC.addOutPort("out"); + out->addMessage(value); + + if (top_model->getInPort(data.second)->compatible(out)){ + top_model->getInPort(data.second)->propagate(out); + } else { + std::cerr << "[Interrupt Component] Incompatible ports!!" << std::endl; + } + } + + }, data.first); + + + rTimeLast = T::now(); + break; + } + + std::this_thread::sleep_for(std::chrono::microseconds(1)); //(T::now() - rTimeLast) << std::endl; +#endif + if (maxJitter.has_value()) { + auto jitter = T::now() - rTimeLast; + if (jitter > maxJitter.value()) { + throw cadmium::CadmiumRTClockException("delay jitter is too high"); + } + } + + auto epoch = T::now().time_since_epoch(); + double time_now = std::chrono::duration(epoch).count(); + return RealTimeClock::waitUntil(std::min(timeNext, time_now - startTime)); + } + }; +} + +#endif // CADMIUM_SIMULATION_RT_CLOCK_CHRONO_HPP diff --git a/include/cadmium/simulation/rt_clock/interrupt_handler.hpp b/include/cadmium/simulation/rt_clock/interrupt_handler.hpp new file mode 100644 index 0000000..fcf83bc --- /dev/null +++ b/include/cadmium/simulation/rt_clock/interrupt_handler.hpp @@ -0,0 +1,53 @@ +/** + * Interrupt Component Handler for the real time clock. + * Copyright (C) 2025 Sasisekhar Mangalam Govind + * ARSLab - Carleton University + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef INTERRUPT_HANDLER_HPP +#define INTERRUPT_HANDLER_HPP + +namespace cadmium { + + template + class InterruptHandler { + + public: + /** + * The interrupt handler abstract class. Override this class + * to enable asynchronous inputs in yout model + */ + InterruptHandler(){}; + + /** + * This function must be overriden to return true when an input arrives. + * This function is called within the clock to check for the arrival of an input. + * + * @return true if an input has arrived + */ + virtual bool ISRcb() = 0; + + /** + * This method must be overriden to obtain the value of the input, and convert it + * to a format understandable by your model. + * + * @return std::pair), string id of the input port> + */ + virtual std::pair decodeISR() = 0; + }; +} + +#endif \ No newline at end of file diff --git a/include/cadmium/simulation/rt_clock/mbedclock.hpp b/include/cadmium/simulation/rt_clock/mbedclock.hpp new file mode 100644 index 0000000..fe2fcce --- /dev/null +++ b/include/cadmium/simulation/rt_clock/mbedclock.hpp @@ -0,0 +1,198 @@ +/** + * Real-time clock for Mbed-OS version 5 + * Copyright (C) 2023 Ezequiel Pecker Marcosig + * SEDLab - University of Buenos Aires + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_RT_CLOCK_MBED_HPP +#define CADMIUM_SIMULATION_RT_CLOCK_MBED_HPP + +#include +#include +#include +#include "rt_clock.hpp" +#include "../../exception.hpp" +#include + +static long MIN_TO_MICRO = (1000 * 1000 * 60); +static long SEC_TO_MICRO = (1000 * 1000); +static long MILI_TO_MICRO = (1000); + +namespace cadmium { + /** + * Real-time clock based on the Driver APIs provided by MBED-OS version 5: https://os.mbed.com/docs/mbed-os/v5.15/apis/drivers.html. + * @tparam T Internal clock type. By default, it uses a double. + */ + template + class MBEDClock : RealTimeClock { + private: + Timer executionTimer; //!< used in the waitUntil() to measure the elapsed time between consecutive calls from the Root Coordinator and the time elapsed between an event and an external interruption + Timeout _timeout; + bool expired; + + //! schedulerSlip = 0 if the next event (actualDelay) is in the future, i.e. we are ahead of schedule + //! schedulerSlip = if actualDelay is negative, i.e. we are behind schedule. + //! This is then added to the next actualDelay and updated until we surpass the tolerance or recover from the slip. + long schedulerSlip = 0; + + /** + * Returns a long with the time in microseconds (ignore anything below 1 microsecond). + * @param Time value in seconds. + */ + long secondsToMicros(const double t) const { + if (t == std::numeric_limits::infinity()) { + return std::numeric_limits::max(); + } + return t * SEC_TO_MICRO; + } + + /** + * Returns a double with the time in seconds. + * @param Time in microseconds. + */ + double microsToSeconds(long us) const { + return (double) us / (double) SEC_TO_MICRO; + } + + /** + * Sleeps during specified time in microseconds. + * @param timeLeft time to sleep (in microseconds). + * @return the actual elapsed time since the method was triggered. + */ + long setTimeout(long delayMicroSec) { + expired = false; + long timeLeft = delayMicroSec; + + executionTimer.start(); + executionTimer.reset(); + + // Handle waits of over ~35 minutes as timer overflows + while (!interrupted && (timeLeft > INT_MAX)) { + this->expired = false; + this->_timeout.attach_us(callback(this, &MBEDClock::timeoutExpired), INT_MAX); + + while (!expired && !interrupted) { + sleep(); + } + + if (!interrupted) { + timeLeft -= INT_MAX; + } + } + + // Handle waits of under INT_MAX microseconds + if (!interrupted && timeLeft > 0) { + this->_timeout.attach_us(callback(this, &MBEDClock::timeoutExpired), timeLeft); // sets callback to change expired after timeLeft time + while (!expired && !interrupted) { + sleep(); // remains here until expired is set true by the _timeout() callback + } + } + executionTimer.stop(); + + expired = false; + timeLeft -= executionTimer.read_us(); + return std::max(delayMicroSec - timeLeft, 0l); // returns the elapsed time + } + + protected: + T rTimeLast; //!< last real system time. + long maxJitter; //!< Maximum allowed delay jitter. This parameter is optional. + + public: + volatile bool interrupted; //!< used for external interrupts + + //! The empty constructor does not check the accumulated delay jitter. + MBEDClock() : RealTimeClock(), executionTimer(), _timeout() { + rTimeLast = 0.0; + maxJitter = -1; + expired = false; + interrupted = false; + } + + /** + * Use this constructor to select the maximum allowed delay jitter. + * @param maxJitter duration of the maximum allowed jitter (long). + */ + [[maybe_unused]] explicit MBEDClock(long maxJitter) : MBEDClock() { + maxJitter = maxJitter; + } + + /** + * Starts the real-time clock. + * @param timeLast initial simulation time. + */ + void start(double timeLast) override { + RealTimeClock::start(timeLast); + rTimeLast = 0.0; + // executionTimer.reset(); + executionTimer.start(); + } + + /** + * Stops the real-time clock. + * @param timeLast last simulation time. + */ + void stop(double timeLast) override { + // rTimeLast = executionTimer.read_us(); + executionTimer.stop(); + RealTimeClock::stop(timeLast); + } + + /** + * Waits until the next simulation time. + * @param nextTime next simulation time (in seconds). + */ + T waitUntil(double timeNext) override { + // take the time between consecutive calls to waitUntil() + executionTimer.stop(); + long internalElapsedTime = executionTimer.read_us(); + + // subtract from duration the time elapsed between successive calls to waitUntil() + long expectedDelay = secondsToMicros(timeNext - vTimeLast) - internalElapsedTime + schedulerSlip; + schedulerSlip = std::min(expectedDelay, 0l); // schedulerSlip keeps track of how far behind schedule we are + if (maxJitter >= 0) { + auto jitter = std::abs(schedulerSlip); + if (jitter > maxJitter) { + throw cadmium::CadmiumRTClockException("delay jitter is too high"); + } + } + + long actualDelay = setTimeout(expectedDelay); + double duration = microsToSeconds(actualDelay); + executionTimer.start(); + executionTimer.reset(); // reset timer to measure the time elapsed until the next call to waitUntil() + + rTimeLast += duration; + return RealTimeClock::waitUntil(vTimeLast + duration); + } + + /** + * Sets the interrupted flag in case of an external interruption comes up. + */ + void update() { + interrupted = true; + } + + /** + * Handler for the timeout interrupt. + */ + void timeoutExpired() { + expired = true; + } + }; +} + +#endif // CADMIUM_SIMULATION_RT_CLOCK_MBED_HPP diff --git a/include/cadmium/simulation/rt_clock/rt_clock.hpp b/include/cadmium/simulation/rt_clock/rt_clock.hpp new file mode 100644 index 0000000..b3518b9 --- /dev/null +++ b/include/cadmium/simulation/rt_clock/rt_clock.hpp @@ -0,0 +1,65 @@ +/** + * Abstract Base Class of a real-time clock. + * Copyright (C) 2023 Román Cárdenas Rodríguez + * ARSLab - Carleton University + * GreenLSI - Polytechnic University of Madrid + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_RT_CLOCK_RT_CLOCK_HPP +#define CADMIUM_SIMULATION_RT_CLOCK_RT_CLOCK_HPP + +namespace cadmium { + //! Abstract base class of a real-time clock. + class RealTimeClock { + protected: + double vTimeLast; //!< Last virtual time (i.e., the clock time in the simulation). + public: + + RealTimeClock() : vTimeLast() {} + + virtual ~RealTimeClock() = default; + + /** + * Virtual method for starting the real-time clock. + * @param timeLast initial virtual time (in seconds). + */ + virtual void start(double timeLast) { + vTimeLast = timeLast; + }; + + /** + * Virtual method for stopping the real-time clock. + * @param timeLast final virtual time (in seconds). + */ + virtual void stop(double timeLast) { + vTimeLast = timeLast; + } + + /** + * Waits until the next simulation time or until an external event happens. + * In this abstract implementation, it does nothing. Thus, it always return timeNext. + * + * @param nextTime next simulation time (in seconds). + * @return next simulation time (in seconds). Return value must be less than or equal to nextTime. + */ + virtual double waitUntil(double timeNext) { + vTimeLast = timeNext; + return vTimeLast; + } + }; +} + +#endif // CADMIUM_SIMULATION_RT_CLOCK_RT_CLOCK_HPP diff --git a/include/cadmium/simulation/rt_clock/ti_clock.hpp b/include/cadmium/simulation/rt_clock/ti_clock.hpp new file mode 100644 index 0000000..fdb0c2c --- /dev/null +++ b/include/cadmium/simulation/rt_clock/ti_clock.hpp @@ -0,0 +1,138 @@ +/** + * Real-time clock for the MSP432P401R board + * Copyright (C) 2023 Srijan Gupta & James Grieder + * ARSLab - Carleton University + * GreenLSI - Polytechnic University of Madrid + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_RT_CLOCK_TI_HPP +#define CADMIUM_SIMULATION_RT_CLOCK_TI_HPP +#define MILI_TO_MICRO 1000.0 + +#include +#include "rt_clock.hpp" +#include "../../exception.hpp" +#include +#include +#include +#include +#include + +volatile bool expired = false; +volatile long numSeconds = 0; + +extern "C" { +const Timer_A_UpModeConfig config = { + TIMER_A_CLOCKSOURCE_SMCLK, + TIMER_A_CLOCKSOURCE_DIVIDER_1, + 127, + TIMER_A_TAIE_INTERRUPT_DISABLE, + TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE, + TIMER_A_DO_CLEAR +}; + +void T32_INT1_IRQHandler(void){ + ROM_Timer32_clearInterruptFlag(TIMER32_0_BASE); // reset interrupt flag + numSeconds++; +} + +void TA3_0_IRQHandler(void){ + ROM_Timer_A_clearCaptureCompareInterrupt(TIMER_A3_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0); + expired = true; +} +} + +namespace cadmium { + /** + * Real-time clock based on the Timer32 and TimerA APIs provided by TI for MSP432P401R + */ + class TIClock : RealTimeClock { + private: + protected: + double rTimeLast; + public: + volatile bool interrupted; + + /** This constructor configures the timer + */ + TIClock(): RealTimeClock(){ + interrupted = false; + ROM_CS_setReferenceOscillatorFrequency(CS_REFO_128KHZ); + ROM_CS_initClockSignal(CS_SMCLK,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1); + ROM_CS_initClockSignal(CS_MCLK,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1); + ROM_Timer_A_configureUpMode(TIMER_A3_BASE,&config); + ROM_Timer32_initModule(TIMER32_0_BASE,TIMER32_PRESCALER_1,TIMER32_32BIT,TIMER32_PERIODIC_MODE); + ROM_Interrupt_enableInterrupt(INT_TA3_0); + ROM_Interrupt_enableInterrupt(TIMER32_0_INTERRUPT); + ROM_Timer32_enableInterrupt(TIMER32_0_BASE); + ROM_Interrupt_enableMaster(); + } + + /** + * Starts the real-time clock. + * @param timeLast initial simulation time. + */ + void start(double timeLast) override { + RealTimeClock::start(timeLast); + rTimeLast = 0.0; + numSeconds = 0; + ROM_Timer32_setCount(TIMER32_0_BASE,128000); + ROM_Timer32_startTimer(TIMER32_0_BASE,false); + } + + /** + * Stops the real-time clock. + * @param timeLast last simulation time. + */ + void stop(double timeLast) override { + ROM_Timer32_haltTimer(TIMER32_0_BASE); + rTimeLast = timeLast; + RealTimeClock::stop(timeLast); + } + + /** + * Waits until the next simulation time. + * @param nextTime next simulation time (in seconds). + */ + double waitUntil(double timeNext) override { + // TODO Use timer32 to measure time required for computations and timer_a for delay. + ROM_Timer32_haltTimer(TIMER32_0_BASE); + long internal = numSeconds*MILI_TO_MICRO + (128064-ROM_Timer32_getValue(TIMER32_0_BASE))/128; + long expected = std::max((timeNext-vTimeLast)*MILI_TO_MICRO + 0.5 - internal, 1.0); + long left = expected; + expired = false; + ROM_Timer_A_startCounter(TIMER_A3_BASE,TIMER_A_UP_MODE); + while(!interrupted && left){ + expired = false; + while(!expired && !interrupted){} + if(!interrupted) left--; + } + ROM_Timer_A_stopTimer(TIMER_A3_BASE); + double duration = (expected+internal-left)/MILI_TO_MICRO; + rTimeLast += duration; + numSeconds = 0; + ROM_Timer32_setCount(TIMER32_0_BASE,128000); + ROM_Timer32_startTimer(TIMER32_0_BASE,false); + return RealTimeClock::waitUntil(vTimeLast+duration); + } + + void update(){ + interrupted = true; + } + }; +} // namespace cadmium + +#endif // CADMIUM_SIMULATION_RT_CLOCK_TI_HPP diff --git a/include/cadmium/simulation/rt_root_coordinator.hpp b/include/cadmium/simulation/rt_root_coordinator.hpp new file mode 100644 index 0000000..919e1ab --- /dev/null +++ b/include/cadmium/simulation/rt_root_coordinator.hpp @@ -0,0 +1,85 @@ +/** + * Root coordinator for real-time sequential simulation. + * Copyright (C) 2021 Román Cárdenas Rodríguez + * ARSLab - Carleton University + * GreenLSI - Polytechnic University of Madrid + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef CADMIUM_SIMULATION_RT_ROOT_COORDINATOR_HPP_ +#define CADMIUM_SIMULATION_RT_ROOT_COORDINATOR_HPP_ + +#include +#include +#include +#include +#include +#include "root_coordinator.hpp" +#include "core/coordinator.hpp" +#include "rt_clock/rt_clock.hpp" + +namespace cadmium { + /** + * Real-time root coordinator. + * @tparam T type of the real-time clock. + */ + template + class RealTimeRootCoordinator: public RootCoordinator { + static_assert(std::is_base_of::value, "T must inherit cadmium::RealTimeClock"); + protected: + T clock; //!< Real-time clock. + + /** + * The only difference with the sequential simulation is that we first wait until timeNext. + * @param timeNext next simulation time (in seconds). + */ + void simulationAdvance(double timeNext) override { + double t = clock.waitUntil(timeNext); + // double t = timeNext; + RootCoordinator::simulationAdvance(t); + } + + public: + RealTimeRootCoordinator(std::shared_ptr model, double time, T clock): + RootCoordinator(model, time), clock(clock) {} + + RealTimeRootCoordinator(std::shared_ptr model, T clock): RealTimeRootCoordinator(model, 0, clock) {} + + //! Starts the root coordinator and the real-time clock. + void start() override { + RootCoordinator::start(); + clock.start(topCoordinator->getTimeLast()); + } + + //! Stops the root coordinator and the real-time clock. + void stop() override { + clock.stop(topCoordinator->getTimeLast()); + RootCoordinator::stop(); + } + + void simulate(double timeInterval) override { + double timeNext = topCoordinator->getTimeNext(); + double timeFinal = topCoordinator->getTimeLast() + timeInterval; + + while(timeNext <= timeFinal || timeInterval == std::numeric_limits::infinity()) { + this->simulationAdvance(timeNext); + timeNext = topCoordinator->getTimeNext(); + } + } + + }; +} + +#endif // CADMIUM_SIMULATION_RT_ROOT_COORDINATOR_HPP_ diff --git a/templates/celldevs_asymm/config.json b/templates/celldevs_asymm/config.json index 5c08582..f4eebfc 100644 --- a/templates/celldevs_asymm/config.json +++ b/templates/celldevs_asymm/config.json @@ -2,7 +2,7 @@ "cells": { "default": { "delay": "inertial", - "cell_type": "default", + "model": "default", "state": {}, "config": {} }, diff --git a/templates/celldevs_grid/config.json b/templates/celldevs_grid/config.json index e8adf12..f86dfcc 100644 --- a/templates/celldevs_grid/config.json +++ b/templates/celldevs_grid/config.json @@ -7,7 +7,7 @@ "cells": { "default": { "delay": "inertial", - "cell_type": "default", + "model": "default", "state": {}, "config": {}, "neighborhood": [ diff --git a/test/core_celldevs/test_celldevs_queue.cpp b/test/core_celldevs/test_celldevs_queue.cpp index d680e6c..25f729f 100644 --- a/test/core_celldevs/test_celldevs_queue.cpp +++ b/test/core_celldevs/test_celldevs_queue.cpp @@ -1,6 +1,6 @@ #define BOOST_TEST_MODULE CellDEVSQueueTests #include -#include +#include using namespace cadmium::celldevs; diff --git a/test/core_modeling/test_atomic.cpp b/test/core_modeling/test_atomic.cpp index b461ce1..7219ead 100644 --- a/test/core_modeling/test_atomic.cpp +++ b/test/core_modeling/test_atomic.cpp @@ -1,6 +1,6 @@ #define BOOST_TEST_MODULE AtomicTests #include -#include +#include using namespace cadmium; diff --git a/test/core_modeling/test_coupled.cpp b/test/core_modeling/test_coupled.cpp index c04a058..e93ed92 100644 --- a/test/core_modeling/test_coupled.cpp +++ b/test/core_modeling/test_coupled.cpp @@ -1,7 +1,7 @@ #define BOOST_TEST_MODULE CoupledTests #include -#include -#include +#include +#include using namespace cadmium; diff --git a/test/core_modeling/test_port.cpp b/test/core_modeling/test_port.cpp index f7751f2..43710b6 100644 --- a/test/core_modeling/test_port.cpp +++ b/test/core_modeling/test_port.cpp @@ -1,6 +1,6 @@ #define BOOST_TEST_MODULE PortTests #include -#include +#include using namespace cadmium; diff --git a/test/grid_celldevs/test_grid_scenario.cpp b/test/grid_celldevs/test_grid_scenario.cpp index ac3c77a..dac0baa 100644 --- a/test/grid_celldevs/test_grid_scenario.cpp +++ b/test/grid_celldevs/test_grid_scenario.cpp @@ -1,6 +1,6 @@ #define BOOST_TEST_MODULE GridScenarioTests #include -#include +#include using namespace cadmium; using namespace cadmium::celldevs;