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