test

Fork of nRF51822 by Nordic Semiconductor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers softdevice_handler.c Source File

softdevice_handler.c

00001 /*
00002  * Copyright (c) Nordic Semiconductor ASA
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without modification,
00006  * are permitted provided that the following conditions are met:
00007  *
00008  *   1. Redistributions of source code must retain the above copyright notice, this
00009  *   list of conditions and the following disclaimer.
00010  *
00011  *   2. Redistributions in binary form must reproduce the above copyright notice, this
00012  *   list of conditions and the following disclaimer in the documentation and/or
00013  *   other materials provided with the distribution.
00014  *
00015  *   3. Neither the name of Nordic Semiconductor ASA nor the names of other
00016  *   contributors to this software may be used to endorse or promote products
00017  *   derived from this software without specific prior written permission.
00018  *
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00022  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00023  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00024  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00025  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00027  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  */
00032 
00033 #include "softdevice_handler.h "
00034 #include <stdlib.h>
00035 #include "nordic_common.h"
00036 #include "app_error.h"
00037 #include "app_util.h"
00038 #include "nrf_assert.h"
00039 #include "nrf_soc.h"
00040 
00041 #if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD)
00042     #include "ant_interface.h"
00043 #elif defined(ANT_STACK_SUPPORT_REQD) 
00044     #include "ant_interface.h"
00045 #elif defined(BLE_STACK_SUPPORT_REQD)
00046     #include "ble.h"
00047 #endif
00048 
00049 
00050 static softdevice_evt_schedule_func_t m_evt_schedule_func;              /**< Pointer to function for propagating SoftDevice events to the scheduler. */
00051 
00052 static volatile bool                  m_softdevice_enabled = false;     /**< Variable to indicate whether the SoftDevice is enabled. */
00053 
00054 #ifdef BLE_STACK_SUPPORT_REQD
00055 // The following three definitions is needed only if BLE events are needed to be pulled from the stack.
00056 static uint8_t                      * mp_ble_evt_buffer;                /**< Buffer for receiving BLE events from the SoftDevice. */
00057 static uint16_t                       m_ble_evt_buffer_size;            /**< Size of BLE event buffer. */
00058 static ble_evt_handler_t              m_ble_evt_handler;                /**< Application event handler for handling BLE events. */
00059 #endif
00060 
00061 #ifdef ANT_STACK_SUPPORT_REQD
00062 // The following two definition is needed only if ANT events are needed to be pulled from the stack.
00063 static ant_evt_t                      m_ant_evt_buffer;                 /**< Buffer for receiving ANT events from the SoftDevice. */
00064 static ant_evt_handler_t              m_ant_evt_handler;                /**< Application event handler for handling ANT events.  */
00065 #endif
00066 
00067 static sys_evt_handler_t              m_sys_evt_handler;                /**< Application event handler for handling System (SOC) events.  */
00068 
00069 
00070 /**@brief       Callback function for asserts in the SoftDevice.
00071  *
00072  * @details     A pointer to this function will be passed to the SoftDevice. This function will be
00073  *              called if an ASSERT statement in the SoftDevice fails.
00074  *
00075  * @param[in]   pc         The value of the program counter when the ASSERT call failed.
00076  * @param[in]   line_num   Line number of the failing ASSERT call.
00077  * @param[in]   file_name  File name of the failing ASSERT call.
00078  */
00079 void softdevice_assertion_handler(uint32_t pc, uint16_t line_num, const uint8_t * file_name)
00080 {
00081     UNUSED_PARAMETER(pc);
00082     assert_nrf_callback(line_num, file_name);
00083 }
00084 
00085 
00086 void intern_softdevice_events_execute(void)
00087 {
00088     if (!m_softdevice_enabled)
00089     {
00090         // SoftDevice not enabled. This can be possible if the SoftDevice was enabled by the
00091         // application without using this module's API (i.e softdevice_handler_init)
00092 
00093         return;
00094     }
00095 
00096     bool no_more_soc_evts = (m_sys_evt_handler == NULL);
00097 #ifdef BLE_STACK_SUPPORT_REQD
00098     bool no_more_ble_evts = (m_ble_evt_handler == NULL);
00099 #endif
00100 #ifdef ANT_STACK_SUPPORT_REQD
00101     bool no_more_ant_evts = (m_ant_evt_handler == NULL);
00102 #endif
00103 
00104     for (;;)
00105     {
00106         uint32_t err_code;
00107 
00108         if (!no_more_soc_evts)
00109         {
00110             uint32_t evt_id;
00111 
00112             // Pull event from SOC.
00113             err_code = sd_evt_get(&evt_id);
00114             
00115             if (err_code == NRF_ERROR_NOT_FOUND)
00116             {
00117                 no_more_soc_evts = true;
00118             }
00119             else if (err_code != NRF_SUCCESS)
00120             {
00121                 APP_ERROR_HANDLER(err_code);
00122             }
00123             else
00124             {
00125                 // Call application's SOC event handler.
00126                 m_sys_evt_handler(evt_id);
00127             }
00128         }
00129 
00130 #ifdef BLE_STACK_SUPPORT_REQD
00131         // Fetch BLE Events.
00132         if (!no_more_ble_evts)
00133         {
00134             // Pull event from stack
00135             uint16_t evt_len = m_ble_evt_buffer_size;
00136 
00137             err_code = sd_ble_evt_get(mp_ble_evt_buffer, &evt_len);
00138             if (err_code == NRF_ERROR_NOT_FOUND)
00139             {
00140                 no_more_ble_evts = true;
00141             }
00142             else if (err_code != NRF_SUCCESS)
00143             {
00144                 APP_ERROR_HANDLER(err_code);
00145             }
00146             else
00147             {
00148                 // Call application's BLE stack event handler.
00149                 m_ble_evt_handler((ble_evt_t *)mp_ble_evt_buffer);
00150             }
00151         }
00152 #endif
00153 
00154 #ifdef ANT_STACK_SUPPORT_REQD
00155         // Fetch ANT Events.
00156         if (!no_more_ant_evts)
00157         {
00158             // Pull event from stack
00159             err_code = sd_ant_event_get(&m_ant_evt_buffer.channel,
00160                                         &m_ant_evt_buffer.event,
00161                                         m_ant_evt_buffer.evt_buffer);
00162             if (err_code == NRF_ERROR_NOT_FOUND)
00163             {
00164                 no_more_ant_evts = true;
00165             }
00166             else if (err_code != NRF_SUCCESS)
00167             {
00168                 APP_ERROR_HANDLER(err_code);
00169             }
00170             else
00171             {
00172                 // Call application's ANT stack event handler.
00173                 m_ant_evt_handler(&m_ant_evt_buffer);
00174             }
00175         }
00176 #endif
00177 
00178         if (no_more_soc_evts)
00179         {
00180             // There are no remaining System (SOC) events to be fetched from the SoftDevice.
00181 #if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD)
00182             // Check if there are any remaining BLE and ANT events.
00183             if (no_more_ble_evts && no_more_ant_evts)
00184             {
00185                 break;
00186             }
00187 #elif defined(BLE_STACK_SUPPORT_REQD)
00188             // Check if there are any remaining BLE events.
00189             if (no_more_ble_evts)
00190             {
00191                 break;
00192             }
00193 #elif defined(ANT_STACK_SUPPORT_REQD)
00194             // Check if there are any remaining ANT events.
00195             if (no_more_ant_evts)
00196             {
00197                 break;
00198             }
00199 #else
00200             // No need to check for BLE or ANT events since there is no support for BLE and ANT
00201             // required.
00202             break;
00203 #endif
00204         }
00205     }
00206 }
00207 
00208 
00209 uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t           clock_source,
00210                                  void *                         p_ble_evt_buffer,
00211                                  uint16_t                       ble_evt_buffer_size,
00212                                  softdevice_evt_schedule_func_t evt_schedule_func)
00213 {
00214     uint32_t err_code;
00215 
00216     // Save configuration.
00217 #if defined (BLE_STACK_SUPPORT_REQD)
00218     // Check that buffer is not NULL.
00219     if (p_ble_evt_buffer == NULL)
00220     {
00221         return NRF_ERROR_INVALID_PARAM;
00222     }
00223     
00224     // Check that buffer is correctly aligned.
00225     if (!is_word_aligned(p_ble_evt_buffer))
00226     {
00227         return NRF_ERROR_INVALID_PARAM;
00228     }
00229 
00230     mp_ble_evt_buffer     = (uint8_t *)p_ble_evt_buffer;
00231     m_ble_evt_buffer_size = ble_evt_buffer_size;
00232 #else
00233     // The variables p_ble_evt_buffer and ble_evt_buffer_size is not needed if BLE Stack support
00234     // is not required.
00235     UNUSED_PARAMETER(p_ble_evt_buffer);
00236     UNUSED_PARAMETER(ble_evt_buffer_size);
00237 #endif
00238 
00239     m_evt_schedule_func = evt_schedule_func;
00240 
00241     // Initialize SoftDevice.
00242     err_code = sd_softdevice_enable(clock_source, softdevice_assertion_handler);
00243     if (err_code != NRF_SUCCESS)
00244     {
00245         return err_code;
00246     }
00247 
00248     m_softdevice_enabled = true;
00249 
00250     // Enable BLE event interrupt (interrupt priority has already been set by the stack).
00251     return sd_nvic_EnableIRQ(SWI2_IRQn );
00252 }
00253 
00254 
00255 uint32_t softdevice_handler_sd_disable(void)
00256 {
00257     uint32_t err_code = sd_softdevice_disable();
00258  
00259     m_softdevice_enabled = !(err_code == NRF_SUCCESS);
00260 
00261     return err_code;
00262 }
00263 
00264 
00265 #ifdef BLE_STACK_SUPPORT_REQD
00266 uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler)
00267 {
00268     if (ble_evt_handler == NULL)
00269     {
00270         return NRF_ERROR_NULL;
00271     }
00272 
00273     m_ble_evt_handler = ble_evt_handler;
00274 
00275     return NRF_SUCCESS;
00276 }
00277 #endif
00278 
00279 
00280 #ifdef ANT_STACK_SUPPORT_REQD
00281 uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler)
00282 {
00283     if (ant_evt_handler == NULL)
00284     {
00285         return NRF_ERROR_NULL;
00286     }
00287 
00288     m_ant_evt_handler = ant_evt_handler;
00289 
00290     return NRF_SUCCESS;
00291 }
00292 #endif
00293 
00294 
00295 uint32_t softdevice_sys_evt_handler_set(sys_evt_handler_t sys_evt_handler)
00296 {
00297     if (sys_evt_handler == NULL)
00298     {
00299         return NRF_ERROR_NULL;
00300     }
00301 
00302     m_sys_evt_handler = sys_evt_handler;
00303 
00304     return NRF_SUCCESS;
00305 }
00306 
00307 
00308 /**@brief   Function for handling the Application's BLE Stack events interrupt.
00309  *
00310  * @details This function is called whenever an event is ready to be pulled.
00311  */
00312 void SWI2_IRQHandler(void)
00313 {
00314     if (m_evt_schedule_func != NULL)
00315     {
00316         uint32_t err_code = m_evt_schedule_func();
00317         APP_ERROR_CHECK(err_code);
00318     }
00319     else
00320     {
00321         intern_softdevice_events_execute();
00322     }
00323 }