Ejemplo n.º 1
0
/**@brief Function for executing the state entry action.
 */
static __INLINE void state_entry_action_execute(void)
{
    spi_slave_evt_t event;
    
    switch (m_spi_state)
    {                             
        case SPI_BUFFER_RESOURCE_REQUESTED:
            NRF_SPIS1->TASKS_ACQUIRE = 1u;                                  
            break;            
     
        case SPI_BUFFER_RESOURCE_CONFIGURED:
            event.evt_type  = SPI_SLAVE_BUFFERS_SET_DONE;
            event.rx_amount = 0;
            event.tx_amount = 0;     
            
            APP_ERROR_CHECK_BOOL(m_event_callback != NULL);
            m_event_callback(event);         
            break;
            
        case SPI_XFER_COMPLETED:        
            event.evt_type  = SPI_SLAVE_XFER_DONE;
            event.rx_amount = NRF_SPIS1->AMOUNTRX;
            event.tx_amount = NRF_SPIS1->AMOUNTTX;
            
            APP_ERROR_CHECK_BOOL(m_event_callback != NULL);
            m_event_callback(event);
            break;
            
        default:
            // No implementation required.            
            break;
    }
}
Ejemplo n.º 2
0
/**@brief Function for application main entry.
 */
int main(void)
{
    gpio_config();

    bool success = nrf6350_lcd_init();
    APP_ERROR_CHECK_BOOL(success);
    success = nrf6350_lcd_write_string("    BLE ANCS    ", MAX_CHARACTERS_PER_LINE, LCD_UPPER_LINE, 0);
    APP_ERROR_CHECK_BOOL(success);

    // Initialize.
    leds_init();
    timers_init();
    gpiote_init();
    buttons_init();
    ble_stack_init();    
    bond_manager_init();
    gap_params_init();
    service_add();    
    advertising_init();
    conn_params_init();
    sec_params_init();
    radio_notification_init();
    
    // Start execution.
    advertising_start();

    // Enter main loop.
    for (;;)
    {
        power_manage();
    }

}
Ejemplo n.º 3
0
/**@brief Function for executing the state entry action. */
static void spis_state_entry_action_execute(NRF_SPIS_Type * p_spis,
                                                     spis_cb_t * p_cb)
{
    nrf_drv_spis_event_t event;
    
    switch (p_cb->spi_state)
    {                             
        case SPIS_BUFFER_RESOURCE_REQUESTED:
            nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_ACQUIRE);
            break;            
     
        case SPIS_BUFFER_RESOURCE_CONFIGURED:
            event.evt_type  = NRF_DRV_SPIS_BUFFERS_SET_DONE;
            event.rx_amount = 0;
            event.tx_amount = 0;     
            
            APP_ERROR_CHECK_BOOL(p_cb->handler != NULL);
            p_cb->handler(event);
            break;
            
        case SPIS_XFER_COMPLETED:        
            event.evt_type  = NRF_DRV_SPIS_XFER_DONE;
            event.rx_amount = nrf_spis_rx_amount_get(p_spis);
            event.tx_amount = nrf_spis_tx_amount_get(p_spis);
            APP_ERROR_CHECK_BOOL(p_cb->handler != NULL);
            p_cb->handler(event);
            break;
            
        default:
            // No implementation required.            
            break;
    }
}
Ejemplo n.º 4
0
/**@brief Function for releasing TX or RX buffer. */
static __INLINE void spi_master_buffer_release(uint8_t * * const pp_buf, uint16_t * const p_buf_len)
{
    APP_ERROR_CHECK_BOOL(pp_buf != NULL);
    APP_ERROR_CHECK_BOOL(p_buf_len != NULL);

    *pp_buf    = NULL;
    *p_buf_len = 0;
}
Ejemplo n.º 5
0
/**@brief Function for bootloader main entry.
 */
int main(void)
{
    uint32_t err_code;
    bool     dfu_start = false;
    bool     app_reset = (NRF_POWER->GPREGRET == BOOTLOADER_DFU_START);

    // This check ensures that the defined fields in the bootloader corresponds with actual
    // setting in the nRF51 chip.
    APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
    APP_ERROR_CHECK_BOOL(NRF_FICR->CODEPAGESIZE == CODE_PAGE_SIZE);

    // Initialize.
    timers_init();
    gpiote_init();
    buttons_init();
    bootloader_init();

    // Check if we reset in the middle of a firmware update
    if (bootloader_dfu_sd_in_progress()) {
        err_code = bootloader_dfu_sd_update_continue();
        APP_ERROR_CHECK(err_code);

        softdevice_init(!app_reset);
        scheduler_init();

        err_code = bootloader_dfu_sd_update_finalize();
        APP_ERROR_CHECK(err_code);

    } else {
        // If stack is present then continue initialization of bootloader.
        softdevice_init(!app_reset);
        scheduler_init();
    }

    // Check if the Bootloader Control pin is low. If so, enter the bootloader
    // mode.
    dfu_start = (nrf_gpio_pin_read(BOOTLOADER_CTRL_PIN) == 0);

    // If the Bootloader Control pin is low or the application in the flash
    // is not valid, enter the bootloader mode.
    if (dfu_start || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START))) {
        err_code = sd_power_gpregret_clr(POWER_GPREGRET_GPREGRET_Msk);
        APP_ERROR_CHECK(err_code);

        // Initiate an update of the firmware.
        err_code = bootloader_dfu_start();
        APP_ERROR_CHECK(err_code);
    }

    // If the application was or now is valid, run it
    if (bootloader_app_is_valid(DFU_BANK_0_REGION_START)) {
        // Select a bank region to use as application region.
        // @note: Only applications running from DFU_BANK_0_REGION_START is supported.
        bootloader_app_start(DFU_BANK_0_REGION_START);
    }

    NVIC_SystemReset();
}
static uint32_t	indication_char_add(uint16_t 							uuid, 
									uint8_t 							*p_char_value, 
									uint16_t 							char_len, 
									const ble_srv_cccd_security_mode_t* idc_char_attr_md, 
									ble_gatts_char_handles_t* 			p_handles)
{
	ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
	ble_gatts_attr_md_t attr_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;

	APP_ERROR_CHECK_BOOL(p_char_value != NULL);
    APP_ERROR_CHECK_BOOL(char_len > 0);

	memset(&cccd_md, 0, sizeof(cccd_md));

	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);

	cccd_md.vloc = BLE_GATTS_VLOC_STACK;
	cccd_md.write_perm = idc_char_attr_md->cccd_write_perm;

	memset(&char_md, 0, sizeof(char_md));

	char_md.char_props.indicate	= 1;
	char_md.p_char_user_desc	= NULL;
	char_md.p_char_pf			= NULL;
	char_md.p_user_desc_md		= NULL;
	char_md.p_cccd_md 			= &cccd_md;
	char_md.p_sccd_md			= NULL;

	BLE_UUID_BLE_ASSIGN(ble_uuid, uuid);

	memset(&attr_md, 0, sizeof(attr_md));

	attr_md.vloc		=	BLE_GATTS_VLOC_STACK;
	attr_md.read_perm	=	idc_char_attr_md->read_perm;
	attr_md.write_perm	=	idc_char_attr_md->write_perm;
	attr_md.rd_auth		=	0;
	attr_md.wr_auth		=	0;
	attr_md.vlen		=	1;

	memset(&attr_char_value, 0, sizeof(attr_char_value));

	attr_char_value.p_uuid		= &ble_uuid;
	attr_char_value.p_attr_md	= &attr_md;
	attr_char_value.init_len	= char_len;
	attr_char_value.init_offs	= 0;
	attr_char_value.max_len		= char_len;
	attr_char_value.p_value		= p_char_value;

	return sd_ble_gatts_characteristic_add(service_handle, \
										   &char_md, \
										   &attr_char_value, \
										   p_handles);		
}
Ejemplo n.º 7
0
/**@brief Display iOS notification message contents
 *
 */
static void display_ios_message(void)
{
    bool success;

    success = nrf6350_lcd_write_string(display_title, strlen(display_title), LCD_UPPER_LINE, 0);
    APP_ERROR_CHECK_BOOL(success);
    success = nrf6350_lcd_write_string(display_message, strlen(display_message), LCD_LOWER_LINE, 0);
    APP_ERROR_CHECK_BOOL(success);

    display_offset = 0;
}
Ejemplo n.º 8
0
/**@brief Function for receiving and sending data from IRQ. (The same for both IRQs). */
static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance)
{

    uint8_t rx_byte;

    APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
    APP_ERROR_CHECK_BOOL(p_spi_instance->state == SPI_MASTER_STATE_BUSY);

    p_spi_instance->bytes_count++;
    rx_byte = p_spi_instance->p_nrf_spi->RXD;

    if (p_spi_instance->start_flag)
    {
        p_spi_instance->start_flag = false;
        spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, (uint16_t)rx_byte);
    }
    else if (p_spi_instance->abort_flag  ) //this is tricky, but callback for SPI_MASTER_EVT_FIRST_BYTE_RECEIVED will set this flag for a first byte, which is bad because there is still byte in a buffer
    {                                      //and for a single byte transaction you will get XFERDONE event to restart
        p_spi_instance->abort_flag = false;
        p_spi_instance->state      = SPI_MASTER_STATE_ABORTED;
        nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
        spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_ABORTED, 0);
        return;
    }

    if ((p_spi_instance->p_rx_buffer != NULL) &&
        (p_spi_instance->rx_index < p_spi_instance->rx_length))
    {
        p_spi_instance->p_rx_buffer[p_spi_instance->rx_index++] = rx_byte;
    }

    if ((p_spi_instance->tx_index < p_spi_instance->max_length) && (!(p_spi_instance->abort_flag))) //do not TX if you know that there is an abort to be done - this should work for a DOUBLE BUFFERING ???
    {
        p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) &&
                                          (p_spi_instance->tx_index < p_spi_instance->tx_length)) ?
                                         p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] :
                                         SPI_DEFAULT_TX_BYTE;
        (p_spi_instance->tx_index)++;
    }

    if (p_spi_instance->bytes_count >= p_spi_instance->max_length)
    {
        APP_ERROR_CHECK_BOOL(p_spi_instance->bytes_count == p_spi_instance->max_length);
        nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
        p_spi_instance->state = SPI_MASTER_STATE_IDLE;
        spi_master_signal_evt(p_spi_instance,
                              SPI_MASTER_EVT_TRANSFER_COMPLETED,
                              p_spi_instance->tx_index);
    }
    return;
}
Ejemplo n.º 9
0
/**@brief Function for application main entry.
 */
int main(void)
{
    uint32_t err_code;
    bool     bootloader_is_pushed = false;
    
    leds_init();

    // This check ensures that the defined fields in the bootloader corresponds with actual
    // setting in the nRF51 chip.
    APP_ERROR_CHECK_BOOL(NRF_UICR->CLENR0 == CODE_REGION_1_START);

    APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
    APP_ERROR_CHECK_BOOL(NRF_FICR->CODEPAGESIZE == CODE_PAGE_SIZE);

    // Initialize.
    timers_init();
    gpiote_init();
    buttons_init();
    ble_stack_init();
    scheduler_init();

    bootloader_is_pushed = ((nrf_gpio_pin_read(BOOTLOADER_BUTTON_PIN) == 0)? true: false);
    
    if (bootloader_is_pushed || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)))
    {
        nrf_gpio_pin_set(LED_2);

        // Initiate an update of the firmware.
        err_code = bootloader_dfu_start();
        APP_ERROR_CHECK(err_code);

        nrf_gpio_pin_clear(LED_2);
    }

    if (bootloader_app_is_valid(DFU_BANK_0_REGION_START))
    {
        leds_off();
        
        // Select a bank region to use as application region.
        // @note: Only applications running from DFU_BANK_0_REGION_START is supported.
        bootloader_app_start(DFU_BANK_0_REGION_START);
        
    }

    nrf_gpio_pin_clear(LED_0);
    nrf_gpio_pin_clear(LED_1);
    nrf_gpio_pin_clear(LED_2);
    nrf_gpio_pin_clear(LED_7);
    
    NVIC_SystemReset();
}
Ejemplo n.º 10
0
/**
 * @brief Function for initializing TX or RX buffer.
 */
static __INLINE void spi_master_buffer_init(uint8_t * const           p_buf,
                                            const uint16_t            buf_len,
                                            uint8_t * volatile *      pp_buf,
                                            volatile uint16_t * const p_buf_len,
                                            volatile uint16_t * const p_index)
{
    APP_ERROR_CHECK_BOOL(pp_buf != NULL);
    APP_ERROR_CHECK_BOOL(p_buf_len != NULL);
    APP_ERROR_CHECK_BOOL(p_index != NULL);

    *pp_buf    = p_buf;
    *p_buf_len = (p_buf != NULL) ? buf_len : 0;
    *p_index   = 0;
}
Ejemplo n.º 11
0
/**@brief Function for encoding a PnP ID.
 *
 * @param[out]  p_encoded_buffer   Buffer where the encoded data will be written.
 * @param[in]   p_pnp_id           PnP ID to be encoded.
 */
static void pnp_id_encode(uint8_t * p_encoded_buffer, const ble_dis_pnp_id_t * p_pnp_id)
{
    uint8_t len = 0;

    APP_ERROR_CHECK_BOOL(p_pnp_id != NULL);
    APP_ERROR_CHECK_BOOL(p_encoded_buffer != NULL);

    p_encoded_buffer[len++] = p_pnp_id->vendor_id_source;

    len += uint16_encode(p_pnp_id->vendor_id, &p_encoded_buffer[len]);
    len += uint16_encode(p_pnp_id->product_id, &p_encoded_buffer[len]);
    len += uint16_encode(p_pnp_id->product_version, &p_encoded_buffer[len]);

    APP_ERROR_CHECK_BOOL(len == BLE_DIS_PNP_ID_LEN);
}
Ejemplo n.º 12
0
/**@brief Function for encoding a System ID.
 *
 * @param[out]  p_encoded_buffer   Buffer where the encoded data will be written.
 * @param[in]   p_sys_id           System ID to be encoded.
 */
static void sys_id_encode(uint8_t * p_encoded_buffer, const ble_dis_sys_id_t * p_sys_id)
{
    APP_ERROR_CHECK_BOOL(p_sys_id != NULL);
    APP_ERROR_CHECK_BOOL(p_encoded_buffer != NULL);

    p_encoded_buffer[0] = (p_sys_id->manufacturer_id & 0x00000000FF);
    p_encoded_buffer[1] = (p_sys_id->manufacturer_id & 0x000000FF00) >> 8;
    p_encoded_buffer[2] = (p_sys_id->manufacturer_id & 0x0000FF0000) >> 16;
    p_encoded_buffer[3] = (p_sys_id->manufacturer_id & 0x00FF000000) >> 24;
    p_encoded_buffer[4] = (p_sys_id->manufacturer_id & 0xFF00000000) >> 32;

    p_encoded_buffer[5] = (p_sys_id->organizationally_unique_id & 0x0000FF);
    p_encoded_buffer[6] = (p_sys_id->organizationally_unique_id & 0x00FF00) >> 8;
    p_encoded_buffer[7] = (p_sys_id->organizationally_unique_id & 0xFF0000) >> 16;
}
Ejemplo n.º 13
0
/**@brief Function for SPI master event callback.
 *
 * Upon receiving an SPI transaction complete event, checks if received data are valid.
 *
 * @param[in] spi_master_evt    SPI master driver event.
 */
static void spi_master_event_handler(spi_master_evt_t spi_master_evt)
{
    uint32_t err_code = NRF_SUCCESS;
    bool result = false;

    switch (spi_master_evt.evt_type)
    {
        case SPI_MASTER_EVT_TRANSFER_COMPLETED:

            // Check if data are vaild.
            result = buf_check(m_rx_data, spi_master_evt.data_count);
            APP_ERROR_CHECK_BOOL(result);

            err_code = bsp_indication_set(BSP_INDICATE_RCV_OK);
            APP_ERROR_CHECK(err_code);

            // Inform application that transfer is completed.
            m_transfer_completed = true;
            break;

        default:
            // No implementation needed.
            break;
    }
}
/**@brief Timeout handler that is responsible for toggling the Advertisement LED.
 *
 * @details This function will be called each time the timer that was started for the sake of
 *          blinking the Advertisement LED expires. This function toggle the state of the
 *          Advertisement LED.
 *
 * @param[in]   p_context   Pointer used for passing some arbitrary information (context) from the
 *                          app_start_timer() call to the timeout handler.
 */
static void adv_led_blink_timeout_handler(void * p_context)
{
    if (m_is_adv_led_blinking)
    {
        bool *          p_is_led_on;
        uint32_t        next_timer_interval;
        uint32_t        err_code;
    
        APP_ERROR_CHECK_BOOL(p_context != NULL);

        nrf_gpio_pin_toggle(ADVERTISING_LED_PIN_NO);

        p_is_led_on = (bool *)(p_context);

        *p_is_led_on = !(*p_is_led_on);

        if(*p_is_led_on )
        {
            // The toggle operation above would have resulted in an ON state. So start a timer that
            // will expire after ADV_LED_ON_TIME.
            next_timer_interval = ADV_LED_ON_TIME;
        }
        else
        {
            // The toggle operation above would have resulted in an OFF state. So start a timer that
            // will expire after ADV_LED_OFF_TIME.
            next_timer_interval = ADV_LED_OFF_TIME;
        }

        err_code = app_timer_start(m_adv_led_blink_timer_id,
                                   next_timer_interval,
                                   p_is_led_on );
        APP_ERROR_CHECK(err_code);
    }
}
Ejemplo n.º 15
0
void check_report(int32_t expected)
{
    // only first run is specific...
    if ((expected > 0) && m_first_report_flag)
    {
       expected = expected-1;
    }
    else if ((expected < 0) && m_first_report_flag)
    {
       expected = expected+1;
    }
    APP_ERROR_CHECK_BOOL( m_accdblread == 0);
    APP_ERROR_CHECK_BOOL( m_accread == expected );
    m_first_report_flag = false;  // clear silently after first run

}
Ejemplo n.º 16
0
/**@brief Handler for SPI1 master events.
 *
 * @param[in] spi_master_evt    SPI master event.
 */
void spi_master_1_event_handler(spi_master_evt_t spi_master_evt)
{
    uint32_t err_code = NRF_SUCCESS;
    bool result = false;

    switch (spi_master_evt.evt_type)
    {
        case SPI_MASTER_EVT_TRANSFER_COMPLETED:
            // Check if received data is correct.
            result = check_buf_equal(m_tx_data_spi, m_rx_data_spi, TX_RX_MSG_LENGTH);
            APP_ERROR_CHECK_BOOL(result);

            // Close SPI master.
            spi_master_close(SPI_MASTER_1);

            err_code = bsp_indication_set(BSP_INDICATE_RCV_OK);
            APP_ERROR_CHECK(err_code);

            m_transfer_completed = true;
            break;

        default:
            // No implementation needed.
            break;
    }
}
Ejemplo n.º 17
0
void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance)
{
    #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)

    volatile spi_master_instance_t * p_spi_instance = spi_master_get_instance(
        spi_master_hw_instance);
    APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);

    /* Disable interrupt */
    APP_ERROR_CHECK(sd_nvic_ClearPendingIRQ(p_spi_instance->irq_type));
    APP_ERROR_CHECK(sd_nvic_DisableIRQ(p_spi_instance->irq_type));

    p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);

    /* Set Slave Select pin as input with pull-up. */
    nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
    nrf_gpio_cfg_input(p_spi_instance->pin_slave_select, NRF_GPIO_PIN_PULLUP);
    p_spi_instance->pin_slave_select = (uint8_t)0xFF;

    /* Disconnect pins from SPI hardware */
    p_spi_instance->p_nrf_spi->PSELSCK  = (uint32_t)SPI_PIN_DISCONNECTED;
    p_spi_instance->p_nrf_spi->PSELMOSI = (uint32_t)SPI_PIN_DISCONNECTED;
    p_spi_instance->p_nrf_spi->PSELMISO = (uint32_t)SPI_PIN_DISCONNECTED;

    /* Reset to default values */
    spi_master_init_hw_instance(NULL, (IRQn_Type)0, p_spi_instance, false);
    #else
    return;
    #endif
}
Ejemplo n.º 18
0
/**
 * @brief Function for initializing instance of SPI master by default values.
 */
static __INLINE void spi_master_init_hw_instance(NRF_SPI_Type *                   p_nrf_spi,
                                                 IRQn_Type                        irq_type,
                                                 volatile spi_master_instance_t * p_spi_instance,
                                                 volatile bool                    disable_all_irq)
{
    APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);

    p_spi_instance->p_nrf_spi = p_nrf_spi;
    p_spi_instance->irq_type  = irq_type;

    p_spi_instance->p_tx_buffer = NULL;
    p_spi_instance->tx_length   = 0;
    p_spi_instance->tx_index    = 0;

    p_spi_instance->p_rx_buffer = NULL;
    p_spi_instance->rx_length   = 0;
    p_spi_instance->rx_index    = 0;

    p_spi_instance->bytes_count      = 0;
    p_spi_instance->max_length       = 0;
    p_spi_instance->pin_slave_select = 0;

    p_spi_instance->callback_event_handler = NULL;

    p_spi_instance->state           = SPI_MASTER_STATE_DISABLED;
    p_spi_instance->started_flag    = false;
    p_spi_instance->disable_all_irq = disable_all_irq;
}
/**@brief   Function for receiving callbacks from the micro-esb library.
 */
static void uesb_event_handler(void)
{
    uint32_t rf_interrupts;

    uesb_get_clear_interrupts(&rf_interrupts);

    if(rf_interrupts & UESB_INT_TX_FAILED_MSK)
    {
        // Transmit failed: flush buffer
        uesb_flush_tx();

        m_tx_attempts += 1;
        m_ut_state     = UT_STATE_RX;
    }
    if (rf_interrupts & UESB_INT_TX_SUCCESS_MSK)
    {
        uesb_payload_t payload;
        uint32_t       payload_len;
        
        // Successful transmission. Can now remove packet from our FIFO
        payload_len = sizeof(payload);
        fifo_get_pkt(&m_transmit_fifo, (uint8_t *) &payload, &payload_len);
        APP_ERROR_CHECK_BOOL(payload_len == sizeof(payload));
        
        m_tx_attempts = 0;
        m_ut_state    = UT_STATE_RX;
    }
    if(rf_interrupts & UESB_INT_RX_DR_MSK)
    {
        // Data reception is handled in a lower priority interrupt
        NVIC_SetPendingIRQ(UESB_RX_HANDLE_IRQn);
    }
}
Ejemplo n.º 20
0
static void app_timer_evt_get(void * p_event_data, uint16_t event_size)
{
    app_timer_event_t * p_timer_event = (app_timer_event_t *)p_event_data;

    APP_ERROR_CHECK_BOOL(event_size == sizeof(app_timer_event_t));
    p_timer_event->timeout_handler(p_timer_event->p_context);
}
Ejemplo n.º 21
0
/**@brief HID Report Characteristic Write event handler.
 *
 * @param[in]   p_evt   HID service event.
 */
static void on_hid_rep_char_write(ble_hids_evt_t *p_evt)
{
    if (p_evt->params.char_write.char_id.rep_type == BLE_HIDS_REP_TYPE_OUTPUT)
    {
        uint32_t err_code;
        uint8_t  report_val;
        uint8_t  report_index = p_evt->params.char_write.char_id.rep_index;
        
        if (report_index == OUTPUT_REPORT_INDEX)
        {
            APP_ERROR_CHECK_BOOL(OUTPUT_REPORT_MAX_LEN == 1);

            err_code = ble_hids_outp_rep_get(&m_hids, 
                                             report_index, 
                                             OUTPUT_REPORT_MAX_LEN, 
                                             0,
                                             &report_val);
            APP_ERROR_CHECK(err_code);

            if ((report_val & OUTPUT_REPORT_BIT_MASK_CAPS_LOCK) != 0)
            {
                // Caps Lock On
                nrf_gpio_pin_set(CAPS_ON_LED_PIN_NO);
                keys_send(sizeof(m_caps_on_key_pattern), m_caps_on_key_pattern);
            }
            else
            {
                // Caps Lock Off
                nrf_gpio_pin_clear(CAPS_ON_LED_PIN_NO);
                keys_send(sizeof(m_caps_off_key_pattern), m_caps_off_key_pattern);
            }
        }
    }
}
Ejemplo n.º 22
0
/**@brief Function for application main entry.
 */
int main(void)
{
    uint32_t err_code;
    bool     bootloader_is_pushed = false;
		static uint32_t TestAdr;
	
		TestAdr = (uint32_t)*(&(BluetoothDFU));
	
    if(TestAdr == 100) {
			bootloader_is_pushed = true;
			F_flash_page_erase(&BluetoothDFU);
			ble_flash_word_write(&BluetoothDFU , 0);
		}
	
    // This check ensures that the defined fields in the bootloader corresponds with actual
    // setting in the nRF51 chip.
    APP_ERROR_CHECK_BOOL(NRF_UICR->CLENR0 == CODE_REGION_1_START);

    APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
    APP_ERROR_CHECK_BOOL(NRF_FICR->CODEPAGESIZE == CODE_PAGE_SIZE);

    // Initialize.
    timers_init();
    gpiote_init();
    buttons_init();
    ble_stack_init();
    scheduler_init();

    //bootloader_is_pushed = ((nrf_gpio_pin_read(BOOTLOADER_BUTTON_PIN) == 0)? true: false);

    if (bootloader_is_pushed || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)))
    {
        // Initiate an update of the firmware.
        err_code = bootloader_dfu_start();
        APP_ERROR_CHECK(err_code);
    }

    if (bootloader_app_is_valid(DFU_BANK_0_REGION_START))
    {
        // Select a bank region to use as application region.
        // @note: Only applications running from DFU_BANK_0_REGION_START is supported.
        bootloader_app_start(DFU_BANK_0_REGION_START);
        
    }
    
    NVIC_SystemReset();
}
/**@brief IRQHandler used for execution context management. 
  *        Any available handler can be used as we're not using the associated hardware.
  *        This handler is used to initiate UESB RX/TX
  */
void TIMESLOT_BEGIN_IRQHandler(void)
{
    uesb_payload_t payload;
    uint32_t       payload_len;
    uint32_t       err_code;
    
    uesb_init(&m_uesb_config);
    
    // Packet transmission is syncrhonized to the beginning of timeslots
    // Check FIFO for packets and transmit if not empty
    if (m_transmit_fifo.free_items < sizeof(m_transmit_fifo.buf) && m_ut_state != UT_STATE_TX)
    {
        // There are packets in the FIFO: Start transmitting
        payload_len = sizeof(payload);
        
        // Copy packet from FIFO. Packet isn't removed until transmissions succeeds or max retries has been exceeded
        if (m_tx_attempts < MAX_TX_ATTEMPTS)
        {        
            fifo_peek_pkt(&m_transmit_fifo, (uint8_t *) &payload, &payload_len);
            APP_ERROR_CHECK_BOOL(payload_len == sizeof(payload));
        }
        else
        {
            fifo_get_pkt(&m_transmit_fifo, (uint8_t *) &payload, &payload_len);
            APP_ERROR_CHECK_BOOL(payload_len == sizeof(payload));
            
            m_tx_attempts = 0;
        }
        
        if (m_ut_state == UT_STATE_RX)
        {
            uesb_stop_rx();
        }
        
        err_code = uesb_write_tx_payload(&payload);
        APP_ERROR_CHECK(err_code);
        
        m_ut_state = UT_STATE_TX;
    }
    else
    {
        // No packets in the FIFO: start reception
        err_code = uesb_start_rx();
        m_ut_state = UT_STATE_RX;

    }
}
Ejemplo n.º 24
0
uint32_t ble_hids_boot_mouse_inp_rep_send(ble_hids_t * p_hids,
                                          uint8_t      buttons,
                                          int8_t       x_delta,
                                          int8_t       y_delta,
                                          uint16_t     optional_data_len,
                                          uint8_t    * p_optional_data)
{
    uint32_t err_code;

    if (p_hids->conn_handle != BLE_CONN_HANDLE_INVALID)
    {
        uint16_t hvx_len = BOOT_MOUSE_INPUT_REPORT_MIN_SIZE + optional_data_len;

        if (hvx_len <= BOOT_MOUSE_INPUT_REPORT_MAX_SIZE)
        {
            uint8_t                buffer[BOOT_MOUSE_INPUT_REPORT_MAX_SIZE];
            ble_gatts_hvx_params_t hvx_params;

            APP_ERROR_CHECK_BOOL(BOOT_MOUSE_INPUT_REPORT_MIN_SIZE == 3);

            // Build buffer
            buffer[0] = buttons;
            buffer[1] = (uint8_t)x_delta;
            buffer[2] = (uint8_t)y_delta;

            if (optional_data_len > 0)
            {
                memcpy(&buffer[3], p_optional_data, optional_data_len);
            }

            // Pass buffer to stack
            memset(&hvx_params, 0, sizeof(hvx_params));

            hvx_params.handle = p_hids->boot_mouse_inp_rep_handles.value_handle;
            hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
            hvx_params.offset = 0;
            hvx_params.p_len  = &hvx_len;
            hvx_params.p_data = buffer;

            err_code = sd_ble_gatts_hvx(p_hids->conn_handle, &hvx_params);
            if ((err_code == NRF_SUCCESS) &&
                (hvx_len != BOOT_MOUSE_INPUT_REPORT_MIN_SIZE + optional_data_len)
               )
            {
                err_code = NRF_ERROR_DATA_SIZE;
            }
        }
        else
        {
            err_code = NRF_ERROR_DATA_SIZE;
        }
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
    }

    return err_code;
}
Ejemplo n.º 25
0
void bootloader_enable(void)
{
#ifdef RBC_MESH_SERIAL
    mesh_aci_start();
#endif
    bl_cmd_t enable_cmd;
    enable_cmd.type = BL_CMD_TYPE_ENABLE;
    bl_cmd_handler(&enable_cmd);
    transport_start();

    /* Recover from broken state */
    if (dfu_mesh_app_is_valid())
    {
        set_timeout(TIMER_YIELD_TIMEOUT, TIMEOUT_ACTION_GO_TO_APP);
    }
    else
    {
#ifdef RTT_LOG
        __LOG(RTT_CTRL_TEXT_RED "APP is invalid.\n");
        bl_info_flags_t* p_flags = &bootloader_info_entry_get(BL_INFO_TYPE_FLAGS)->flags;
        bl_info_segment_t* p_seg = &bootloader_info_entry_get(BL_INFO_TYPE_SEGMENT_APP)->segment;
        __LOG("\tINTACT: SD: %d APP: %d BL: %d\n",
                p_flags->sd_intact,
                p_flags->app_intact,
                p_flags->bl_intact);
        if (*((uint32_t*) p_seg->start) == 0xFFFFFFFF)
        {
            __LOG("\tNo application at 0x%x\n", p_seg->start);
        }
#endif
        /* update the bootloader if a bank is available */
        if (dfu_bank_flash(DFU_TYPE_BOOTLOADER) == NRF_SUCCESS)
        {
            return;
        }

        dfu_type_t missing = dfu_mesh_missing_type_get();
        if (missing != DFU_TYPE_NONE && dfu_bank_flash(missing) == NRF_ERROR_NOT_FOUND)
        {
            fwid_union_t req_fwid;
            bl_info_entry_t* p_fwid_entry = bootloader_info_entry_get(BL_INFO_TYPE_VERSION);
            APP_ERROR_CHECK_BOOL(p_fwid_entry != NULL);

            switch (missing)
            {
                case DFU_TYPE_SD:
                    req_fwid.sd = p_fwid_entry->version.sd;
                    break;
                case DFU_TYPE_APP:
                    req_fwid.app = p_fwid_entry->version.app;
                    break;
                default:
                    APP_ERROR_CHECK(NRF_ERROR_INVALID_DATA);
            }

            dfu_mesh_req(missing, &req_fwid, (uint32_t*) 0xFFFFFFFF);
        }
    }
}
Ejemplo n.º 26
0
/**@brief Display an iOS notification
 *
 */
void evt_ios_notification(ble_ancs_c_evt_ios_notification_t *p_notice)
{
    bool success;
    char buffer[DISPLAY_BUFFER_SIZE];
    
    success = nrf6350_lcd_write_string(lit_catid[p_notice->category_id], 
        strlen(lit_catid[p_notice->category_id]), LCD_UPPER_LINE, 0);
    APP_ERROR_CHECK_BOOL(success);
    
    sprintf(buffer, "%s %02x%02x%02x%02x",
        lit_eventid[p_notice->event_id], 
        p_notice->notification_uid[0], p_notice->notification_uid[1], 
        p_notice->notification_uid[2], p_notice->notification_uid[3]);

    success = nrf6350_lcd_write_string(buffer, strlen(buffer), LCD_LOWER_LINE, 0);
    APP_ERROR_CHECK_BOOL(success);
}
Ejemplo n.º 27
0
/** @brief Function for executing method for entering calibration not active state. 
 *
 * Execute method for entering calibration not active state, meaning notifying the application of 
 * the state entry event. Additionally, if the timeout handler is running, it will be stopped.
 */
static __INLINE void calibration_not_active_execute(void)
{
    const uint32_t err_code = app_timer_stop(m_timer_id);
    APP_ERROR_CHECK(err_code);
    
    APP_ERROR_CHECK_BOOL(m_calibration_process_callback != NULL);    
    m_calibration_process_callback(CALIBRATION_NOT_ACTIVE_STATE_ENTER);
}
Ejemplo n.º 28
0
/**@brief Function for adding the Characteristic.
 *
 * @param[in]   uuid           UUID of characteristic to be added.
 * @param[in]   p_char_value   Initial value of characteristic to be added.
 * @param[in]   char_len       Length of initial value. This will also be the maximum value.
 * @param[in]   dis_attr_md    Security settings of characteristic to be added.
 * @param[out]  p_handles      Handles of new characteristic.
 *
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
static uint32_t char_add(uint16_t                        uuid,
                         uint8_t                       * p_char_value,
                         uint16_t                        char_len,
                         const ble_srv_security_mode_t * dis_attr_md,
                         ble_gatts_char_handles_t      * p_handles)
{
    ble_uuid_t          ble_uuid;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_t    attr_char_value;
    ble_gatts_attr_md_t attr_md;

    APP_ERROR_CHECK_BOOL(p_char_value != NULL);
    APP_ERROR_CHECK_BOOL(char_len > 0);

    // The ble_gatts_char_md_t structure uses bit fields. So we reset the memory to zero.
    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.read  = 1;
    char_md.p_char_user_desc = NULL;
    char_md.p_char_pf        = NULL;
    char_md.p_user_desc_md   = NULL;
    char_md.p_cccd_md        = NULL;
    char_md.p_sccd_md        = NULL;

    BLE_UUID_BLE_ASSIGN(ble_uuid, uuid);

    memset(&attr_md, 0, sizeof(attr_md));

    attr_md.read_perm  = dis_attr_md->read_perm;
    attr_md.write_perm = dis_attr_md->write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = char_len;
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = char_len;
    attr_char_value.p_value   = p_char_value;

    return sd_ble_gatts_characteristic_add(service_handle, &char_md, &attr_char_value, p_handles);
}
Ejemplo n.º 29
0
/**@brief Function for processing a received vendor specific packet.
 *
 * @param[in] p_buffer Pointer to the packet data.
 * @param[in] length   Length of packet data in bytes.
 */
static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_t length)
{
    // @note: no pointer validation check needed as allready checked by calling function.
    uint32_t err_code;

    if (is_rx_pkt_valid(p_buffer, length))
    {
        // RX packet is valid: validate sequence number.
        const uint8_t rx_seq_number = packet_seq_nmbr_extract(p_buffer);
        if (packet_number_expected_get() == rx_seq_number)
        {
            // Sequence number is valid: transmit acknowledgement.
            packet_number_expected_inc();
            ack_transmit();

            m_is_slip_decode_ready = true;

            err_code = hci_mem_pool_rx_data_size_set(length);
            APP_ERROR_CHECK(err_code);

            err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
            APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));

            // If memory pool RX buffer produce succeeded we register that buffer to slip layer
            // otherwise we register the internal acknowledgement buffer.
            err_code = hci_slip_rx_buffer_register(
                (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
                (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);

            APP_ERROR_CHECK(err_code);

            if (m_transport_event_handle != NULL)
            {
                // Send application event of RX packet reception.
                const hci_transport_evt_t evt = {HCI_TRANSPORT_RX_RDY};
                m_transport_event_handle(evt);
            }
        }
        else
        {
            // RX packet discarded: sequence number not valid, set the same buffer to slip layer in
            // order to avoid buffer overrun.
            err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
            APP_ERROR_CHECK(err_code);

            // As packet did not have expected sequence number: send acknowledgement with the
            // current expected sequence number.
            ack_transmit();
        }
    }
    else
    {
        // RX packet discarded: reset the same buffer to slip layer in order to avoid buffer
        // overrun.
        err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
        APP_ERROR_CHECK(err_code);
    }
}
Ejemplo n.º 30
0
/**@brief Connection Parameters Module handler.
 *
 * @details This function will be called for all events in the Connection Parameters Module which
 *          are passed to the application.
 *          @note All this function does is to disconnect. This could have been done by simply
 *                setting the disconnect_on_fail config parameter, but instead we use the event
 *                handler mechanism to demonstrate its use.
 *
 * @param[in]   p_evt   Event received from the Connection Parameters Module.
 */
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
{
    uint32_t err_code;
    
    APP_ERROR_CHECK_BOOL(p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED);
    
    err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
    APP_ERROR_CHECK(err_code);
}