void proprietary_rf_init(void)
{
    uint32_t err_code;

    m_uesb_config.rf_channel                     = 64;
    m_uesb_config.crc                            = UESB_CRC_16BIT;
    m_uesb_config.payload_length                 = 10;
    m_uesb_config.protocol                       = UESB_PROTOCOL_SB;
    m_uesb_config.bitrate                        = UESB_BITRATE_250KBPS;
    m_uesb_config.mode                           = UESB_MODE_PTX;
    m_uesb_config.rf_addr_length                 = 5;
    m_uesb_config.tx_output_power                = UESB_TX_POWER_4DBM;
    m_uesb_config.dynamic_ack_enabled            = 0;
    m_uesb_config.dynamic_payload_length_enabled = 0;
    m_uesb_config.rx_pipes_enabled               = 0x01;
    m_uesb_config.retransmit_delay               = 3750;
    m_uesb_config.retransmit_count               = 0;
    m_uesb_config.event_handler                  = uesb_event_handler;
    m_uesb_config.radio_irq_priority             = 0;

    m_tx_payload.pipe = FIXED_PIPE_INDEX;

    // The radio timeslot API will use the QDEC interrupt because that is rarely used.
    err_code = sd_nvic_ClearPendingIRQ(QDEC_IRQn);
    APP_ERROR_CHECK(err_code);

    err_code = sd_nvic_SetPriority(QDEC_IRQn, NRF_APP_PRIORITY_HIGH);
    APP_ERROR_CHECK(err_code);

    err_code = sd_nvic_EnableIRQ(QDEC_IRQn);
    APP_ERROR_CHECK(err_code);

    syma_init();
}
示例#2
0
/**@brief Function for application main entry, does not return.
 * 
 * @details The main function will do all necessary initalization. This includes sdm rx module 
 * and softdevice. 
 */ 
int main(void)
{
    uint32_t err_code;
    
    // In case of logging enabled, we enable sdm_rx module first.
    err_code = sdm_rx_init();
    APP_ERROR_CHECK(err_code);
  
    // Enable softdevice.
    err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, softdevice_assert_callback);
    APP_ERROR_CHECK(err_code);

    // Set application IRQ to lowest priority.
    err_code = sd_nvic_SetPriority(PROTOCOL_EVENT_IRQn, NRF_APP_PRIORITY_LOW); 
    APP_ERROR_CHECK(err_code);
  
    // Enable application IRQ (triggered from protocol).
    err_code = sd_nvic_EnableIRQ(PROTOCOL_EVENT_IRQn);      
    APP_ERROR_CHECK(err_code);

    // Setup Channel_0 as a SDM RX.
    ant_channel_sdm_rx_setup();
  
    sdm_main_loop();
}
示例#3
0
void battery_start(void)
{
    uint32_t err_code;

    // Configure ADC
    NRF_ADC->INTENSET   = ADC_INTENSET_END_Msk;
    NRF_ADC->CONFIG     = (ADC_CONFIG_RES_8bit                        << ADC_CONFIG_RES_Pos)     |
                          (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos)  |
                          (ADC_CONFIG_REFSEL_VBG                      << ADC_CONFIG_REFSEL_Pos)  |
                          (ADC_CONFIG_PSEL_Disabled                   << ADC_CONFIG_PSEL_Pos)    |
                          (ADC_CONFIG_EXTREFSEL_None                  << ADC_CONFIG_EXTREFSEL_Pos);
    NRF_ADC->EVENTS_END = 0;
    NRF_ADC->ENABLE     = ADC_ENABLE_ENABLE_Enabled;

    // Enable ADC interrupt
    err_code = sd_nvic_ClearPendingIRQ(ADC_IRQn);
    APP_ERROR_CHECK(err_code);

    err_code = sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);
    APP_ERROR_CHECK(err_code);

    err_code = sd_nvic_EnableIRQ(ADC_IRQn);
    APP_ERROR_CHECK(err_code);

    NRF_ADC->EVENTS_END  = 0;    // Stop any running conversions.
    NRF_ADC->TASKS_START = 1;
}
示例#4
0
/** @brief main function */
int main(void)
{
    /* Enable Softdevice (including sd_ble before framework */
    uint32_t error_code = 
        sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_75_PPM, sd_assert_handler);
    APP_ERROR_CHECK(error_code);
    
    ble_enable_params_t ble_enable_params;
    ble_enable_params.gatts_enable_params.service_changed = 0;
    
    error_code = sd_ble_enable(&ble_enable_params);
    APP_ERROR_CHECK(error_code);
    
    /* init leds and pins */
    gpio_init();
    
#ifdef RBC_MESH_SERIAL
    
    /* only want to enable serial interface, and let external host setup the framework */
    mesh_aci_init();

#else    
    /* Enable mesh framework on channel 37, min adv interval at 100ms, 
        2 characteristics */
    rbc_mesh_init_params_t init_params;

    init_params.access_addr = 0xA541A68F;
    init_params.adv_int_ms = 100;
    init_params.channel = 38;
    init_params.handle_count = 2;
    init_params.packet_format = RBC_MESH_PACKET_FORMAT_ORIGINAL;
    init_params.radio_mode = RBC_MESH_RADIO_MODE_BLE_1MBIT;
    
    error_code = rbc_mesh_init(init_params);
    APP_ERROR_CHECK(error_code);
    
    /* request values for both LEDs on the mesh */
    error_code = rbc_mesh_value_enable(1);
    APP_ERROR_CHECK(error_code);
    error_code = rbc_mesh_value_enable(2);
    APP_ERROR_CHECK(error_code);
    
    
    /* init BLE gateway softdevice application: */
    nrf_adv_conn_init();
    
#endif
    
    /* enable softdevice IRQ */
    sd_nvic_EnableIRQ(SD_EVT_IRQn);
    
    
    /* sleep */
    while (true)
    {
        sd_app_evt_wait();
    }
    

}
uint32_t ble_radio_notification_init(nrf_app_irq_priority_t               irq_priority,
                                     nrf_radio_notification_distance_t    distance,
                                     ble_radio_notification_evt_handler_t evt_handler)
{
    uint32_t err_code;

    m_evt_handler = evt_handler;

    // Initialize Radio Notification software interrupt
    err_code = sd_nvic_ClearPendingIRQ(SWI1_IRQn);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = sd_nvic_SetPriority(SWI1_IRQn, irq_priority);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = sd_nvic_EnableIRQ(SWI1_IRQn);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    // Configure the event
    return sd_radio_notification_cfg_set(NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, distance);
}
int main(void)
{
  /* Silence the compiler */
  (void) g_sd_assert_pc;
  (void) g_evt;

  uart_init();

  char start_msg[128];
  sprintf(&start_msg[0], "\n| %s |---------------------------------------------------\r\n\n", __TIME__);
  uart_putstring((uint8_t*) &start_msg[0]);

  nrf_gpio_range_cfg_output(0, 30);
  for(int i = LED_START; i <= LED_STOP; ++i)
    nrf_gpio_pin_set(i);

  uint32_t error_code = sd_softdevice_enable((uint32_t)NRF_CLOCK_LFCLKSRC_XTAL_75_PPM, sd_assert_cb);
  APP_ERROR_CHECK(error_code);


  error_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
  APP_ERROR_CHECK(error_code);

  ble_setup();

  /* Enable a generic SD advertiser to display concurrent operation */
  nrf_adv_conn_init();

  while (true)
  {
    sd_app_evt_wait();
  }
}
void
protocol_init(struct ir_protocol *protocol, uint8_t led_pin, struct rtc_ctx *c)
{
	ctx = c;
	context.protocol = protocol;
	context.led_pin = led_pin;

	// low freq clock
	NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
	NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
	NRF_CLOCK->TASKS_LFCLKSTART = 1;
	while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
		/* NOTHING */;
	NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;

	// rtc1 interrupt
	sd_nvic_ClearPendingIRQ(RTC1_IRQn);
	sd_nvic_SetPriority(RTC1_IRQn, NRF_APP_PRIORITY_LOW);
	sd_nvic_EnableIRQ(RTC1_IRQn);
	NRF_RTC1->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
	NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;

	// high freq clock
	sd_clock_hfclk_request();

	// timer1
	NRF_TIMER1->TASKS_STOP = 1;
	NRF_TIMER1->TASKS_CLEAR = 1;
	NRF_TIMER1->PRESCALER = 4;
	NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;
	NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
	NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE2_CLEAR_Msk;
	NRF_TIMER1->CC[0] = 1;
	NRF_TIMER1->CC[1] = ROUNDED_DIV(context.protocol->pulse_width, 3);
	NRF_TIMER1->CC[2] = context.protocol->pulse_width;

	// timer2 (counter)
	NRF_TIMER2->TASKS_STOP = 1;
	NRF_TIMER2->TASKS_CLEAR = 1;
	NRF_TIMER2->MODE = TIMER_MODE_MODE_Counter;
	NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
	NRF_TIMER2->TASKS_START = 1;
	NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Msk;

	// gpio (led)
	nrf_gpio_cfg_output(led_pin);

	// ppi's
	sd_ppi_channel_assign(0, &NRF_TIMER1->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[0]); // toggle led
	sd_ppi_channel_assign(1, &NRF_TIMER1->EVENTS_COMPARE[1], &NRF_GPIOTE->TASKS_OUT[0]); // toggle led
	sd_ppi_channel_assign(2, &NRF_TIMER1->EVENTS_COMPARE[2], &NRF_TIMER2->TASKS_COUNT); // inc timer2
	sd_ppi_channel_assign(3, &NRF_TIMER2->EVENTS_COMPARE[0], &NRF_TIMER1->TASKS_STOP); // stops timer1 after timer2 reaches N
	sd_ppi_channel_enable_set(PPI_CHEN_CH0_Msk |
		PPI_CHEN_CH1_Msk |
		PPI_CHEN_CH2_Msk |
		PPI_CHEN_CH3_Msk);
}
示例#8
0
文件: main.c 项目: JulianYG/WNR
/**@brief Function for application main entry. Does not return.
 */
int main(void)
{
    // ANT event message buffer.
    static ANT_MESSAGE ant_message_buffer;

    // Enable SoftDevice.
    uint32_t err_code;
#if defined(S212) || defined(S332)
    err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, 
                                    softdevice_assert_callback,
                                    ANT_LICENSE_KEY);
#else
   err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, 
                                   softdevice_assert_callback);
#endif
    APP_ERROR_CHECK(err_code);

    // Set application IRQ to lowest priority.
    err_code = sd_nvic_SetPriority(SD_EVT_IRQn, NRF_APP_PRIORITY_LOW);
    APP_ERROR_CHECK(err_code);

    // Enable application IRQ (triggered from protocol).
    err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
    APP_ERROR_CHECK(err_code);

    // Configure ant stack regards used channels.
    err_code = ant_stack_static_config();
    APP_ERROR_CHECK(err_code);
    
    // Setup channel
    ant_channel_tx_broadcast_setup();

    uint8_t event;
    uint8_t ant_channel;

    // Main loop.
    for (;;)
    {
        // Put CPU in sleep if possible.
        err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);

        // Extract and process all pending ANT events as long as there are any left.
        do
        {
            // Fetch the event.
            err_code = sd_ant_event_get(&ant_channel, &event, ant_message_buffer.aucMessage);
            if (err_code == NRF_SUCCESS)
            {
                // Handle event
                channel_event_handle(event, &ant_message_buffer);
            }
        }
        while (err_code == NRF_SUCCESS);
    }
}
uint32_t nrf_pwm_init(nrf_pwm_config_t *config)
{
    static volatile uint32_t err_code;
    
    if(config->num_channels < 1 || config->num_channels > 2) return 0xFFFFFFFF;
    
    switch(config->mode)
    {
		case PWM_MODE_LED_255:   // 8-bit resolution, 122 Hz PWM frequency, 65 kHz timer frequency (prescaler 8)
            PWM_TIMER->PRESCALER = 8;
            pwm_max_value = 255;     
            pwm_period_us = (pwm_max_value * 2 * 1000000) / (16000000 / 256);        
            break;
		case PWM_MODE_LED_4095:  // 0-4095 resolution, 488Hz PWM frequency, 2MHz timer frequency (prescaler 2)
            PWM_TIMER->PRESCALER = 2;
            pwm_max_value = 4095;
            pwm_period_us = (pwm_max_value * 2 * 1000000) / (16000000 / 4);        
            break;
        default:
            return 0xFFFFFFFF;
    }
    pwm_ppi_chg      = config->ppi_group[0];
    pwm_num_channels = config->num_channels;
    for(int i = 0; i < pwm_num_channels; i++)
    {
        pwm_io_ch[i] = (uint32_t)config->gpio_num[i];
        nrf_gpio_cfg_output(pwm_io_ch[i]);
        pwm_gpiote_channel[i] = config->gpiote_channel[i];        
    }
    PWM_TIMER->TASKS_CLEAR = 1;
	PWM_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
    PWM_TIMER->CC[3] = pwm_max_value*2;
	PWM_TIMER->MODE = TIMER_MODE_MODE_Timer;
    PWM_TIMER->SHORTS = TIMER_SHORTS_COMPARE3_CLEAR_Msk;
    PWM_TIMER->EVENTS_COMPARE[0] = PWM_TIMER->EVENTS_COMPARE[1] = PWM_TIMER->EVENTS_COMPARE[2] = PWM_TIMER->EVENTS_COMPARE[3] = 0;     

    for(int i = 0; i < pwm_num_channels; i++)
    {
        ppi_configure_channel(config->ppi_channel[i*2],   &PWM_TIMER->EVENTS_COMPARE[i], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);
        ppi_configure_channel(config->ppi_channel[i*2+1], &PWM_TIMER->EVENTS_COMPARE[3], &NRF_GPIOTE->TASKS_OUT[pwm_gpiote_channel[i]]);        
    }
    
    #if(USE_WITH_SOFTDEVICE == 1)
    sd_nvic_SetPriority(PWM_IRQn, 1);
    sd_nvic_ClearPendingIRQ(PWM_IRQn);
    sd_nvic_EnableIRQ(PWM_IRQn);
    #else
    NVIC_SetPriority(PWM_IRQn, 3);
    NVIC_ClearPendingIRQ(PWM_IRQn);
    NVIC_EnableIRQ(PWM_IRQn);
    #endif

    PWM_TIMER->TASKS_START = 1;
    
    return 0;
}
示例#10
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
}
示例#11
0
/**@brief Function for application main entry, does not return.
 *
 * @details The main function will do all necessary initalization. This includes sdm rx module
 * and SoftDevice.
 */
int main(void)
{
    uint32_t err_code;

#if defined(TRACE_UART)
    app_uart_comm_params_t comm_params =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_DISABLED,
        false,
        UART_BAUDRATE_BAUDRATE_Baud38400
    };

    APP_UART_FIFO_INIT(&comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_error_handle,
                       APP_IRQ_PRIORITY_LOW,
                       err_code);
    APP_ERROR_CHECK(err_code);
#endif // TRACE_UART
#if defined(TRACE_GPIO)
    // Initialize timer module.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);

    err_code = bsp_init(BSP_INIT_LED, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), NULL);
    APP_ERROR_CHECK(err_code);
#endif // TRACE_GPIO

    // In case of logging enabled, we enable sdm_rx module first.
    err_code = sdm_rx_init();
    APP_ERROR_CHECK(err_code);

    // Enable SoftDevice.
    err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, softdevice_assert_callback);
    APP_ERROR_CHECK(err_code);

    // Set application IRQ to lowest priority.
    err_code = sd_nvic_SetPriority(SD_EVT_IRQn, NRF_APP_PRIORITY_LOW);
    APP_ERROR_CHECK(err_code);

    // Enable application IRQ (triggered from protocol).
    err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
    APP_ERROR_CHECK(err_code);

    err_code = ant_stack_static_config();
    APP_ERROR_CHECK(err_code);

    // Setup Channel_0 as a SDM RX.
    ant_channel_sdm_rx_setup();

    sdm_main_loop();
}
示例#12
0
static void ble_stack_init(void)
{
    uint32_t err_code;

    err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, assert_nrf_callback);
    APP_ERR_CHECK(err_code);

    err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
    APP_ERR_CHECK(err_code);
}
void timeslot_handler_init(nrf_clock_lfclksrc_t lfclksrc)
{
    if (g_framework_initialized)
    {
        /* may happen with serial interface, can safely skip redundant inits */
        return;
    }
    uint32_t error;


    switch (lfclksrc)
    {
        case NRF_CLOCK_LFCLKSRC_XTAL_100_PPM:
            g_lfclk_ppm = 100;
            break;
        case NRF_CLOCK_LFCLKSRC_XTAL_150_PPM:
            g_lfclk_ppm = 150;
            break;
        case NRF_CLOCK_LFCLKSRC_XTAL_20_PPM:
            g_lfclk_ppm = 20;
            break;
        case NRF_CLOCK_LFCLKSRC_XTAL_250_PPM:
            g_lfclk_ppm = 250;
            break;
        case NRF_CLOCK_LFCLKSRC_XTAL_30_PPM:
            g_lfclk_ppm = 30;
            break;
        case NRF_CLOCK_LFCLKSRC_XTAL_500_PPM:
            g_lfclk_ppm = 500;
            break;
        case NRF_CLOCK_LFCLKSRC_XTAL_50_PPM:
            g_lfclk_ppm = 50;
            break;
        case NRF_CLOCK_LFCLKSRC_XTAL_75_PPM:
            g_lfclk_ppm = 75;
            break;
        default:
            g_lfclk_ppm = 250;
    }


    g_is_in_callback = false;
    g_framework_initialized = true;

    error = sd_nvic_EnableIRQ(SD_EVT_IRQn);
    APP_ERROR_CHECK(error);

    error = sd_radio_session_open(&radio_signal_callback);
    APP_ERROR_CHECK(error);

    timer_init();
    g_start_time_ref = NRF_RTC0->COUNTER;
    g_timeslot_length = TIMESLOT_SLOT_LENGTH;
    timeslot_order_earliest(g_timeslot_length, true);
}
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);
}
示例#15
0
/**@brief Function for configuring and setting up the SoftDevice. 
 */
static __INLINE void softdevice_setup(void)
{        
    uint32_t err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, 
                                             softdevice_assert_callback); 
    APP_ERROR_CHECK(err_code);

    // Configure application-specific interrupts. Set application IRQ to lowest priority and enable 
    // application IRQ (triggered from ANT protocol stack).
    err_code = sd_nvic_SetPriority(SD_EVT_IRQn, NRF_APP_PRIORITY_LOW);
    APP_ERROR_CHECK(err_code);
    
    err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
    APP_ERROR_CHECK(err_code);
}
示例#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);
}
示例#17
0
/**@brief Function for application main entry. Does not return.
 */
int main(void)
{
#if 0    
    led_init();
    
    led_on(BSP_LED_0);    
    led_on(BSP_LED_1);        
    
    for (;;)
    {
        
    }
#endif // 0    
    
    uint32_t err_code;

    // Configure pins LED_A - LED_D as outputs.
    led_init();

    // Enable SoftDevice.
    err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, softdevice_assert_callback);
    APP_ERROR_CHECK(err_code);

    // Set application IRQ to lowest priority.
    err_code = sd_nvic_SetPriority(SD_EVT_IRQn, NRF_APP_PRIORITY_LOW);
    APP_ERROR_CHECK(err_code);

    // Enable application IRQ (triggered from protocol).
    err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
    APP_ERROR_CHECK(err_code);

    //Initialise and start the one second timer;
    init_timer();

    //Initialise and start the auto shared channel module
    ascs_init(&m_asc_parameters);
    ascs_turn_on();
    check_and_handle_asc_flags();

    // Main loop.
    for (;;)
    {
        // Put CPU in sleep if possible.
        err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);

        poll_for_ant_events();
        check_and_handle_asc_flags();
    }
}
示例#18
0
文件: main.c 项目: tkadom/TWBLE
int main(void)
{
    uint32_t error_code;
    (void) error_code;

    uart_init();

    PUTS("LED Mesh initializing");

    error_code = 
        sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_75_PPM, sd_assert_handler);
    
    test_app_init();


#ifdef RBC_MESH_SERIAL
    mesh_aci_init();
#else

    PUTS("mesh service init");

    rbc_mesh_init_params_t init_params;

    init_params.access_addr = 0xA541A68F;
    init_params.adv_int_ms = 100;
    init_params.channel = 38;
    init_params.handle_count = 2;
    init_params.packet_format = RBC_MESH_PACKET_FORMAT_ORIGINAL;
    init_params.radio_mode = RBC_MESH_RADIO_MODE_BLE_1MBIT;

    error_code = rbc_mesh_init(init_params);
    APP_ERROR_CHECK(error_code);

    error_code = rbc_mesh_value_enable(1);
    APP_ERROR_CHECK(error_code);
    error_code = rbc_mesh_value_enable(2);
    APP_ERROR_CHECK(error_code);
#endif

    sd_nvic_EnableIRQ(SD_EVT_IRQn);

    /* sleep */
    while (true)
    {
        sd_app_evt_wait();
    }

}
示例#19
0
void timeslot_handler_init(void)
{
    uint32_t error;

    g_is_in_callback = false;
    g_framework_initialized = true;

    error = sd_nvic_EnableIRQ(SD_EVT_IRQn);
    APP_ERROR_CHECK(error);

    error = sd_radio_session_open(&radio_signal_callback);
    APP_ERROR_CHECK(error);
    g_start_time_ref = NRF_RTC0->COUNTER;
    g_timeslot_length = TIMESLOT_SLOT_LENGTH;
    timeslot_order_earliest(g_timeslot_length, true);
}
bool twi_master_init(twi_init_config_t *init_cfg,twi_config_t *cfg)
{
    cfg->twi_operation_complete = true;
    cfg->twi_ack_received = true;

          
    /* To secure correct signal levels on the pins used by the TWI
       master when the system is in OFF mode, and when the TWI master is 
       disabled, these pins must be configured in the GPIO peripheral.
    */ 
    NRF_GPIO->PIN_CNF[init_cfg->twi_pinselect_scl] = 
        (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
      | (GPIO_PIN_CNF_DRIVE_S0D1     << GPIO_PIN_CNF_DRIVE_Pos)
      | (GPIO_PIN_CNF_PULL_Pullup    << GPIO_PIN_CNF_PULL_Pos)
      | (GPIO_PIN_CNF_INPUT_Connect  << GPIO_PIN_CNF_INPUT_Pos)
      | (GPIO_PIN_CNF_DIR_Input      << GPIO_PIN_CNF_DIR_Pos);    

    NRF_GPIO->PIN_CNF[init_cfg->twi_pinselect_sda] = 
        (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
      | (GPIO_PIN_CNF_DRIVE_S0D1     << GPIO_PIN_CNF_DRIVE_Pos)
      | (GPIO_PIN_CNF_PULL_Pullup    << GPIO_PIN_CNF_PULL_Pos)
      | (GPIO_PIN_CNF_INPUT_Connect  << GPIO_PIN_CNF_INPUT_Pos)
      | (GPIO_PIN_CNF_DIR_Input      << GPIO_PIN_CNF_DIR_Pos); 
    
    cfg->twi->EVENTS_RXDREADY = 0;
    cfg->twi->EVENTS_TXDSENT = 0;
    cfg->twi->PSELSCL = init_cfg->twi_pinselect_scl;
    cfg->twi->PSELSDA = init_cfg->twi_pinselect_sda;
    
    switch(init_cfg->frequency)
    {
        case TWI_FREQ_100KHZ:
            cfg->twi->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos;
            break;
        case TWI_FREQ_400KHZ:
            cfg->twi->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos;
            break;
    }
    sd_ppi_channel_assign(cfg->twi_ppi_ch, &cfg->twi->EVENTS_BB, &cfg->twi->TASKS_SUSPEND);
    sd_ppi_channel_enable_clr(1 << cfg->twi_ppi_ch);
    sd_nvic_SetPriority(init_cfg->twi_interrupt_no, TWI_IRQ_PRIORITY_SD);
    sd_nvic_EnableIRQ(init_cfg->twi_interrupt_no);
    cfg->twi->INTENSET = TWI_INTENSET_TXDSENT_Msk | TWI_INTENSET_STOPPED_Msk | TWI_INTENSET_ERROR_Msk | TWI_INTENSET_RXDREADY_Msk;
    cfg->twi->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
    return twi_master_clear_bus(init_cfg);
}
示例#21
0
uint32_t ir_lib_init(uint32_t ir_pin)
{
    uint32_t err_code = 0;

    NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Task         << GPIOTE_CONFIG_MODE_Pos |
                            GPIOTE_CONFIG_OUTINIT_Low       << GPIOTE_CONFIG_OUTINIT_Pos |
                            GPIOTE_CONFIG_POLARITY_Toggle   << GPIOTE_CONFIG_POLARITY_Pos |
                            ir_pin                          << GPIOTE_CONFIG_PSEL_Pos;
    
    // Carrier timer init
    IR_TIMER_CARRIER->MODE          = TIMER_MODE_MODE_Timer;
    IR_TIMER_CARRIER->BITMODE       = TIMER_BITMODE_BITMODE_16Bit;
    IR_TIMER_CARRIER->PRESCALER     = 4;
    IR_TIMER_CARRIER->CC[0]         = IR_CARRIER_LOW_US;    
    IR_TIMER_CARRIER->CC[1]         = IR_CARRIER_LOW_US + IR_CARRIER_HIGH_US; 
    IR_TIMER_CARRIER->SHORTS        = TIMER_SHORTS_COMPARE1_CLEAR_Msk;

    // Modulation timer init
    IR_CARRIER_COUNTER->MODE        = TIMER_MODE_MODE_Counter;  
    IR_CARRIER_COUNTER->BITMODE     = TIMER_BITMODE_BITMODE_16Bit;
    IR_CARRIER_COUNTER->INTENSET    = TIMER_INTENSET_COMPARE0_Msk | TIMER_INTENSET_COMPARE1_Msk;
    IR_CARRIER_COUNTER->EVENTS_COMPARE[0] = 0;
    IR_CARRIER_COUNTER->EVENTS_COMPARE[1] = 0;

    err_code |= sd_nvic_SetPriority(IR_CARRIER_COUNTER_IRQn, IR_CARRIER_COUNTER_IRQ_Priority);
    err_code |= sd_nvic_EnableIRQ(IR_CARRIER_COUNTER_IRQn);

    err_code |= sd_ppi_channel_assign(IR_PPI_CH_A, &IR_TIMER_CARRIER->EVENTS_COMPARE[1], &IR_CARRIER_COUNTER->TASKS_COUNT);
    
    err_code |= sd_ppi_channel_assign(IR_PPI_CH_B, &IR_TIMER_CARRIER->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[0]);
    err_code |= sd_ppi_channel_assign(IR_PPI_CH_C, &IR_TIMER_CARRIER->EVENTS_COMPARE[1], &NRF_GPIOTE->TASKS_OUT[0]);

    err_code |= sd_ppi_group_assign(IR_PPI_GROUP, 1 << IR_PPI_CH_B | 1 << IR_PPI_CH_C);
    err_code |= sd_ppi_group_task_disable(IR_PPI_GROUP);
    
    err_code |= sd_ppi_channel_assign(IR_PPI_CH_D, &IR_CARRIER_COUNTER->EVENTS_COMPARE[0], &NRF_PPI->TASKS_CHG[IR_PPI_GROUP].DIS);
    err_code |= sd_ppi_channel_assign(IR_PPI_CH_E, &IR_CARRIER_COUNTER->EVENTS_COMPARE[1], &NRF_PPI->TASKS_CHG[IR_PPI_GROUP].EN);

    err_code |= sd_ppi_channel_enable_set(1 << IR_PPI_CH_A | 1 << IR_PPI_CH_B | 1 << IR_PPI_CH_C | 1 << IR_PPI_CH_D | 1 << IR_PPI_CH_E);
    
    m_busy = false;
    return err_code;
}
//Start supercapacitor voltage measurement
void supercap_measure_start(void)
{
	// Configure ADC
	/* Enable interrupt on ADC sample ready event*/		
	NRF_ADC->INTENSET = ADC_INTENSET_END_Msk;   
	sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);  
	sd_nvic_EnableIRQ(ADC_IRQn);
	
	NRF_ADC->CONFIG	= (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos) /* Bits 17..16 : ADC external reference pin selection. */
									| (ADC_CONFIG_PSEL_AnalogInput7 << ADC_CONFIG_PSEL_Pos)					/*!< Use analog input 2 as analog input. */
									| (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos)							/*!< Use internal 1.2V bandgap voltage as reference for conversion. */
									| (ADC_CONFIG_INPSEL_AnalogInputNoPrescaling << ADC_CONFIG_INPSEL_Pos) /*!< Analog input specified by PSEL with no prescaling used as input for the conversion. */
									| (ADC_CONFIG_RES_8bit << ADC_CONFIG_RES_Pos);									/*!< 8bit ADC resolution. */ 
  sd_nvic_ClearPendingIRQ(ADC_IRQn);
	NRF_ADC->EVENTS_END = 0;	
	/* Enable ADC*/
	NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
	NRF_ADC->TASKS_START = 1;
}
示例#23
0
文件: board.c 项目: hexanoid/polymcu
// Initialize newlib
void hardware_init_hook(void) {
    // Configure LED-pins as outputs.
    LEDS_CONFIGURE(LEDS_MASK);
    LEDS_OFF(LEDS_MASK);

	// Initialize UART
	Driver_UART_DEBUG.Initialize(NULL);

#if defined(__CMSIS_RTOS) && defined(SOFTDEVICE_PRESENT)
    // Initialize the SoftDevice handler module.
    SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL);

    // We need to configure the interrupt before starting the kernel as we cannot call an SVC in an SVC Handler
    uint32_t err_code = sd_nvic_SetPriority(RTC1_IRQn, NRF_APP_PRIORITY_LOW);
    assert(err_code == NRF_SUCCESS);

    err_code = sd_nvic_EnableIRQ(RTC1_IRQn);
    assert(err_code == NRF_SUCCESS);
#endif
}
示例#24
0
/**@brief Function for configuring and setting up the SoftDevice. 
 */
static __INLINE void softdevice_setup(void)
{
    printf("softdevice_setup\n");

    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;

    uint32_t err_code = sd_softdevice_enable(&clock_lf_cfg, 
                                             softdevice_assert_callback,
                                             ANT_LICENSE_KEY);
    APP_ERROR_CHECK(err_code);

    // Configure application-specific interrupts. Set application IRQ to lowest priority and enable 
    // application IRQ (triggered from ANT protocol stack).
    err_code = sd_nvic_SetPriority(SD_EVT_IRQn, APP_IRQ_PRIORITY_LOW); 
    APP_ERROR_CHECK(err_code);    
    err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);      
    APP_ERROR_CHECK(err_code);

    err_code = ant_stack_static_config();
    APP_ERROR_CHECK(err_code);
}
示例#25
0
void softdevice_handler_resume()
{
    if (!m_suspended) return;
    m_suspended = false;

#ifdef SOFTDEVICE_PRESENT
    ret_code_t err_code;

    // Force calling ISR again to make sure that events not pulled previously
    // has been processed.
    err_code = sd_nvic_SetPendingIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ);
    APP_ERROR_CHECK(err_code);
    err_code = sd_nvic_EnableIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ);
    APP_ERROR_CHECK(err_code);
#else
    NVIC_SetPendingIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ);
    NVIC_EnableIRQ(SOFTDEVICE_EVT_IRQ);
#endif

    return;
}
示例#26
0
文件: main.c 项目: RobinLin/Espruino
/**@brief Function for configuring ADC to do battery level conversion.
 */
static void adc_configure(void)
{
    uint32_t err_code;
    nrf_adc_config_t adc_config = NRF_ADC_CONFIG_DEFAULT;

    // Configure ADC
    adc_config.reference  = NRF_ADC_CONFIG_REF_VBG;
    adc_config.resolution = NRF_ADC_CONFIG_RES_8BIT;
    adc_config.scaling    = NRF_ADC_CONFIG_SCALING_SUPPLY_ONE_THIRD;
    nrf_adc_configure(&adc_config);

    // Enable ADC interrupt
    nrf_adc_int_enable(ADC_INTENSET_END_Msk);
    err_code = sd_nvic_ClearPendingIRQ(ADC_IRQn);
    APP_ERROR_CHECK(err_code);

    err_code = sd_nvic_SetPriority(ADC_IRQn, NRF_APP_PRIORITY_LOW);
    APP_ERROR_CHECK(err_code);

    err_code = sd_nvic_EnableIRQ(ADC_IRQn);
    APP_ERROR_CHECK(err_code);
}
示例#27
0
文件: main.c 项目: JulianYG/WNR
/**@brief Function for configuring and setting up the SoftDevice. 
 */
static __INLINE void softdevice_setup(void)
{
    printf("softdevice_setup\n");

#if defined(S212) || defined(S332)
    uint32_t err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC, 
                                             softdevice_assert_callback,
                                             ANT_LICENSE_KEY);
#else
    uint32_t err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC, 
                                             softdevice_assert_callback);
#endif
    APP_ERROR_CHECK(err_code);

    // Configure application-specific interrupts. Set application IRQ to lowest priority and enable 
    // application IRQ (triggered from ANT protocol stack).
    err_code = sd_nvic_SetPriority(SD_EVT_IRQn, NRF_APP_PRIORITY_LOW); 
    APP_ERROR_CHECK(err_code);    
    err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);      
    APP_ERROR_CHECK(err_code);

    err_code = ant_stack_static_config();
    APP_ERROR_CHECK(err_code);
}
示例#28
0
uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance,
                              uint8_t * const p_tx_buf, const uint16_t tx_buf_len,
                              uint8_t * const p_rx_buf, const uint16_t rx_buf_len)
{
    #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);

    uint32_t err_code   = NRF_SUCCESS;
    uint16_t max_length = 0;
    
    uint8_t nested_critical_region = 0;
    
    //Check if disable all IRQs flag is set
    if (p_spi_instance->disable_all_irq)
    {
        //Disable interrupts.
        APP_ERROR_CHECK(sd_nvic_critical_region_enter(&nested_critical_region));
    }
    else
    {
        //Disable interrupt SPI.
        APP_ERROR_CHECK(sd_nvic_DisableIRQ(p_spi_instance->irq_type));
    }

    //Initialize and perform data transfer
    if (p_spi_instance->state == SPI_MASTER_STATE_IDLE)
    {
        max_length = (rx_buf_len > tx_buf_len) ? rx_buf_len : tx_buf_len;

        if (max_length > 0)
        {
            p_spi_instance->state        = SPI_MASTER_STATE_BUSY;
            p_spi_instance->bytes_count  = 0;
            p_spi_instance->started_flag = false;
            p_spi_instance->max_length   = max_length;

            /* Initialize buffers */
            spi_master_buffer_init(p_tx_buf,
                                   tx_buf_len,
                                   &(p_spi_instance->p_tx_buffer),
                                   &(p_spi_instance->tx_length),
                                   &(p_spi_instance->tx_index));
            spi_master_buffer_init(p_rx_buf,
                                   rx_buf_len,
                                   &(p_spi_instance->p_rx_buffer),
                                   &(p_spi_instance->rx_length),
                                   &(p_spi_instance->rx_index));

            nrf_gpio_pin_clear(p_spi_instance->pin_slave_select);
            spi_master_send_initial_bytes(p_spi_instance);
        }
        else
        {
            err_code = NRF_ERROR_INVALID_PARAM;
        }
    }
    else
    {
        err_code = NRF_ERROR_BUSY;
    }
    
    //Check if disable all IRQs flag is set.
    if (p_spi_instance->disable_all_irq)
    {   
        //Enable interrupts.
        APP_ERROR_CHECK(sd_nvic_critical_region_exit(nested_critical_region));
    }
    else
    {
        //Enable SPI interrupt.
        APP_ERROR_CHECK(sd_nvic_EnableIRQ(p_spi_instance->irq_type));
    }

    return err_code;
    #else
    return NRF_ERROR_NOT_SUPPORTED;
    #endif
}
示例#29
0
/**@brief Function for application main entry, does not return.
 */
int main(void)
{   
    uint32_t err_code;
    
    // Setup UART. 
#if defined(TRACE_UART)
    const app_uart_comm_params_t comm_params =  
    {
        RX_PIN_NUMBER, 
        TX_PIN_NUMBER, 
        RTS_PIN_NUMBER, 
        CTS_PIN_NUMBER, 
        APP_UART_FLOW_CONTROL_DISABLED, 
        false, 
        UART_BAUDRATE_BAUDRATE_Baud38400
    }; 
        
    APP_UART_FIFO_INIT(&comm_params, 
                       UART_RX_BUF_SIZE, 
                       UART_TX_BUF_SIZE, 
                       uart_error_handle, 
                       APP_IRQ_PRIORITY_LOW,
                       err_code);
    APP_ERROR_CHECK(err_code);
#endif
  
    err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, softdevice_assert_callback);
    APP_ERROR_CHECK(err_code);
  
    // Set application IRQ to lowest priority.
    err_code = sd_nvic_SetPriority(SD_EVT_IRQn, NRF_APP_PRIORITY_LOW);
    APP_ERROR_CHECK(err_code);  
    
    // Enable application IRQ (triggered from protocol). 
    err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
    APP_ERROR_CHECK(err_code);    
    
    // Open HRM RX channel.
    hrm_rx_open();

    uint8_t event;
    uint8_t ant_channel;  
    uint8_t event_message_buffer[ANT_EVENT_MSG_BUFFER_MIN_SIZE]; 
    
    printf("Enter hrm rx main processing loop...\n");   
    
    // Main loop.   
    for (;;)
    {   
        err_code = sd_app_evt_wait(); 
        APP_ERROR_CHECK(err_code);    

        // Extract and process all pending ANT events.      
        do
        {
            err_code = sd_ant_event_get(&ant_channel, &event, event_message_buffer);
            if (err_code == NRF_SUCCESS)
            {
                if (event == EVENT_RX)
                {
                    // We are only interested of RX events.
                    hrm_rx_channel_event_handle(event_message_buffer);            
                }
            }            
        } 
        while (err_code == NRF_SUCCESS);
    }
} 
示例#30
0
uint32_t spi_master_open(const spi_master_hw_instance_t    spi_master_hw_instance,
                         spi_master_config_t const * const p_spi_master_config)
{
    #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)

    /* Check against null */
    if (p_spi_master_config == NULL)
    {
        return NRF_ERROR_NULL;
    }

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

    switch (spi_master_hw_instance)
    {
    #ifdef SPI_MASTER_0_ENABLE
        case SPI_MASTER_0:
            spi_master_init_hw_instance(NRF_SPI0, SPI0_TWI0_IRQn, p_spi_instance, p_spi_master_config->SPI_DisableAllIRQ);
            break;
    #endif /* SPI_MASTER_0_ENABLE */

    #ifdef SPI_MASTER_1_ENABLE
        case SPI_MASTER_1:
            spi_master_init_hw_instance(NRF_SPI1, SPI1_TWI1_IRQn, p_spi_instance, p_spi_master_config->SPI_DisableAllIRQ);
            break;
    #endif /* SPI_MASTER_1_ENABLE */

        default:
            break;
    }

    //A Slave select must be set as high before setting it as output,
    //because during connect it to the pin it causes glitches.
    nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS);
    nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SS);
    nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS);

    //Configure GPIO
    nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SCK);
    nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_MOSI);
    nrf_gpio_cfg_input(p_spi_master_config->SPI_Pin_MISO, NRF_GPIO_PIN_NOPULL);
    p_spi_instance->pin_slave_select = p_spi_master_config->SPI_Pin_SS;

    /* Configure SPI hardware */
    p_spi_instance->p_nrf_spi->PSELSCK  = p_spi_master_config->SPI_Pin_SCK;
    p_spi_instance->p_nrf_spi->PSELMOSI = p_spi_master_config->SPI_Pin_MOSI;
    p_spi_instance->p_nrf_spi->PSELMISO = p_spi_master_config->SPI_Pin_MISO;

    p_spi_instance->p_nrf_spi->FREQUENCY = p_spi_master_config->SPI_Freq;

    p_spi_instance->p_nrf_spi->CONFIG =
        (uint32_t)(p_spi_master_config->SPI_CONFIG_CPHA << SPI_CONFIG_CPHA_Pos) |
        (p_spi_master_config->SPI_CONFIG_CPOL << SPI_CONFIG_CPOL_Pos) |
        (p_spi_master_config->SPI_CONFIG_ORDER << SPI_CONFIG_ORDER_Pos);

    /* Clear waiting interrupts and events */
    p_spi_instance->p_nrf_spi->EVENTS_READY = 0;

    APP_ERROR_CHECK(sd_nvic_ClearPendingIRQ(p_spi_instance->irq_type));
    APP_ERROR_CHECK(sd_nvic_SetPriority(p_spi_instance->irq_type, p_spi_master_config->SPI_PriorityIRQ));

    /* Clear event handler */
    p_spi_instance->callback_event_handler = NULL;

    /* Enable interrupt */
    p_spi_instance->p_nrf_spi->INTENSET = (SPI_INTENSET_READY_Set << SPI_INTENCLR_READY_Pos);
    APP_ERROR_CHECK(sd_nvic_EnableIRQ(p_spi_instance->irq_type));

    /* Enable SPI hardware */
    p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);

    /* Change state to IDLE */
    p_spi_instance->state = SPI_MASTER_STATE_IDLE;

    return NRF_SUCCESS;
    #else
    return NRF_ERROR_NOT_SUPPORTED;
    #endif
}