1 /* 2 * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA 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 are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef NRF_COMP_H_ 33 #define NRF_COMP_H_ 34 35 #include <nrfx.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /** 42 * @defgroup nrf_comp_hal COMP HAL 43 * @{ 44 * @ingroup nrf_comp 45 * @brief Hardware access layer for managing the Comparator (COMP) peripheral. 46 */ 47 48 /** 49 * @enum nrf_comp_input_t 50 * @brief COMP analog pin selection. 51 */ 52 typedef enum 53 { 54 NRF_COMP_INPUT_0 = COMP_PSEL_PSEL_AnalogInput0, /*!< AIN0 selected as analog input. */ 55 NRF_COMP_INPUT_1 = COMP_PSEL_PSEL_AnalogInput1, /*!< AIN1 selected as analog input. */ 56 NRF_COMP_INPUT_2 = COMP_PSEL_PSEL_AnalogInput2, /*!< AIN2 selected as analog input. */ 57 NRF_COMP_INPUT_3 = COMP_PSEL_PSEL_AnalogInput3, /*!< AIN3 selected as analog input. */ 58 NRF_COMP_INPUT_4 = COMP_PSEL_PSEL_AnalogInput4, /*!< AIN4 selected as analog input. */ 59 NRF_COMP_INPUT_5 = COMP_PSEL_PSEL_AnalogInput5, /*!< AIN5 selected as analog input. */ 60 NRF_COMP_INPUT_6 = COMP_PSEL_PSEL_AnalogInput6, /*!< AIN6 selected as analog input. */ 61 #if defined (COMP_PSEL_PSEL_AnalogInput7) || defined (__NRFX_DOXYGEN__) 62 NRF_COMP_INPUT_7 = COMP_PSEL_PSEL_AnalogInput7, /*!< AIN7 selected as analog input. */ 63 #endif 64 #if defined (COMP_PSEL_PSEL_VddDiv2) || defined (__NRFX_DOXYGEN__) 65 NRF_COMP_VDD_DIV2 = COMP_PSEL_PSEL_VddDiv2, /*!< VDD/2 selected as analog input. */ 66 #endif 67 }nrf_comp_input_t; 68 69 /** 70 * @enum nrf_comp_ref_t 71 * @brief COMP reference selection. 72 */ 73 typedef enum 74 { 75 NRF_COMP_REF_Int1V2 = COMP_REFSEL_REFSEL_Int1V2, /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V). */ 76 NRF_COMP_REF_Int1V8 = COMP_REFSEL_REFSEL_Int1V8, /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V). */ 77 NRF_COMP_REF_Int2V4 = COMP_REFSEL_REFSEL_Int2V4, /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V). */ 78 NRF_COMP_REF_VDD = COMP_REFSEL_REFSEL_VDD, /*!< VREF = VDD. */ 79 NRF_COMP_REF_ARef = COMP_REFSEL_REFSEL_ARef /*!< VREF = AREF (VDD >= VREF >= AREFMIN). */ 80 }nrf_comp_ref_t; 81 82 /** 83 * @enum nrf_comp_ext_ref_t 84 * @brief COMP external analog reference selection. 85 */ 86 typedef enum 87 { 88 NRF_COMP_EXT_REF_0 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference0, /*!< Use AIN0 as external analog reference. */ 89 NRF_COMP_EXT_REF_1 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference1 /*!< Use AIN1 as external analog reference. */ 90 }nrf_comp_ext_ref_t; 91 92 /** 93 * @brief COMP THDOWN and THUP values that are used to calculate the threshold voltages VDOWN and VUP. 94 */ 95 typedef struct 96 { 97 uint8_t th_down; /*!< THDOWN value. */ 98 uint8_t th_up; /*!< THUP value. */ 99 }nrf_comp_th_t; 100 101 /** 102 * @enum nrf_comp_main_mode_t 103 * @brief COMP main operation mode. 104 */ 105 typedef enum 106 { 107 NRF_COMP_MAIN_MODE_SE = COMP_MODE_MAIN_SE, /*!< Single ended mode. */ 108 NRF_COMP_MAIN_MODE_Diff = COMP_MODE_MAIN_Diff /*!< Differential mode. */ 109 }nrf_comp_main_mode_t; 110 111 /** 112 * @enum nrf_comp_sp_mode_t 113 * @brief COMP speed and power mode. 114 */ 115 typedef enum 116 { 117 NRF_COMP_SP_MODE_Low = COMP_MODE_SP_Low, /*!< Low power mode. */ 118 NRF_COMP_SP_MODE_Normal = COMP_MODE_SP_Normal, /*!< Normal mode. */ 119 NRF_COMP_SP_MODE_High = COMP_MODE_SP_High /*!< High speed mode. */ 120 }nrf_comp_sp_mode_t; 121 122 /** 123 * @enum nrf_comp_hyst_t 124 * @brief COMP comparator hysteresis. 125 */ 126 typedef enum 127 { 128 NRF_COMP_HYST_NoHyst = COMP_HYST_HYST_NoHyst, /*!< Comparator hysteresis disabled. */ 129 NRF_COMP_HYST_50mV = COMP_HYST_HYST_Hyst50mV /*!< Comparator hysteresis enabled. */ 130 }nrf_comp_hyst_t; 131 132 #if defined (COMP_ISOURCE_ISOURCE_Msk) || defined (__NRFX_DOXYGEN__) 133 /** 134 * @brief COMP current source selection on analog input. 135 */ 136 typedef enum 137 { 138 NRF_COMP_ISOURCE_Off = COMP_ISOURCE_ISOURCE_Off, /*!< Current source disabled. */ 139 NRF_COMP_ISOURCE_Ien2uA5 = COMP_ISOURCE_ISOURCE_Ien2mA5, /*!< Current source enabled (+/- 2.5 uA). */ 140 NRF_COMP_ISOURCE_Ien5uA = COMP_ISOURCE_ISOURCE_Ien5mA, /*!< Current source enabled (+/- 5 uA). */ 141 NRF_COMP_ISOURCE_Ien10uA = COMP_ISOURCE_ISOURCE_Ien10mA /*!< Current source enabled (+/- 10 uA). */ 142 }nrf_isource_t; 143 #endif 144 145 /** 146 * @enum nrf_comp_task_t 147 * @brief COMP tasks. 148 */ 149 typedef enum 150 { 151 /*lint -save -e30*/ 152 NRF_COMP_TASK_START = offsetof(NRF_COMP_Type, TASKS_START), /*!< COMP start sampling task. */ 153 NRF_COMP_TASK_STOP = offsetof(NRF_COMP_Type, TASKS_STOP), /*!< COMP stop sampling task. */ 154 NRF_COMP_TASK_SAMPLE = offsetof(NRF_COMP_Type, TASKS_SAMPLE) /*!< Sample comparator value. */ 155 /*lint -restore*/ 156 }nrf_comp_task_t; 157 158 /** 159 * @enum nrf_comp_event_t 160 * @brief COMP events. 161 */ 162 typedef enum 163 { 164 /*lint -save -e30*/ 165 NRF_COMP_EVENT_READY = offsetof(NRF_COMP_Type, EVENTS_READY), /*!< COMP is ready and output is valid. */ 166 NRF_COMP_EVENT_DOWN = offsetof(NRF_COMP_Type, EVENTS_DOWN), /*!< Input voltage crossed the threshold going down. */ 167 NRF_COMP_EVENT_UP = offsetof(NRF_COMP_Type, EVENTS_UP), /*!< Input voltage crossed the threshold going up. */ 168 NRF_COMP_EVENT_CROSS = offsetof(NRF_COMP_Type, EVENTS_CROSS) /*!< Input voltage crossed the threshold in any direction. */ 169 /*lint -restore*/ 170 }nrf_comp_event_t; 171 172 /** 173 * @brief COMP reference configuration. 174 */ 175 typedef struct 176 { 177 nrf_comp_ref_t reference; /*!< COMP reference selection. */ 178 nrf_comp_ext_ref_t external; /*!< COMP external analog reference selection. */ 179 }nrf_comp_ref_conf_t; 180 181 182 /** 183 * @brief Function for enabling the COMP peripheral. 184 */ 185 __STATIC_INLINE void nrf_comp_enable(void); 186 187 188 /** 189 * @brief Function for disabling the COMP peripheral. 190 */ 191 192 __STATIC_INLINE void nrf_comp_disable(void); 193 194 /** 195 * @brief Function for checking if the COMP peripheral is enabled. 196 * 197 * @retval true If the COMP peripheral is enabled. 198 * @retval false If the COMP peripheral is not enabled. 199 */ 200 __STATIC_INLINE bool nrf_comp_enable_check(void); 201 202 /** 203 * @brief Function for setting the reference source. 204 * 205 * @param[in] reference COMP reference selection. 206 */ 207 __STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference); 208 209 210 /** 211 * @brief Function for setting the external analog reference source. 212 * 213 * @param[in] ext_ref COMP external analog reference selection. 214 */ 215 __STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref); 216 217 218 /** 219 * @brief Function for setting threshold voltages. 220 * 221 * @param[in] threshold COMP VDOWN and VUP thresholds. 222 */ 223 __STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold); 224 225 226 /** 227 * @brief Function for setting the main mode. 228 * 229 * @param[in] main_mode COMP main operation mode. 230 */ 231 __STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode); 232 233 234 /** 235 * @brief Function for setting the speed mode. 236 * 237 * @param[in] speed_mode COMP speed and power mode. 238 */ 239 __STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode); 240 241 242 /** 243 * @brief Function for setting the hysteresis. 244 * 245 * @param[in] hyst COMP comparator hysteresis. 246 */ 247 __STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst); 248 249 250 #if defined (COMP_ISOURCE_ISOURCE_Msk) || defined (__NRFX_DOXYGEN__) 251 /** 252 * @brief Function for setting the current source on the analog input. 253 * 254 * @param[in] isource COMP current source selection on analog input. 255 */ 256 __STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource); 257 #endif 258 259 260 /** 261 * @brief Function for selecting the active input of the COMP. 262 * 263 * @param[in] input Input to be selected. 264 */ 265 __STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input); 266 267 268 /** 269 * @brief Function for getting the last COMP compare result. 270 * 271 * @return The last compare result. If 0, then VIN+ < VIN-. If 1, then VIN+ > VIN-. 272 * 273 * @note If VIN+ == VIN-, the return value depends on the previous result. 274 */ 275 __STATIC_INLINE uint32_t nrf_comp_result_get(void); 276 277 278 /** 279 * @brief Function for enabling interrupts from COMP. 280 * 281 * @param[in] comp_int_mask Mask of interrupts to be enabled. 282 * 283 * @sa nrf_comp_int_enable_check() 284 */ 285 __STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask); 286 287 /** 288 * @brief Function for disabling interrupts from COMP. 289 * 290 * @param[in] comp_int_mask Mask of interrupts to be disabled. 291 * 292 * @sa nrf_comp_int_enable_check() 293 */ 294 __STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask); 295 296 297 /** 298 * @brief Function for getting the enabled interrupts of COMP. 299 * 300 * @param[in] comp_int_mask Mask of interrupts to be checked. 301 * 302 * @retval true If any interrupts of the specified mask are enabled. 303 */ 304 __STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask); 305 306 307 308 /** 309 * @brief Function for getting the address of a specific COMP task register. 310 * 311 * @param[in] comp_task COMP task. 312 * 313 * @return Address of the specified COMP task. 314 */ 315 __STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task); 316 317 318 /** 319 * @brief Function for getting the address of a specific COMP event register. 320 * 321 * @param[in] comp_event COMP event. 322 * 323 * @return Address of the specified COMP event. 324 */ 325 __STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event); 326 327 328 /** 329 * @brief Function for setting COMP shorts. 330 * 331 * @param[in] comp_short_mask COMP shorts by mask. 332 * 333 */ 334 __STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask); 335 336 337 /** 338 * @brief Function for clearing COMP shorts by mask. 339 * 340 * @param[in] comp_short_mask COMP shorts to be cleared. 341 * 342 */ 343 __STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask); 344 345 346 /** 347 * @brief Function for setting a specific COMP task. 348 * 349 * @param[in] comp_task COMP task to be set. 350 * 351 */ 352 __STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task); 353 354 355 /** 356 * @brief Function for clearing a specific COMP event. 357 * 358 * @param[in] comp_event COMP event to be cleared. 359 * 360 */ 361 __STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event); 362 363 364 /** 365 * @brief Function for getting the state of a specific COMP event. 366 * 367 * @retval true If the specified COMP event is active. 368 * 369 */ 370 __STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event); 371 372 #ifndef SUPPRESS_INLINE_IMPLEMENTATION 373 374 __STATIC_INLINE void nrf_comp_enable(void) 375 { 376 NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Enabled << COMP_ENABLE_ENABLE_Pos); 377 } 378 379 __STATIC_INLINE void nrf_comp_disable(void) 380 { 381 NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Disabled << COMP_ENABLE_ENABLE_Pos); 382 } 383 384 __STATIC_INLINE bool nrf_comp_enable_check(void) 385 { 386 return ((NRF_COMP->ENABLE) & COMP_ENABLE_ENABLE_Enabled); 387 } 388 389 __STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference) 390 { 391 NRF_COMP->REFSEL = (reference << COMP_REFSEL_REFSEL_Pos); 392 } 393 394 __STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref) 395 { 396 NRF_COMP->EXTREFSEL = (ext_ref << COMP_EXTREFSEL_EXTREFSEL_Pos); 397 } 398 399 __STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold) 400 { 401 NRF_COMP->TH = 402 ((threshold.th_down << COMP_TH_THDOWN_Pos) & COMP_TH_THDOWN_Msk) | 403 ((threshold.th_up << COMP_TH_THUP_Pos) & COMP_TH_THUP_Msk); 404 } 405 406 __STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode) 407 { 408 NRF_COMP->MODE |= (main_mode << COMP_MODE_MAIN_Pos); 409 } 410 411 __STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode) 412 { 413 NRF_COMP->MODE |= (speed_mode << COMP_MODE_SP_Pos); 414 } 415 416 __STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst) 417 { 418 NRF_COMP->HYST = (hyst << COMP_HYST_HYST_Pos) & COMP_HYST_HYST_Msk; 419 } 420 421 #if defined (COMP_ISOURCE_ISOURCE_Msk) 422 __STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource) 423 { 424 NRF_COMP->ISOURCE = (isource << COMP_ISOURCE_ISOURCE_Pos) & COMP_ISOURCE_ISOURCE_Msk; 425 } 426 #endif 427 428 __STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input) 429 { 430 NRF_COMP->PSEL = ((uint32_t)input << COMP_PSEL_PSEL_Pos); 431 } 432 433 __STATIC_INLINE uint32_t nrf_comp_result_get(void) 434 { 435 return (uint32_t)NRF_COMP->RESULT; 436 } 437 438 __STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask) 439 { 440 NRF_COMP->INTENSET = comp_int_mask; 441 } 442 443 __STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask) 444 { 445 NRF_COMP->INTENCLR = comp_int_mask; 446 } 447 448 __STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask) 449 { 450 return (NRF_COMP->INTENSET & comp_int_mask); // when read this register will return the value of INTEN. 451 } 452 453 __STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task) 454 { 455 return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_task); 456 } 457 458 __STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event) 459 { 460 return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event); 461 } 462 463 __STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask) 464 { 465 NRF_COMP->SHORTS |= comp_short_mask; 466 } 467 468 __STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask) 469 { 470 NRF_COMP->SHORTS &= ~comp_short_mask; 471 } 472 473 __STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task) 474 { 475 *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_task) ) = 1; 476 } 477 478 __STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event) 479 { 480 *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + (uint32_t)comp_event) ) = 0; 481 #if __CORTEX_M == 0x04 482 volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event)); 483 (void)dummy; 484 #endif 485 } 486 487 __STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event) 488 { 489 return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_event)); 490 } 491 492 #endif // SUPPRESS_INLINE_IMPLEMENTATION 493 494 /** @} */ 495 496 #ifdef __cplusplus 497 } 498 #endif 499 500 #endif // NRF_COMP_H_ 501