Wallbot_CaaS
Dependencies: MPU6050 mbed PID
Fork of BLE_MPU6050_test6_challenge_sb by
app_gpiote.c
00001 /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. 00002 * 00003 * The information contained herein is property of Nordic Semiconductor ASA. 00004 * Terms and conditions of usage are described in detail in NORDIC 00005 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 00006 * 00007 * Licensees are granted free, non-transferable use of the information. NO 00008 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 00009 * the file. 00010 * 00011 */ 00012 00013 #if NEED_APP_GPIOTE /* disabled by default */ 00014 00015 #include "app_gpiote.h " 00016 #include <stdlib.h> 00017 #include <string.h> 00018 #include "app_util.h " 00019 #include "app_util_platform.h " 00020 #include "nrf_error.h" 00021 #include "nrf_gpio.h" 00022 00023 00024 /**@brief GPIOTE user type. */ 00025 typedef struct 00026 { 00027 uint32_t pins_mask; /**< Mask defining which pins user wants to monitor. */ 00028 uint32_t pins_low_to_high_mask; /**< Mask defining which pins will generate events to this user when toggling low->high. */ 00029 uint32_t pins_high_to_low_mask; /**< Mask defining which pins will generate events to this user when toggling high->low. */ 00030 uint32_t sense_high_pins; /**< Mask defining which pins are configured to generate GPIOTE interrupt on transition to high level. */ 00031 app_gpiote_event_handler_t event_handler; /**< Pointer to function to be executed when an event occurs. */ 00032 } gpiote_user_t; 00033 00034 STATIC_ASSERT(sizeof(gpiote_user_t) <= GPIOTE_USER_NODE_SIZE); 00035 STATIC_ASSERT(sizeof(gpiote_user_t) % 4 == 0); 00036 00037 static uint32_t m_enabled_users_mask; /**< Mask for tracking which users are enabled. */ 00038 static uint8_t m_user_array_size; /**< Size of user array. */ 00039 static uint8_t m_user_count; /**< Number of registered users. */ 00040 static gpiote_user_t * mp_users = NULL; /**< Array of GPIOTE users. */ 00041 00042 00043 /**@brief Function for toggling sense level for specified pins. 00044 * 00045 * @param[in] p_user Pointer to user structure. 00046 * @param[in] pins Bitmask specifying for which pins the sense level is to be toggled. 00047 */ 00048 static void sense_level_toggle(gpiote_user_t * p_user, uint32_t pins) 00049 { 00050 uint32_t pin_no; 00051 00052 for (pin_no = 0; pin_no < NO_OF_PINS; pin_no++) 00053 { 00054 uint32_t pin_mask = (1 << pin_no); 00055 00056 if ((pins & pin_mask) != 0) 00057 { 00058 uint32_t sense; 00059 00060 // Invert sensing. 00061 if ((p_user->sense_high_pins & pin_mask) == 0) 00062 { 00063 sense = GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; 00064 p_user->sense_high_pins |= pin_mask; 00065 } 00066 else 00067 { 00068 sense = GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; 00069 p_user->sense_high_pins &= ~pin_mask; 00070 } 00071 00072 NRF_GPIO->PIN_CNF[pin_no] &= ~GPIO_PIN_CNF_SENSE_Msk; 00073 NRF_GPIO->PIN_CNF[pin_no] |= sense; 00074 } 00075 } 00076 } 00077 00078 00079 /**@brief Function for handling the GPIOTE interrupt. 00080 */ 00081 void GPIOTE_IRQHandler(void) 00082 { 00083 uint8_t i; 00084 uint32_t pins_changed; 00085 uint32_t pins_state = NRF_GPIO->IN; 00086 00087 // Clear event. 00088 NRF_GPIOTE->EVENTS_PORT = 0; 00089 00090 // Check all users. 00091 for (i = 0; i < m_user_count; i++) 00092 { 00093 gpiote_user_t * p_user = &mp_users[i]; 00094 00095 // Check if user is enabled. 00096 if (((1 << i) & m_enabled_users_mask) != 0) 00097 { 00098 uint32_t transition_pins; 00099 uint32_t event_low_to_high; 00100 uint32_t event_high_to_low; 00101 00102 // Find set of pins on which there has been a transition. 00103 transition_pins = (pins_state ^ ~p_user->sense_high_pins) & p_user->pins_mask; 00104 00105 // Toggle SENSE level for all pins that have changed state. 00106 sense_level_toggle(p_user, transition_pins); 00107 00108 // Second read after setting sense. 00109 // Check if any pins have changed while serving this interrupt. 00110 pins_changed = NRF_GPIO->IN ^ pins_state; 00111 if (pins_changed) 00112 { 00113 // Transition pins detected in late stage. 00114 uint32_t late_transition_pins; 00115 00116 pins_state |= pins_changed; 00117 00118 // Find set of pins on which there has been a transition. 00119 late_transition_pins = (pins_state ^ ~p_user->sense_high_pins) & p_user->pins_mask; 00120 00121 // Toggle SENSE level for all pins that have changed state in last phase. 00122 sense_level_toggle(p_user, late_transition_pins); 00123 00124 // Update pins that has changed state since the interrupt occurred. 00125 transition_pins |= late_transition_pins; 00126 } 00127 00128 // Call user event handler if an event has occurred. 00129 event_high_to_low = (~pins_state & p_user->pins_high_to_low_mask) & transition_pins; 00130 event_low_to_high = (pins_state & p_user->pins_low_to_high_mask) & transition_pins; 00131 00132 if ((event_low_to_high | event_high_to_low) != 0) 00133 { 00134 p_user->event_handler(event_low_to_high, event_high_to_low); 00135 } 00136 } 00137 } 00138 } 00139 00140 00141 /**@brief Function for sense disabling for all pins for specified user. 00142 * 00143 * @param[in] user_id User id. 00144 */ 00145 static void pins_sense_disable(app_gpiote_user_id_t user_id) 00146 { 00147 uint32_t pin_no; 00148 00149 for (pin_no = 0; pin_no < 32; pin_no++) 00150 { 00151 if ((mp_users[user_id].pins_mask & (1 << pin_no)) != 0) 00152 { 00153 NRF_GPIO->PIN_CNF[pin_no] &= ~GPIO_PIN_CNF_SENSE_Msk; 00154 NRF_GPIO->PIN_CNF[pin_no] |= GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos; 00155 } 00156 } 00157 } 00158 00159 00160 uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer) 00161 { 00162 if (p_buffer == NULL) 00163 { 00164 return NRF_ERROR_INVALID_PARAM; 00165 } 00166 00167 // Check that buffer is correctly aligned. 00168 if (!is_word_aligned(p_buffer)) 00169 { 00170 return NRF_ERROR_INVALID_PARAM; 00171 } 00172 00173 // Initialize file globals. 00174 mp_users = (gpiote_user_t *)p_buffer; 00175 m_user_array_size = max_users; 00176 m_user_count = 0; 00177 m_enabled_users_mask = 0; 00178 00179 memset(mp_users, 0, m_user_array_size * sizeof(gpiote_user_t)); 00180 00181 // Initialize GPIOTE interrupt (will not be enabled until app_gpiote_user_enable() is called). 00182 NRF_GPIOTE->INTENCLR = 0xFFFFFFFF; 00183 00184 NVIC_ClearPendingIRQ(GPIOTE_IRQn); 00185 NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH); 00186 NVIC_EnableIRQ(GPIOTE_IRQn); 00187 00188 return NRF_SUCCESS; 00189 } 00190 00191 00192 uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id, 00193 uint32_t pins_low_to_high_mask, 00194 uint32_t pins_high_to_low_mask, 00195 app_gpiote_event_handler_t event_handler) 00196 { 00197 // Check state and parameters. 00198 if (mp_users == NULL) 00199 { 00200 return NRF_ERROR_INVALID_STATE; 00201 } 00202 if (event_handler == NULL) 00203 { 00204 return NRF_ERROR_INVALID_PARAM; 00205 } 00206 if (m_user_count >= m_user_array_size) 00207 { 00208 return NRF_ERROR_NO_MEM; 00209 } 00210 00211 // Allocate new user. 00212 mp_users[m_user_count].pins_mask = pins_low_to_high_mask | pins_high_to_low_mask; 00213 mp_users[m_user_count].pins_low_to_high_mask = pins_low_to_high_mask; 00214 mp_users[m_user_count].pins_high_to_low_mask = pins_high_to_low_mask; 00215 mp_users[m_user_count].event_handler = event_handler; 00216 00217 *p_user_id = m_user_count++; 00218 00219 // Make sure SENSE is disabled for all pins. 00220 pins_sense_disable(*p_user_id); 00221 00222 return NRF_SUCCESS; 00223 } 00224 00225 00226 uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id) 00227 { 00228 uint32_t pin_no; 00229 uint32_t pins_state; 00230 00231 // Check state and parameters. 00232 if (mp_users == NULL) 00233 { 00234 return NRF_ERROR_INVALID_STATE; 00235 } 00236 if (user_id >= m_user_count) 00237 { 00238 return NRF_ERROR_INVALID_PARAM; 00239 } 00240 00241 // Clear any pending event. 00242 NRF_GPIOTE->EVENTS_PORT = 0; 00243 pins_state = NRF_GPIO->IN; 00244 00245 // Enable user. 00246 if (m_enabled_users_mask == 0) 00247 { 00248 NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk; 00249 } 00250 m_enabled_users_mask |= (1 << user_id); 00251 00252 // Enable sensing for all pins for specified user. 00253 mp_users[user_id].sense_high_pins = 0; 00254 for (pin_no = 0; pin_no < 32; pin_no++) 00255 { 00256 uint32_t pin_mask = (1 << pin_no); 00257 00258 if ((mp_users[user_id].pins_mask & pin_mask) != 0) 00259 { 00260 uint32_t sense; 00261 00262 if ((pins_state & pin_mask) != 0) 00263 { 00264 sense = GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; 00265 } 00266 else 00267 { 00268 sense = GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; 00269 mp_users[user_id].sense_high_pins |= pin_mask; 00270 } 00271 00272 NRF_GPIO->PIN_CNF[pin_no] &= ~GPIO_PIN_CNF_SENSE_Msk; 00273 NRF_GPIO->PIN_CNF[pin_no] |= sense; 00274 } 00275 } 00276 00277 return NRF_SUCCESS; 00278 } 00279 00280 00281 uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id) 00282 { 00283 // Check state and parameters. 00284 if (mp_users == NULL) 00285 { 00286 return NRF_ERROR_INVALID_STATE; 00287 } 00288 if (user_id >= m_user_count) 00289 { 00290 return NRF_ERROR_INVALID_PARAM; 00291 } 00292 00293 // Disable sensing for all pins for specified user. 00294 pins_sense_disable(user_id); 00295 00296 // Disable user. 00297 m_enabled_users_mask &= ~(1UL << user_id); 00298 if (m_enabled_users_mask == 0) 00299 { 00300 NRF_GPIOTE->INTENCLR = GPIOTE_INTENSET_PORT_Msk; 00301 } 00302 00303 return NRF_SUCCESS; 00304 } 00305 00306 00307 uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins) 00308 { 00309 gpiote_user_t * p_user; 00310 00311 // Check state and parameters. 00312 if (mp_users == NULL) 00313 { 00314 return NRF_ERROR_INVALID_STATE; 00315 } 00316 if (user_id >= m_user_count) 00317 { 00318 return NRF_ERROR_INVALID_PARAM; 00319 } 00320 00321 // Get pins. 00322 p_user = &mp_users[user_id]; 00323 *p_pins = NRF_GPIO->IN & p_user->pins_mask; 00324 00325 return NRF_SUCCESS; 00326 } 00327 00328 #if defined(SVCALL_AS_NORMAL_FUNCTION) || defined(SER_CONNECTIVITY) 00329 uint32_t app_gpiote_input_event_handler_register(const uint8_t channel, 00330 const uint32_t pin, 00331 const uint32_t polarity, 00332 app_gpiote_input_event_handler_t event_handler) 00333 { 00334 (void)sense_level_toggle(NULL, pin); 00335 return NRF_ERROR_NOT_SUPPORTED; 00336 } 00337 00338 uint32_t app_gpiote_input_event_handler_unregister(const uint8_t channel) 00339 { 00340 return NRF_ERROR_NOT_SUPPORTED; 00341 } 00342 00343 uint32_t app_gpiote_end_irq_event_handler_register(app_gpiote_input_event_handler_t event_handler) 00344 { 00345 return NRF_ERROR_NOT_SUPPORTED; 00346 } 00347 00348 uint32_t app_gpiote_end_irq_event_handler_unregister(void) 00349 { 00350 return NRF_ERROR_NOT_SUPPORTED; 00351 } 00352 00353 uint32_t app_gpiote_enable_interrupts(void) 00354 { 00355 return NRF_ERROR_NOT_SUPPORTED; 00356 } 00357 00358 uint32_t app_gpiote_disable_interrupts(void) 00359 { 00360 return NRF_ERROR_NOT_SUPPORTED; 00361 } 00362 #endif // SVCALL_AS_NORMAL_FUNCTION || SER_CONNECTIVITY 00363 00364 #endif // #if NEED_APP_GPIOTE
Generated on Tue Jul 12 2022 18:33:08 by 1.7.2