Beispiel #1
0
uint32_t pstorage_store(pstorage_handle_t * p_dest,
                        uint8_t           * p_src,
                        pstorage_size_t     size,
                        pstorage_size_t     offset)
{
    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_src);
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK(p_dest);
    BLOCK_ID_RANGE_CHECK(p_dest);
    SIZE_CHECK(p_dest, size);
    OFFSET_CHECK(p_dest, offset,size);

    // Verify word alignment.
    if ((!is_word_aligned(p_src)) || (!is_word_aligned((void *)(uint32_t)offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    if ((!is_word_aligned((uint32_t *)p_dest->block_id)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset);
}
Beispiel #2
0
uint32_t pstorage_load(uint8_t *           p_dest,
                       pstorage_handle_t * p_src,
                       pstorage_size_t     size,
                       pstorage_size_t     offset)
{
    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_src);
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK (p_src);
    BLOCK_ID_RANGE_CHECK(p_src);
    SIZE_CHECK(p_src,size);
    OFFSET_CHECK(p_src,offset,size);

    // Verify word alignment.
    if ((!is_word_aligned(p_dest)) || (!is_word_aligned((void *)(uint32_t)offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    memcpy(p_dest, (((uint8_t *)p_src->block_id) + offset), size);

    app_notify(p_src, p_dest, PSTORAGE_LOAD_OP_CODE, size, NRF_SUCCESS);

    return NRF_SUCCESS;
}
Beispiel #3
0
uint32_t pstorage_store(pstorage_handle_t * p_dest,
                        uint8_t           * p_src,
                        pstorage_size_t     size,
                        pstorage_size_t     offset)
{
    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_src);
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK(p_dest);
    BLOCK_ID_RANGE_CHECK(p_dest);
    SIZE_CHECK(p_dest, size);
    OFFSET_CHECK(p_dest, offset, size);

    // Verify word alignment.
    if ((!is_word_aligned(p_src)) || (!is_word_aligned((void *)(uint32_t)offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    uint32_t storage_addr = p_dest->block_id + offset;

    uint32_t retval = ble_flash_block_write((uint32_t *)storage_addr,
                                            (uint32_t *)p_src,
                                            (size /sizeof(uint32_t)));

    app_notify(p_dest, p_src, PSTORAGE_STORE_OP_CODE, size, retval);
    
    return retval;
}
Beispiel #4
0
uint32_t pstorage_store(pstorage_handle_t * p_dest,
                        uint8_t           * p_src,
                        pstorage_size_t     size,
                        pstorage_size_t     offset)
{
    // Verify word alignment.
    if ((!is_word_aligned(p_src)) || (!is_word_aligned(p_src+offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset);
}
uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer)
{
    if (p_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    // Check that buffer is correctly aligned.
    if (!is_word_aligned(p_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    
    // Initialize file globals.
    mp_users             = (gpiote_user_t *)p_buffer;
    m_user_array_size    = max_users;
    m_user_count         = 0;
    m_enabled_users_mask = 0;
    
    memset(mp_users, 0, m_user_array_size * sizeof(gpiote_user_t));
    
    // Initialize GPIOTE interrupt (will not be enabled until app_gpiote_user_enable() is called).
    NRF_GPIOTE->INTENCLR = 0xFFFFFFFF;
    
    NVIC_ClearPendingIRQ(GPIOTE_IRQn);
    NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
    NVIC_EnableIRQ(GPIOTE_IRQn);
    
    return NRF_SUCCESS;
}
Beispiel #6
0
ret_code_t fs_store(fs_config_t const *       p_config,
                    uint32_t    const *       p_addr,
                    uint32_t    const * const p_data,
                    fs_length_t               length_words)
{
    if ((m_flags & FS_FLAG_INIT) == 0)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    if (!check_config(p_config))
    {
        return NRF_ERROR_FORBIDDEN;
    }

    if (!is_word_aligned(p_addr))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    // Check that the erase operation is on pages owned by this user (configuration).
    if ((p_addr < p_config->p_start_addr) || ((p_addr + length_words) > p_config->p_end_addr))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    return cmd_enqueue(p_config, FS_OP_STORE, p_addr, p_data, length_words);
}
uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer)
{
    if (p_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    //Check that buffer is correctly aligned.
    if (!is_word_aligned(p_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    //Initialize file globals.
    mp_users             = (gpiote_user_t *)p_buffer;
    m_user_array_size    = max_users;
    m_user_count         = 0;
    m_enabled_users_mask = 0;

    memset(mp_users, 0, m_user_array_size * sizeof (gpiote_user_t));

    (void)app_gpiote_enable_interrupts();

    return NRF_SUCCESS;
}
Beispiel #8
0
uint32_t pstorage_clear(pstorage_handle_t * p_dest, pstorage_size_t size)
{
    uint32_t retval;

    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK(p_dest);
    BLOCK_ID_RANGE_CHECK(p_dest);

    if ((!is_word_aligned((uint32_t *)p_dest->block_id)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    if (
        !(
            ((p_dest->block_id - m_app_table[p_dest->module_id].base_id) %
             m_app_table[p_dest->module_id].block_size) == 0
            )
        )
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    retval = cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL, size, 0);

    return retval;
}
Beispiel #9
0
uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer)
{
    uint32_t ret_code = NRF_SUCCESS;

    if (p_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    // Check that buffer is correctly aligned.
    if (!is_word_aligned(p_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    // Initialize file globals.
    mp_users             = (gpiote_user_t *)p_buffer;
    m_user_array_size    = max_users;
    m_user_count         = 0;
    m_pins              = 0;

    memset(mp_users, 0, m_user_array_size * sizeof(gpiote_user_t));

    if (nrf_drv_gpiote_is_init()==false)
    {
        ret_code = nrf_drv_gpiote_init();
    }

    return ret_code;
}
Beispiel #10
0
uint32_t app_timer_init(uint32_t                      prescaler,
                        uint8_t                       op_queues_size,
                        void *                        p_buffer,
                        app_timer_evt_schedule_func_t evt_schedule_func)
{
    int i;

    // Check that buffer is correctly aligned
    if (!is_word_aligned(p_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    // Check for NULL buffer
    if (p_buffer == NULL)
    {
        mp_users = NULL;
        return NRF_ERROR_INVALID_PARAM;
    }
    
    // Stop RTC to prevent any running timers from expiring (in case of reinitialization)
    rtc1_stop();
    
    m_evt_schedule_func = evt_schedule_func;
    
    // Initialize users array
    m_user_array_size = APP_TIMER_INT_LEVELS;
    mp_users          = p_buffer;
    
    // Skip user array
    p_buffer = &((uint8_t *)p_buffer)[APP_TIMER_INT_LEVELS * sizeof(timer_user_t)];

    // Initialize operation queues
    for (i = 0; i < APP_TIMER_INT_LEVELS; i++)
    {
        timer_user_t * p_user = &mp_users[i];
        
        p_user->first              = 0;
        p_user->last               = 0;
        p_user->user_op_queue_size = op_queues_size;
        p_user->p_user_op_queue    = p_buffer;
    
        // Skip operation queue
        p_buffer = &((uint8_t *)p_buffer)[op_queues_size * sizeof(timer_user_op_t)];
    }

    mp_timer_id_head             = NULL;
    m_ticks_elapsed_q_read_ind  = 0;
    m_ticks_elapsed_q_write_ind = 0;

    NVIC_ClearPendingIRQ(SWI_IRQn);
    NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI);
    NVIC_EnableIRQ(SWI_IRQn);

    rtc1_init(prescaler);

    m_ticks_latest = rtc1_counter_get();
    
    return NRF_SUCCESS;
}
Beispiel #11
0
/**
 * @brief API to store data persistently.
 */
uint32_t pstorage_raw_store(pstorage_handle_t * p_dest,
                            uint8_t           * p_src,
                            uint32_t            size,
                            uint32_t            offset)
{
    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_src);
    NULL_PARAM_CHECK(p_dest);
    MODULE_RAW_ID_RANGE_CHECK(p_dest);

    // Verify word alignment.
    if ((!is_word_aligned(p_src)) || (!is_word_aligned(p_src+offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset);
}
Beispiel #12
0
uint32_t softdevice_handler_init(nrf_clock_lf_cfg_t	*           p_clock_lf_cfg,
                                 void *                         p_ble_evt_buffer,
                                 uint16_t                       ble_evt_buffer_size,
                                 softdevice_evt_schedule_func_t evt_schedule_func)
{
    uint32_t err_code;

    SD_HANDLER_LOG_INIT();

    // Save configuration.
#if defined (BLE_STACK_SUPPORT_REQD)
    // Check that buffer is not NULL.
    if (p_ble_evt_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    // Check that buffer is correctly aligned.
    if (!is_word_aligned(p_ble_evt_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    mp_ble_evt_buffer     = (uint8_t *)p_ble_evt_buffer;
    m_ble_evt_buffer_size = ble_evt_buffer_size;
#else
    // The variables p_ble_evt_buffer and ble_evt_buffer_size is not needed if BLE Stack support
    // is not required.
    UNUSED_PARAMETER(p_ble_evt_buffer);
    UNUSED_PARAMETER(ble_evt_buffer_size);
#endif

    m_evt_schedule_func = evt_schedule_func;

    // Initialize SoftDevice.
#if defined(S212) || defined(S332)
    err_code = sd_softdevice_enable(p_clock_lf_cfg, softdevice_fault_handler, ANT_LICENSE_KEY);
#else
    err_code = sd_softdevice_enable(p_clock_lf_cfg, softdevice_fault_handler);
#endif
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    m_softdevice_enabled = true;

    // Enable BLE event interrupt (interrupt priority has already been set by the stack).
#ifdef SOFTDEVICE_PRESENT
    return sd_nvic_EnableIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ);
#else
    //In case of Serialization NVIC must be accessed directly.
    NVIC_EnableIRQ(SOFTDEVICE_EVT_IRQ);
    return NRF_SUCCESS;
#endif
}
uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t           clock_source,
                                 void *                         p_ble_evt_buffer,
                                 uint16_t                       ble_evt_buffer_size,
                                 softdevice_evt_schedule_func_t evt_schedule_func)
{
    uint32_t err_code;

    // Save configuration.
#if defined (BLE_STACK_SUPPORT_REQD)
    // Check that buffer is not NULL.
    if (p_ble_evt_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    
    // Check that buffer is correctly aligned.
    if (!is_word_aligned(p_ble_evt_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    mp_ble_evt_buffer     = (uint8_t *)p_ble_evt_buffer;
    m_ble_evt_buffer_size = ble_evt_buffer_size;
#else
    // The variables p_ble_evt_buffer and ble_evt_buffer_size is not needed if BLE Stack support
    // is not required.
    UNUSED_PARAMETER(p_ble_evt_buffer);
    UNUSED_PARAMETER(ble_evt_buffer_size);
#endif

    m_evt_schedule_func = evt_schedule_func;

//Enabling FPU for SoftDevice
#ifdef S132
    SCB->CPACR |= (3UL << 20) | (3UL << 22);
    __DSB();
    __ISB();
#endif
    // Initialize SoftDevice.
    err_code = sd_softdevice_enable(clock_source, softdevice_assertion_handler);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
#ifdef S132
    SCB->CPACR = 0;
    __DSB();
    __ISB();
#endif

    m_softdevice_enabled = true;

    // Enable BLE event interrupt (interrupt priority has already been set by the stack).
    return sd_nvic_EnableIRQ(SOFTDEVICE_EVT_IRQ);
}
Beispiel #14
0
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
{
    uint32_t  err_code;
    uint32_t  data_length;
    uint8_t * p_data;
    
    if (p_packet == NULL)
    {
        return NRF_ERROR_NULL;
    }

    // Check pointer alignment.
    if (!is_word_aligned(p_packet->p_data_packet))
    {
        // The p_data_packet is not word aligned address.
        return NRF_ERROR_INVALID_ADDR;
    }

    switch (m_dfu_state)
    {
        case DFU_STATE_RDY:
            // Fall-through.
        
        case DFU_STATE_RX_INIT_PKT:
            m_dfu_state = DFU_STATE_RX_DATA_PKT;
        
            // Fall-through.
        
        case DFU_STATE_RX_DATA_PKT:
            data_length = p_packet->packet_length  * sizeof(uint32_t);
            if ((uint32_t)(m_received_data + data_length) > m_image_size)
            {
                // The caller is trying to write more bytes into the flash than the size provided to 
                // the dfu_image_size_set function.
                return NRF_ERROR_DATA_SIZE;
            }

            p_data   = (uint8_t *)p_packet->p_data_packet;            
            err_code = pstorage_raw_store(&m_storage_handle_app, p_data, data_length, m_received_data);
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }
            m_received_data += data_length;        
            
            break;
            
        default:
            err_code = NRF_ERROR_INVALID_STATE;
            break;
    }
    
    return err_code;
}
Beispiel #15
0
void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
  assert(mr.word_size() > 0, "Error");
  assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned");
  // mr.end() may not necessarily be card aligned.
  jbyte* cur_entry = _ct->byte_for(mr.last());
  const jbyte* limit = _ct->byte_for(mr.start());
  HeapWord* end_of_non_clean = mr.end();
  HeapWord* start_of_non_clean = end_of_non_clean;
  while (cur_entry >= limit) {
    HeapWord* cur_hw = _ct->addr_for(cur_entry);
    if ((*cur_entry != CardTableRS::clean_card_val()) && clear_card(cur_entry)) {
      // Continue the dirty range by opening the
      // dirty window one card to the left.
      start_of_non_clean = cur_hw;
    } else {
      // We hit a "clean" card; process any non-empty
      // "dirty" range accumulated so far.
      if (start_of_non_clean < end_of_non_clean) {
        const MemRegion mrd(start_of_non_clean, end_of_non_clean);
        _dirty_card_closure->do_MemRegion(mrd);
      }

      // fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
      if (is_word_aligned(cur_entry)) {
        jbyte* cur_row = cur_entry - BytesPerWord;
        while (cur_row >= limit && *((intptr_t*)cur_row) ==  CardTableRS::clean_card_row()) {
          cur_row -= BytesPerWord;
        }
        cur_entry = cur_row + BytesPerWord;
        cur_hw = _ct->addr_for(cur_entry);
      }

      // Reset the dirty window, while continuing to look
      // for the next dirty card that will start a
      // new dirty window.
      end_of_non_clean = cur_hw;
      start_of_non_clean = cur_hw;
    }
    // Note that "cur_entry" leads "start_of_non_clean" in
    // its leftward excursion after this point
    // in the loop and, when we hit the left end of "mr",
    // will point off of the left end of the card-table
    // for "mr".
    cur_entry--;
  }
  // If the first card of "mr" was dirty, we will have
  // been left with a dirty window, co-initial with "mr",
  // which we now process.
  if (start_of_non_clean < end_of_non_clean) {
    const MemRegion mrd(start_of_non_clean, end_of_non_clean);
    _dirty_card_closure->do_MemRegion(mrd);
  }
}
Beispiel #16
0
uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t           clock_source,
                                 void *                         p_evt_buffer,
                                 uint16_t                       evt_buffer_size,
                                 softdevice_evt_schedule_func_t evt_schedule_func)
{
    uint32_t err_code;

    // Save configuration.
#if defined (BLE_STACK_SUPPORT_REQD) || defined (ANT_STACK_SUPPORT_REQD)
    // Check that buffer is not NULL.
    if (p_evt_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    // Check that buffer is correctly aligned.
    if (!is_word_aligned(p_evt_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    m_evt_buffer = (uint8_t *)p_evt_buffer;
#else
    // The variable p_evt_buffer is not needed if neither BLE Stack nor ANT stack support is
    // required.
    UNUSED_PARAMETER(p_evt_buffer);
#endif

#if defined (BLE_STACK_SUPPORT_REQD)
    m_ble_evt_buffer_size = evt_buffer_size;
#else
    // The variable evt_buffer_size is not needed if BLE Stack support is NOT required.
    UNUSED_PARAMETER(evt_buffer_size);
#endif

    m_evt_schedule_func = evt_schedule_func;

    // Initialize SoftDevice.

    err_code = sd_softdevice_enable(clock_source, softdevice_assertion_handler);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    m_softdevice_enabled = true;

    // Enable BLE event interrupt (interrupt priority has already been set by the stack).
    return sd_nvic_EnableIRQ(SWI2_IRQn);
}
Beispiel #17
0
uint32_t app_timer_init(uint32_t                      prescaler,
                        uint8_t                       op_queue_size,
                        void *                        p_buffer,
                        app_timer_evt_schedule_func_t evt_schedule_func)
{
    // Check that buffer is correctly aligned
    if (!is_word_aligned(p_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    // Check for NULL buffer
    if (p_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    // Stop RTC to prevent any running timers from expiring (in case of reinitialization)
    rtc1_stop();

    m_evt_schedule_func = evt_schedule_func;

    // Initialize operation queue
    m_op_queue.first           = 0;
    m_op_queue.last            = 0;
    m_op_queue.size            = op_queue_size;
    m_op_queue.p_user_op_queue = p_buffer;

    mp_timer_id_head            = NULL;
    m_ticks_elapsed_q_read_ind  = 0;
    m_ticks_elapsed_q_write_ind = 0;

#if APP_TIMER_WITH_PROFILER
    m_max_user_op_queue_utilization   = 0;
#endif

    NVIC_ClearPendingIRQ(SWI_IRQn);
    NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI);
    NVIC_EnableIRQ(SWI_IRQn);

    rtc1_init(prescaler);

    m_ticks_latest = rtc1_counter_get();

    return NRF_SUCCESS;
}
uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer)
{
    uint16_t data_start_index = (queue_size + 1) * sizeof(event_header_t);

    // Check that buffer is correctly aligned
    if (!is_word_aligned(p_event_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    // Initialize event scheduler
    m_queue_event_headers = (event_header_t*)p_event_buffer;
    m_queue_event_data    = &((uint8_t *)p_event_buffer)[data_start_index];
    m_queue_end_index     = 0;
    m_queue_start_index   = 0;
    m_queue_event_size    = event_size;
    m_queue_size          = queue_size;

    return NRF_SUCCESS;
}
Beispiel #19
0
uint32_t app_timer_init(uint32_t                      prescaler,
                        uint8_t                       max_timers,
                        uint8_t                       op_queues_size,
                        void *                        p_buffer,
                        app_timer_evt_schedule_func_t evt_schedule_func)
{
    int i;

    // Check that buffer is correctly aligned
    if (!is_word_aligned(p_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    // Check for NULL buffer
    if (p_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    
    // Stop RTC to prevent any running timers from expiring (in case of reinitialization)
    rtc1_stop();
    
    m_evt_schedule_func = evt_schedule_func;

    // Initialize timer node array
    m_node_array_size = max_timers;
    mp_nodes          = p_buffer;
    
    for (i = 0; i < max_timers; i++)
    {
        mp_nodes[i].state      = STATE_FREE;
        mp_nodes[i].is_running = false;
    }
    
    // Skip timer node array
    p_buffer = &((uint8_t *)p_buffer)[max_timers * sizeof(timer_node_t)];
    
    // Initialize users array
    m_user_array_size = APP_TIMER_INT_LEVELS;
    mp_users          = p_buffer;
    
    // Skip user array
    p_buffer = &((uint8_t *)p_buffer)[APP_TIMER_INT_LEVELS * sizeof(timer_user_t)];

    // Initialize operation queues
    for (i = 0; i < APP_TIMER_INT_LEVELS; i++)
    {
        timer_user_t * p_user = &mp_users[i];
        
        p_user->first              = 0;
        p_user->last               = 0;
        p_user->user_op_queue_size = op_queues_size;
        p_user->p_user_op_queue    = p_buffer;
    
        // Skip operation queue
        p_buffer = &((uint8_t *)p_buffer)[op_queues_size * sizeof(timer_user_op_t)];
    }

    m_timer_id_head             = TIMER_NULL;
    m_ticks_elapsed_q_read_ind  = 0;
    m_ticks_elapsed_q_write_ind = 0;

		/*
    NVIC_ClearPendingIRQ(SWI0_IRQn);
    NVIC_SetPriority(SWI0_IRQn, SWI0_IRQ_PRI);
    NVIC_EnableIRQ(SWI0_IRQn);
		*/
		
		
		/*--khai-- : temporarily use SWI1 for app_timer so that conflict with event_handler won't occur*/
    NVIC_ClearPendingIRQ(SWI1_IRQn);
    NVIC_SetPriority(SWI1_IRQn, SWI0_IRQ_PRI);
    NVIC_EnableIRQ(SWI1_IRQn);
		
    rtc1_init(prescaler);

    m_ticks_latest = rtc1_counter_get();
    
    return NRF_SUCCESS;
}
Beispiel #20
0
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
{
    uint32_t   data_length;
    uint32_t   err_code;
    uint32_t * p_data;

    if (p_packet == NULL)
    {
        return NRF_ERROR_NULL;
    }

    // Check pointer alignment.
    if (!is_word_aligned(p_packet->params.data_packet.p_data_packet))
    {
        // The p_data_packet is not word aligned address.
        return NRF_ERROR_INVALID_ADDR;
    }

    switch (m_dfu_state)
    {
        case DFU_STATE_RDY:
        case DFU_STATE_RX_INIT_PKT:
            return NRF_ERROR_INVALID_STATE;

        case DFU_STATE_RX_DATA_PKT:
            data_length = p_packet->params.data_packet.packet_length * sizeof(uint32_t);

            if ((m_data_received + data_length) > m_image_size)
            {
                // The caller is trying to write more bytes into the flash than the size provided to
                // the dfu_image_size_set function. This is treated as a serious error condition and
                // an unrecoverable one. Hence point the variable mp_app_write_address to the top of
                // the flash area. This will ensure that all future application data packet writes
                // will be blocked because of the above check.
                m_data_received = 0xFFFFFFFF;

                return NRF_ERROR_DATA_SIZE;
            }

            // Valid peer activity detected. Hence restart the DFU timer.
            err_code = dfu_timer_restart();
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }

            p_data = (uint32_t *)p_packet->params.data_packet.p_data_packet;

            err_code = pstorage_store(mp_storage_handle_active,
                                          (uint8_t *)p_data,
                                          data_length,
                                          m_data_received);
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }

            m_data_received += data_length;

            if (m_data_received != m_image_size)
            {
                // The entire image is not received yet. More data is expected.
                err_code = NRF_ERROR_INVALID_LENGTH;
            }
            else
            {
                // The entire image has been received. Return NRF_SUCCESS.
                err_code = NRF_SUCCESS;
            }
            break;

        default:
            err_code = NRF_ERROR_INVALID_STATE;
            break;
    }

    return err_code;
}
uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t           clock_source,
                                 void *                         p_evt_buffer,
                                 uint16_t                       evt_buffer_size,
                                 softdevice_evt_schedule_func_t evt_schedule_func)
{
    uint32_t err_code;

    // Save configuration.
#if defined (BLE_STACK_SUPPORT_REQD) || defined (ANT_STACK_SUPPORT_REQD)
    // Check that buffer is not NULL.
    if (p_evt_buffer == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    // Check that buffer is correctly aligned.
    if (!is_word_aligned(p_evt_buffer))
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    m_evt_buffer = (uint8_t *)p_evt_buffer;
#else
    // The variable p_evt_buffer is not needed if neither BLE Stack nor ANT stack support is
    // required.
    UNUSED_PARAMETER(p_evt_buffer);
#endif

#if defined (BLE_STACK_SUPPORT_REQD)
    m_ble_evt_buffer_size = evt_buffer_size;
#else
    // The variable evt_buffer_size is not needed if BLE Stack support is NOT required.
    UNUSED_PARAMETER(evt_buffer_size);
#endif

    m_evt_schedule_func = evt_schedule_func;

    // Initialize SoftDevice.

    err_code = sd_softdevice_enable(clock_source, softdevice_assertion_handler);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    /**
     * Using this call, the application can select whether to include the
     * Service Changed characteristic in the GATT Server. The default in all
     * previous releases has been to include the Service Changed characteristic,
     * but this affects how GATT clients behave. Specifically, it requires
     * clients to subscribe to this attribute and not to cache attribute handles
     * between connections unless the devices are bonded. If the application
     * does not need to change the structure of the GATT server attributes at
     * runtime this adds unnecessary complexity to the interaction with peer
     * clients. If the SoftDevice is enabled with the Service Changed
     * Characteristics turned off, then clients are allowed to cache attribute
     * handles making applications simpler on both sides.
     */
    ble_enable_params_t enableParams = {
        .gatts_enable_params = {
            .service_changed = 0
        }
    };
    if ((err_code = sd_ble_enable(&enableParams)) != NRF_SUCCESS) {
        return err_code;
    }

    ble_gap_addr_t addr;
    if ((err_code = sd_ble_gap_address_get(&addr)) != NRF_SUCCESS) {
        return err_code;
    }
    if ((err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr)) != NRF_SUCCESS) {
        return err_code;
    }

    m_softdevice_enabled = true;
    // Enable BLE event interrupt (interrupt priority has already been set by the stack).
    return sd_nvic_EnableIRQ(SWI2_IRQn);
}
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
{
    uint32_t   data_length;
    uint32_t   err_code;
    uint32_t * p_data;

    VERIFY_PARAM_NOT_NULL(p_packet);

    // Check pointer alignment.
    if (!is_word_aligned(p_packet->params.data_packet.p_data_packet))
    {
        // The p_data_packet is not word aligned address.
        return NRF_ERROR_INVALID_ADDR;
    }

    switch (m_dfu_state)
    {
        case DFU_STATE_RDY:
        case DFU_STATE_RX_INIT_PKT:
            return NRF_ERROR_INVALID_STATE;

        case DFU_STATE_RX_DATA_PKT:
            data_length = p_packet->params.data_packet.packet_length * sizeof(uint32_t);

            if ((m_data_received + data_length) > m_image_size)
            {
                // The caller is trying to write more bytes into the flash than the size provided to
                // the dfu_image_size_set function. This is treated as a serious error condition and
                // an unrecoverable one. Hence point the variable mp_app_write_address to the top of
                // the flash area. This will ensure that all future application data packet writes
                // will be blocked because of the above check.
                m_data_received = 0xFFFFFFFF;

                return NRF_ERROR_DATA_SIZE;
            }

            // Valid peer activity detected. Hence restart the DFU timer.
            err_code = dfu_timer_restart();
            VERIFY_SUCCESS(err_code);

            p_data = (uint32_t *)p_packet->params.data_packet.p_data_packet;

            // Do AES Decrption.
            dfu_aes_128_ofb_decrypt(p_data, data_length/sizeof(uint32_t), m_data_received);

            // Check the protected data before copying it and make sure its retain or update the data.
            uint32_t bootloader_position = m_data_received - m_start_packet.sd_image_size;
    	    for (int w = 0; w < data_length/sizeof(uint32_t); w++)
    	    {
    			bootloader_position = bootloader_position + 4;
    			if(m_start_packet.bl_image_size > 0 && (m_data_received > m_start_packet.sd_image_size) && (bootloader_position >= ((uint32_t)(&__start_protected_data) - m_uicr_bootloader_start_address)))
    			{
    				if(p_data[w] == 0x00000000)
    				{
    					p_data[w] = 0xFFFFFFFF;
    				}
    				else if(p_data[w] == 0xFFFFFFFF)
    				p_data[w] = (uint32_t)(*((uint32_t *)(bootloader_position - 4 + m_uicr_bootloader_start_address)));
    			}
    	    }
            err_code = pstorage_store(mp_storage_handle_active,
                                          (uint8_t *)p_data,
                                          data_length,
                                          m_data_received);
            VERIFY_SUCCESS(err_code);

            m_data_received += data_length;

            if (m_data_received != m_image_size)
            {
                // The entire image is not received yet. More data is expected.
                err_code = NRF_ERROR_INVALID_LENGTH;
            }
            else
            {
                // The entire image has been received. Return NRF_SUCCESS.
                err_code = NRF_SUCCESS;
            }
            break;

        default:
            err_code = NRF_ERROR_INVALID_STATE;
            break;
    }

    return err_code;
}
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
{
    uint32_t  err_code;
    uint32_t  data_length;
    uint8_t * p_data;

    if (p_packet == NULL)
    {
        return NRF_ERROR_NULL;
    }

    // Check pointer alignment.
    if (!is_word_aligned(p_packet->p_data_packet))
    {
        // The p_data_packet is not word aligned address.
        return NRF_ERROR_INVALID_ADDR;
    }

    switch (m_dfu_state)
    {
    case DFU_STATE_RDY:
    // Fall-through.

    case DFU_STATE_RX_INIT_PKT:
        m_dfu_state = DFU_STATE_RX_DATA_PKT;

    // Fall-through.

    case DFU_STATE_RX_DATA_PKT:
        data_length = p_packet->packet_length  * sizeof(uint32_t);
        if ((uint32_t)(m_received_data + data_length) > m_image_size)
        {
            // The caller is trying to write more bytes into the flash than the size provided to
            // the dfu_image_size_set function.
            return NRF_ERROR_DATA_SIZE;
        }

        p_data   = (uint8_t *)p_packet->p_data_packet;
        err_code = pstorage_raw_store(&m_storage_handle_app, p_data, data_length, m_received_data);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
        m_received_data += data_length;

        // SINGLEBANK PATCH: added so that it will return NRF_ERROR_INVALID_LENGTH instead of NRF_SUCCESS if the full image is not received.
        if (m_received_data != m_image_size)
        {
            // The entire image is not received yet. More data is expected.

            err_code = NRF_ERROR_INVALID_LENGTH;
        }
        else
        {
            // The entire image has been received. Return NRF_SUCCESS.

            err_code = NRF_SUCCESS;
        }
        //PATCH END
        break;

    default:
        err_code = NRF_ERROR_INVALID_STATE;
        break;
    }

    return err_code;
}
Beispiel #24
0
uint32_t pstorage_update(pstorage_handle_t * p_dest,
                        uint8_t           * p_src,
                        pstorage_size_t     size,
                        pstorage_size_t     offset)
{

    uint32_t *p_swap_addr = (uint32_t *)PSTORAGE_SWAP_ADDR;
    uint32_t *p_page_addr1 =  (uint32_t *) PAGE_BASE_ADDR(p_dest->block_id + offset);
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    uint32_t *p_page_addr2 =  (uint32_t *) PAGE_BASE_ADDR(p_dest->block_id + offset + size-1);
#endif
    uint16_t head_word_count =  offset/sizeof(uint32_t);
    uint16_t body_word_count =  size/sizeof(uint32_t);
    uint16_t tail_word_count;
    uint32_t retval;


	VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_src);
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK(p_dest);
    BLOCK_ID_RANGE_CHECK(p_dest);
    SIZE_CHECK(p_dest, size);
    OFFSET_CHECK(p_dest, offset, size);

    // Verify word alignment.
    if ((!is_word_aligned(p_src)) || (!is_word_aligned((void *)(uint32_t)offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }
    // erase swap page
    (void) ble_flash_page_erase(PSTORAGE_SWAP_ADDR / BLE_FLASH_PAGE_SIZE);
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    if (p_page_addr1 == p_page_addr2)
    {
#endif
    	// tail is in the same page as head
        tail_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - head_word_count - body_word_count;
    	// copy of the head
        if (head_word_count)
        {
        	retval = ble_flash_block_write(p_swap_addr, p_page_addr1, head_word_count );
        	if (retval != NRF_SUCCESS)
        	{
        		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
        		return retval;
        	}
        }
        // copy of the body
        retval = ble_flash_block_write(p_swap_addr+head_word_count, (uint32_t *)p_src, body_word_count);
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy of the tail
        if (tail_word_count)
        {
        	retval = ble_flash_block_write(p_swap_addr+head_word_count+body_word_count, p_page_addr1+head_word_count+body_word_count, tail_word_count );
        	if (retval != NRF_SUCCESS)
        	{
        		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
        		return retval;
        	}
        }
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr1 / BLE_FLASH_PAGE_SIZE);
        // restore updated page
        retval = ble_flash_block_write(p_page_addr1, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    }
    else
    {
    	// tail is in NOT in the same page as head - need to swap twice
    	uint16_t body1_word_count =  BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - head_word_count;
    	uint16_t body2_word_count =  body_word_count - body1_word_count;
        tail_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - body2_word_count;
        // copy head
        retval = ble_flash_block_write(p_swap_addr, p_page_addr1, head_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy body1
        retval = ble_flash_block_write(p_swap_addr, (uint32_t *)p_src, body1_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr1 / BLE_FLASH_PAGE_SIZE);
        // restore updated page1
        retval = ble_flash_block_write(p_page_addr1, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase swap page
        (void) ble_flash_page_erase(PSTORAGE_SWAP_ADDR / BLE_FLASH_PAGE_SIZE);
        // copy body2
        retval = ble_flash_block_write(p_swap_addr, (uint32_t *)p_src + body1_word_count, body2_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy tail
        retval = ble_flash_block_write(p_swap_addr, p_page_addr2+body2_word_count, tail_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr2 / BLE_FLASH_PAGE_SIZE);
        // restore updated page2
        retval = ble_flash_block_write(p_page_addr2, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
    }
#endif
    app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    return retval;

}