bool twi_master_read(uint8_t address, uint8_t *rx_data, uint8_t rx_data_length,twi_config_t *cfg)
{
    if(rx_data_length == 0)
    {
        return false;
    }
		active_config =cfg;

    cfg->twi->ADDRESS = address;
    rx_data_ptr = rx_data;
    rx_bytes_to_receive = rx_data_length;
    
    if (rx_bytes_to_receive == 1)
    {
        sd_ppi_channel_assign(cfg->twi_ppi_ch, &cfg->twi->EVENTS_BB, &cfg->twi->TASKS_STOP);
    }
    else
    {
        sd_ppi_channel_assign(cfg->twi_ppi_ch, &cfg->twi->EVENTS_BB, &cfg->twi->TASKS_SUSPEND);
    }
    sd_ppi_channel_enable_set(1 << cfg->twi_ppi_ch);
    
    cfg->twi->TASKS_STARTRX = 1;
    cfg->twi_operation_complete = false;

    while(cfg->twi_operation_complete == false);
		active_config =0;
    return cfg->twi_ack_received;
}
static void ppi_enable_channels(uint32_t ch_msk)
{
#if(USE_WITH_SOFTDEVICE == 1)
    sd_ppi_channel_enable_set(ch_msk);
#else
    NRF_PPI->CHENSET = (ch_msk);   
#endif
}
Пример #3
0
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*/

	if (data_length == 0) {
		/* gently return false for requesting data of size 0 */
		return false;
	}

	if (data_length == 1) {
		//NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP;

		sd_ppi_channel_assign(0, &(NRF_TWI1->EVENTS_BB),
				&(NRF_TWI1->TASKS_STOP));
	} else {
		//NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_SUSPEND;
		sd_ppi_channel_assign(0, &(NRF_TWI1->EVENTS_BB),
				&(NRF_TWI1->TASKS_SUSPEND));

	}
	//NRF_PPI->CHENSET = PPI_CHENSET_CH0_Msk;
	sd_ppi_channel_enable_set(PPI_CHEN_CH0_Msk);
	NRF_TWI1->TASKS_STARTRX = 1;
	while (true) {

		while ((NRF_TWI1->EVENTS_RXDREADY == 0) && (--timeout)) { //nrf_app_event_wait();
		}

		if (timeout == 0) {
			/* timeout before receiving event*/
			return false;
		}

		NRF_TWI1->EVENTS_RXDREADY = 0;
		*data++ = NRF_TWI1->RXD;

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

		if (data_length == 0)
			break;

		NRF_TWI1->TASKS_RESUME = 1;
	}

	/* wait until stop sequence is sent and clear the EVENTS_STOPPED */
	while (NRF_TWI1->EVENTS_STOPPED == 0) {  //nrf_app_event_wait();
	}
	NRF_TWI1->EVENTS_STOPPED = 0;

	//  NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk;
	sd_ppi_channel_enable_clr(PPI_CHEN_CH0_Msk);
	return true;
}
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);
}
Пример #5
0
void gpiote_toggle_led_init()
{
    sd_ppi_channel_assign(TOGGLE_LED_GPIOTE_CHANNEL, &(NRF_TIMER2->EVENTS_COMPARE[0]) ,&(NRF_GPIOTE->TASKS_OUT[0]));

    nrf_gpio_cfg_output(SECONDARY_LED_PIN);
    nrf_gpio_pin_clear(SECONDARY_LED_PIN);
    nrf_gpiote_task_config(TOGGLE_LED_GPIOTE_CHANNEL, SECONDARY_LED_PIN, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    sd_ppi_channel_enable_set(PPI_CHEN_CH0_Msk);
}
Пример #6
0
/* @brief PPI initialisation function.
 *
 * @details This function will initialise Programmable Peripheral Interconnect peripheral. It will
 *          configure the PPI channels as follows -
 *              PPI Channel 0 - Connecting CC0 Compare event to GPIOTE Task to toggle the LED state
 *          This configuration will feed a PWM input to the LED thereby making it flash in an
 *          interval that is dependent on the TIMER configuration.
 */
static void ppi_init(void)
{
    /* Configure PPI channel 0 to toggle PWM_OUTPUT_PIN on every TIMER2 COMPARE[0] match */
    sd_ppi_channel_assign(0, &(NRF_TIMER1->EVENTS_COMPARE[0]), &(NRF_GPIOTE->TASKS_OUT[0]));

    /* Configure PPI channel 1 to toggle PWM_OUTPUT_PIN on every TIMER2 COMPARE[1] match */
    sd_ppi_channel_assign(1,&(NRF_TIMER1->EVENTS_COMPARE[1]),&(NRF_GPIOTE->TASKS_OUT[0]));

    /* Enable only PPI channels 0 and 1 */
    sd_ppi_channel_enable_set(PPI_CHEN_CH0_Msk | PPI_CHEN_CH1_Msk);
}
static void twi_interrupt_internal(NRF_TWI_Type * twi_master)
{
    if(twi_master->EVENTS_TXDSENT)
    {
        twi_master->EVENTS_TXDSENT = 0;
        if(tx_bytes_to_send)
        {
            twi_master->TXD = *tx_data_ptr++;  
            tx_bytes_to_send--;
        }
        else 
        {
            if(rx_bytes_to_receive == 0)
            {
                twi_master->TASKS_STOP = 1; 
            }
            else
            {
                sd_ppi_channel_enable_set(1 << active_config->twi_ppi_ch);

                twi_master->TASKS_STARTRX = 1;
            }
        }
    }
    if(twi_master->EVENTS_STOPPED)
    {
        twi_master->EVENTS_STOPPED = 0;
        active_config->twi_operation_complete = true;
        active_config->twi_ack_received = true;
    }
    if(twi_master->EVENTS_RXDREADY)
    {
        twi_master->EVENTS_RXDREADY = 0;
        *rx_data_ptr++ = twi_master->RXD;
        if (--rx_bytes_to_receive == 1)
        {
            sd_ppi_channel_assign(active_config->twi_ppi_ch, &twi_master->EVENTS_BB, &twi_master->TASKS_STOP);  
        }

        if(rx_bytes_to_receive > 0)
        {
            twi_master->TASKS_RESUME = 1;
        }
    }
    if(twi_master->EVENTS_ERROR)
    {
        twi_master->EVENTS_ERROR = 0;
        active_config->twi_operation_complete = true;
        active_config->twi_ack_received = false;
    }
}
Пример #8
0
/** @brief Function for the PPI initialization.
 *
 * @details This function will initialise Programmable Peripheral Interconnect peripheral. It will
 *          configure the PPI channels as follows -
 *              PPI Channel 0 - Connecting CC0 Compare event to GPIOTE Task to toggle the LED state
 *          This configuration will feed a PWM input to the LED thereby making it flash in an
 *          interval that is dependent on the TIMER configuration.
 */
static void ppi_init(void)
{
    uint32_t err_code;

    // Configure PPI channel 0 to toggle ADVERTISING_LED_PIN_NO on every TIMER1 COMPARE[0] match
    err_code = sd_ppi_channel_assign(PPI_CHAN0_TO_TOGGLE_LED,
                                     &(NRF_TIMER1->EVENTS_COMPARE[0]),
                                     &(NRF_GPIOTE->TASKS_OUT[GPIOTE_CHAN_FOR_LED_TASK]));
    APP_ERROR_CHECK(err_code);

    // Enable PPI channel 0
    err_code = sd_ppi_channel_enable_set(PPI_CHEN_CH0_Msk);
    APP_ERROR_CHECK(err_code);
}
Пример #9
0
/*---------------------------------------------------------------------------*/ 
static void buzzer_ppi_config(void)
{
    /*  
     *  Configure PPI channel 0 to toggle GPIO_OUTPUT_PIN on 
     *  every TIMER0 COMPARE[0] match (300µs)
     */
    sd_ppi_channel_assign(GPIOTE_CHANNEL_NUMBER_0,
                          &BUZZ_TIMER->EVENTS_COMPARE[0],
                          &NRF_GPIOTE->TASKS_OUT[GPIOTE_CHANNEL_NUMBER_0]);

    sd_ppi_channel_assign(GPIOTE_CHANNEL_NUMBER_1, 
                          &BUZZ_TIMER->EVENTS_COMPARE[0], 
                          &NRF_GPIOTE->TASKS_OUT[GPIOTE_CHANNEL_NUMBER_1]);

    /* Enable PPI channels */
    sd_ppi_channel_enable_set((PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos) |
                              (PPI_CHEN_CH1_Enabled << PPI_CHEN_CH1_Pos));
}
Пример #10
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;
}
void enablePPIChannel(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_set(1 << channel_num);
		APP_ERROR_CHECK(err_code);
	}
}
Пример #12
0
uint32_t nrf_drv_ppi_channel_enable(nrf_ppi_channel_t channel)
{
    uint32_t err_code;

    if (!is_app_channel(channel))
    {
        err_code = NRF_ERROR_INVALID_PARAM;
    }
    else if (is_programmable_app_channel(channel) && !is_allocated_channel(channel))
    {
        err_code = NRF_ERROR_INVALID_STATE;
    }
    else
    {
#if (NRF_PPI_RESTRICTED > 0)
        err_code = sd_ppi_channel_enable_set(channel_to_mask(channel));
#else
        nrf_ppi_channel_enable(channel);
        err_code = NRF_SUCCESS;
#endif
    }

    return err_code;
}
Пример #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;
}
/** @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;
}
Пример #15
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;
	}
Пример #16
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;		
	}
	*/
}