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 #include <nrfx.h> 33 34 #if NRFX_CHECK(NRFX_LPCOMP_ENABLED) 35 36 #include <nrfx_lpcomp.h> 37 #include "prs/nrfx_prs.h" 38 39 #define NRFX_LOG_MODULE LPCOMP 40 #include <nrfx_log.h> 41 42 #define EVT_TO_STR(event) \ 43 (event == NRF_LPCOMP_EVENT_READY ? "NRF_LPCOMP_EVENT_READY" : \ 44 (event == NRF_LPCOMP_EVENT_DOWN ? "NRF_LPCOMP_EVENT_DOWN" : \ 45 (event == NRF_LPCOMP_EVENT_UP ? "NRF_LPCOMP_EVENT_UP" : \ 46 (event == NRF_LPCOMP_EVENT_CROSS ? "NRF_LPCOMP_EVENT_CROSS" : \ 47 "UNKNOWN EVENT")))) 48 49 50 static nrfx_lpcomp_event_handler_t m_lpcomp_event_handler = NULL; 51 static nrfx_drv_state_t m_state = NRFX_DRV_STATE_UNINITIALIZED; 52 53 static void lpcomp_execute_handler(nrf_lpcomp_event_t event, uint32_t event_mask) 54 { 55 if (nrf_lpcomp_event_check(event) && nrf_lpcomp_int_enable_check(event_mask)) 56 { 57 nrf_lpcomp_event_clear(event); 58 NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(event)); 59 60 m_lpcomp_event_handler(event); 61 } 62 } 63 64 void nrfx_lpcomp_irq_handler(void) 65 { 66 lpcomp_execute_handler(NRF_LPCOMP_EVENT_READY, LPCOMP_INTENSET_READY_Msk); 67 lpcomp_execute_handler(NRF_LPCOMP_EVENT_DOWN, LPCOMP_INTENSET_DOWN_Msk); 68 lpcomp_execute_handler(NRF_LPCOMP_EVENT_UP, LPCOMP_INTENSET_UP_Msk); 69 lpcomp_execute_handler(NRF_LPCOMP_EVENT_CROSS, LPCOMP_INTENSET_CROSS_Msk); 70 } 71 72 nrfx_err_t nrfx_lpcomp_init(nrfx_lpcomp_config_t const * p_config, 73 nrfx_lpcomp_event_handler_t event_handler) 74 { 75 NRFX_ASSERT(p_config); 76 NRFX_ASSERT(event_handler); 77 nrfx_err_t err_code; 78 79 if (m_state != NRFX_DRV_STATE_UNINITIALIZED) 80 { // LPCOMP driver is already initialized 81 err_code = NRFX_ERROR_INVALID_STATE; 82 NRFX_LOG_WARNING("Function: %s, error code: %s.", 83 __func__, 84 NRFX_LOG_ERROR_STRING_GET(err_code)); 85 return err_code; 86 } 87 88 m_lpcomp_event_handler = event_handler; 89 90 #if NRFX_CHECK(NRFX_PRS_ENABLED) 91 if (nrfx_prs_acquire(NRF_LPCOMP, nrfx_lpcomp_irq_handler) != NRFX_SUCCESS) 92 { 93 err_code = NRFX_ERROR_BUSY; 94 NRFX_LOG_WARNING("Function: %s, error code: %s.", 95 __func__, 96 NRFX_LOG_ERROR_STRING_GET(err_code)); 97 return err_code; 98 } 99 #endif 100 101 nrf_lpcomp_configure(&(p_config->hal)); 102 103 nrf_lpcomp_input_select(p_config->input); 104 105 switch (p_config->hal.detection) 106 { 107 case NRF_LPCOMP_DETECT_UP: 108 nrf_lpcomp_int_enable(LPCOMP_INTENSET_UP_Msk); 109 break; 110 111 case NRF_LPCOMP_DETECT_DOWN: 112 nrf_lpcomp_int_enable(LPCOMP_INTENSET_DOWN_Msk); 113 break; 114 115 case NRF_LPCOMP_DETECT_CROSS: 116 nrf_lpcomp_int_enable(LPCOMP_INTENSET_CROSS_Msk); 117 break; 118 119 default: 120 break; 121 } 122 nrf_lpcomp_shorts_enable(NRF_LPCOMP_SHORT_READY_SAMPLE_MASK); 123 124 NRFX_IRQ_PRIORITY_SET(LPCOMP_IRQn, p_config->interrupt_priority); 125 NRFX_IRQ_ENABLE(LPCOMP_IRQn); 126 127 m_state = NRFX_DRV_STATE_INITIALIZED; 128 129 err_code = NRFX_SUCCESS; 130 NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); 131 return err_code; 132 } 133 134 void nrfx_lpcomp_uninit(void) 135 { 136 NRFX_ASSERT(m_state != NRFX_DRV_STATE_UNINITIALIZED); 137 NRFX_IRQ_DISABLE(LPCOMP_IRQn); 138 nrfx_lpcomp_disable(); 139 #if NRFX_CHECK(NRFX_PRS_ENABLED) 140 nrfx_prs_release(NRF_LPCOMP); 141 #endif 142 m_state = NRFX_DRV_STATE_UNINITIALIZED; 143 m_lpcomp_event_handler = NULL; 144 NRFX_LOG_INFO("Uninitialized."); 145 } 146 147 void nrfx_lpcomp_enable(void) 148 { 149 NRFX_ASSERT(m_state == NRFX_DRV_STATE_INITIALIZED); 150 nrf_lpcomp_enable(); 151 nrf_lpcomp_task_trigger(NRF_LPCOMP_TASK_START); 152 m_state = NRFX_DRV_STATE_POWERED_ON; 153 NRFX_LOG_INFO("Enabled."); 154 } 155 156 void nrfx_lpcomp_disable(void) 157 { 158 NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON); 159 nrf_lpcomp_disable(); 160 nrf_lpcomp_task_trigger(NRF_LPCOMP_TASK_STOP); 161 m_state = NRFX_DRV_STATE_INITIALIZED; 162 NRFX_LOG_INFO("Disabled."); 163 } 164 165 #endif // NRFX_CHECK(NRFX_LPCOMP_ENABLED) 166