konashi/SBBLEのテスト

Dependencies:   BLE_API mbed

Fork of BLE_LoopbackUART by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers app_gpiote.c Source File

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