1 /* --COPYRIGHT--,BSD 2 * Copyright (c) 2017, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * --/COPYRIGHT--*/ 32 #include <ti/devices/msp432p4xx/driverlib/comp_e.h> 33 #include <ti/devices/msp432p4xx/driverlib/interrupt.h> 34 #include <ti/devices/msp432p4xx/driverlib/debug.h> 35 36 static uint16_t __getRegisterSettingForInput(uint32_t input) 37 { 38 switch (input) 39 { 40 case COMP_E_INPUT0: 41 return COMP_E_CTL0_IPSEL_0; 42 case COMP_E_INPUT1: 43 return COMP_E_CTL0_IPSEL_1; 44 case COMP_E_INPUT2: 45 return COMP_E_CTL0_IPSEL_2; 46 case COMP_E_INPUT3: 47 return COMP_E_CTL0_IPSEL_3; 48 case COMP_E_INPUT4: 49 return COMP_E_CTL0_IPSEL_4; 50 case COMP_E_INPUT5: 51 return COMP_E_CTL0_IPSEL_5; 52 case COMP_E_INPUT6: 53 return COMP_E_CTL0_IPSEL_6; 54 case COMP_E_INPUT7: 55 return COMP_E_CTL0_IPSEL_7; 56 case COMP_E_INPUT8: 57 return COMP_E_CTL0_IPSEL_8; 58 case COMP_E_INPUT9: 59 return COMP_E_CTL0_IPSEL_9; 60 case COMP_E_INPUT10: 61 return COMP_E_CTL0_IPSEL_10; 62 case COMP_E_INPUT11: 63 return COMP_E_CTL0_IPSEL_11; 64 case COMP_E_INPUT12: 65 return COMP_E_CTL0_IPSEL_12; 66 case COMP_E_INPUT13: 67 return COMP_E_CTL0_IPSEL_13; 68 case COMP_E_INPUT14: 69 return COMP_E_CTL0_IPSEL_14; 70 case COMP_E_INPUT15: 71 return COMP_E_CTL0_IPSEL_15; 72 case COMP_E_VREF: 73 return COMP_E_VREF; 74 default: 75 ASSERT(false); 76 return 0x11; 77 } 78 79 } 80 81 bool COMP_E_initModule(uint32_t comparator, const COMP_E_Config *config) 82 { 83 uint_fast8_t positiveTerminalInput = __getRegisterSettingForInput( 84 config->positiveTerminalInput); 85 uint_fast8_t negativeTerminalInput = __getRegisterSettingForInput( 86 config->negativeTerminalInput); 87 bool retVal = true; 88 89 ASSERT(positiveTerminalInput < 0x10); ASSERT(negativeTerminalInput < 0x10); 90 ASSERT(positiveTerminalInput != negativeTerminalInput); 91 ASSERT( 92 config->outputFilterEnableAndDelayLevel 93 <= COMP_E_FILTEROUTPUT_DLYLVL4); 94 95 /* Reset COMPE Control 1 & Interrupt Registers for initialization */ 96 COMP_E_CMSIS(comparator)->CTL0 = 0; 97 COMP_E_CMSIS(comparator)->INT = 0; 98 99 // Set the Positive Terminal 100 if (COMP_E_VREF != positiveTerminalInput) 101 { 102 // Enable Positive Terminal Input Mux and Set to the appropriate input 103 COMP_E_CMSIS(comparator)->CTL0 |= COMP_E_CTL0_IPEN 104 + positiveTerminalInput; 105 106 // Disable the input buffer 107 COMP_E_CMSIS(comparator)->CTL3 |= (1 << positiveTerminalInput); 108 } else 109 { 110 // Reset and Set COMPE Control 2 Register 111 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL2,COMP_E_CTL2_RSEL_OFS) = 0; 112 } 113 114 // Set the Negative Terminal 115 if (COMP_E_VREF != negativeTerminalInput) 116 { 117 // Enable Negative Terminal Input Mux and Set to the appropriate input 118 COMP_E_CMSIS(comparator)->CTL0 |= COMP_E_CTL0_IMEN 119 + (negativeTerminalInput << 8); 120 121 // Disable the input buffer 122 COMP_E_CMSIS(comparator)->CTL3 |= (1 << negativeTerminalInput); 123 } else 124 { 125 // Reset and Set COMPE Control 2 Register 126 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL2, COMP_E_CTL2_RSEL_OFS) = 1; 127 } 128 129 // Reset and Set COMPE Control 1 Register 130 COMP_E_CMSIS(comparator)->CTL1 = config->powerMode 131 + config->outputFilterEnableAndDelayLevel 132 + config->invertedOutputPolarity; 133 134 return retVal; 135 } 136 137 void COMP_E_setReferenceVoltage(uint32_t comparator, 138 uint_fast16_t supplyVoltageReferenceBase, 139 uint_fast16_t lowerLimitSupplyVoltageFractionOf32, 140 uint_fast16_t upperLimitSupplyVoltageFractionOf32) 141 { 142 ASSERT(supplyVoltageReferenceBase <= COMP_E_VREFBASE2_5V); 143 ASSERT(upperLimitSupplyVoltageFractionOf32 <= 32); 144 ASSERT(lowerLimitSupplyVoltageFractionOf32 <= 32); 145 ASSERT(upperLimitSupplyVoltageFractionOf32 146 >= lowerLimitSupplyVoltageFractionOf32); 147 148 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_MRVS_OFS) = 0; 149 COMP_E_CMSIS(comparator)->CTL2 &= COMP_E_CTL2_RSEL; 150 151 // Set Voltage Source(Vcc | Vref, resistor ladder or not) 152 if (COMP_E_REFERENCE_AMPLIFIER_DISABLED == supplyVoltageReferenceBase) 153 { 154 COMP_E_CMSIS(comparator)->CTL2 |= COMP_E_CTL2_RS_1; 155 } else if (lowerLimitSupplyVoltageFractionOf32 == 32) 156 { 157 COMP_E_CMSIS(comparator)->CTL2 |= COMP_E_CTL2_RS_3; 158 } else 159 { 160 COMP_E_CMSIS(comparator)->CTL2 |= COMP_E_CTL2_RS_2; 161 } 162 163 // Set COMPE Control 2 Register 164 COMP_E_CMSIS(comparator)->CTL2 |= supplyVoltageReferenceBase 165 + ((upperLimitSupplyVoltageFractionOf32 - 1) << 8) 166 + (lowerLimitSupplyVoltageFractionOf32 - 1); 167 } 168 169 void COMP_E_setReferenceAccuracy(uint32_t comparator, 170 uint_fast16_t referenceAccuracy) 171 { 172 ASSERT( 173 (referenceAccuracy == COMP_E_ACCURACY_STATIC) 174 || (referenceAccuracy == COMP_E_ACCURACY_CLOCKED)); 175 176 if (referenceAccuracy) 177 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL2, COMP_E_CTL2_REFACC_OFS) = 1; 178 else 179 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL2, COMP_E_CTL2_REFACC_OFS) = 0; 180 181 } 182 183 void COMP_E_setPowerMode(uint32_t comparator, uint_fast16_t powerMode) 184 { 185 COMP_E_CMSIS(comparator)->CTL1 = (COMP_E_CMSIS(comparator)->CTL1 186 & ~(COMP_E_CTL1_PWRMD_MASK)) | powerMode; 187 } 188 189 void COMP_E_enableModule(uint32_t comparator) 190 { 191 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_ON_OFS) = 1; 192 } 193 194 void COMP_E_disableModule(uint32_t comparator) 195 { 196 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_ON_OFS) = 0; 197 } 198 199 void COMP_E_shortInputs(uint32_t comparator) 200 { 201 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_SHORT_OFS) = 1; 202 } 203 204 void COMP_E_unshortInputs(uint32_t comparator) 205 { 206 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_SHORT_OFS) = 0; 207 } 208 209 void COMP_E_disableInputBuffer(uint32_t comparator, uint_fast16_t inputPort) 210 { 211 ASSERT(inputPort <= COMP_E_INPUT15); 212 213 COMP_E_CMSIS(comparator)->CTL3 |= (inputPort); 214 } 215 216 void COMP_E_enableInputBuffer(uint32_t comparator, uint_fast16_t inputPort) 217 { 218 ASSERT(inputPort <= COMP_E_INPUT15); 219 220 COMP_E_CMSIS(comparator)->CTL3 &= ~(inputPort); 221 } 222 223 void COMP_E_swapIO(uint32_t comparator) 224 { 225 COMP_E_CMSIS(comparator)->CTL1 ^= COMP_E_CTL1_EX; // Toggle CEEX bit 226 } 227 228 uint8_t COMP_E_outputValue(uint32_t comparator) 229 { 230 return COMP_E_CMSIS(comparator)->CTL1 & COMP_E_CTL1_OUT; 231 } 232 233 void COMP_E_enableInterrupt(uint32_t comparator, uint_fast16_t mask) 234 { 235 // Set the Interrupt enable bit 236 COMP_E_CMSIS(comparator)->INT |= mask; 237 } 238 239 uint_fast16_t COMP_E_getEnabledInterruptStatus(uint32_t comparator) 240 { 241 return COMP_E_getInterruptStatus(comparator) & 242 COMP_E_CMSIS(comparator)->INT; 243 } 244 245 void COMP_E_disableInterrupt(uint32_t comparator, uint_fast16_t mask) 246 { 247 COMP_E_CMSIS(comparator)->INT &= ~(mask); 248 } 249 250 void COMP_E_clearInterruptFlag(uint32_t comparator, uint_fast16_t mask) 251 { 252 COMP_E_CMSIS(comparator)->INT &= ~(mask); 253 } 254 255 uint_fast16_t COMP_E_getInterruptStatus(uint32_t comparator) 256 { 257 return (COMP_E_CMSIS(comparator)->INT & (COMP_E_OUTPUT_INTERRUPT_FLAG | 258 COMP_E_INTERRUPT_FLAG_INVERTED_POLARITY | 259 COMP_E_INTERRUPT_FLAG_READY)); 260 } 261 262 void COMP_E_setInterruptEdgeDirection(uint32_t comparator, 263 uint_fast8_t edgeDirection) 264 { 265 ASSERT(edgeDirection <= COMP_E_RISINGEDGE); 266 267 // Set the edge direction that will trigger an interrupt 268 if (COMP_E_RISINGEDGE == edgeDirection) 269 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_IES_OFS) = 0; 270 else if (COMP_E_FALLINGEDGE == edgeDirection) 271 BITBAND_PERI(COMP_E_CMSIS(comparator)->CTL1, COMP_E_CTL1_IES_OFS) = 1; 272 } 273 274 void COMP_E_toggleInterruptEdgeDirection(uint32_t comparator) 275 { 276 COMP_E_CMSIS(comparator)->CTL1 ^= COMP_E_CTL1_IES; 277 } 278 279 void COMP_E_registerInterrupt(uint32_t comparator, void (*intHandler)(void)) 280 { 281 switch (comparator) 282 { 283 case COMP_E0_BASE: 284 Interrupt_registerInterrupt(INT_COMP_E0, intHandler); 285 Interrupt_enableInterrupt(INT_COMP_E0); 286 break; 287 case COMP_E1_BASE: 288 Interrupt_registerInterrupt(INT_COMP_E1, intHandler); 289 Interrupt_enableInterrupt(INT_COMP_E1); 290 break; 291 default: 292 ASSERT(false); 293 } 294 } 295 296 void COMP_E_unregisterInterrupt(uint32_t comparator) 297 { 298 switch (comparator) 299 { 300 case COMP_E0_BASE: 301 Interrupt_disableInterrupt(INT_COMP_E0); 302 Interrupt_unregisterInterrupt(INT_COMP_E0); 303 break; 304 case COMP_E1_BASE: 305 Interrupt_disableInterrupt(INT_COMP_E1); 306 Interrupt_unregisterInterrupt(INT_COMP_E1); 307 break; 308 default: 309 ASSERT(false); 310 } 311 } 312 313