1 /*
2 * Copyright (c) 2022 - 2024, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <nrfx_example.h>
35 #include <saadc_examples_common.h>
36 #include <nrfx_saadc.h>
37 #include <nrfx_gpiote.h>
38
39 #define NRFX_LOG_MODULE EXAMPLE
40 #define NRFX_EXAMPLE_CONFIG_LOG_ENABLED 1
41 #define NRFX_EXAMPLE_CONFIG_LOG_LEVEL 3
42 #include <nrfx_log.h>
43
44 /**
45 * @defgroup nrfx_saadc_advanced_blocking_example Advanced blocking SAADC example
46 * @{
47 * @ingroup nrfx_saadc_examples
48 *
49 * @brief Example showing advanced functionality of nrfx_saadc driver operating in the blocking mode.
50 *
51 * @details Application initializes nrfx_saadc driver and starts operating in the blocking mode.
52 * In the example, @ref m_single_channel is configured and the SAADC driver is set to the advanced mode.
53 *
54 * Before every sampling, calibration in a blocking manner is performed. Sampling is invoked
55 * by @p nrfx_saadc_mode_trigger() function afterwards.
56 *
57 * In the example there is GPIOTE task configured to toggle specified ( @ref OUT_GPIO_PIN ) pin. This task
58 * is being triggered between successive samplings to verify the functionality of the SAADC on the non-constant analog signal.
59 */
60
61 /** @brief Symbol specifying analog input to be observed by SAADC channel 0. */
62 #define CH0_AIN ANALOG_INPUT_TO_SAADC_AIN(ANALOG_INPUT_A0)
63
64 /** @brief Symbol specifying GPIOTE instance to be used. */
65 #define GPIOTE_INST_IDX 0
66
67 /** @brief Symbol specifying GPIO pin used to test the functionality of SAADC. */
68 #define OUT_GPIO_PIN LOOPBACK_PIN_1B
69
70 /** @brief Symbol specifying the size of singular sample buffer ( @ref m_samples_buffer ). */
71 #define BUFFER_SIZE 2UL
72
73 /** @brief Symbol specifying the number of SAADC samplings to trigger. */
74 #define SAMPLING_ITERATIONS 5UL
75
76 /** @brief Symbol specifying the resolution of the SAADC. */
77 #define RESOLUTION NRF_SAADC_RESOLUTION_10BIT
78
79 /** @brief SAADC channel configuration structure for single channel use. */
80 static const nrfx_saadc_channel_t m_single_channel = SAADC_CHANNEL_SE_ACQ_3US(CH0_AIN, 0);
81
82 /** @brief Samples buffer to store values from a SAADC channel. */
83 #if (NRF_SAADC_8BIT_SAMPLE_WIDTH == 8) && (RESOLUTION == NRF_SAADC_RESOLUTION_8BIT)
84 static uint8_t m_samples_buffer[BUFFER_SIZE];
85 #else
86 static uint16_t m_samples_buffer[BUFFER_SIZE];
87 #endif
88
89 /**
90 * @brief Function for application main entry.
91 *
92 * @return Nothing.
93 */
main(void)94 int main(void)
95 {
96 nrfx_err_t status;
97 (void)status;
98
99 #if defined(__ZEPHYR__)
100 IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_GPIOTE_INST_GET(GPIOTE_INST_IDX)), IRQ_PRIO_LOWEST,
101 NRFX_GPIOTE_INST_HANDLER_GET(GPIOTE_INST_IDX), 0, 0);
102 #endif
103
104 NRFX_EXAMPLE_LOG_INIT();
105 NRFX_LOG_INFO("Starting nrfx_saadc advanced blocking example.");
106 NRFX_EXAMPLE_LOG_PROCESS();
107
108 status = nrfx_saadc_init(NRFX_SAADC_DEFAULT_CONFIG_IRQ_PRIORITY);
109 NRFX_ASSERT(status == NRFX_SUCCESS);
110
111 nrfx_gpiote_t const gpiote_inst = NRFX_GPIOTE_INSTANCE(GPIOTE_INST_IDX);
112 status = nrfx_gpiote_init(&gpiote_inst, NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);
113 NRFX_ASSERT(status == NRFX_SUCCESS);
114 NRFX_LOG_INFO("GPIOTE status: %s",
115 nrfx_gpiote_init_check(&gpiote_inst) ? "initialized" : "not initialized");
116
117 gpiote_pin_toggle_task_setup(&gpiote_inst, OUT_GPIO_PIN);
118
119 status = nrfx_saadc_channel_config(&m_single_channel);
120 NRFX_ASSERT(status == NRFX_SUCCESS);
121
122 nrfx_saadc_adv_config_t adv_config = NRFX_SAADC_DEFAULT_ADV_CONFIG;
123
124 uint32_t channel_mask = nrfx_saadc_channels_configured_get();
125 status = nrfx_saadc_advanced_mode_set(channel_mask,
126 RESOLUTION,
127 &adv_config,
128 NULL);
129 NRFX_ASSERT(status == NRFX_SUCCESS);
130
131 status = nrfx_saadc_buffer_set(m_samples_buffer, BUFFER_SIZE);
132 NRFX_ASSERT(status == NRFX_SUCCESS);
133
134 uint16_t sampling_index = 0;
135 while (1)
136 {
137 if (sampling_index < SAMPLING_ITERATIONS)
138 {
139 nrfx_gpiote_out_task_trigger(&gpiote_inst, OUT_GPIO_PIN);
140
141 status = nrfx_saadc_offset_calibrate(NULL);
142 NRFX_ASSERT(status == NRFX_SUCCESS);
143 NRFX_LOG_INFO("Calibration in the blocking manner finished successfully.");
144
145 /*
146 * If function nrfx_saadc_mode_trigger() returns NRFX_ERROR_BUSY it means that the conversion in the advanced
147 * blocking mode is still being performed. Then the function must be called again to continue the conversion.
148 */
149 while ((status = nrfx_saadc_mode_trigger()) == NRFX_ERROR_BUSY)
150 {}
151 NRFX_ASSERT(status == NRFX_SUCCESS);
152 NRFX_LOG_INFO("Sampling %d / %ld", sampling_index + 1, SAMPLING_ITERATIONS);
153
154 for (uint32_t buffer_index = 0; buffer_index < BUFFER_SIZE; buffer_index++)
155 {
156 NRFX_LOG_INFO("[Sample %u] value == %d",
157 buffer_index,
158 NRFX_SAADC_SAMPLE_GET(RESOLUTION, m_samples_buffer, buffer_index));
159 }
160
161 status = nrfx_saadc_buffer_set(m_samples_buffer, BUFFER_SIZE);
162 NRFX_ASSERT(status == NRFX_SUCCESS);
163
164 sampling_index++;
165 }
166 NRFX_EXAMPLE_LOG_PROCESS();
167 }
168 }
169
170 /** @} */
171