xref: /nrf52832-nimble/nordic/nrfx/drivers/src/nrfx_qdec.c (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
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_QDEC_ENABLED)
35 
36 #include <nrfx_qdec.h>
37 #include <hal/nrf_gpio.h>
38 
39 #define NRFX_LOG_MODULE QDEC
40 #include <nrfx_log.h>
41 
42 #define EVT_TO_STR(event)                                             \
43     (event == NRF_QDEC_EVENT_SAMPLERDY ? "NRF_QDEC_EVENT_SAMPLERDY" : \
44     (event == NRF_QDEC_EVENT_REPORTRDY ? "NRF_QDEC_EVENT_REPORTRDY" : \
45     (event == NRF_QDEC_EVENT_ACCOF     ? "NRF_QDEC_EVENT_ACCOF"     : \
46                                          "UNKNOWN EVENT")))
47 
48 
49 static nrfx_qdec_event_handler_t m_qdec_event_handler = NULL;
50 static nrfx_drv_state_t m_state = NRFX_DRV_STATE_UNINITIALIZED;
51 
nrfx_qdec_irq_handler(void)52 void nrfx_qdec_irq_handler(void)
53 {
54     nrfx_qdec_event_t event;
55     if ( nrf_qdec_event_check(NRF_QDEC_EVENT_SAMPLERDY) &&
56          nrf_qdec_int_enable_check(NRF_QDEC_INT_SAMPLERDY_MASK) )
57     {
58         nrf_qdec_event_clear(NRF_QDEC_EVENT_SAMPLERDY);
59         NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_SAMPLERDY));
60 
61         event.type = NRF_QDEC_EVENT_SAMPLERDY;
62         event.data.sample.value = (int8_t)nrf_qdec_sample_get();
63         m_qdec_event_handler(event);
64     }
65 
66     if ( nrf_qdec_event_check(NRF_QDEC_EVENT_REPORTRDY) &&
67          nrf_qdec_int_enable_check(NRF_QDEC_INT_REPORTRDY_MASK) )
68     {
69         nrf_qdec_event_clear(NRF_QDEC_EVENT_REPORTRDY);
70         NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_REPORTRDY));
71 
72         event.type = NRF_QDEC_EVENT_REPORTRDY;
73 
74         event.data.report.acc    = (int16_t)nrf_qdec_accread_get();
75         event.data.report.accdbl = (uint16_t)nrf_qdec_accdblread_get();
76         m_qdec_event_handler(event);
77     }
78 
79     if ( nrf_qdec_event_check(NRF_QDEC_EVENT_ACCOF) &&
80          nrf_qdec_int_enable_check(NRF_QDEC_INT_ACCOF_MASK) )
81     {
82         nrf_qdec_event_clear(NRF_QDEC_EVENT_ACCOF);
83         NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_ACCOF));
84 
85         event.type = NRF_QDEC_EVENT_ACCOF;
86         m_qdec_event_handler(event);
87     }
88 }
89 
90 
nrfx_qdec_init(nrfx_qdec_config_t const * p_config,nrfx_qdec_event_handler_t event_handler)91 nrfx_err_t nrfx_qdec_init(nrfx_qdec_config_t const * p_config,
92                           nrfx_qdec_event_handler_t  event_handler)
93 {
94     NRFX_ASSERT(p_config);
95     NRFX_ASSERT(event_handler);
96     nrfx_err_t err_code;
97 
98     if (m_state != NRFX_DRV_STATE_UNINITIALIZED)
99     {
100         err_code = NRFX_ERROR_INVALID_STATE;
101         NRFX_LOG_WARNING("Function: %s, error code: %s.",
102                          __func__,
103                          NRFX_LOG_ERROR_STRING_GET(err_code));
104         return err_code;
105     }
106 
107     m_qdec_event_handler = event_handler;
108 
109     nrf_qdec_sampleper_set(p_config->sampleper);
110     nrf_gpio_cfg_input(p_config->psela, NRF_GPIO_PIN_NOPULL);
111     nrf_gpio_cfg_input(p_config->pselb, NRF_GPIO_PIN_NOPULL);
112     if (p_config->pselled != NRF_QDEC_LED_NOT_CONNECTED)
113     {
114         nrf_gpio_cfg_input(p_config->pselled, NRF_GPIO_PIN_NOPULL);
115         nrf_qdec_ledpre_set(p_config->ledpre);
116         nrf_qdec_ledpol_set(p_config->ledpol);
117     }
118     nrf_qdec_pio_assign(p_config->psela, p_config->pselb, p_config->pselled);
119     nrf_qdec_shorts_enable(NRF_QDEC_SHORT_REPORTRDY_READCLRACC_MASK);
120 
121     if (p_config->dbfen)
122     {
123         nrf_qdec_dbfen_enable();
124     }
125     else
126     {
127         nrf_qdec_dbfen_disable();
128     }
129 
130     uint32_t int_mask = NRF_QDEC_INT_ACCOF_MASK;
131 
132     if (p_config->reportper != NRF_QDEC_REPORTPER_DISABLED)
133     {
134         nrf_qdec_reportper_set(p_config->reportper);
135         int_mask |= NRF_QDEC_INT_REPORTRDY_MASK;
136     }
137 
138     if (p_config->sample_inten)
139     {
140         int_mask |= NRF_QDEC_INT_SAMPLERDY_MASK;
141     }
142 
143     nrf_qdec_int_enable(int_mask);
144     NRFX_IRQ_PRIORITY_SET(QDEC_IRQn, p_config->interrupt_priority);
145     NRFX_IRQ_ENABLE(QDEC_IRQn);
146 
147     m_state = NRFX_DRV_STATE_INITIALIZED;
148 
149     err_code = NRFX_SUCCESS;
150     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
151     return err_code;
152 }
153 
nrfx_qdec_uninit(void)154 void nrfx_qdec_uninit(void)
155 {
156     NRFX_ASSERT(m_state != NRFX_DRV_STATE_UNINITIALIZED);
157     nrfx_qdec_disable();
158     NRFX_IRQ_DISABLE(QDEC_IRQn);
159     m_state = NRFX_DRV_STATE_UNINITIALIZED;
160     NRFX_LOG_INFO("Uninitialized.");
161 }
162 
nrfx_qdec_enable(void)163 void nrfx_qdec_enable(void)
164 {
165     NRFX_ASSERT(m_state == NRFX_DRV_STATE_INITIALIZED);
166     nrf_qdec_enable();
167     nrf_qdec_task_trigger(NRF_QDEC_TASK_START);
168     m_state = NRFX_DRV_STATE_POWERED_ON;
169     NRFX_LOG_INFO("Enabled.");
170 }
171 
nrfx_qdec_disable(void)172 void nrfx_qdec_disable(void)
173 {
174     NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON);
175     nrf_qdec_task_trigger(NRF_QDEC_TASK_STOP);
176     nrf_qdec_disable();
177     m_state = NRFX_DRV_STATE_INITIALIZED;
178     NRFX_LOG_INFO("Disabled.");
179 }
180 
nrfx_qdec_accumulators_read(int16_t * p_acc,int16_t * p_accdbl)181 void nrfx_qdec_accumulators_read(int16_t * p_acc, int16_t * p_accdbl)
182 {
183     NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON);
184     nrf_qdec_task_trigger(NRF_QDEC_TASK_READCLRACC);
185 
186     *p_acc    = (int16_t)nrf_qdec_accread_get();
187     *p_accdbl = (int16_t)nrf_qdec_accdblread_get();
188 
189     NRFX_LOG_DEBUG("Accumulators data, ACC register:");
190     NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)p_acc, sizeof(p_acc[0]));
191     NRFX_LOG_DEBUG("Accumulators data, ACCDBL register:");
192     NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)p_accdbl, sizeof(p_accdbl[0]));
193 }
194 
195 #endif // NRFX_CHECK(NRFX_QDEC_ENABLED)
196