From 426dea59f01c876e829d6ec066face03f6f220ce Mon Sep 17 00:00:00 2001 From: yenru0 Date: Wed, 22 Oct 2025 12:39:31 +0900 Subject: [PATCH] add initial labs --- .gitignore | 10 +- labs/.gitignore | 1 + labs/lab_w2/.ccsproject | 17 + labs/lab_w2/.cproject | 187 +++++++++ labs/lab_w2/.project | 27 ++ labs/lab_w2/Clock.c | 169 +++++++++ labs/lab_w2/Clock.h | 99 +++++ labs/lab_w2/main.c | 46 +++ labs/lab_w2/msp432p401r.cmd | 138 +++++++ labs/lab_w2/startup_msp432p401r_ccs.c | 206 ++++++++++ labs/lab_w2/system_msp432p401r.c | 401 ++++++++++++++++++++ labs/lab_w2/targetConfigs/MSP432P401R.ccxml | 21 + labs/lab_w2/targetConfigs/readme.txt | 9 + labs/lab_w4/.ccsproject | 17 + labs/lab_w4/.cproject | 187 +++++++++ labs/lab_w4/.project | 27 ++ labs/lab_w4/Clock.c | 169 +++++++++ labs/lab_w4/Clock.h | 99 +++++ labs/lab_w4/main.c | 162 ++++++++ labs/lab_w4/msp432p401r.cmd | 138 +++++++ labs/lab_w4/startup_msp432p401r_ccs.c | 206 ++++++++++ labs/lab_w4/system_msp432p401r.c | 401 ++++++++++++++++++++ labs/lab_w4/targetConfigs/MSP432P401R.ccxml | 21 + labs/lab_w4/targetConfigs/readme.txt | 9 + labs/lab_w5/.ccsproject | 17 + labs/lab_w5/.cproject | 187 +++++++++ labs/lab_w5/.gitignore | 1 + labs/lab_w5/.project | 27 ++ labs/lab_w5/Clock.c | 169 +++++++++ labs/lab_w5/Clock.h | 99 +++++ labs/lab_w5/main.c | 12 + labs/lab_w5/msp432p401r.cmd | 138 +++++++ labs/lab_w5/startup_msp432p401r_ccs.c | 206 ++++++++++ labs/lab_w5/system_msp432p401r.c | 401 ++++++++++++++++++++ labs/lab_w5/targetConfigs/MSP432P401R.ccxml | 21 + labs/lab_w5/targetConfigs/readme.txt | 9 + 36 files changed, 4053 insertions(+), 1 deletion(-) create mode 100644 labs/.gitignore create mode 100644 labs/lab_w2/.ccsproject create mode 100644 labs/lab_w2/.cproject create mode 100644 labs/lab_w2/.project create mode 100644 labs/lab_w2/Clock.c create mode 100644 labs/lab_w2/Clock.h create mode 100644 labs/lab_w2/main.c create mode 100644 labs/lab_w2/msp432p401r.cmd create mode 100644 labs/lab_w2/startup_msp432p401r_ccs.c create mode 100644 labs/lab_w2/system_msp432p401r.c create mode 100644 labs/lab_w2/targetConfigs/MSP432P401R.ccxml create mode 100644 labs/lab_w2/targetConfigs/readme.txt create mode 100644 labs/lab_w4/.ccsproject create mode 100644 labs/lab_w4/.cproject create mode 100644 labs/lab_w4/.project create mode 100644 labs/lab_w4/Clock.c create mode 100644 labs/lab_w4/Clock.h create mode 100644 labs/lab_w4/main.c create mode 100644 labs/lab_w4/msp432p401r.cmd create mode 100644 labs/lab_w4/startup_msp432p401r_ccs.c create mode 100644 labs/lab_w4/system_msp432p401r.c create mode 100644 labs/lab_w4/targetConfigs/MSP432P401R.ccxml create mode 100644 labs/lab_w4/targetConfigs/readme.txt create mode 100644 labs/lab_w5/.ccsproject create mode 100644 labs/lab_w5/.cproject create mode 100644 labs/lab_w5/.gitignore create mode 100644 labs/lab_w5/.project create mode 100644 labs/lab_w5/Clock.c create mode 100644 labs/lab_w5/Clock.h create mode 100644 labs/lab_w5/main.c create mode 100644 labs/lab_w5/msp432p401r.cmd create mode 100644 labs/lab_w5/startup_msp432p401r_ccs.c create mode 100644 labs/lab_w5/system_msp432p401r.c create mode 100644 labs/lab_w5/targetConfigs/MSP432P401R.ccxml create mode 100644 labs/lab_w5/targetConfigs/readme.txt diff --git a/.gitignore b/.gitignore index d48c759..7c3fa1b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,10 @@ .idea -.vscode \ No newline at end of file +.vscode + +.metadata +.jxbrowser.userdata +RemoteSystemsTempFiles + +Debug +.settings +.launches diff --git a/labs/.gitignore b/labs/.gitignore new file mode 100644 index 0000000..e10e727 --- /dev/null +++ b/labs/.gitignore @@ -0,0 +1 @@ +/.metadata/ diff --git a/labs/lab_w2/.ccsproject b/labs/lab_w2/.ccsproject new file mode 100644 index 0000000..024ecb0 --- /dev/null +++ b/labs/lab_w2/.ccsproject @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/labs/lab_w2/.cproject b/labs/lab_w2/.cproject new file mode 100644 index 0000000..5ab9eb2 --- /dev/null +++ b/labs/lab_w2/.cproject @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/lab_w2/.project b/labs/lab_w2/.project new file mode 100644 index 0000000..32f0a01 --- /dev/null +++ b/labs/lab_w2/.project @@ -0,0 +1,27 @@ + + + lab_w2 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/labs/lab_w2/Clock.c b/labs/lab_w2/Clock.c new file mode 100644 index 0000000..74daa13 --- /dev/null +++ b/labs/lab_w2/Clock.c @@ -0,0 +1,169 @@ +// Clock.c +// Runs on the MSP432 +// Daniel and Jonathan Valvano +// February 23, 2017 + +/* This example accompanies the book + "Embedded Systems: Introduction to Robotics, + Jonathan W. Valvano, ISBN: 9781074544300, copyright (c) 2019 + For more information about my classes, my research, and my books, see + http://users.ece.utexas.edu/~valvano/ + +Simplified BSD License (FreeBSD License) +Copyright (c) 2019, Jonathan Valvano, All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. 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. + +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. + +The views and conclusions contained in the software and documentation are +those of the authors and should not be interpreted as representing official +policies, either expressed or implied, of the FreeBSD Project. +*/ + +#include +#include "msp.h" + +uint32_t ClockFrequency = 3000000; // cycles/second +//static uint32_t SubsystemFrequency = 3000000; // cycles/second + +// ------------Clock_InitFastest------------ +// Configure the system clock to run at the fastest +// and most accurate settings. For example, if the +// LaunchPad has a crystal, it should be used here. +// Call BSP_Clock_GetFreq() to get the current system +// clock frequency for the LaunchPad. +// Input: none +// Output: none +uint32_t Prewait = 0; // loops between BSP_Clock_InitFastest() called and PCM idle (expect 0) +uint32_t CPMwait = 0; // loops between Power Active Mode Request and Current Power Mode matching requested mode (expect small) +uint32_t Postwait = 0; // loops between Current Power Mode matching requested mode and PCM module idle (expect about 0) +uint32_t IFlags = 0; // non-zero if transition is invalid +uint32_t Crystalstable = 0; // loops before the crystal stabilizes (expect small) +void Clock_Init48MHz(void){ + // wait for the PCMCTL0 and Clock System to be write-able by waiting for Power Control Manager to be idle + while(PCM->CTL1&0x00000100){ +// while(PCMCTL1&0x00000100){ + Prewait = Prewait + 1; + if(Prewait >= 100000){ + return; // time out error + } + } + // request power active mode LDO VCORE1 to support the 48 MHz frequency + PCM->CTL0 = (PCM->CTL0&~0xFFFF000F) | // clear PCMKEY bit field and AMR bit field +// PCMCTL0 = (PCMCTL0&~0xFFFF000F) | // clear PCMKEY bit field and AMR bit field + 0x695A0000 | // write the proper PCM key to unlock write access + 0x00000001; // request power active mode LDO VCORE1 + // check if the transition is invalid (see Figure 7-3 on p344 of datasheet) + if(PCM->IFG&0x00000004){ + IFlags = PCM->IFG; // bit 2 set on active mode transition invalid; bits 1-0 are for LPM-related errors; bit 6 is for DC-DC-related error + PCM->CLRIFG = 0x00000004; // clear the transition invalid flag + // to do: look at CPM bit field in PCMCTL0, figure out what mode you're in, and step through the chart to transition to the mode you want + // or be lazy and do nothing; this should work out of reset at least, but it WILL NOT work if Clock_Int32kHz() or Clock_InitLowPower() has been called + return; + } + // wait for the CPM (Current Power Mode) bit field to reflect a change to active mode LDO VCORE1 + while((PCM->CTL0&0x00003F00) != 0x00000100){ + CPMwait = CPMwait + 1; + if(CPMwait >= 500000){ + return; // time out error + } + } + // wait for the PCMCTL0 and Clock System to be write-able by waiting for Power Control Manager to be idle + while(PCM->CTL1&0x00000100){ + Postwait = Postwait + 1; + if(Postwait >= 100000){ + return; // time out error + } + } + // initialize PJ.3 and PJ.2 and make them HFXT (PJ.3 built-in 48 MHz crystal out; PJ.2 built-in 48 MHz crystal in) + PJ->SEL0 |= 0x0C; + PJ->SEL1 &= ~0x0C; // configure built-in 48 MHz crystal for HFXT operation +// PJDIR |= 0x08; // make PJ.3 HFXTOUT (unnecessary) +// PJDIR &= ~0x04; // make PJ.2 HFXTIN (unnecessary) + CS->KEY = 0x695A; // unlock CS module for register access + CS->CTL2 = (CS->CTL2&~0x00700000) | // clear HFXTFREQ bit field + 0x00600000 | // configure for 48 MHz external crystal + 0x00010000 | // HFXT oscillator drive selection for crystals >4 MHz + 0x01000000; // enable HFXT + CS->CTL2 &= ~0x02000000; // disable high-frequency crystal bypass + // wait for the HFXT clock to stabilize + while(CS->IFG&0x00000002){ + CS->CLRIFG = 0x00000002; // clear the HFXT oscillator interrupt flag + Crystalstable = Crystalstable + 1; + if(Crystalstable > 100000){ + return; // time out error + } + } + // configure for 2 wait states (minimum for 48 MHz operation) for flash Bank 0 + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL&~0x0000F000)|FLCTL_BANK0_RDCTL_WAIT_2; + // configure for 2 wait states (minimum for 48 MHz operation) for flash Bank 1 + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL&~0x0000F000)|FLCTL_BANK1_RDCTL_WAIT_2; + CS->CTL1 = 0x20000000 | // configure for SMCLK divider /4 + 0x00100000 | // configure for HSMCLK divider /2 + 0x00000200 | // configure for ACLK sourced from REFOCLK + 0x00000050 | // configure for SMCLK and HSMCLK sourced from HFXTCLK + 0x00000005; // configure for MCLK sourced from HFXTCLK + CS->KEY = 0; // lock CS module from unintended access + ClockFrequency = 48000000; +// SubsystemFrequency = 12000000; +} + +// ------------Clock_GetFreq------------ +// Return the current system clock frequency for the +// LaunchPad. +// Input: none +// Output: system clock frequency in cycles/second +uint32_t Clock_GetFreq(void){ + return ClockFrequency; +} + + +// delay function +// which delays about 6*ulCount cycles +// ulCount=8000 => 1ms = (8000 loops)*(6 cycles/loop)*(20.83 ns/cycle) + //Code Composer Studio Code +void delay(unsigned long ulCount){ + __asm ( "pdloop: subs r0, #1\n" + " bne pdloop\n"); +} + +// ------------Clock_Delay1us------------ +// Simple delay function which delays about n microseconds. +// Inputs: n, number of us to wait +// Outputs: none +void Clock_Delay1us(uint32_t n){ + n = (382*n)/100;; // 1 us, tuned at 48 MHz + while(n){ + n--; + } +} + +// ------------Clock_Delay1ms------------ +// Simple delay function which delays about n milliseconds. +// Inputs: n, number of msec to wait +// Outputs: none +void Clock_Delay1ms(uint32_t n){ + while(n){ + delay(ClockFrequency/9162); // 1 msec, tuned at 48 MHz + n--; + } +} + + diff --git a/labs/lab_w2/Clock.h b/labs/lab_w2/Clock.h new file mode 100644 index 0000000..be8a5e0 --- /dev/null +++ b/labs/lab_w2/Clock.h @@ -0,0 +1,99 @@ +/** + * @file Clock.h + * @brief Provide functions that initialize the MSP432 clock module + * @details Reconfigure MSP432 to run at 48 MHz + * @version TI-RSLK MAX v1.1 + * @author Daniel Valvano and Jonathan Valvano + * @copyright Copyright 2019 by Jonathan W. Valvano, valvano@mail.utexas.edu, + * @warning AS-IS + * @note For more information see http://users.ece.utexas.edu/~valvano/ + * @date June 28, 2019 + + ******************************************************************************/ + +/* This example accompanies the book + "Embedded Systems: Introduction to Robotics, + Jonathan W. Valvano, ISBN: 9781074544300, copyright (c) 2019 + For more information about my classes, my research, and my books, see + http://users.ece.utexas.edu/~valvano/ + +Simplified BSD License (FreeBSD License) +Copyright (c) 2017, Jonathan Valvano, All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. 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. + +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. + +The views and conclusions contained in the software and documentation are +those of the authors and should not be interpreted as representing official +policies, either expressed or implied, of the FreeBSD Project. +*/ +#include +/** + * Configure the MSP432 clock to run at 48 MHz + * @param none + * @return none + * @note Since the crystal is used, the bus clock will be very accurate + * @see Clock_GetFreq() + * @brief Initialize clock to 48 MHz + */ +void Clock_Init48MHz(void); + + +/** + * Return the current bus clock frequency + * @param none + * @return frequency of the system clock in Hz + * @note In this module, the return result will be 3000000 or 48000000 + * @see Clock_Init48MHz() + * @brief Returns current clock bus frequency in Hz + */ +uint32_t Clock_GetFreq(void); + + +/** + * Simple delay function which delays about n milliseconds. + * It is implemented with a nested for-loop and is very approximate. + * @param n is the number of msec to wait + * @return none + * @note This function assumes a 48 MHz clock. + * This implementation is not very accurate. + * To improve accuracy, you could tune this function + * by adjusting the constant within the implementation + * found in the Clock.c file. + * For a more accurate time delay, you could use the SysTick module. + * @brief Software implementation of a busy-wait delay + */ +void Clock_Delay1ms(uint32_t n); + +/** + * Simple delay function which delays about n microseconds. + * It is implemented with a nested for-loop and is very approximate. + * @param n is the number of usec to wait + * @return none + * @note This function assumes a 48 MHz clock. + * This implementation is not very accurate. + * To improve accuracy, you could tune this function + * by adjusting the constant within the implementation + * found in the Clock.c file. + * For a more accurate time delay, you could use the SysTick module. + * @brief Software implementation of a busy-wait delay + */ +void Clock_Delay1us(uint32_t n); + diff --git a/labs/lab_w2/main.c b/labs/lab_w2/main.c new file mode 100644 index 0000000..6502ca5 --- /dev/null +++ b/labs/lab_w2/main.c @@ -0,0 +1,46 @@ +#include + +#include "msp.h" +#include "Clock.h" + + +void systick_init(void) { + + SysTick->LOAD = 0x00FFFFFF; + SysTick->CTRL = 0x00000005; +} + +void systick_wait1ms() { + SysTick->LOAD = 48000; + SysTick->VAL = 0; + while((SysTick->CTRL & 0x00010000) == 0) {} +} + +void systick_wait1s() { + int i; + int count = 1000; + for(i=0;iSEL0 &= ~0x07; + P2->SEL1 &= ~0x07; + P2->DIR |= 0x07; + P2->OUT &= ~0x07; + + printf("init end\n"); + + P2->OUT |= 0b00000111; + Clock_Delay1ms(10000); + + + +} diff --git a/labs/lab_w2/msp432p401r.cmd b/labs/lab_w2/msp432p401r.cmd new file mode 100644 index 0000000..e880348 --- /dev/null +++ b/labs/lab_w2/msp432p401r.cmd @@ -0,0 +1,138 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2017 Texas Instruments Incorporated - http://www.ti.com/ +* +* 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. +* +* Default linker command file for Texas Instruments MSP432P401R +* +* File creation date: 12/06/17 +* +*****************************************************************************/ +/* Suppress warnings and errors: */ +/* #10199-D CRC table operator (crc_table_for_<>) ignored: + CRC table operator cannot be associated with empty output section */ +--diag_suppress=10199 + +--retain=flashMailbox + +MEMORY +{ + MAIN (RX) : origin = 0x00000000, length = 0x00040000 + INFO (RX) : origin = 0x00200000, length = 0x00004000 +#ifdef __TI_COMPILER_VERSION__ +#if __TI_COMPILER_VERSION__ >= 15009000 + ALIAS + { + SRAM_CODE (RWX): origin = 0x01000000 + SRAM_DATA (RW) : origin = 0x20000000 + } length = 0x00010000 +#else + /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE */ + /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate */ + /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/ + SRAM_CODE (RWX): origin = 0x01000000, length = 0x00010000 + SRAM_DATA (RW) : origin = 0x20000000, length = 0x00010000 +#endif +#endif +} + +/* The following command line options are set as part of the CCS project. */ +/* If you are building using the command line, or for some reason want to */ +/* define them here, you can uncomment and modify these lines as needed. */ +/* If you are using CCS for building, it is probably better to make any such */ +/* modifications in your CCS project and leave this file alone. */ +/* */ +/* A heap size of 1024 bytes is recommended when you plan to use printf() */ +/* for debug output to the console window. */ +/* */ +/* --heap_size=1024 */ +/* --stack_size=512 */ +/* --library=rtsv7M4_T_le_eabi.lib */ + +/* Section allocation in memory */ + +SECTIONS +{ +#ifndef gen_crc_table + .intvecs: > 0x00000000 + .text : > MAIN + .const : > MAIN + .cinit : > MAIN + .pinit : > MAIN + .init_array : > MAIN + .binit : {} > MAIN + + /* The following sections show the usage of the INFO flash memory */ + /* INFO flash memory is intended to be used for the following */ + /* device specific purposes: */ + /* Flash mailbox for device security operations */ + .flashMailbox : > 0x00200000 + /* TLV table for device identification and characterization */ + .tlvTable : > 0x00201000 + /* BSL area for device bootstrap loader */ + .bslArea : > 0x00202000 +#else + .intvecs: > 0x00000000, crc_table(crc_table_for_intvecs) + .text : > MAIN, crc_table(crc_table_for_text) + .const : > MAIN, crc_table(crc_table_for_const) + .cinit : > MAIN, crc_table(crc_table_for_cinit) + .pinit : > MAIN, crc_table(crc_table_for_pinit) + .init_array : > MAIN, crc_table(crc_table_for_init_array) + .binit : {} > MAIN, crc_table(crc_table_for_binit) + + /* The following sections show the usage of the INFO flash memory */ + /* INFO flash memory is intended to be used for the following */ + /* device specific purposes: */ + /* Flash mailbox for device security operations */ + .flashMailbox : > 0x00200000, crc_table(crc_table_for_flashMailbox) + /* TLV table for device identification and characterization */ + /* This one is read only memory in flash - generate no CRC */ + .tlvTable : > 0x00201000 + /* BSL area for device bootstrap loader */ + .bslArea : > 0x00202000, crc_table(crc_table_for_bslArea) + .TI.crctab : > MAIN +#endif + + .vtable : > 0x20000000 + .data : > SRAM_DATA + .bss : > SRAM_DATA + .sysmem : > SRAM_DATA + .stack : > SRAM_DATA (HIGH) + +#ifdef __TI_COMPILER_VERSION__ +#if __TI_COMPILER_VERSION__ >= 15009000 + .TI.ramfunc : {} load=MAIN, run=SRAM_CODE, table(BINIT) +#endif +#endif +} + +/* Symbolic definition of the WDTCTL register for RTS */ +WDTCTL_SYM = 0x4000480C; + diff --git a/labs/lab_w2/startup_msp432p401r_ccs.c b/labs/lab_w2/startup_msp432p401r_ccs.c new file mode 100644 index 0000000..d403cca --- /dev/null +++ b/labs/lab_w2/startup_msp432p401r_ccs.c @@ -0,0 +1,206 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2017 Texas Instruments Incorporated - http://www.ti.com/ +* +* 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. +* +* MSP432P401R Interrupt Vector Table +* +*****************************************************************************/ + +#include + +/* Linker variable that marks the top of the stack. */ +extern unsigned long __STACK_END; + +/* External declaration for the reset handler that is to be called when the */ +/* processor is started */ +extern void _c_int00(void); + +/* External declaration for system initialization function */ +extern void SystemInit(void); + +/* Forward declaration of the default fault handlers. */ +void Default_Handler (void) __attribute__((weak)); +extern void Reset_Handler (void) __attribute__((weak)); + +/* Cortex-M4 Processor Exceptions */ +extern void NMI_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void HardFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void MemManage_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void BusFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void UsageFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void SVC_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void DebugMon_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void PendSV_Handler (void) __attribute__((weak, alias("Default_Handler"))); + +/* device specific interrupt handler */ +extern void SysTick_Handler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PSS_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void CS_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PCM_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void WDT_A_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void FPU_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void FLCTL_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void COMP_E0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void COMP_E1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA0_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA0_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA1_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA1_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA2_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA2_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA3_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA3_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void ADC14_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INTC_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void AES256_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void RTC_C_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_ERR_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT4_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT5_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT6_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); + +/* Interrupt vector table. Note that the proper constructs must be placed on this to */ +/* ensure that it ends up at physical address 0x0000.0000 or at the start of */ +/* the program if located at a start address other than 0. */ +#pragma RETAIN(interruptVectors) +#pragma DATA_SECTION(interruptVectors, ".intvecs") +void (* const interruptVectors[])(void) = +{ + (void (*)(void))((uint32_t)&__STACK_END), + /* The initial stack pointer */ + Reset_Handler, /* The reset handler */ + NMI_Handler, /* The NMI handler */ + HardFault_Handler, /* The hard fault handler */ + MemManage_Handler, /* The MPU fault handler */ + BusFault_Handler, /* The bus fault handler */ + UsageFault_Handler, /* The usage fault handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall handler */ + DebugMon_Handler, /* Debug monitor handler */ + 0, /* Reserved */ + PendSV_Handler, /* The PendSV handler */ + SysTick_Handler, /* The SysTick handler */ + PSS_IRQHandler, /* PSS Interrupt */ + CS_IRQHandler, /* CS Interrupt */ + PCM_IRQHandler, /* PCM Interrupt */ + WDT_A_IRQHandler, /* WDT_A Interrupt */ + FPU_IRQHandler, /* FPU Interrupt */ + FLCTL_IRQHandler, /* Flash Controller Interrupt*/ + COMP_E0_IRQHandler, /* COMP_E0 Interrupt */ + COMP_E1_IRQHandler, /* COMP_E1 Interrupt */ + TA0_0_IRQHandler, /* TA0_0 Interrupt */ + TA0_N_IRQHandler, /* TA0_N Interrupt */ + TA1_0_IRQHandler, /* TA1_0 Interrupt */ + TA1_N_IRQHandler, /* TA1_N Interrupt */ + TA2_0_IRQHandler, /* TA2_0 Interrupt */ + TA2_N_IRQHandler, /* TA2_N Interrupt */ + TA3_0_IRQHandler, /* TA3_0 Interrupt */ + TA3_N_IRQHandler, /* TA3_N Interrupt */ + EUSCIA0_IRQHandler, /* EUSCIA0 Interrupt */ + EUSCIA1_IRQHandler, /* EUSCIA1 Interrupt */ + EUSCIA2_IRQHandler, /* EUSCIA2 Interrupt */ + EUSCIA3_IRQHandler, /* EUSCIA3 Interrupt */ + EUSCIB0_IRQHandler, /* EUSCIB0 Interrupt */ + EUSCIB1_IRQHandler, /* EUSCIB1 Interrupt */ + EUSCIB2_IRQHandler, /* EUSCIB2 Interrupt */ + EUSCIB3_IRQHandler, /* EUSCIB3 Interrupt */ + ADC14_IRQHandler, /* ADC14 Interrupt */ + T32_INT1_IRQHandler, /* T32_INT1 Interrupt */ + T32_INT2_IRQHandler, /* T32_INT2 Interrupt */ + T32_INTC_IRQHandler, /* T32_INTC Interrupt */ + AES256_IRQHandler, /* AES256 Interrupt */ + RTC_C_IRQHandler, /* RTC_C Interrupt */ + DMA_ERR_IRQHandler, /* DMA_ERR Interrupt */ + DMA_INT3_IRQHandler, /* DMA_INT3 Interrupt */ + DMA_INT2_IRQHandler, /* DMA_INT2 Interrupt */ + DMA_INT1_IRQHandler, /* DMA_INT1 Interrupt */ + DMA_INT0_IRQHandler, /* DMA_INT0 Interrupt */ + PORT1_IRQHandler, /* Port1 Interrupt */ + PORT2_IRQHandler, /* Port2 Interrupt */ + PORT3_IRQHandler, /* Port3 Interrupt */ + PORT4_IRQHandler, /* Port4 Interrupt */ + PORT5_IRQHandler, /* Port5 Interrupt */ + PORT6_IRQHandler /* Port6 Interrupt */ +}; + +/* Forward declaration of the default fault handlers. */ +/* This is the code that gets called when the processor first starts execution */ +/* following a reset event. Only the absolutely necessary set is performed, */ +/* after which the application supplied entry() routine is called. Any fancy */ +/* actions (such as making decisions based on the reset cause register, and */ +/* resetting the bits in that register) are left solely in the hands of the */ +/* application. */ +void Reset_Handler(void) +{ + SystemInit(); + + /* Jump to the CCS C Initialization Routine. */ + __asm(" .global _c_int00\n" + " b.w _c_int00"); +} + + +/* This is the code that gets called when the processor receives an unexpected */ +/* interrupt. This simply enters an infinite loop, preserving the system state */ +/* for examination by a debugger. */ +void Default_Handler(void) +{ + /* Fault trap exempt from ULP advisor */ + #pragma diag_push + #pragma CHECK_ULP("-2.1") + + /* Enter an infinite loop. */ + while(1) + { + } + + #pragma diag_pop +} diff --git a/labs/lab_w2/system_msp432p401r.c b/labs/lab_w2/system_msp432p401r.c new file mode 100644 index 0000000..ab1f2fe --- /dev/null +++ b/labs/lab_w2/system_msp432p401r.c @@ -0,0 +1,401 @@ +/****************************************************************************** +* @file system_msp432p401r.c +* @brief CMSIS Cortex-M4F Device Peripheral Access Layer Source File for +* MSP432P401R +* @version 3.231 +* @date 01/26/18 +* +* @note View configuration instructions embedded in comments +* +******************************************************************************/ +//***************************************************************************** +// +// Copyright (C) 2015 - 2018 Texas Instruments Incorporated - http://www.ti.com/ +// +// 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. +// +//***************************************************************************** + +#include +#include "msp.h" + +/*--------------------- Configuration Instructions ---------------------------- + 1. If you prefer to halt the Watchdog Timer, set __HALT_WDT to 1: + #define __HALT_WDT 1 + 2. Insert your desired CPU frequency in Hz at: + #define __SYSTEM_CLOCK 12000000 + 3. If you prefer the DC-DC power regulator (more efficient at higher + frequencies), set the __REGULATOR to 1: + #define __REGULATOR 1 + *---------------------------------------------------------------------------*/ + +/*--------------------- Watchdog Timer Configuration ------------------------*/ +// Halt the Watchdog Timer +// <0> Do not halt the WDT +// <1> Halt the WDT +#define __HALT_WDT 1 + +/*--------------------- CPU Frequency Configuration -------------------------*/ +// CPU Frequency +// <1500000> 1.5 MHz +// <3000000> 3 MHz +// <12000000> 12 MHz +// <24000000> 24 MHz +// <48000000> 48 MHz +#define __SYSTEM_CLOCK 3000000 + +/*--------------------- Power Regulator Configuration -----------------------*/ +// Power Regulator Mode +// <0> LDO +// <1> DC-DC +#define __REGULATOR 0 + +/*---------------------------------------------------------------------------- + Define clocks, used for SystemCoreClockUpdate() + *---------------------------------------------------------------------------*/ +#define __VLOCLK 10000 +#define __MODCLK 24000000 +#define __LFXT 32768 +#define __HFXT 48000000 + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *---------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock)*/ + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void) +{ + uint32_t source = 0, divider = 0, dividerValue = 0, centeredFreq = 0, calVal = 0; + int16_t dcoTune = 0; + float dcoConst = 0.0; + + divider = (CS->CTL1 & CS_CTL1_DIVM_MASK) >> CS_CTL1_DIVM_OFS; + dividerValue = 1 << divider; + source = CS->CTL1 & CS_CTL1_SELM_MASK; + + switch(source) + { + case CS_CTL1_SELM__LFXTCLK: + if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + // Clear interrupt flag + CS->KEY = CS_KEY_VAL; + CS->CLRIFG |= CS_CLRIFG_CLR_LFXTIFG; + CS->KEY = 1; + + if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + } + else + { + SystemCoreClock = __LFXT / dividerValue; + } + } + else + { + SystemCoreClock = __LFXT / dividerValue; + } + break; + case CS_CTL1_SELM__VLOCLK: + SystemCoreClock = __VLOCLK / dividerValue; + break; + case CS_CTL1_SELM__REFOCLK: + if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + break; + case CS_CTL1_SELM__DCOCLK: + dcoTune = (CS->CTL0 & CS_CTL0_DCOTUNE_MASK) >> CS_CTL0_DCOTUNE_OFS; + + switch(CS->CTL0 & CS_CTL0_DCORSEL_MASK) + { + case CS_CTL0_DCORSEL_0: + centeredFreq = 1500000; + break; + case CS_CTL0_DCORSEL_1: + centeredFreq = 3000000; + break; + case CS_CTL0_DCORSEL_2: + centeredFreq = 6000000; + break; + case CS_CTL0_DCORSEL_3: + centeredFreq = 12000000; + break; + case CS_CTL0_DCORSEL_4: + centeredFreq = 24000000; + break; + case CS_CTL0_DCORSEL_5: + centeredFreq = 48000000; + break; + } + + if(dcoTune == 0) + { + SystemCoreClock = centeredFreq; + } + else + { + + if(dcoTune & 0x1000) + { + dcoTune = dcoTune | 0xF000; + } + + if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) + { + dcoConst = *((volatile const float *) &TLV->DCOER_CONSTK_RSEL04); + calVal = TLV->DCOER_FCAL_RSEL04; + } + /* Internal Resistor */ + else + { + dcoConst = *((volatile const float *) &TLV->DCOIR_CONSTK_RSEL04); + calVal = TLV->DCOIR_FCAL_RSEL04; + } + + SystemCoreClock = (uint32_t) ((centeredFreq) + / (1 + - ((dcoConst * dcoTune) + / (8 * (1 + dcoConst * (768 - calVal)))))); + } + break; + case CS_CTL1_SELM__MODOSC: + SystemCoreClock = __MODCLK / dividerValue; + break; + case CS_CTL1_SELM__HFXTCLK: + if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + // Clear interrupt flag + CS->KEY = CS_KEY_VAL; + CS->CLRIFG |= CS_CLRIFG_CLR_HFXTIFG; + CS->KEY = 1; + + if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + } + else + { + SystemCoreClock = __HFXT / dividerValue; + } + } + else + { + SystemCoreClock = __HFXT / dividerValue; + } + break; + } +} + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * + * Performs the following initialization steps: + * 1. Enables the FPU + * 2. Halts the WDT if requested + * 3. Enables all SRAM banks + * 4. Sets up power regulator and VCORE + * 5. Enable Flash wait states if needed + * 6. Change MCLK to desired frequency + * 7. Enable Flash read buffering + */ +void SystemInit(void) +{ + // Enable FPU if used + #if (__FPU_USED == 1) // __FPU_USED is defined in core_cm4.h + SCB->CPACR |= ((3UL << 10 * 2) | // Set CP10 Full Access + (3UL << 11 * 2)); // Set CP11 Full Access + #endif + + #if (__HALT_WDT == 1) + WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // Halt the WDT + #endif + + SYSCTL->SRAM_BANKEN = SYSCTL_SRAM_BANKEN_BNK7_EN; // Enable all SRAM banks + + #if (__SYSTEM_CLOCK == 1500000) // 1.5 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // No flash wait states necessary + + // DCO = 1.5 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_0; // Set DCO to 1.5MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 3000000) // 3 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while(PCM->CTL1 & PCM_CTL1_PMR_BUSY); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while(PCM->CTL1 & PCM_CTL1_PMR_BUSY); + #endif + + // No flash wait states necessary + + // DCO = 3 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_1; // Set DCO to 1.5MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 12000000) // 12 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // No flash wait states necessary + + // DCO = 12 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_3; // Set DCO to 12MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 24000000) // 24 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // 1 flash wait state (BANK0 VCORE0 max is 12 MHz) + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1; + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1; + + // DCO = 24 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_4; // Set DCO to 24MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 48000000) // 48 MHz + // Switches LDO VCORE0 to LDO VCORE1; mandatory for 48 MHz setting + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + + // Switches LDO VCORE1 to DCDC VCORE1 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // 1 flash wait states (BANK0 VCORE1 max is 16 MHz, BANK1 VCORE1 max is 32 MHz) + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1; + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1; + + // DCO = 48 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_5; // Set DCO to 48MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL | (FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + #endif + +} + + diff --git a/labs/lab_w2/targetConfigs/MSP432P401R.ccxml b/labs/lab_w2/targetConfigs/MSP432P401R.ccxml new file mode 100644 index 0000000..92ce945 --- /dev/null +++ b/labs/lab_w2/targetConfigs/MSP432P401R.ccxml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/lab_w2/targetConfigs/readme.txt b/labs/lab_w2/targetConfigs/readme.txt new file mode 100644 index 0000000..d783fef --- /dev/null +++ b/labs/lab_w2/targetConfigs/readme.txt @@ -0,0 +1,9 @@ +The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based +on the device and connection settings specified in your project on the Properties > General page. + +Please note that in automatic target-configuration management, changes to the project's device and/or +connection settings will either modify an existing or generate a new target-configuration file. Thus, +if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively, +you may create your own target-configuration file for this project and manage it manually. You can +always switch back to automatic target-configuration management by checking the "Manage the project's +target-configuration automatically" checkbox on the project's Properties > General page. \ No newline at end of file diff --git a/labs/lab_w4/.ccsproject b/labs/lab_w4/.ccsproject new file mode 100644 index 0000000..024ecb0 --- /dev/null +++ b/labs/lab_w4/.ccsproject @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/labs/lab_w4/.cproject b/labs/lab_w4/.cproject new file mode 100644 index 0000000..86faae9 --- /dev/null +++ b/labs/lab_w4/.cproject @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/lab_w4/.project b/labs/lab_w4/.project new file mode 100644 index 0000000..9289232 --- /dev/null +++ b/labs/lab_w4/.project @@ -0,0 +1,27 @@ + + + lab_w4 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/labs/lab_w4/Clock.c b/labs/lab_w4/Clock.c new file mode 100644 index 0000000..74daa13 --- /dev/null +++ b/labs/lab_w4/Clock.c @@ -0,0 +1,169 @@ +// Clock.c +// Runs on the MSP432 +// Daniel and Jonathan Valvano +// February 23, 2017 + +/* This example accompanies the book + "Embedded Systems: Introduction to Robotics, + Jonathan W. Valvano, ISBN: 9781074544300, copyright (c) 2019 + For more information about my classes, my research, and my books, see + http://users.ece.utexas.edu/~valvano/ + +Simplified BSD License (FreeBSD License) +Copyright (c) 2019, Jonathan Valvano, All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. 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. + +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. + +The views and conclusions contained in the software and documentation are +those of the authors and should not be interpreted as representing official +policies, either expressed or implied, of the FreeBSD Project. +*/ + +#include +#include "msp.h" + +uint32_t ClockFrequency = 3000000; // cycles/second +//static uint32_t SubsystemFrequency = 3000000; // cycles/second + +// ------------Clock_InitFastest------------ +// Configure the system clock to run at the fastest +// and most accurate settings. For example, if the +// LaunchPad has a crystal, it should be used here. +// Call BSP_Clock_GetFreq() to get the current system +// clock frequency for the LaunchPad. +// Input: none +// Output: none +uint32_t Prewait = 0; // loops between BSP_Clock_InitFastest() called and PCM idle (expect 0) +uint32_t CPMwait = 0; // loops between Power Active Mode Request and Current Power Mode matching requested mode (expect small) +uint32_t Postwait = 0; // loops between Current Power Mode matching requested mode and PCM module idle (expect about 0) +uint32_t IFlags = 0; // non-zero if transition is invalid +uint32_t Crystalstable = 0; // loops before the crystal stabilizes (expect small) +void Clock_Init48MHz(void){ + // wait for the PCMCTL0 and Clock System to be write-able by waiting for Power Control Manager to be idle + while(PCM->CTL1&0x00000100){ +// while(PCMCTL1&0x00000100){ + Prewait = Prewait + 1; + if(Prewait >= 100000){ + return; // time out error + } + } + // request power active mode LDO VCORE1 to support the 48 MHz frequency + PCM->CTL0 = (PCM->CTL0&~0xFFFF000F) | // clear PCMKEY bit field and AMR bit field +// PCMCTL0 = (PCMCTL0&~0xFFFF000F) | // clear PCMKEY bit field and AMR bit field + 0x695A0000 | // write the proper PCM key to unlock write access + 0x00000001; // request power active mode LDO VCORE1 + // check if the transition is invalid (see Figure 7-3 on p344 of datasheet) + if(PCM->IFG&0x00000004){ + IFlags = PCM->IFG; // bit 2 set on active mode transition invalid; bits 1-0 are for LPM-related errors; bit 6 is for DC-DC-related error + PCM->CLRIFG = 0x00000004; // clear the transition invalid flag + // to do: look at CPM bit field in PCMCTL0, figure out what mode you're in, and step through the chart to transition to the mode you want + // or be lazy and do nothing; this should work out of reset at least, but it WILL NOT work if Clock_Int32kHz() or Clock_InitLowPower() has been called + return; + } + // wait for the CPM (Current Power Mode) bit field to reflect a change to active mode LDO VCORE1 + while((PCM->CTL0&0x00003F00) != 0x00000100){ + CPMwait = CPMwait + 1; + if(CPMwait >= 500000){ + return; // time out error + } + } + // wait for the PCMCTL0 and Clock System to be write-able by waiting for Power Control Manager to be idle + while(PCM->CTL1&0x00000100){ + Postwait = Postwait + 1; + if(Postwait >= 100000){ + return; // time out error + } + } + // initialize PJ.3 and PJ.2 and make them HFXT (PJ.3 built-in 48 MHz crystal out; PJ.2 built-in 48 MHz crystal in) + PJ->SEL0 |= 0x0C; + PJ->SEL1 &= ~0x0C; // configure built-in 48 MHz crystal for HFXT operation +// PJDIR |= 0x08; // make PJ.3 HFXTOUT (unnecessary) +// PJDIR &= ~0x04; // make PJ.2 HFXTIN (unnecessary) + CS->KEY = 0x695A; // unlock CS module for register access + CS->CTL2 = (CS->CTL2&~0x00700000) | // clear HFXTFREQ bit field + 0x00600000 | // configure for 48 MHz external crystal + 0x00010000 | // HFXT oscillator drive selection for crystals >4 MHz + 0x01000000; // enable HFXT + CS->CTL2 &= ~0x02000000; // disable high-frequency crystal bypass + // wait for the HFXT clock to stabilize + while(CS->IFG&0x00000002){ + CS->CLRIFG = 0x00000002; // clear the HFXT oscillator interrupt flag + Crystalstable = Crystalstable + 1; + if(Crystalstable > 100000){ + return; // time out error + } + } + // configure for 2 wait states (minimum for 48 MHz operation) for flash Bank 0 + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL&~0x0000F000)|FLCTL_BANK0_RDCTL_WAIT_2; + // configure for 2 wait states (minimum for 48 MHz operation) for flash Bank 1 + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL&~0x0000F000)|FLCTL_BANK1_RDCTL_WAIT_2; + CS->CTL1 = 0x20000000 | // configure for SMCLK divider /4 + 0x00100000 | // configure for HSMCLK divider /2 + 0x00000200 | // configure for ACLK sourced from REFOCLK + 0x00000050 | // configure for SMCLK and HSMCLK sourced from HFXTCLK + 0x00000005; // configure for MCLK sourced from HFXTCLK + CS->KEY = 0; // lock CS module from unintended access + ClockFrequency = 48000000; +// SubsystemFrequency = 12000000; +} + +// ------------Clock_GetFreq------------ +// Return the current system clock frequency for the +// LaunchPad. +// Input: none +// Output: system clock frequency in cycles/second +uint32_t Clock_GetFreq(void){ + return ClockFrequency; +} + + +// delay function +// which delays about 6*ulCount cycles +// ulCount=8000 => 1ms = (8000 loops)*(6 cycles/loop)*(20.83 ns/cycle) + //Code Composer Studio Code +void delay(unsigned long ulCount){ + __asm ( "pdloop: subs r0, #1\n" + " bne pdloop\n"); +} + +// ------------Clock_Delay1us------------ +// Simple delay function which delays about n microseconds. +// Inputs: n, number of us to wait +// Outputs: none +void Clock_Delay1us(uint32_t n){ + n = (382*n)/100;; // 1 us, tuned at 48 MHz + while(n){ + n--; + } +} + +// ------------Clock_Delay1ms------------ +// Simple delay function which delays about n milliseconds. +// Inputs: n, number of msec to wait +// Outputs: none +void Clock_Delay1ms(uint32_t n){ + while(n){ + delay(ClockFrequency/9162); // 1 msec, tuned at 48 MHz + n--; + } +} + + diff --git a/labs/lab_w4/Clock.h b/labs/lab_w4/Clock.h new file mode 100644 index 0000000..be8a5e0 --- /dev/null +++ b/labs/lab_w4/Clock.h @@ -0,0 +1,99 @@ +/** + * @file Clock.h + * @brief Provide functions that initialize the MSP432 clock module + * @details Reconfigure MSP432 to run at 48 MHz + * @version TI-RSLK MAX v1.1 + * @author Daniel Valvano and Jonathan Valvano + * @copyright Copyright 2019 by Jonathan W. Valvano, valvano@mail.utexas.edu, + * @warning AS-IS + * @note For more information see http://users.ece.utexas.edu/~valvano/ + * @date June 28, 2019 + + ******************************************************************************/ + +/* This example accompanies the book + "Embedded Systems: Introduction to Robotics, + Jonathan W. Valvano, ISBN: 9781074544300, copyright (c) 2019 + For more information about my classes, my research, and my books, see + http://users.ece.utexas.edu/~valvano/ + +Simplified BSD License (FreeBSD License) +Copyright (c) 2017, Jonathan Valvano, All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. 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. + +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. + +The views and conclusions contained in the software and documentation are +those of the authors and should not be interpreted as representing official +policies, either expressed or implied, of the FreeBSD Project. +*/ +#include +/** + * Configure the MSP432 clock to run at 48 MHz + * @param none + * @return none + * @note Since the crystal is used, the bus clock will be very accurate + * @see Clock_GetFreq() + * @brief Initialize clock to 48 MHz + */ +void Clock_Init48MHz(void); + + +/** + * Return the current bus clock frequency + * @param none + * @return frequency of the system clock in Hz + * @note In this module, the return result will be 3000000 or 48000000 + * @see Clock_Init48MHz() + * @brief Returns current clock bus frequency in Hz + */ +uint32_t Clock_GetFreq(void); + + +/** + * Simple delay function which delays about n milliseconds. + * It is implemented with a nested for-loop and is very approximate. + * @param n is the number of msec to wait + * @return none + * @note This function assumes a 48 MHz clock. + * This implementation is not very accurate. + * To improve accuracy, you could tune this function + * by adjusting the constant within the implementation + * found in the Clock.c file. + * For a more accurate time delay, you could use the SysTick module. + * @brief Software implementation of a busy-wait delay + */ +void Clock_Delay1ms(uint32_t n); + +/** + * Simple delay function which delays about n microseconds. + * It is implemented with a nested for-loop and is very approximate. + * @param n is the number of usec to wait + * @return none + * @note This function assumes a 48 MHz clock. + * This implementation is not very accurate. + * To improve accuracy, you could tune this function + * by adjusting the constant within the implementation + * found in the Clock.c file. + * For a more accurate time delay, you could use the SysTick module. + * @brief Software implementation of a busy-wait delay + */ +void Clock_Delay1us(uint32_t n); + diff --git a/labs/lab_w4/main.c b/labs/lab_w4/main.c new file mode 100644 index 0000000..d05a4fe --- /dev/null +++ b/labs/lab_w4/main.c @@ -0,0 +1,162 @@ +#include +#ifdef __MSP432P401R__ +#else +#define __MSP432P401R__ +#endif + +//#define DEBUG_PRINT + + +#include "Clock.h" +#include "msp.h" + +#define LOOP_PERIOD_MS 20 + +#define BASE_SPEED_PERCENT 30 +#define TURN_SPEED_PERCENT 25 + +#define BASE_ON_TIME (LOOP_PERIOD_MS * BASE_SPEED_PERCENT / 100) +#define BASE_OFF_TIME (LOOP_PERIOD_MS - BASE_ON_TIME) + +#define TURN_ON_TIME (LOOP_PERIOD_MS * TURN_SPEED_PERCENT / 100) +#define TURN_OFF_TIME (LOOP_PERIOD_MS - TURN_ON_TIME) + +// IR +void ir_init(void) { + P5->SEL0 &= ~0x08; + P5->SEL1 &= ~0x08; + P5->DIR |= 0x08; + P5->OUT &= ~0x08; + P9->SEL0 &= ~0x04; + P9->SEL1 &= ~0x04; + P9->DIR |= 0x04; + P9->OUT &= ~0x04; + P7->SEL0 &= ~0xff; + P7->SEL1 &= ~0xff; + P7->DIR &= ~0xff; +} + +// Motor +void motor_init(void) { + P3->SEL0 &= ~0xc0; + P3->SEL1 &= ~0xc0; + P3->DIR |= 0xc0; + P3->OUT &= ~0xc0; + + P5->SEL0 &= ~0x30; + P5->SEL1 &= ~0x30; + P5->DIR |= 0x30; + P5->OUT &= ~0x30; + + P2->SEL0 &= ~0xc0; + P2->SEL1 &= ~0xc0; + P2->DIR |= 0xc0; + P2->OUT &= ~0xc0; +} + +void motor_move_forward() { + P5->OUT &= ~0b00110000; + P3->OUT |= 0b11000000; + P2->OUT |= 0b11000000; +} + +void motor_move_biases_left() { + P5->OUT = (P5->OUT & ~0x30) | 0x10; + P3->OUT |= 0b11000000; + P2->OUT |= 0b11000000; +} + +void motor_move_biases_right() { + P5->OUT = (P5->OUT & ~0x30) | 0x20; + P3->OUT |= 0b11000000; + P2->OUT |= 0b11000000; +} + +void motor_move_stop() { + P2->OUT &= ~0xc0; +} + +void ir_read_ready() { + P5->OUT |= 0x08; + P9->OUT |= 0x04; + P7->DIR = 0xff; + P7->OUT = 0xff; + Clock_Delay1us(10); + P7->DIR = 0x00; + Clock_Delay1us(1000); +} + +void ir_read_value(char *value) { + int i; + uint8_t port_value = P7->IN; + for (i = 0; i < 8; i++) { + value[i] = !!(port_value & (0x01 << i)); + } +} + +void ir_read_off() { + P5->OUT &= ~0x08; + P9->OUT &= ~0x04; +} + +void main(void) { + Clock_Init48MHz(); + printf("start init\n"); + + //led_init(); + ir_init(); + motor_init(); + + printf("end init\n"); + + char ir_value[8]; + + uint32_t current_on_time = BASE_ON_TIME; + uint32_t current_off_time = BASE_OFF_TIME; + + while (1) { + ir_read_ready(); + ir_read_value(ir_value); + ir_read_off(); + int i; +#ifdef DEBUG_PRINT + + for (i = 7; i >= 0; i--) { printf("%d", ir_value[i]); } + printf("\n"); +#endif + int cnt = 0; + for (i = 0; i < 8; i++) { + if (ir_value[i]) cnt++; + } + + if (cnt >= 7) { + motor_move_stop(); +#ifdef DEBUG_PRINT + printf("T-detected.\n"); +#endif + } else if (ir_value[3] && ir_value[4]) { + motor_move_forward(); + current_on_time = BASE_ON_TIME; + current_off_time = BASE_OFF_TIME; + } else if (ir_value[5] || ir_value[6] || ir_value[7]) { + motor_move_biases_left(); + current_on_time = TURN_ON_TIME; + current_off_time = TURN_OFF_TIME; + } else if (ir_value[0] || ir_value[1] || ir_value[2]) { + motor_move_biases_right(); + current_on_time = TURN_ON_TIME; + current_off_time = TURN_OFF_TIME; + } else { + motor_move_stop(); + current_on_time = 0; + current_off_time = LOOP_PERIOD_MS; + } + + if (current_on_time > 0) { + Clock_Delay1ms(current_on_time); + motor_move_stop(); + } + + Clock_Delay1ms(current_off_time); + } +} diff --git a/labs/lab_w4/msp432p401r.cmd b/labs/lab_w4/msp432p401r.cmd new file mode 100644 index 0000000..e880348 --- /dev/null +++ b/labs/lab_w4/msp432p401r.cmd @@ -0,0 +1,138 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2017 Texas Instruments Incorporated - http://www.ti.com/ +* +* 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. +* +* Default linker command file for Texas Instruments MSP432P401R +* +* File creation date: 12/06/17 +* +*****************************************************************************/ +/* Suppress warnings and errors: */ +/* #10199-D CRC table operator (crc_table_for_<>) ignored: + CRC table operator cannot be associated with empty output section */ +--diag_suppress=10199 + +--retain=flashMailbox + +MEMORY +{ + MAIN (RX) : origin = 0x00000000, length = 0x00040000 + INFO (RX) : origin = 0x00200000, length = 0x00004000 +#ifdef __TI_COMPILER_VERSION__ +#if __TI_COMPILER_VERSION__ >= 15009000 + ALIAS + { + SRAM_CODE (RWX): origin = 0x01000000 + SRAM_DATA (RW) : origin = 0x20000000 + } length = 0x00010000 +#else + /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE */ + /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate */ + /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/ + SRAM_CODE (RWX): origin = 0x01000000, length = 0x00010000 + SRAM_DATA (RW) : origin = 0x20000000, length = 0x00010000 +#endif +#endif +} + +/* The following command line options are set as part of the CCS project. */ +/* If you are building using the command line, or for some reason want to */ +/* define them here, you can uncomment and modify these lines as needed. */ +/* If you are using CCS for building, it is probably better to make any such */ +/* modifications in your CCS project and leave this file alone. */ +/* */ +/* A heap size of 1024 bytes is recommended when you plan to use printf() */ +/* for debug output to the console window. */ +/* */ +/* --heap_size=1024 */ +/* --stack_size=512 */ +/* --library=rtsv7M4_T_le_eabi.lib */ + +/* Section allocation in memory */ + +SECTIONS +{ +#ifndef gen_crc_table + .intvecs: > 0x00000000 + .text : > MAIN + .const : > MAIN + .cinit : > MAIN + .pinit : > MAIN + .init_array : > MAIN + .binit : {} > MAIN + + /* The following sections show the usage of the INFO flash memory */ + /* INFO flash memory is intended to be used for the following */ + /* device specific purposes: */ + /* Flash mailbox for device security operations */ + .flashMailbox : > 0x00200000 + /* TLV table for device identification and characterization */ + .tlvTable : > 0x00201000 + /* BSL area for device bootstrap loader */ + .bslArea : > 0x00202000 +#else + .intvecs: > 0x00000000, crc_table(crc_table_for_intvecs) + .text : > MAIN, crc_table(crc_table_for_text) + .const : > MAIN, crc_table(crc_table_for_const) + .cinit : > MAIN, crc_table(crc_table_for_cinit) + .pinit : > MAIN, crc_table(crc_table_for_pinit) + .init_array : > MAIN, crc_table(crc_table_for_init_array) + .binit : {} > MAIN, crc_table(crc_table_for_binit) + + /* The following sections show the usage of the INFO flash memory */ + /* INFO flash memory is intended to be used for the following */ + /* device specific purposes: */ + /* Flash mailbox for device security operations */ + .flashMailbox : > 0x00200000, crc_table(crc_table_for_flashMailbox) + /* TLV table for device identification and characterization */ + /* This one is read only memory in flash - generate no CRC */ + .tlvTable : > 0x00201000 + /* BSL area for device bootstrap loader */ + .bslArea : > 0x00202000, crc_table(crc_table_for_bslArea) + .TI.crctab : > MAIN +#endif + + .vtable : > 0x20000000 + .data : > SRAM_DATA + .bss : > SRAM_DATA + .sysmem : > SRAM_DATA + .stack : > SRAM_DATA (HIGH) + +#ifdef __TI_COMPILER_VERSION__ +#if __TI_COMPILER_VERSION__ >= 15009000 + .TI.ramfunc : {} load=MAIN, run=SRAM_CODE, table(BINIT) +#endif +#endif +} + +/* Symbolic definition of the WDTCTL register for RTS */ +WDTCTL_SYM = 0x4000480C; + diff --git a/labs/lab_w4/startup_msp432p401r_ccs.c b/labs/lab_w4/startup_msp432p401r_ccs.c new file mode 100644 index 0000000..d403cca --- /dev/null +++ b/labs/lab_w4/startup_msp432p401r_ccs.c @@ -0,0 +1,206 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2017 Texas Instruments Incorporated - http://www.ti.com/ +* +* 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. +* +* MSP432P401R Interrupt Vector Table +* +*****************************************************************************/ + +#include + +/* Linker variable that marks the top of the stack. */ +extern unsigned long __STACK_END; + +/* External declaration for the reset handler that is to be called when the */ +/* processor is started */ +extern void _c_int00(void); + +/* External declaration for system initialization function */ +extern void SystemInit(void); + +/* Forward declaration of the default fault handlers. */ +void Default_Handler (void) __attribute__((weak)); +extern void Reset_Handler (void) __attribute__((weak)); + +/* Cortex-M4 Processor Exceptions */ +extern void NMI_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void HardFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void MemManage_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void BusFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void UsageFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void SVC_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void DebugMon_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void PendSV_Handler (void) __attribute__((weak, alias("Default_Handler"))); + +/* device specific interrupt handler */ +extern void SysTick_Handler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PSS_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void CS_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PCM_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void WDT_A_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void FPU_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void FLCTL_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void COMP_E0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void COMP_E1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA0_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA0_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA1_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA1_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA2_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA2_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA3_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA3_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void ADC14_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INTC_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void AES256_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void RTC_C_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_ERR_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT4_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT5_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT6_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); + +/* Interrupt vector table. Note that the proper constructs must be placed on this to */ +/* ensure that it ends up at physical address 0x0000.0000 or at the start of */ +/* the program if located at a start address other than 0. */ +#pragma RETAIN(interruptVectors) +#pragma DATA_SECTION(interruptVectors, ".intvecs") +void (* const interruptVectors[])(void) = +{ + (void (*)(void))((uint32_t)&__STACK_END), + /* The initial stack pointer */ + Reset_Handler, /* The reset handler */ + NMI_Handler, /* The NMI handler */ + HardFault_Handler, /* The hard fault handler */ + MemManage_Handler, /* The MPU fault handler */ + BusFault_Handler, /* The bus fault handler */ + UsageFault_Handler, /* The usage fault handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall handler */ + DebugMon_Handler, /* Debug monitor handler */ + 0, /* Reserved */ + PendSV_Handler, /* The PendSV handler */ + SysTick_Handler, /* The SysTick handler */ + PSS_IRQHandler, /* PSS Interrupt */ + CS_IRQHandler, /* CS Interrupt */ + PCM_IRQHandler, /* PCM Interrupt */ + WDT_A_IRQHandler, /* WDT_A Interrupt */ + FPU_IRQHandler, /* FPU Interrupt */ + FLCTL_IRQHandler, /* Flash Controller Interrupt*/ + COMP_E0_IRQHandler, /* COMP_E0 Interrupt */ + COMP_E1_IRQHandler, /* COMP_E1 Interrupt */ + TA0_0_IRQHandler, /* TA0_0 Interrupt */ + TA0_N_IRQHandler, /* TA0_N Interrupt */ + TA1_0_IRQHandler, /* TA1_0 Interrupt */ + TA1_N_IRQHandler, /* TA1_N Interrupt */ + TA2_0_IRQHandler, /* TA2_0 Interrupt */ + TA2_N_IRQHandler, /* TA2_N Interrupt */ + TA3_0_IRQHandler, /* TA3_0 Interrupt */ + TA3_N_IRQHandler, /* TA3_N Interrupt */ + EUSCIA0_IRQHandler, /* EUSCIA0 Interrupt */ + EUSCIA1_IRQHandler, /* EUSCIA1 Interrupt */ + EUSCIA2_IRQHandler, /* EUSCIA2 Interrupt */ + EUSCIA3_IRQHandler, /* EUSCIA3 Interrupt */ + EUSCIB0_IRQHandler, /* EUSCIB0 Interrupt */ + EUSCIB1_IRQHandler, /* EUSCIB1 Interrupt */ + EUSCIB2_IRQHandler, /* EUSCIB2 Interrupt */ + EUSCIB3_IRQHandler, /* EUSCIB3 Interrupt */ + ADC14_IRQHandler, /* ADC14 Interrupt */ + T32_INT1_IRQHandler, /* T32_INT1 Interrupt */ + T32_INT2_IRQHandler, /* T32_INT2 Interrupt */ + T32_INTC_IRQHandler, /* T32_INTC Interrupt */ + AES256_IRQHandler, /* AES256 Interrupt */ + RTC_C_IRQHandler, /* RTC_C Interrupt */ + DMA_ERR_IRQHandler, /* DMA_ERR Interrupt */ + DMA_INT3_IRQHandler, /* DMA_INT3 Interrupt */ + DMA_INT2_IRQHandler, /* DMA_INT2 Interrupt */ + DMA_INT1_IRQHandler, /* DMA_INT1 Interrupt */ + DMA_INT0_IRQHandler, /* DMA_INT0 Interrupt */ + PORT1_IRQHandler, /* Port1 Interrupt */ + PORT2_IRQHandler, /* Port2 Interrupt */ + PORT3_IRQHandler, /* Port3 Interrupt */ + PORT4_IRQHandler, /* Port4 Interrupt */ + PORT5_IRQHandler, /* Port5 Interrupt */ + PORT6_IRQHandler /* Port6 Interrupt */ +}; + +/* Forward declaration of the default fault handlers. */ +/* This is the code that gets called when the processor first starts execution */ +/* following a reset event. Only the absolutely necessary set is performed, */ +/* after which the application supplied entry() routine is called. Any fancy */ +/* actions (such as making decisions based on the reset cause register, and */ +/* resetting the bits in that register) are left solely in the hands of the */ +/* application. */ +void Reset_Handler(void) +{ + SystemInit(); + + /* Jump to the CCS C Initialization Routine. */ + __asm(" .global _c_int00\n" + " b.w _c_int00"); +} + + +/* This is the code that gets called when the processor receives an unexpected */ +/* interrupt. This simply enters an infinite loop, preserving the system state */ +/* for examination by a debugger. */ +void Default_Handler(void) +{ + /* Fault trap exempt from ULP advisor */ + #pragma diag_push + #pragma CHECK_ULP("-2.1") + + /* Enter an infinite loop. */ + while(1) + { + } + + #pragma diag_pop +} diff --git a/labs/lab_w4/system_msp432p401r.c b/labs/lab_w4/system_msp432p401r.c new file mode 100644 index 0000000..ab1f2fe --- /dev/null +++ b/labs/lab_w4/system_msp432p401r.c @@ -0,0 +1,401 @@ +/****************************************************************************** +* @file system_msp432p401r.c +* @brief CMSIS Cortex-M4F Device Peripheral Access Layer Source File for +* MSP432P401R +* @version 3.231 +* @date 01/26/18 +* +* @note View configuration instructions embedded in comments +* +******************************************************************************/ +//***************************************************************************** +// +// Copyright (C) 2015 - 2018 Texas Instruments Incorporated - http://www.ti.com/ +// +// 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. +// +//***************************************************************************** + +#include +#include "msp.h" + +/*--------------------- Configuration Instructions ---------------------------- + 1. If you prefer to halt the Watchdog Timer, set __HALT_WDT to 1: + #define __HALT_WDT 1 + 2. Insert your desired CPU frequency in Hz at: + #define __SYSTEM_CLOCK 12000000 + 3. If you prefer the DC-DC power regulator (more efficient at higher + frequencies), set the __REGULATOR to 1: + #define __REGULATOR 1 + *---------------------------------------------------------------------------*/ + +/*--------------------- Watchdog Timer Configuration ------------------------*/ +// Halt the Watchdog Timer +// <0> Do not halt the WDT +// <1> Halt the WDT +#define __HALT_WDT 1 + +/*--------------------- CPU Frequency Configuration -------------------------*/ +// CPU Frequency +// <1500000> 1.5 MHz +// <3000000> 3 MHz +// <12000000> 12 MHz +// <24000000> 24 MHz +// <48000000> 48 MHz +#define __SYSTEM_CLOCK 3000000 + +/*--------------------- Power Regulator Configuration -----------------------*/ +// Power Regulator Mode +// <0> LDO +// <1> DC-DC +#define __REGULATOR 0 + +/*---------------------------------------------------------------------------- + Define clocks, used for SystemCoreClockUpdate() + *---------------------------------------------------------------------------*/ +#define __VLOCLK 10000 +#define __MODCLK 24000000 +#define __LFXT 32768 +#define __HFXT 48000000 + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *---------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock)*/ + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void) +{ + uint32_t source = 0, divider = 0, dividerValue = 0, centeredFreq = 0, calVal = 0; + int16_t dcoTune = 0; + float dcoConst = 0.0; + + divider = (CS->CTL1 & CS_CTL1_DIVM_MASK) >> CS_CTL1_DIVM_OFS; + dividerValue = 1 << divider; + source = CS->CTL1 & CS_CTL1_SELM_MASK; + + switch(source) + { + case CS_CTL1_SELM__LFXTCLK: + if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + // Clear interrupt flag + CS->KEY = CS_KEY_VAL; + CS->CLRIFG |= CS_CLRIFG_CLR_LFXTIFG; + CS->KEY = 1; + + if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + } + else + { + SystemCoreClock = __LFXT / dividerValue; + } + } + else + { + SystemCoreClock = __LFXT / dividerValue; + } + break; + case CS_CTL1_SELM__VLOCLK: + SystemCoreClock = __VLOCLK / dividerValue; + break; + case CS_CTL1_SELM__REFOCLK: + if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + break; + case CS_CTL1_SELM__DCOCLK: + dcoTune = (CS->CTL0 & CS_CTL0_DCOTUNE_MASK) >> CS_CTL0_DCOTUNE_OFS; + + switch(CS->CTL0 & CS_CTL0_DCORSEL_MASK) + { + case CS_CTL0_DCORSEL_0: + centeredFreq = 1500000; + break; + case CS_CTL0_DCORSEL_1: + centeredFreq = 3000000; + break; + case CS_CTL0_DCORSEL_2: + centeredFreq = 6000000; + break; + case CS_CTL0_DCORSEL_3: + centeredFreq = 12000000; + break; + case CS_CTL0_DCORSEL_4: + centeredFreq = 24000000; + break; + case CS_CTL0_DCORSEL_5: + centeredFreq = 48000000; + break; + } + + if(dcoTune == 0) + { + SystemCoreClock = centeredFreq; + } + else + { + + if(dcoTune & 0x1000) + { + dcoTune = dcoTune | 0xF000; + } + + if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) + { + dcoConst = *((volatile const float *) &TLV->DCOER_CONSTK_RSEL04); + calVal = TLV->DCOER_FCAL_RSEL04; + } + /* Internal Resistor */ + else + { + dcoConst = *((volatile const float *) &TLV->DCOIR_CONSTK_RSEL04); + calVal = TLV->DCOIR_FCAL_RSEL04; + } + + SystemCoreClock = (uint32_t) ((centeredFreq) + / (1 + - ((dcoConst * dcoTune) + / (8 * (1 + dcoConst * (768 - calVal)))))); + } + break; + case CS_CTL1_SELM__MODOSC: + SystemCoreClock = __MODCLK / dividerValue; + break; + case CS_CTL1_SELM__HFXTCLK: + if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + // Clear interrupt flag + CS->KEY = CS_KEY_VAL; + CS->CLRIFG |= CS_CLRIFG_CLR_HFXTIFG; + CS->KEY = 1; + + if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + } + else + { + SystemCoreClock = __HFXT / dividerValue; + } + } + else + { + SystemCoreClock = __HFXT / dividerValue; + } + break; + } +} + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * + * Performs the following initialization steps: + * 1. Enables the FPU + * 2. Halts the WDT if requested + * 3. Enables all SRAM banks + * 4. Sets up power regulator and VCORE + * 5. Enable Flash wait states if needed + * 6. Change MCLK to desired frequency + * 7. Enable Flash read buffering + */ +void SystemInit(void) +{ + // Enable FPU if used + #if (__FPU_USED == 1) // __FPU_USED is defined in core_cm4.h + SCB->CPACR |= ((3UL << 10 * 2) | // Set CP10 Full Access + (3UL << 11 * 2)); // Set CP11 Full Access + #endif + + #if (__HALT_WDT == 1) + WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // Halt the WDT + #endif + + SYSCTL->SRAM_BANKEN = SYSCTL_SRAM_BANKEN_BNK7_EN; // Enable all SRAM banks + + #if (__SYSTEM_CLOCK == 1500000) // 1.5 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // No flash wait states necessary + + // DCO = 1.5 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_0; // Set DCO to 1.5MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 3000000) // 3 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while(PCM->CTL1 & PCM_CTL1_PMR_BUSY); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while(PCM->CTL1 & PCM_CTL1_PMR_BUSY); + #endif + + // No flash wait states necessary + + // DCO = 3 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_1; // Set DCO to 1.5MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 12000000) // 12 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // No flash wait states necessary + + // DCO = 12 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_3; // Set DCO to 12MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 24000000) // 24 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // 1 flash wait state (BANK0 VCORE0 max is 12 MHz) + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1; + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1; + + // DCO = 24 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_4; // Set DCO to 24MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 48000000) // 48 MHz + // Switches LDO VCORE0 to LDO VCORE1; mandatory for 48 MHz setting + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + + // Switches LDO VCORE1 to DCDC VCORE1 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // 1 flash wait states (BANK0 VCORE1 max is 16 MHz, BANK1 VCORE1 max is 32 MHz) + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1; + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1; + + // DCO = 48 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_5; // Set DCO to 48MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL | (FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + #endif + +} + + diff --git a/labs/lab_w4/targetConfigs/MSP432P401R.ccxml b/labs/lab_w4/targetConfigs/MSP432P401R.ccxml new file mode 100644 index 0000000..92ce945 --- /dev/null +++ b/labs/lab_w4/targetConfigs/MSP432P401R.ccxml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/lab_w4/targetConfigs/readme.txt b/labs/lab_w4/targetConfigs/readme.txt new file mode 100644 index 0000000..d783fef --- /dev/null +++ b/labs/lab_w4/targetConfigs/readme.txt @@ -0,0 +1,9 @@ +The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based +on the device and connection settings specified in your project on the Properties > General page. + +Please note that in automatic target-configuration management, changes to the project's device and/or +connection settings will either modify an existing or generate a new target-configuration file. Thus, +if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively, +you may create your own target-configuration file for this project and manage it manually. You can +always switch back to automatic target-configuration management by checking the "Manage the project's +target-configuration automatically" checkbox on the project's Properties > General page. \ No newline at end of file diff --git a/labs/lab_w5/.ccsproject b/labs/lab_w5/.ccsproject new file mode 100644 index 0000000..024ecb0 --- /dev/null +++ b/labs/lab_w5/.ccsproject @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/labs/lab_w5/.cproject b/labs/lab_w5/.cproject new file mode 100644 index 0000000..afd2d5b --- /dev/null +++ b/labs/lab_w5/.cproject @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/labs/lab_w5/.gitignore b/labs/lab_w5/.gitignore new file mode 100644 index 0000000..3df573f --- /dev/null +++ b/labs/lab_w5/.gitignore @@ -0,0 +1 @@ +/Debug/ diff --git a/labs/lab_w5/.project b/labs/lab_w5/.project new file mode 100644 index 0000000..c4f5c81 --- /dev/null +++ b/labs/lab_w5/.project @@ -0,0 +1,27 @@ + + + lab_w5 + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + com.ti.ccstudio.core.ccsNature + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/labs/lab_w5/Clock.c b/labs/lab_w5/Clock.c new file mode 100644 index 0000000..74daa13 --- /dev/null +++ b/labs/lab_w5/Clock.c @@ -0,0 +1,169 @@ +// Clock.c +// Runs on the MSP432 +// Daniel and Jonathan Valvano +// February 23, 2017 + +/* This example accompanies the book + "Embedded Systems: Introduction to Robotics, + Jonathan W. Valvano, ISBN: 9781074544300, copyright (c) 2019 + For more information about my classes, my research, and my books, see + http://users.ece.utexas.edu/~valvano/ + +Simplified BSD License (FreeBSD License) +Copyright (c) 2019, Jonathan Valvano, All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. 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. + +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. + +The views and conclusions contained in the software and documentation are +those of the authors and should not be interpreted as representing official +policies, either expressed or implied, of the FreeBSD Project. +*/ + +#include +#include "msp.h" + +uint32_t ClockFrequency = 3000000; // cycles/second +//static uint32_t SubsystemFrequency = 3000000; // cycles/second + +// ------------Clock_InitFastest------------ +// Configure the system clock to run at the fastest +// and most accurate settings. For example, if the +// LaunchPad has a crystal, it should be used here. +// Call BSP_Clock_GetFreq() to get the current system +// clock frequency for the LaunchPad. +// Input: none +// Output: none +uint32_t Prewait = 0; // loops between BSP_Clock_InitFastest() called and PCM idle (expect 0) +uint32_t CPMwait = 0; // loops between Power Active Mode Request and Current Power Mode matching requested mode (expect small) +uint32_t Postwait = 0; // loops between Current Power Mode matching requested mode and PCM module idle (expect about 0) +uint32_t IFlags = 0; // non-zero if transition is invalid +uint32_t Crystalstable = 0; // loops before the crystal stabilizes (expect small) +void Clock_Init48MHz(void){ + // wait for the PCMCTL0 and Clock System to be write-able by waiting for Power Control Manager to be idle + while(PCM->CTL1&0x00000100){ +// while(PCMCTL1&0x00000100){ + Prewait = Prewait + 1; + if(Prewait >= 100000){ + return; // time out error + } + } + // request power active mode LDO VCORE1 to support the 48 MHz frequency + PCM->CTL0 = (PCM->CTL0&~0xFFFF000F) | // clear PCMKEY bit field and AMR bit field +// PCMCTL0 = (PCMCTL0&~0xFFFF000F) | // clear PCMKEY bit field and AMR bit field + 0x695A0000 | // write the proper PCM key to unlock write access + 0x00000001; // request power active mode LDO VCORE1 + // check if the transition is invalid (see Figure 7-3 on p344 of datasheet) + if(PCM->IFG&0x00000004){ + IFlags = PCM->IFG; // bit 2 set on active mode transition invalid; bits 1-0 are for LPM-related errors; bit 6 is for DC-DC-related error + PCM->CLRIFG = 0x00000004; // clear the transition invalid flag + // to do: look at CPM bit field in PCMCTL0, figure out what mode you're in, and step through the chart to transition to the mode you want + // or be lazy and do nothing; this should work out of reset at least, but it WILL NOT work if Clock_Int32kHz() or Clock_InitLowPower() has been called + return; + } + // wait for the CPM (Current Power Mode) bit field to reflect a change to active mode LDO VCORE1 + while((PCM->CTL0&0x00003F00) != 0x00000100){ + CPMwait = CPMwait + 1; + if(CPMwait >= 500000){ + return; // time out error + } + } + // wait for the PCMCTL0 and Clock System to be write-able by waiting for Power Control Manager to be idle + while(PCM->CTL1&0x00000100){ + Postwait = Postwait + 1; + if(Postwait >= 100000){ + return; // time out error + } + } + // initialize PJ.3 and PJ.2 and make them HFXT (PJ.3 built-in 48 MHz crystal out; PJ.2 built-in 48 MHz crystal in) + PJ->SEL0 |= 0x0C; + PJ->SEL1 &= ~0x0C; // configure built-in 48 MHz crystal for HFXT operation +// PJDIR |= 0x08; // make PJ.3 HFXTOUT (unnecessary) +// PJDIR &= ~0x04; // make PJ.2 HFXTIN (unnecessary) + CS->KEY = 0x695A; // unlock CS module for register access + CS->CTL2 = (CS->CTL2&~0x00700000) | // clear HFXTFREQ bit field + 0x00600000 | // configure for 48 MHz external crystal + 0x00010000 | // HFXT oscillator drive selection for crystals >4 MHz + 0x01000000; // enable HFXT + CS->CTL2 &= ~0x02000000; // disable high-frequency crystal bypass + // wait for the HFXT clock to stabilize + while(CS->IFG&0x00000002){ + CS->CLRIFG = 0x00000002; // clear the HFXT oscillator interrupt flag + Crystalstable = Crystalstable + 1; + if(Crystalstable > 100000){ + return; // time out error + } + } + // configure for 2 wait states (minimum for 48 MHz operation) for flash Bank 0 + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL&~0x0000F000)|FLCTL_BANK0_RDCTL_WAIT_2; + // configure for 2 wait states (minimum for 48 MHz operation) for flash Bank 1 + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL&~0x0000F000)|FLCTL_BANK1_RDCTL_WAIT_2; + CS->CTL1 = 0x20000000 | // configure for SMCLK divider /4 + 0x00100000 | // configure for HSMCLK divider /2 + 0x00000200 | // configure for ACLK sourced from REFOCLK + 0x00000050 | // configure for SMCLK and HSMCLK sourced from HFXTCLK + 0x00000005; // configure for MCLK sourced from HFXTCLK + CS->KEY = 0; // lock CS module from unintended access + ClockFrequency = 48000000; +// SubsystemFrequency = 12000000; +} + +// ------------Clock_GetFreq------------ +// Return the current system clock frequency for the +// LaunchPad. +// Input: none +// Output: system clock frequency in cycles/second +uint32_t Clock_GetFreq(void){ + return ClockFrequency; +} + + +// delay function +// which delays about 6*ulCount cycles +// ulCount=8000 => 1ms = (8000 loops)*(6 cycles/loop)*(20.83 ns/cycle) + //Code Composer Studio Code +void delay(unsigned long ulCount){ + __asm ( "pdloop: subs r0, #1\n" + " bne pdloop\n"); +} + +// ------------Clock_Delay1us------------ +// Simple delay function which delays about n microseconds. +// Inputs: n, number of us to wait +// Outputs: none +void Clock_Delay1us(uint32_t n){ + n = (382*n)/100;; // 1 us, tuned at 48 MHz + while(n){ + n--; + } +} + +// ------------Clock_Delay1ms------------ +// Simple delay function which delays about n milliseconds. +// Inputs: n, number of msec to wait +// Outputs: none +void Clock_Delay1ms(uint32_t n){ + while(n){ + delay(ClockFrequency/9162); // 1 msec, tuned at 48 MHz + n--; + } +} + + diff --git a/labs/lab_w5/Clock.h b/labs/lab_w5/Clock.h new file mode 100644 index 0000000..be8a5e0 --- /dev/null +++ b/labs/lab_w5/Clock.h @@ -0,0 +1,99 @@ +/** + * @file Clock.h + * @brief Provide functions that initialize the MSP432 clock module + * @details Reconfigure MSP432 to run at 48 MHz + * @version TI-RSLK MAX v1.1 + * @author Daniel Valvano and Jonathan Valvano + * @copyright Copyright 2019 by Jonathan W. Valvano, valvano@mail.utexas.edu, + * @warning AS-IS + * @note For more information see http://users.ece.utexas.edu/~valvano/ + * @date June 28, 2019 + + ******************************************************************************/ + +/* This example accompanies the book + "Embedded Systems: Introduction to Robotics, + Jonathan W. Valvano, ISBN: 9781074544300, copyright (c) 2019 + For more information about my classes, my research, and my books, see + http://users.ece.utexas.edu/~valvano/ + +Simplified BSD License (FreeBSD License) +Copyright (c) 2017, Jonathan Valvano, All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. 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. + +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. + +The views and conclusions contained in the software and documentation are +those of the authors and should not be interpreted as representing official +policies, either expressed or implied, of the FreeBSD Project. +*/ +#include +/** + * Configure the MSP432 clock to run at 48 MHz + * @param none + * @return none + * @note Since the crystal is used, the bus clock will be very accurate + * @see Clock_GetFreq() + * @brief Initialize clock to 48 MHz + */ +void Clock_Init48MHz(void); + + +/** + * Return the current bus clock frequency + * @param none + * @return frequency of the system clock in Hz + * @note In this module, the return result will be 3000000 or 48000000 + * @see Clock_Init48MHz() + * @brief Returns current clock bus frequency in Hz + */ +uint32_t Clock_GetFreq(void); + + +/** + * Simple delay function which delays about n milliseconds. + * It is implemented with a nested for-loop and is very approximate. + * @param n is the number of msec to wait + * @return none + * @note This function assumes a 48 MHz clock. + * This implementation is not very accurate. + * To improve accuracy, you could tune this function + * by adjusting the constant within the implementation + * found in the Clock.c file. + * For a more accurate time delay, you could use the SysTick module. + * @brief Software implementation of a busy-wait delay + */ +void Clock_Delay1ms(uint32_t n); + +/** + * Simple delay function which delays about n microseconds. + * It is implemented with a nested for-loop and is very approximate. + * @param n is the number of usec to wait + * @return none + * @note This function assumes a 48 MHz clock. + * This implementation is not very accurate. + * To improve accuracy, you could tune this function + * by adjusting the constant within the implementation + * found in the Clock.c file. + * For a more accurate time delay, you could use the SysTick module. + * @brief Software implementation of a busy-wait delay + */ +void Clock_Delay1us(uint32_t n); + diff --git a/labs/lab_w5/main.c b/labs/lab_w5/main.c new file mode 100644 index 0000000..ed305a0 --- /dev/null +++ b/labs/lab_w5/main.c @@ -0,0 +1,12 @@ +#define __MSP432P401R__ + +#include "msp.h" +#include "Clock.h" + +void main(void) { + Clock_Init48MHz(); + + WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD;// stop watchdog timer + + Clock_Delay1ms(100); +} diff --git a/labs/lab_w5/msp432p401r.cmd b/labs/lab_w5/msp432p401r.cmd new file mode 100644 index 0000000..e880348 --- /dev/null +++ b/labs/lab_w5/msp432p401r.cmd @@ -0,0 +1,138 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2017 Texas Instruments Incorporated - http://www.ti.com/ +* +* 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. +* +* Default linker command file for Texas Instruments MSP432P401R +* +* File creation date: 12/06/17 +* +*****************************************************************************/ +/* Suppress warnings and errors: */ +/* #10199-D CRC table operator (crc_table_for_<>) ignored: + CRC table operator cannot be associated with empty output section */ +--diag_suppress=10199 + +--retain=flashMailbox + +MEMORY +{ + MAIN (RX) : origin = 0x00000000, length = 0x00040000 + INFO (RX) : origin = 0x00200000, length = 0x00004000 +#ifdef __TI_COMPILER_VERSION__ +#if __TI_COMPILER_VERSION__ >= 15009000 + ALIAS + { + SRAM_CODE (RWX): origin = 0x01000000 + SRAM_DATA (RW) : origin = 0x20000000 + } length = 0x00010000 +#else + /* Hint: If the user wants to use ram functions, please observe that SRAM_CODE */ + /* and SRAM_DATA memory areas are overlapping. You need to take measures to separate */ + /* data from code in RAM. This is only valid for Compiler version earlier than 15.09.0.STS.*/ + SRAM_CODE (RWX): origin = 0x01000000, length = 0x00010000 + SRAM_DATA (RW) : origin = 0x20000000, length = 0x00010000 +#endif +#endif +} + +/* The following command line options are set as part of the CCS project. */ +/* If you are building using the command line, or for some reason want to */ +/* define them here, you can uncomment and modify these lines as needed. */ +/* If you are using CCS for building, it is probably better to make any such */ +/* modifications in your CCS project and leave this file alone. */ +/* */ +/* A heap size of 1024 bytes is recommended when you plan to use printf() */ +/* for debug output to the console window. */ +/* */ +/* --heap_size=1024 */ +/* --stack_size=512 */ +/* --library=rtsv7M4_T_le_eabi.lib */ + +/* Section allocation in memory */ + +SECTIONS +{ +#ifndef gen_crc_table + .intvecs: > 0x00000000 + .text : > MAIN + .const : > MAIN + .cinit : > MAIN + .pinit : > MAIN + .init_array : > MAIN + .binit : {} > MAIN + + /* The following sections show the usage of the INFO flash memory */ + /* INFO flash memory is intended to be used for the following */ + /* device specific purposes: */ + /* Flash mailbox for device security operations */ + .flashMailbox : > 0x00200000 + /* TLV table for device identification and characterization */ + .tlvTable : > 0x00201000 + /* BSL area for device bootstrap loader */ + .bslArea : > 0x00202000 +#else + .intvecs: > 0x00000000, crc_table(crc_table_for_intvecs) + .text : > MAIN, crc_table(crc_table_for_text) + .const : > MAIN, crc_table(crc_table_for_const) + .cinit : > MAIN, crc_table(crc_table_for_cinit) + .pinit : > MAIN, crc_table(crc_table_for_pinit) + .init_array : > MAIN, crc_table(crc_table_for_init_array) + .binit : {} > MAIN, crc_table(crc_table_for_binit) + + /* The following sections show the usage of the INFO flash memory */ + /* INFO flash memory is intended to be used for the following */ + /* device specific purposes: */ + /* Flash mailbox for device security operations */ + .flashMailbox : > 0x00200000, crc_table(crc_table_for_flashMailbox) + /* TLV table for device identification and characterization */ + /* This one is read only memory in flash - generate no CRC */ + .tlvTable : > 0x00201000 + /* BSL area for device bootstrap loader */ + .bslArea : > 0x00202000, crc_table(crc_table_for_bslArea) + .TI.crctab : > MAIN +#endif + + .vtable : > 0x20000000 + .data : > SRAM_DATA + .bss : > SRAM_DATA + .sysmem : > SRAM_DATA + .stack : > SRAM_DATA (HIGH) + +#ifdef __TI_COMPILER_VERSION__ +#if __TI_COMPILER_VERSION__ >= 15009000 + .TI.ramfunc : {} load=MAIN, run=SRAM_CODE, table(BINIT) +#endif +#endif +} + +/* Symbolic definition of the WDTCTL register for RTS */ +WDTCTL_SYM = 0x4000480C; + diff --git a/labs/lab_w5/startup_msp432p401r_ccs.c b/labs/lab_w5/startup_msp432p401r_ccs.c new file mode 100644 index 0000000..d403cca --- /dev/null +++ b/labs/lab_w5/startup_msp432p401r_ccs.c @@ -0,0 +1,206 @@ +/****************************************************************************** +* +* Copyright (C) 2012 - 2017 Texas Instruments Incorporated - http://www.ti.com/ +* +* 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. +* +* MSP432P401R Interrupt Vector Table +* +*****************************************************************************/ + +#include + +/* Linker variable that marks the top of the stack. */ +extern unsigned long __STACK_END; + +/* External declaration for the reset handler that is to be called when the */ +/* processor is started */ +extern void _c_int00(void); + +/* External declaration for system initialization function */ +extern void SystemInit(void); + +/* Forward declaration of the default fault handlers. */ +void Default_Handler (void) __attribute__((weak)); +extern void Reset_Handler (void) __attribute__((weak)); + +/* Cortex-M4 Processor Exceptions */ +extern void NMI_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void HardFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void MemManage_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void BusFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void UsageFault_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void SVC_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void DebugMon_Handler (void) __attribute__((weak, alias("Default_Handler"))); +extern void PendSV_Handler (void) __attribute__((weak, alias("Default_Handler"))); + +/* device specific interrupt handler */ +extern void SysTick_Handler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PSS_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void CS_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PCM_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void WDT_A_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void FPU_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void FLCTL_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void COMP_E0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void COMP_E1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA0_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA0_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA1_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA1_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA2_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA2_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA3_0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void TA3_N_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIA3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void EUSCIB3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void ADC14_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void T32_INTC_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void AES256_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void RTC_C_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_ERR_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void DMA_INT0_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT1_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT2_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT3_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT4_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT5_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); +extern void PORT6_IRQHandler (void) __attribute__((weak,alias("Default_Handler"))); + +/* Interrupt vector table. Note that the proper constructs must be placed on this to */ +/* ensure that it ends up at physical address 0x0000.0000 or at the start of */ +/* the program if located at a start address other than 0. */ +#pragma RETAIN(interruptVectors) +#pragma DATA_SECTION(interruptVectors, ".intvecs") +void (* const interruptVectors[])(void) = +{ + (void (*)(void))((uint32_t)&__STACK_END), + /* The initial stack pointer */ + Reset_Handler, /* The reset handler */ + NMI_Handler, /* The NMI handler */ + HardFault_Handler, /* The hard fault handler */ + MemManage_Handler, /* The MPU fault handler */ + BusFault_Handler, /* The bus fault handler */ + UsageFault_Handler, /* The usage fault handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall handler */ + DebugMon_Handler, /* Debug monitor handler */ + 0, /* Reserved */ + PendSV_Handler, /* The PendSV handler */ + SysTick_Handler, /* The SysTick handler */ + PSS_IRQHandler, /* PSS Interrupt */ + CS_IRQHandler, /* CS Interrupt */ + PCM_IRQHandler, /* PCM Interrupt */ + WDT_A_IRQHandler, /* WDT_A Interrupt */ + FPU_IRQHandler, /* FPU Interrupt */ + FLCTL_IRQHandler, /* Flash Controller Interrupt*/ + COMP_E0_IRQHandler, /* COMP_E0 Interrupt */ + COMP_E1_IRQHandler, /* COMP_E1 Interrupt */ + TA0_0_IRQHandler, /* TA0_0 Interrupt */ + TA0_N_IRQHandler, /* TA0_N Interrupt */ + TA1_0_IRQHandler, /* TA1_0 Interrupt */ + TA1_N_IRQHandler, /* TA1_N Interrupt */ + TA2_0_IRQHandler, /* TA2_0 Interrupt */ + TA2_N_IRQHandler, /* TA2_N Interrupt */ + TA3_0_IRQHandler, /* TA3_0 Interrupt */ + TA3_N_IRQHandler, /* TA3_N Interrupt */ + EUSCIA0_IRQHandler, /* EUSCIA0 Interrupt */ + EUSCIA1_IRQHandler, /* EUSCIA1 Interrupt */ + EUSCIA2_IRQHandler, /* EUSCIA2 Interrupt */ + EUSCIA3_IRQHandler, /* EUSCIA3 Interrupt */ + EUSCIB0_IRQHandler, /* EUSCIB0 Interrupt */ + EUSCIB1_IRQHandler, /* EUSCIB1 Interrupt */ + EUSCIB2_IRQHandler, /* EUSCIB2 Interrupt */ + EUSCIB3_IRQHandler, /* EUSCIB3 Interrupt */ + ADC14_IRQHandler, /* ADC14 Interrupt */ + T32_INT1_IRQHandler, /* T32_INT1 Interrupt */ + T32_INT2_IRQHandler, /* T32_INT2 Interrupt */ + T32_INTC_IRQHandler, /* T32_INTC Interrupt */ + AES256_IRQHandler, /* AES256 Interrupt */ + RTC_C_IRQHandler, /* RTC_C Interrupt */ + DMA_ERR_IRQHandler, /* DMA_ERR Interrupt */ + DMA_INT3_IRQHandler, /* DMA_INT3 Interrupt */ + DMA_INT2_IRQHandler, /* DMA_INT2 Interrupt */ + DMA_INT1_IRQHandler, /* DMA_INT1 Interrupt */ + DMA_INT0_IRQHandler, /* DMA_INT0 Interrupt */ + PORT1_IRQHandler, /* Port1 Interrupt */ + PORT2_IRQHandler, /* Port2 Interrupt */ + PORT3_IRQHandler, /* Port3 Interrupt */ + PORT4_IRQHandler, /* Port4 Interrupt */ + PORT5_IRQHandler, /* Port5 Interrupt */ + PORT6_IRQHandler /* Port6 Interrupt */ +}; + +/* Forward declaration of the default fault handlers. */ +/* This is the code that gets called when the processor first starts execution */ +/* following a reset event. Only the absolutely necessary set is performed, */ +/* after which the application supplied entry() routine is called. Any fancy */ +/* actions (such as making decisions based on the reset cause register, and */ +/* resetting the bits in that register) are left solely in the hands of the */ +/* application. */ +void Reset_Handler(void) +{ + SystemInit(); + + /* Jump to the CCS C Initialization Routine. */ + __asm(" .global _c_int00\n" + " b.w _c_int00"); +} + + +/* This is the code that gets called when the processor receives an unexpected */ +/* interrupt. This simply enters an infinite loop, preserving the system state */ +/* for examination by a debugger. */ +void Default_Handler(void) +{ + /* Fault trap exempt from ULP advisor */ + #pragma diag_push + #pragma CHECK_ULP("-2.1") + + /* Enter an infinite loop. */ + while(1) + { + } + + #pragma diag_pop +} diff --git a/labs/lab_w5/system_msp432p401r.c b/labs/lab_w5/system_msp432p401r.c new file mode 100644 index 0000000..ab1f2fe --- /dev/null +++ b/labs/lab_w5/system_msp432p401r.c @@ -0,0 +1,401 @@ +/****************************************************************************** +* @file system_msp432p401r.c +* @brief CMSIS Cortex-M4F Device Peripheral Access Layer Source File for +* MSP432P401R +* @version 3.231 +* @date 01/26/18 +* +* @note View configuration instructions embedded in comments +* +******************************************************************************/ +//***************************************************************************** +// +// Copyright (C) 2015 - 2018 Texas Instruments Incorporated - http://www.ti.com/ +// +// 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. +// +//***************************************************************************** + +#include +#include "msp.h" + +/*--------------------- Configuration Instructions ---------------------------- + 1. If you prefer to halt the Watchdog Timer, set __HALT_WDT to 1: + #define __HALT_WDT 1 + 2. Insert your desired CPU frequency in Hz at: + #define __SYSTEM_CLOCK 12000000 + 3. If you prefer the DC-DC power regulator (more efficient at higher + frequencies), set the __REGULATOR to 1: + #define __REGULATOR 1 + *---------------------------------------------------------------------------*/ + +/*--------------------- Watchdog Timer Configuration ------------------------*/ +// Halt the Watchdog Timer +// <0> Do not halt the WDT +// <1> Halt the WDT +#define __HALT_WDT 1 + +/*--------------------- CPU Frequency Configuration -------------------------*/ +// CPU Frequency +// <1500000> 1.5 MHz +// <3000000> 3 MHz +// <12000000> 12 MHz +// <24000000> 24 MHz +// <48000000> 48 MHz +#define __SYSTEM_CLOCK 3000000 + +/*--------------------- Power Regulator Configuration -----------------------*/ +// Power Regulator Mode +// <0> LDO +// <1> DC-DC +#define __REGULATOR 0 + +/*---------------------------------------------------------------------------- + Define clocks, used for SystemCoreClockUpdate() + *---------------------------------------------------------------------------*/ +#define __VLOCLK 10000 +#define __MODCLK 24000000 +#define __LFXT 32768 +#define __HFXT 48000000 + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *---------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock)*/ + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void) +{ + uint32_t source = 0, divider = 0, dividerValue = 0, centeredFreq = 0, calVal = 0; + int16_t dcoTune = 0; + float dcoConst = 0.0; + + divider = (CS->CTL1 & CS_CTL1_DIVM_MASK) >> CS_CTL1_DIVM_OFS; + dividerValue = 1 << divider; + source = CS->CTL1 & CS_CTL1_SELM_MASK; + + switch(source) + { + case CS_CTL1_SELM__LFXTCLK: + if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + // Clear interrupt flag + CS->KEY = CS_KEY_VAL; + CS->CLRIFG |= CS_CLRIFG_CLR_LFXTIFG; + CS->KEY = 1; + + if(BITBAND_PERI(CS->IFG, CS_IFG_LFXTIFG_OFS)) + { + if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + } + else + { + SystemCoreClock = __LFXT / dividerValue; + } + } + else + { + SystemCoreClock = __LFXT / dividerValue; + } + break; + case CS_CTL1_SELM__VLOCLK: + SystemCoreClock = __VLOCLK / dividerValue; + break; + case CS_CTL1_SELM__REFOCLK: + if (BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + break; + case CS_CTL1_SELM__DCOCLK: + dcoTune = (CS->CTL0 & CS_CTL0_DCOTUNE_MASK) >> CS_CTL0_DCOTUNE_OFS; + + switch(CS->CTL0 & CS_CTL0_DCORSEL_MASK) + { + case CS_CTL0_DCORSEL_0: + centeredFreq = 1500000; + break; + case CS_CTL0_DCORSEL_1: + centeredFreq = 3000000; + break; + case CS_CTL0_DCORSEL_2: + centeredFreq = 6000000; + break; + case CS_CTL0_DCORSEL_3: + centeredFreq = 12000000; + break; + case CS_CTL0_DCORSEL_4: + centeredFreq = 24000000; + break; + case CS_CTL0_DCORSEL_5: + centeredFreq = 48000000; + break; + } + + if(dcoTune == 0) + { + SystemCoreClock = centeredFreq; + } + else + { + + if(dcoTune & 0x1000) + { + dcoTune = dcoTune | 0xF000; + } + + if (BITBAND_PERI(CS->CTL0, CS_CTL0_DCORES_OFS)) + { + dcoConst = *((volatile const float *) &TLV->DCOER_CONSTK_RSEL04); + calVal = TLV->DCOER_FCAL_RSEL04; + } + /* Internal Resistor */ + else + { + dcoConst = *((volatile const float *) &TLV->DCOIR_CONSTK_RSEL04); + calVal = TLV->DCOIR_FCAL_RSEL04; + } + + SystemCoreClock = (uint32_t) ((centeredFreq) + / (1 + - ((dcoConst * dcoTune) + / (8 * (1 + dcoConst * (768 - calVal)))))); + } + break; + case CS_CTL1_SELM__MODOSC: + SystemCoreClock = __MODCLK / dividerValue; + break; + case CS_CTL1_SELM__HFXTCLK: + if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + // Clear interrupt flag + CS->KEY = CS_KEY_VAL; + CS->CLRIFG |= CS_CLRIFG_CLR_HFXTIFG; + CS->KEY = 1; + + if(BITBAND_PERI(CS->IFG, CS_IFG_HFXTIFG_OFS)) + { + if(BITBAND_PERI(CS->CLKEN, CS_CLKEN_REFOFSEL_OFS)) + { + SystemCoreClock = (128000 / dividerValue); + } + else + { + SystemCoreClock = (32000 / dividerValue); + } + } + else + { + SystemCoreClock = __HFXT / dividerValue; + } + } + else + { + SystemCoreClock = __HFXT / dividerValue; + } + break; + } +} + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * + * Performs the following initialization steps: + * 1. Enables the FPU + * 2. Halts the WDT if requested + * 3. Enables all SRAM banks + * 4. Sets up power regulator and VCORE + * 5. Enable Flash wait states if needed + * 6. Change MCLK to desired frequency + * 7. Enable Flash read buffering + */ +void SystemInit(void) +{ + // Enable FPU if used + #if (__FPU_USED == 1) // __FPU_USED is defined in core_cm4.h + SCB->CPACR |= ((3UL << 10 * 2) | // Set CP10 Full Access + (3UL << 11 * 2)); // Set CP11 Full Access + #endif + + #if (__HALT_WDT == 1) + WDT_A->CTL = WDT_A_CTL_PW | WDT_A_CTL_HOLD; // Halt the WDT + #endif + + SYSCTL->SRAM_BANKEN = SYSCTL_SRAM_BANKEN_BNK7_EN; // Enable all SRAM banks + + #if (__SYSTEM_CLOCK == 1500000) // 1.5 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // No flash wait states necessary + + // DCO = 1.5 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_0; // Set DCO to 1.5MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 3000000) // 3 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while(PCM->CTL1 & PCM_CTL1_PMR_BUSY); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while(PCM->CTL1 & PCM_CTL1_PMR_BUSY); + #endif + + // No flash wait states necessary + + // DCO = 3 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_1; // Set DCO to 1.5MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 12000000) // 12 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // No flash wait states necessary + + // DCO = 12 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_3; // Set DCO to 12MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL & ~(FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 24000000) // 24 MHz + // Default VCORE is LDO VCORE0 so no change necessary + + // Switches LDO VCORE0 to DCDC VCORE0 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_4; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // 1 flash wait state (BANK0 VCORE0 max is 12 MHz) + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1; + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1; + + // DCO = 24 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_4; // Set DCO to 24MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL & ~(FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + + #elif (__SYSTEM_CLOCK == 48000000) // 48 MHz + // Switches LDO VCORE0 to LDO VCORE1; mandatory for 48 MHz setting + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_1; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + + // Switches LDO VCORE1 to DCDC VCORE1 if requested + #if __REGULATOR + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_AMR_5; + while((PCM->CTL1 & PCM_CTL1_PMR_BUSY)); + #endif + + // 1 flash wait states (BANK0 VCORE1 max is 16 MHz, BANK1 VCORE1 max is 32 MHz) + FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | FLCTL_BANK0_RDCTL_WAIT_1; + FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | FLCTL_BANK1_RDCTL_WAIT_1; + + // DCO = 48 MHz; MCLK = source + CS->KEY = CS_KEY_VAL; // Unlock CS module for register access + CS->CTL0 = CS_CTL0_DCORSEL_5; // Set DCO to 48MHz + CS->CTL1 = (CS->CTL1 & ~(CS_CTL1_SELM_MASK | CS_CTL1_DIVM_MASK)) | CS_CTL1_SELM__DCOCLK; + // Select MCLK as DCO source + CS->KEY = 0; + + // Set Flash Bank read buffering + FLCTL->BANK0_RDCTL = FLCTL->BANK0_RDCTL | (FLCTL_BANK0_RDCTL_BUFD | FLCTL_BANK0_RDCTL_BUFI); + FLCTL->BANK1_RDCTL = FLCTL->BANK1_RDCTL | (FLCTL_BANK1_RDCTL_BUFD | FLCTL_BANK1_RDCTL_BUFI); + #endif + +} + + diff --git a/labs/lab_w5/targetConfigs/MSP432P401R.ccxml b/labs/lab_w5/targetConfigs/MSP432P401R.ccxml new file mode 100644 index 0000000..92ce945 --- /dev/null +++ b/labs/lab_w5/targetConfigs/MSP432P401R.ccxml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/labs/lab_w5/targetConfigs/readme.txt b/labs/lab_w5/targetConfigs/readme.txt new file mode 100644 index 0000000..d783fef --- /dev/null +++ b/labs/lab_w5/targetConfigs/readme.txt @@ -0,0 +1,9 @@ +The 'targetConfigs' folder contains target-configuration (.ccxml) files, automatically generated based +on the device and connection settings specified in your project on the Properties > General page. + +Please note that in automatic target-configuration management, changes to the project's device and/or +connection settings will either modify an existing or generate a new target-configuration file. Thus, +if you manually edit these auto-generated files, you may need to re-apply your changes. Alternatively, +you may create your own target-configuration file for this project and manage it manually. You can +always switch back to automatic target-configuration management by checking the "Manage the project's +target-configuration automatically" checkbox on the project's Properties > General page. \ No newline at end of file