Ejemplo n.º 1
0
/**********************************************************************
name :
function : find free PPI channel
**********************************************************************/
int find_free_PPI_channel(int exclude_channel)
{
	uint32_t err_code = NRF_SUCCESS, chen;
	int start = 0;
	int end = 8;
	int i;

	err_code = sd_softdevice_is_enabled(&softdevice_enabled);
	APP_ERROR_CHECK(err_code);
	if(softdevice_enabled == 0)
	{
		chen = NRF_PPI->CHEN;
	}
	else
	{ 
		err_code = sd_ppi_channel_enable_get(&chen);
		APP_ERROR_CHECK(err_code);
	}
	for (i = start; i < end; i++)
	{	
		//if (! (NRF_PPI->CHEN & (1 << i)))
		if(! ( chen & (1 << i) ) )
		{
			if (i != exclude_channel)
			{
				return i;
			}
		}
	}
	return 255;
}
uint8_t findFreePPIChannel(uint8_t exclude_channel)
{
	uint32_t err_code = NRF_SUCCESS, chen;
	uint8_t  softdevice_enabled;
	uint8_t channelIndex = 0;
	/** Refer S110 Sift Device Specification 10.4 */
	uint8_t nbAppPPIChannels = 0;

	err_code = sd_softdevice_is_enabled(&softdevice_enabled);
	APP_ERROR_CHECK(err_code);
	if(softdevice_enabled == 0)
	{
		chen = NRF_PPI->CHEN;
		nbAppPPIChannels = NB_PPI_APP_CHANNELS_SD_DISABLED;
	}
	else
	{
		err_code = sd_ppi_channel_enable_get(&chen);
		APP_ERROR_CHECK(err_code);
		nbAppPPIChannels = NB_PPI_APP_CHANNELS_SD_ENABLED;
	}
	for (; channelIndex < nbAppPPIChannels; channelIndex++)
	{
		if(! ( chen & (1 << channelIndex) ) )
		{
			if (channelIndex != exclude_channel)
			{
				return channelIndex;
			}
		}
	}
	return UNAVAILABLE_PPI_CHANNEL;
}
Ejemplo n.º 3
0
ret_code_t nrf_drv_clock_init(void)
{
    uint32_t result = NRF_SUCCESS;

    if (m_clock_cb.module_initialized)
    {
        return MODULE_ALREADY_INITIALIZED;
    }

    m_clock_cb.p_hf_head      = NULL;
    m_clock_cb.hfclk_requests = 0;
#ifndef SOFTDEVICE_PRESENT
    m_clock_cb.p_lf_head      = NULL;
    m_clock_cb.lfclk_requests = 0;
    nrf_clock_xtalfreq_set(CLOCK_CONFIG_XTAL_FREQ);
    nrf_clock_lf_src_set((nrf_clock_lf_src_t)CLOCK_CONFIG_LF_SRC);
    nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY);
#if CALIBRATION_SUPPORT
    m_clock_cb.cal_state = CAL_STATE_IDLE;
#endif // CALIBRATION_SUPPORT
#else // SOFTDEVICE_PRESENT
        uint8_t is_enabled;
        result = sd_softdevice_is_enabled(&is_enabled);
        if((result == NRF_SUCCESS) && !is_enabled)
        {
            result = NRF_ERROR_SOFTDEVICE_NOT_ENABLED;
        }
#endif // SOFTDEVICE_PRESENT
    m_clock_cb.module_initialized = true;
    return result;
}
Ejemplo n.º 4
0
void noTone(uint8_t pin)
{
    uint8_t nrf_pin;

    nrf_pin = Pin_nRF51822_to_Arduino(pin);
    if(nrf_pin >= 31)
        return;

    if(nrf_pin != tone_pin)
        return;
    // Stop TIMER
    TONE_USED_TIMER->TASKS_STOP = 1;
    NVIC_DisableIRQ(TONE_USED_TIMER_IRQn);

#if defined(SOFTDEVICE_PRESENT)
    uint8_t softdevice_enabled;
    sd_softdevice_is_enabled(&softdevice_enabled);
    if(softdevice_enabled == 0) {
        NRF_PPI->CHEN &= (1 << TONE_USED_PPI_CHANNAL);
    }
    else {
        sd_ppi_channel_enable_clr(1 << TONE_USED_PPI_CHANNAL);
    }
#else
    NRF_PPI->CHEN &= (1 << TONE_USED_PPI_CHANNAL);
#endif
    // Disable GPIOTE
    NRF_GPIOTE->CONFIG[TONE_USED_GPIOTE_NUM] &= ~( GPIOTE_CONFIG_MODE_Msk | GPIOTE_CONFIG_POLARITY_Msk);
    // Reset variables
    tone_pin    = 0xFF;
    finish_flag = 0;
    inter_count = 0;
}
/**
  * Updates the temperature sample of this instance of MicroBitThermometer
  * only if isSampleNeeded() indicates that an update is required.
  *
  * This call also will add the thermometer to fiber components to receive
  * periodic callbacks.
  *
  * @return MICROBIT_OK on success.
  */
int MicroBitThermometer::updateSample()
{
    if(!(status & MICROBIT_THERMOMETER_ADDED_TO_IDLE))
    {
        // If we're running under a fiber scheduer, register ourselves for a periodic callback to keep our data up to date.
        // Otherwise, we do just do this on demand, when polled through our read() interface.
        fiber_add_idle_component(this);
        status |= MICROBIT_THERMOMETER_ADDED_TO_IDLE;
    }

    // check if we need to update our sample...
    if(isSampleNeeded())
    {
        int32_t processorTemperature;
        uint8_t sd_enabled;

        // For now, we just rely on the nrf senesor to be the most accurate.
        // The compass module also has a temperature sensor, and has the lowest power consumption, so will run the cooler...
        // ...however it isn't trimmed for accuracy during manufacture, so requires calibration.

        sd_softdevice_is_enabled(&sd_enabled);

        if (sd_enabled)
        {
            // If Bluetooth is enabled, we need to go through the Nordic software to safely do this
            sd_temp_get(&processorTemperature);
        }
        else
        {
            // Othwerwise, we access the information directly...
            uint32_t *TEMP = (uint32_t *)0x4000C508;

            NRF_TEMP->TASKS_START = 1;

            while (NRF_TEMP->EVENTS_DATARDY == 0);

            NRF_TEMP->EVENTS_DATARDY = 0;

            processorTemperature = *TEMP;

            NRF_TEMP->TASKS_STOP = 1;
        }


        // Record our reading...
        temperature = processorTemperature / 4;

        // Schedule our next sample.
        sampleTime = system_timer_current_time() + samplePeriod;

        // Send an event to indicate that we'e updated our temperature.
        MicroBitEvent e(id, MICROBIT_THERMOMETER_EVT_UPDATE);
    }

    return MICROBIT_OK;
};
Ejemplo n.º 6
0
ret_code_t nrf_drv_rng_init(nrf_drv_rng_config_t const * p_config)
{
    uint32_t result;

    if (m_rng_cb.state == NRF_DRV_STATE_UNINITIALIZED)
    {
#ifndef SOFTDEVICE_PRESENT

        result = app_fifo_init(&m_rng_cb.rand_pool, m_rng_cb.buffer, RNG_CONFIG_POOL_SIZE);

        if (p_config == NULL)
        {
            p_config = &m_default_config;
        }

        if (result == NRF_SUCCESS)
        {
            if (p_config->error_correction)
            {
                nrf_rng_error_correction_enable();
            }

            nrf_drv_common_irq_enable(RNG_IRQn, p_config->interrupt_priority);

            nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK);

            rng_start();
            m_rng_cb.state = NRF_DRV_STATE_INITIALIZED;
        }
#else
        UNUSED_VARIABLE(p_config);
        uint8_t softdevice_is_enabled;
        result = sd_softdevice_is_enabled(&softdevice_is_enabled);

        if (softdevice_is_enabled)
        {
            m_rng_cb.state = NRF_DRV_STATE_INITIALIZED;
        }
        else
        {
            result = NRF_ERROR_SOFTDEVICE_NOT_ENABLED;
        }
#endif // SOFTDEVICE_PRESENT
    }
    else
    {
        result = NRF_ERROR_INVALID_STATE;
    }
    return result;
}
Ejemplo n.º 7
0
void main_entry(void)
{
	uint32_t res;
	uint8_t enabled;
	volatile int t;
	ble_6lowpan_init_t ble;

	/* enabled LED output */
	nrf_gpio_cfg_output(CONFIG_LED_PIN);
	nrf_gpio_pin_set(CONFIG_LED_PIN);

	/* enabled input pin */
	nrf_gpio_cfg_input(CONFIG_SWITCH_PIN, NRF_GPIO_PIN_NOPULL);

	/* initialize UART */
	uart_init();

	if((res = sd_softdevice_enable(
		NRF_CLOCK_LFCLKSRC_XTAL_20_PPM,
		assert_handler))!=NRF_SUCCESS)
	{
		debug_printf("sd_softdevice_enable failed (0x%02X)\n", res);
		while(1);
	}

	debug_printf("Hello\n");
	ble.p_eui64 = (eui64_t*)&g_eui;
	ble.event_handler = event_handler;
	if((res = ble_6lowpan_init(&ble))!=NRF_SUCCESS)
	{
		debug_printf("ble_6lowpan_init failed (0x%02X)\n", res);
		while(1);
	}

	while(1)
	{
		res = sd_softdevice_is_enabled(&enabled);

		debug_printf("Hello World (0x%08X, %i)\n", res, enabled);
		for(t=0; t<100000; t++);

		if(nrf_gpio_pin_read(CONFIG_SWITCH_PIN))
			nrf_gpio_pin_set(CONFIG_LED_PIN);
		else
			nrf_gpio_pin_clear(CONFIG_LED_PIN);
	}
}
Ejemplo n.º 8
0
void mbed_enter_sleep(sleep_t *obj)
{
    (void)obj;

    // ensure debug is disconnected if semihost is enabled....
    NRF_POWER->TASKS_LOWPWR = 1;

    SCB->SCR |= SCB_SCR_SEVONPEND_Msk; /* send an event when an interrupt is pending.
                                        * This helps with the wakeup from the following app_evt_wait(). */

    uint8_t sd_enabled;

    // look if exceptions are enabled or not, if they are, it is possible to make an SVC call
    // and check if the soft device is running
    if ((__get_PRIMASK() == 0) && (sd_softdevice_is_enabled(&sd_enabled) == NRF_SUCCESS) && (sd_enabled == 1)) {
        // soft device is enabled, use the primitives from the soft device to go to sleep
        sd_app_evt_wait();
    } else {
        // Note: it is not possible to just use WFE at this stage because WFE
        // will read the event register (not accessible) and if an event occured,
        // in the past, it will just clear the event register and continue execution.
        // SVC call like sd_softdevice_is_enabled set the event register to 1.
        // This means that a making an SVC call followed by WFE will never put the
        // CPU to sleep.
        // Our startegy here is to clear the event register then, if there is any
        // interrupt, return from here. If no interrupts are pending, just call
        // WFE.

        // Set an event and wake up whatsoever, this will clear the event
        // register from all previous events set (SVC call included)
        __SEV();
        __WFE();

        // Test if there is an interrupt pending (mask reserved regions)
        if (SCB->ICSR & (SCB_ICSR_RESERVED_BITS_MASK)) {
            // Ok, there is an interrut pending, no need to go to sleep
            return;
        } else {
            // next event will wakeup the CPU
            // If an interrupt occured between the test of SCB->ICSR and this
            // instruction, WFE will just not put the CPU to sleep
            __WFE();
        }
    }
}
/** @brief Function for initializing the twi_master.
 */
bool twi_master_init(void)
{
    /* 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[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] =     \
        (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[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] =      \
        (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_TWI1->EVENTS_RXDREADY = 0;
    NRF_TWI1->EVENTS_TXDSENT  = 0;
    NRF_TWI1->PSELSCL         = TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER;
    NRF_TWI1->PSELSDA         = TWI_MASTER_CONFIG_DATA_PIN_NUMBER;
    NRF_TWI1->FREQUENCY       = TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos;
    
    sd_softdevice_is_enabled(&sd_enabled);
    if(sd_enabled)
    {
        sd_ppi_channel_assign(0, &NRF_TWI1->EVENTS_BB, &NRF_TWI1->TASKS_SUSPEND);
        sd_ppi_channel_enable_clr(1 << 0);
    }
    else
    {
        NRF_PPI->CH[0].EEP        = (uint32_t)&NRF_TWI1->EVENTS_BB;
        NRF_PPI->CH[0].TEP        = (uint32_t)&NRF_TWI1->TASKS_SUSPEND;
        NRF_PPI->CHENCLR          = PPI_CHENCLR_CH0_Msk;
    }    

    NRF_TWI1->ENABLE          = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;

    return twi_master_clear_bus();
}
uint32_t freePPIChannel(uint8_t channel_num)
{
	uint32_t err_code = NRF_SUCCESS;
	uint8_t  softdevice_enabled;

	APP_ERROR_CHECK_BOOL(channel_num != UNAVAILABLE_PPI_CHANNEL
			&& channel_num < NB_PPI_APP_CHANNELS_SD_DISABLED);

	err_code = sd_softdevice_is_enabled(&softdevice_enabled);
	APP_ERROR_CHECK(err_code);
	if (softdevice_enabled == 0)
	{
		NRF_PPI->CHEN &= ~(1 << channel_num);
	}
	else
	{
		err_code = sd_ppi_channel_enable_clr(1 << channel_num);
		APP_ERROR_CHECK(err_code);
	}
}
Ejemplo n.º 11
0
void mbed_enter_sleep(sleep_t *obj)
{
    (void)obj;

    // ensure debug is disconnected if semihost is enabled....
    NRF_POWER->TASKS_LOWPWR = 1;

    SCB->SCR |= SCB_SCR_SEVONPEND_Msk; /* send an event when an interrupt is pending.
                                        * This helps with the wakeup from the following app_evt_wait(). */

    uint8_t sd_enabled;

    // look if exceptions are enabled or not, if they are, it is possible to make an SVC call
    // and check if the soft device is running
    if ((__get_PRIMASK() == 0) && (sd_softdevice_is_enabled(&sd_enabled) == NRF_SUCCESS) && (sd_enabled == 1)) {
        // soft device is enabled, use the primitives from the soft device to go to sleep
        sd_app_evt_wait();
    } else {
        // impossible to use soft device primitive, just wait for events
        __WFE();
    }
}
uint32_t wirePPIChannel(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)
{
	uint32_t err_code = NRF_SUCCESS;
	uint8_t  softdevice_enabled;

	APP_ERROR_CHECK_BOOL(channel_num != UNAVAILABLE_PPI_CHANNEL
			&& channel_num < NB_PPI_APP_CHANNELS_SD_DISABLED);

	err_code = sd_softdevice_is_enabled(&softdevice_enabled);
	APP_ERROR_CHECK(err_code);
	if (softdevice_enabled == 0 )
	{
		NRF_PPI->CH[channel_num].EEP	=	(uint32_t)evt_endpoint;
		NRF_PPI->CH[channel_num].TEP  =	(uint32_t)task_endpoint;
		enablePPIChannel(channel_num);
	}
	else
	{
		err_code = sd_ppi_channel_assign(channel_num, evt_endpoint, task_endpoint);
		APP_ERROR_CHECK(err_code);
		enablePPIChannel(channel_num);
	}
	return 0;
}
Ejemplo n.º 13
0
/****************************************************
*                 Function Definitions
****************************************************/
void tone(uint8_t pin, uint16_t freq, uint32_t duration)
{
    uint8_t nrf_pin;
    uint32_t compare, prescaler;

    nrf_pin = Pin_nRF51822_to_Arduino(pin);
    if(nrf_pin >= 31)
        return;

    log_info("TONE : Start a tone \r\n");
    // Find appropriate values for PRESCALER and COMPARE registers
    uint8_t index;
    for (index=0; index<= 9; index++)
    {
        prescaler = index;
        compare = 16000000UL / freq;
        compare = compare >> (prescaler+1);
        compare = compare - 1;
        if ((compare >= 2) && (compare <= 65535))
            break;
    }
    log_info("TONE : The prescaler is %d \r\n", prescaler);
    log_info("TONE : The compare is %d \r\n", compare);
    // Check duration
    if(duration > 0) {
        finish_flag = 1;
        inter_count = ((freq * duration) / 1000) * 2;
    }
    else {
        finish_flag = 0;
        inter_count = 0xFFFFFFFF;
    }
    // Config GPIOTE task out.
    NRF_GPIOTE->CONFIG[TONE_USED_GPIOTE_NUM] &= ~( GPIOTE_CONFIG_MODE_Msk | GPIOTE_CONFIG_POLARITY_Msk);
    NRF_GPIOTE->CONFIG[TONE_USED_GPIOTE_NUM] = ( (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
                                                 (nrf_pin << GPIOTE_CONFIG_PSEL_Pos) |
                                                 (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |  //Task toggle
                                                 (GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos) //Inital value LOW
                                               );
#if defined(SOFTDEVICE_PRESENT)
    // Check whether softdevice is enbale.
    uint8_t  softdevice_enabled;
    uint32_t error_code;
    sd_softdevice_is_enabled(&softdevice_enabled);
    if(softdevice_enabled == 0) {
        log_info("TONE : Softdevice is disable, config PPI \r\n");
        NRF_PPI->CH[TONE_USED_PPI_CHANNAL].EEP = (uint32_t)(&TONE_USED_TIMER->EVENTS_COMPARE[0]);
        NRF_PPI->CH[TONE_USED_PPI_CHANNAL].TEP = (uint32_t)(&NRF_GPIOTE->TASKS_OUT[TONE_USED_GPIOTE_NUM]);
        NRF_PPI->CHEN |= (1 << TONE_USED_PPI_CHANNAL);
    }
    else {
        log_info("TONE : Softdevice is enable, config PPI \r\n");
        error_code = sd_ppi_channel_assign(TONE_USED_PPI_CHANNAL, &TONE_USED_TIMER->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[TONE_USED_GPIOTE_NUM]);
        APP_ERROR_CHECK(error_code);
        error_code = sd_ppi_channel_enable_set(1 << TONE_USED_PPI_CHANNAL);
        APP_ERROR_CHECK(error_code);
    }
#else
    log_info("TONE : Softdevice is not used, config PPI \r\n");
    NRF_PPI->CH[TONE_USED_PPI_CHANNAL].EEP = (uint32_t)(&TONE_USED_TIMER->EVENTS_COMPARE[0]);
    NRF_PPI->CH[TONE_USED_PPI_CHANNAL].TEP = (uint32_t)(&NRF_GPIOTE->TASKS_OUT[TONE_USED_GPIOTE_NUM]);
    NRF_PPI->CHEN |= (1 << TONE_USED_PPI_CHANNAL);
#endif

    log_info("TONE : Init TIMIERx \r\n");
    // Configure TIMERx
    TONE_USED_TIMER->TASKS_STOP = 1;
    TONE_USED_TIMER->TASKS_CLEAR = 1;

    TONE_USED_TIMER->MODE = TIMER_MODE_MODE_Timer;
    TONE_USED_TIMER->PRESCALER = prescaler;
    TONE_USED_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
    TONE_USED_TIMER->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);

    TONE_USED_TIMER->CC[0] = (uint16_t)(compare);
    TONE_USED_TIMER->EVENTS_COMPARE[0] = 0;

    TONE_USED_TIMER->INTENCLR = 0xFFFFFFFF;
    TONE_USED_TIMER->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos);
    // Enable IRQn
    NVIC_SetPriority(TONE_USED_TIMER_IRQn, APP_IRQ_PRIORITY_LOW);
    NVIC_ClearPendingIRQ(TONE_USED_TIMER_IRQn);
    NVIC_EnableIRQ(TONE_USED_TIMER_IRQn);
    // Start TIMER
    log_info("TONE : Start TIMIERx \r\n");
    TONE_USED_TIMER->TASKS_START = 1;
}
Ejemplo n.º 14
0
static uint8_t wrapper(void) {
    uint8_t softdevice_is_enabled;
    ret_code_t result = sd_softdevice_is_enabled(&softdevice_is_enabled);
    return ((result == NRF_SUCCESS) && (softdevice_is_enabled == 1));
}
Ejemplo n.º 15
0
/**********************************************************************
name :  
function : called by wiring_digital.c
**********************************************************************/
void PPI_ON_TIMER_GPIO(uint32_t gpiote_channel, NRF_TIMER_Type* Timer, uint32_t CC_channel)
{	
	uint32_t err_code = NRF_SUCCESS, chen;

	// Initialize Programmable Peripheral Interconnect
	int chan_0 = find_free_PPI_channel(255);
	int chan_1 = find_free_PPI_channel(chan_0);
	
	if ((chan_0 != 255) && (chan_1 != 255))
	{	
		err_code = sd_softdevice_is_enabled(&softdevice_enabled);
		APP_ERROR_CHECK(err_code);
		if (softdevice_enabled == 0)
		{	
			// Enable PPI using registers
			NRF_PPI->CH[chan_0].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[CC_channel]) );
			NRF_PPI->CH[chan_0].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] );
			NRF_PPI->CHEN |= ( 1 << chan_0);
			// Save PPI channel number
			PPI_Channels_Occupied[gpiote_channel][0] = chan_0;
			
			// Configure PPI channel "chan_1" to toggle "ulPin" pin on every Timer COMPARE[3] match
			NRF_PPI->CH[chan_1].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[3]) );
			NRF_PPI->CH[chan_1].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] );
			NRF_PPI->CHEN |= ( 1 << chan_1);
			// Save PPI channel number
			PPI_Channels_Occupied[gpiote_channel][1] = chan_1;
			//simple_uart_printHEX(NRF_PPI->CHEN);
						
		}
		else
		{	
			//Enable PPI using sd_ppi_x
			err_code = sd_ppi_channel_assign(chan_0, &((*Timer).EVENTS_COMPARE[CC_channel]), &NRF_GPIOTE->TASKS_OUT[gpiote_channel]);
			APP_ERROR_CHECK(err_code);
			err_code = sd_ppi_channel_enable_set(1 << chan_0);
			APP_ERROR_CHECK(err_code);
			//Save PPI channel number
			PPI_Channels_Occupied[gpiote_channel][0] = chan_0;
			
			err_code = sd_ppi_channel_assign(chan_1, &((*Timer).EVENTS_COMPARE[3]), &NRF_GPIOTE->TASKS_OUT[gpiote_channel]);
			APP_ERROR_CHECK(err_code);
			err_code = sd_ppi_channel_enable_set(1 << chan_1 );	
			APP_ERROR_CHECK(err_code);
			//Save PPI channel number
			PPI_Channels_Occupied[gpiote_channel][1] = chan_1;	
			
			err_code = sd_ppi_channel_enable_get(&chen);
			APP_ERROR_CHECK(err_code);
		}

	}

	/*
	if(0 == gpiote_channel)
	{
		NRF_PPI->CH[9].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[CC_channel]) );
		NRF_PPI->CH[9].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] );
		
		NRF_PPI->CHEN |= ( 1 << 9);
		// Save PPI channel number
		PPI_Channels_Occupied[gpiote_channel][0] = 9;

		NRF_PPI->CH[10].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[3]) );
		NRF_PPI->CH[10].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] );
		NRF_PPI->CHEN |= ( 1 << 10);
		// Save PPI channel number
		PPI_Channels_Occupied[gpiote_channel][1] = 10;		
	}
	else if(1 == gpiote_channel)
	{
		NRF_PPI->CH[11].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[CC_channel]) );
		NRF_PPI->CH[11].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] );
		NRF_PPI->CHEN |= ( 1 << 11);
		// Save PPI channel number
		PPI_Channels_Occupied[gpiote_channel][0] = 11;

		NRF_PPI->CH[12].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[3]) );
		NRF_PPI->CH[12].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] );
		NRF_PPI->CHEN |= ( 1 << 12);
		// Save PPI channel number
		PPI_Channels_Occupied[gpiote_channel][1] = 12;		
	}
	else if(2 == gpiote_channel)
	{
		NRF_PPI->CH[13].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[CC_channel]) );
		NRF_PPI->CH[13].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] );
		NRF_PPI->CHEN |= ( 1 << 13);
		// Save PPI channel number
		PPI_Channels_Occupied[gpiote_channel][0] = 13;

		NRF_PPI->CH[14].EEP = (uint32_t)( &((*Timer).EVENTS_COMPARE[3]) );
		NRF_PPI->CH[14].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[gpiote_channel] );
		NRF_PPI->CHEN |= ( 1 << 14);
		// Save PPI channel number
		PPI_Channels_Occupied[gpiote_channel][1] = 14;		
	}
	*/
}
/**********************************************************************
name :
function : disconnect PPI
**********************************************************************/
void ppiOffFromGPIO(uint32_t pin)
{
	uint8_t channel;
	uint32_t err_code = NRF_SUCCESS;
	uint8_t  softdevice_enabled;

	err_code = sd_softdevice_is_enabled(&softdevice_enabled);
	APP_ERROR_CHECK(err_code);

	if(Timer1_Occupied_Pin[0] == pin)
	{
		channel = GPIOTE_Channel_for_Analog[0];

		if(softdevice_enabled == 0)
		{
			NRF_PPI->CHEN &= ~( 1 << PPI_Channels_Occupied[channel][0] );
			NRF_PPI->CHEN &= ~( 1 << PPI_Channels_Occupied[channel][1] );
		}
		else
		{
			err_code = sd_ppi_channel_enable_clr( 1 << PPI_Channels_Occupied[channel][0] );
			APP_ERROR_CHECK(err_code);
			err_code = sd_ppi_channel_enable_clr( 1 << PPI_Channels_Occupied[channel][1] );
			APP_ERROR_CHECK(err_code);
		}
		PPI_Channels_Occupied[channel][0] = 255;
		PPI_Channels_Occupied[channel][1] = 255;
		Timer1_Occupied_Pin[0] = 255;

		gpioteChannelClean(channel);
		GPIOTE_Channel_for_Analog[0] = 255;
	}
	else if(Timer1_Occupied_Pin[1] == pin)
	{

		channel = GPIOTE_Channel_for_Analog[1];
		if(softdevice_enabled == 0)
		{
			NRF_PPI->CHEN &= ~( 1 << PPI_Channels_Occupied[channel][0] );
			NRF_PPI->CHEN &= ~( 1 << PPI_Channels_Occupied[channel][1] );
		}
		else
		{
			err_code = sd_ppi_channel_enable_clr( 1 << PPI_Channels_Occupied[channel][0] );
			APP_ERROR_CHECK(err_code);
			err_code = sd_ppi_channel_enable_clr( 1 << PPI_Channels_Occupied[channel][1] );
			APP_ERROR_CHECK(err_code);
		}
		PPI_Channels_Occupied[channel][0] = 255;
		PPI_Channels_Occupied[channel][1] = 255;
		Timer1_Occupied_Pin[1] = 255;
		gpioteChannelClean(channel);
		GPIOTE_Channel_for_Analog[1] = 255;

	}
	else if(Timer1_Occupied_Pin[2] == pin)
	{
		channel = GPIOTE_Channel_for_Analog[2];
		if(softdevice_enabled == 0)
		{
			NRF_PPI->CHEN &= ~( 1 << PPI_Channels_Occupied[channel][0] );
			NRF_PPI->CHEN &= ~( 1 << PPI_Channels_Occupied[channel][1] );
		}
		else
		{
			err_code = sd_ppi_channel_enable_clr( 1 << PPI_Channels_Occupied[channel][0] );
			APP_ERROR_CHECK(err_code);
			err_code = sd_ppi_channel_enable_clr( 1 << PPI_Channels_Occupied[channel][1] );
			APP_ERROR_CHECK(err_code);
		}
		PPI_Channels_Occupied[channel][0] = 255;
		PPI_Channels_Occupied[channel][1] = 255;
		Timer1_Occupied_Pin[2] = 255;

		gpioteChannelClean(channel);
		GPIOTE_Channel_for_Analog[2] = 255;
	}

	//if all PWM stop, disable TIMER1
	if( Timer1_Occupied_Pin[0] == 255 && Timer1_Occupied_Pin[1] == 255 && Timer1_Occupied_Pin[2] == 255 )
	{
		NRF_TIMER1->TASKS_STOP = 1;
		NRF_TIMER1->INTENCLR = (TIMER_INTENCLR_COMPARE3_Disabled << TIMER_INTENCLR_COMPARE3_Pos);
		NVIC_DisableIRQ(TIMER1_IRQn);
		IntController_unlinkInterrupt(TIMER1_IRQn);
	}

}
Ejemplo n.º 17
0
/**********************************************************************
name :
function : 
**********************************************************************/
void tone(uint32_t pin, uint16_t freq, uint32_t duration)
{
	uint32_t i,prescaler, compare, nrf_pin, err_code = NRF_SUCCESS;
	uint8_t channel, softdevice_enabled;
	
	channel = gpioteChannelFind();
	if(channel == UNAVAILABLE_GPIOTE_CHANNEL)
	{
		return;
	}
	nrf_pin = arduinoToVariantPin(pin);
	if(nrf_pin < 31)
	{
		//save the pin number
		tone_pin = nrf_pin;
		
		// Find appropriate values for PRESCALER and COMPARE registers
		for (i = 0; i <= 9; i++)
		{
			prescaler = i;
			compare = VARIANT_MCK / freq;
			compare = compare >> (prescaler+1);
			compare = compare - 1;
			if ((compare >= 2) && (compare <= 65535))
				break;
		}
		//calculate the interrupts count
		if(duration > 0)
		{	
			finish_flag = 1;
			inter_count = ((freq * duration) / 1000) * 2;
		}
		else
		{
			finish_flag = 0;
			inter_count = 0xFFFFFFFF;
		}
		//
		//pinMode(pin, OUTPUT);
		//digitalWrite(pin, LOW);
		NRF_GPIO->PIN_CNF[nrf_pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
								| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
								| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
								| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
								| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);	
		NRF_GPIO->OUTCLR = (1 << nrf_pin);						
		//pin_state = 0;
		//use ppi and gpiote_task 
		tone_channel = channel;
		gpioteChannelSet(channel);
		nrf_gpiote_task_config(channel, nrf_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
		//configure PPI
		err_code = sd_softdevice_is_enabled(&softdevice_enabled);
		APP_ERROR_CHECK(err_code);
		if (softdevice_enabled == 0)
		{	
			NRF_PPI->CH[6].EEP = (uint32_t)( &NRF_TIMER2->EVENTS_COMPARE[0] );
			NRF_PPI->CH[6].TEP = (uint32_t)( &NRF_GPIOTE->TASKS_OUT[channel]);
			NRF_PPI->CHEN |= ( 1 << 6);
		}
		else
		{
			err_code = sd_ppi_channel_assign(6, &NRF_TIMER2->EVENTS_COMPARE[0], &NRF_GPIOTE->TASKS_OUT[channel]);
			APP_ERROR_CHECK(err_code);
			err_code = sd_ppi_channel_enable_set(1 << 6);
			APP_ERROR_CHECK(err_code);
		}
		//Configure TIMER2
		NRF_TIMER2->TASKS_STOP = 1;
		NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;
		NRF_TIMER2->PRESCALER = prescaler;
		NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
		
		NRF_TIMER2->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);

		NRF_TIMER2->TASKS_CLEAR = 1;
		NRF_TIMER2->CC[0] = (uint16_t)(compare);
		NRF_TIMER2->EVENTS_COMPARE[0] = 0;
		
		NRF_TIMER2->INTENCLR = 0xFFFFFFFF;
		NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos);
		//open IRQ
		IntController_linkInterrupt(TIMER2_IRQn, TIMER2_handler);
		NVIC_EnableIRQ(TIMER2_IRQn);
		NRF_TIMER2->TASKS_START = 1;
	}
/** @brief Function for read by twi_master. 
 */
static bool twi_master_read(uint8_t *data, uint8_t data_length, bool issue_stop_condition)
{
    uint32_t timeout = MAX_TIMEOUT_LOOPS;   /* max loops to wait for RXDREADY event*/

    sd_softdevice_is_enabled(&sd_enabled);
    
    if (data_length == 0)
    {
        /* Return false for requesting data of size 0 */
        return false;
    }
    else if (data_length == 1)
    {
        if(sd_enabled)
        {
            sd_ppi_channel_assign(0, &NRF_TWI1->EVENTS_BB, &NRF_TWI1->TASKS_STOP);
        }
        else
        {
            NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP;
        }
    }
    else
    {
        if(sd_enabled)
        {
            sd_ppi_channel_assign(0, &NRF_TWI1->EVENTS_BB, &NRF_TWI1->TASKS_SUSPEND);
        }
        else
        {
            NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_SUSPEND;
        }
    }
    
    if(sd_enabled)
    {
        sd_ppi_channel_enable_set(1 << 0);
    }
    else
    {
        NRF_PPI->CHENSET          = PPI_CHENSET_CH0_Msk;
    }
    NRF_TWI1->EVENTS_RXDREADY = 0;
    NRF_TWI1->TASKS_STARTRX   = 1;
    
    /** @snippet [TWI HW master read] */                
    while (true)
    {
        while(NRF_TWI1->EVENTS_RXDREADY == 0 && NRF_TWI1->EVENTS_ERROR == 0 && (--timeout))
        {    
            // Do nothing.
        }
        NRF_TWI1->EVENTS_RXDREADY = 0;

        if (timeout == 0 || NRF_TWI1->EVENTS_ERROR != 0)
        {
          // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at 
          // Product Anomaly Notification document found at 
          // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads
          NRF_TWI1->EVENTS_ERROR = 0;
          NRF_TWI1->ENABLE       = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; 
          NRF_TWI1->POWER        = 0; 
          nrf_delay_us(5); 
          NRF_TWI1->POWER        = 1; 
          NRF_TWI1->ENABLE       = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;

          (void)twi_master_init();          
          
          return false;
        }

        *data++ = NRF_TWI1->RXD;

        /* Configure PPI to stop TWI master before we get last BB event */
        if (--data_length == 1)
        {
            sd_softdevice_is_enabled(&sd_enabled);
            if(sd_enabled)
            {
                sd_ppi_channel_assign(0, &NRF_TWI1->EVENTS_BB, &NRF_TWI1->TASKS_STOP);
            }
            else
            {
                NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP;
            }
        }

        if (data_length == 0)
        {
            break;
        }

        // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at 
        // Product Anomaly Notification document found at 
        // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads
        nrf_delay_us(20);      
        NRF_TWI1->TASKS_RESUME = 1;
    }
    /** @snippet [TWI HW master read] */                    

    /* Wait until stop sequence is sent */
    while(NRF_TWI1->EVENTS_STOPPED == 0)
    {
        // Do nothing.
    }
    NRF_TWI1->EVENTS_STOPPED = 0;
    
    sd_softdevice_is_enabled(&sd_enabled);
    if(sd_enabled)
    {
        sd_ppi_channel_enable_clr(1 << 0);
    }
    else
    {
        NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk;
    }
    return true;
}