nrfx_err_t nrfx_twim_xfer(nrfx_twim_t const * p_instance, nrfx_twim_xfer_desc_t const * p_xfer_desc, uint32_t flags) { NRFX_ASSERT(TWIM_LENGTH_VALIDATE(p_instance->drv_inst_idx, p_xfer_desc->primary_length, p_xfer_desc->secondary_length)); nrfx_err_t err_code = NRFX_SUCCESS; twim_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; // TXRX and TXTX transfers are supported only in non-blocking mode. NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXRX))); NRFX_ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRFX_TWIM_XFER_TXTX))); NRFX_LOG_INFO("Transfer type: %s.", TRANSFER_TO_STR(p_xfer_desc->type)); NRFX_LOG_INFO("Transfer buffers length: primary: %d, secondary: %d.", p_xfer_desc->primary_length, p_xfer_desc->secondary_length); NRFX_LOG_DEBUG("Primary buffer data:"); NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length * sizeof(p_xfer_desc->p_primary_buf[0])); NRFX_LOG_DEBUG("Secondary buffer data:"); NRFX_LOG_HEXDUMP_DEBUG(p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length * sizeof(p_xfer_desc->p_secondary_buf[0])); err_code = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->p_twim, p_xfer_desc, flags); NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; }
void nrfx_adc_irq_handler(void) { if (m_cb.p_buffer == NULL) { nrf_adc_event_clear(NRF_ADC_EVENT_END); NRFX_LOG_DEBUG("Event: %s.",NRFX_LOG_ERROR_STRING_GET(NRF_ADC_EVENT_END)); nrf_adc_int_disable(NRF_ADC_INT_END_MASK); nrf_adc_disable(); nrfx_adc_evt_t evt; evt.type = NRFX_ADC_EVT_SAMPLE; evt.data.sample.sample = (nrf_adc_value_t)nrf_adc_result_get(); NRFX_LOG_DEBUG("ADC data:"); NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)(&evt.data.sample.sample), sizeof(nrf_adc_value_t)); m_cb.state = NRFX_DRV_STATE_INITIALIZED; m_cb.event_handler(&evt); } else if (adc_sample_process()) { NRFX_LOG_DEBUG("Event: %s.", NRFX_LOG_ERROR_STRING_GET(NRF_ADC_EVENT_END)); nrf_adc_int_disable(NRF_ADC_INT_END_MASK); nrfx_adc_evt_t evt; evt.type = NRFX_ADC_EVT_DONE; evt.data.done.p_buffer = m_cb.p_buffer; evt.data.done.size = m_cb.size; m_cb.state = NRFX_DRV_STATE_INITIALIZED; NRFX_LOG_DEBUG("ADC data:"); NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)m_cb.p_buffer, m_cb.size * sizeof(nrf_adc_value_t)); m_cb.event_handler(&evt); } }
void nrfx_qdec_accumulators_read(int16_t * p_acc, int16_t * p_accdbl) { NRFX_ASSERT(m_state == NRFX_DRV_STATE_POWERED_ON); nrf_qdec_task_trigger(NRF_QDEC_TASK_READCLRACC); *p_acc = (int16_t)nrf_qdec_accread_get(); *p_accdbl = (int16_t)nrf_qdec_accdblread_get(); NRFX_LOG_DEBUG("Accumulators data, ACC register:"); NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)p_acc, sizeof(p_acc[0])); NRFX_LOG_DEBUG("Accumulators data, ACCDBL register:"); NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)p_accdbl, sizeof(p_accdbl[0])); }
void nrfx_clock_irq_handler(void) { if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_HFCLKSTARTED)); nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK); #if defined(USE_WORKAROUND_FOR_ANOMALY_201) if (!m_clock_cb.hfclk_started) { m_clock_cb.hfclk_started = true; m_clock_cb.event_handler(NRFX_CLOCK_EVT_HFCLK_STARTED); } #else m_clock_cb.event_handler(NRFX_CLOCK_EVT_HFCLK_STARTED); #endif } if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_LFCLKSTARTED)); nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK); m_clock_cb.event_handler(NRFX_CLOCK_EVT_LFCLK_STARTED); } #if CALIBRATION_SUPPORT if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_CTTO)); nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK); m_clock_cb.event_handler(NRFX_CLOCK_EVT_CTTO); } if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE)) { #if defined(USE_WORKAROUND_FOR_ANOMALY_192) *(volatile uint32_t *)0x40000C34 = 0x00000000; #endif nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_DONE)); nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK); m_clock_cb.cal_state = CAL_STATE_IDLE; m_clock_cb.event_handler(NRFX_CLOCK_EVT_CAL_DONE); } #endif // CALIBRATION_SUPPORT }
uint32_t nrfx_pwm_complex_playback(nrfx_pwm_t const * const p_instance, nrf_pwm_sequence_t const * p_sequence_0, nrf_pwm_sequence_t const * p_sequence_1, uint16_t playback_count, uint32_t flags) { pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED); NRFX_ASSERT(playback_count > 0); NRFX_ASSERT(nrfx_is_in_ram(p_sequence_0->values.p_raw)); NRFX_ASSERT(nrfx_is_in_ram(p_sequence_1->values.p_raw)); nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence_0); nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence_1); nrf_pwm_loop_set(p_instance->p_registers, playback_count); uint32_t shorts_mask; if (flags & NRFX_PWM_FLAG_STOP) { shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK; } else if (flags & NRFX_PWM_FLAG_LOOP) { shorts_mask = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; } else { shorts_mask = 0; } nrf_pwm_shorts_set(p_instance->p_registers, shorts_mask); NRFX_LOG_INFO("Function: %s, sequence 0 length: %d.", __func__, p_sequence_0->length); NRFX_LOG_INFO("Function: %s, sequence 1 length: %d.", __func__, p_sequence_1->length); NRFX_LOG_DEBUG("Sequence 0 data:"); NRFX_LOG_HEXDUMP_DEBUG(p_sequence_0->values.p_raw, p_sequence_0->length * sizeof(uint16_t)); NRFX_LOG_DEBUG("Sequence 1 data:"); NRFX_LOG_HEXDUMP_DEBUG(p_sequence_1->values.p_raw, p_sequence_1->length * sizeof(uint16_t)); return start_playback(p_instance, p_cb, flags, NRF_PWM_TASK_SEQSTART0); }
nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance, uint8_t const * p_data, size_t length) { uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED); NRFX_ASSERT(p_data); NRFX_ASSERT(length > 0); nrfx_err_t err_code; if (nrfx_uart_tx_in_progress(p_instance)) { err_code = NRFX_ERROR_BUSY; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } p_cb->tx_buffer_length = length; p_cb->p_tx_buffer = p_data; p_cb->tx_counter = 0; p_cb->tx_abort = false; NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length); NRFX_LOG_DEBUG("Tx data:"); NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer, p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0])); err_code = NRFX_SUCCESS; nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY); nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTTX); tx_byte(p_instance->p_reg, p_cb); if (p_cb->handler == NULL) { if (!tx_blocking(p_instance->p_reg, p_cb)) { // The transfer has been aborted. err_code = NRFX_ERROR_FORBIDDEN; } else { // Wait until the last byte is completely transmitted. while (!nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_TXDRDY)) {} nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX); } p_cb->tx_buffer_length = 0; } NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; }
void nrfx_rng_irq_handler(void) { nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); uint8_t rng_value = nrf_rng_random_value_get(); m_rng_hndl(rng_value); NRFX_LOG_DEBUG("Event: NRF_RNG_EVENT_VALRDY."); }
static void comp_execute_handler(nrf_comp_event_t event, uint32_t event_mask) { if (nrf_comp_event_check(event) && nrf_comp_int_enable_check(event_mask)) { nrf_comp_event_clear(event); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(event)); m_comp_event_handler(event); } }
static void irq_handler(NRF_RTC_Type * p_reg, uint32_t instance_id, uint32_t channel_count) { uint32_t i; uint32_t int_mask = (uint32_t)NRF_RTC_INT_COMPARE0_MASK; nrf_rtc_event_t event = NRF_RTC_EVENT_COMPARE_0; for (i = 0; i < channel_count; i++) { if (nrf_rtc_int_is_enabled(p_reg,int_mask) && nrf_rtc_event_pending(p_reg,event)) { nrf_rtc_event_disable(p_reg,int_mask); nrf_rtc_int_disable(p_reg,int_mask); nrf_rtc_event_clear(p_reg,event); NRFX_LOG_DEBUG("Event: %s, instance id: %lu.", EVT_TO_STR(event), instance_id); m_handlers[instance_id]((nrfx_rtc_int_type_t)i); } int_mask <<= 1; event = (nrf_rtc_event_t)((uint32_t)event + sizeof(uint32_t)); } event = NRF_RTC_EVENT_TICK; if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_TICK_MASK) && nrf_rtc_event_pending(p_reg, event)) { nrf_rtc_event_clear(p_reg, event); NRFX_LOG_DEBUG("Event: %s, instance id: %lu.", EVT_TO_STR(event), instance_id); m_handlers[instance_id](NRFX_RTC_INT_TICK); } event = NRF_RTC_EVENT_OVERFLOW; if (nrf_rtc_int_is_enabled(p_reg,NRF_RTC_INT_OVERFLOW_MASK) && nrf_rtc_event_pending(p_reg, event)) { nrf_rtc_event_clear(p_reg,event); NRFX_LOG_DEBUG("Event: %s, instance id: %lu.", EVT_TO_STR(event), instance_id); m_handlers[instance_id](NRFX_RTC_INT_OVERFLOW); } }
void nrfx_clock_irq_handler(void) { if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_HFCLKSTARTED)); nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK); m_clock_cb.event_handler(NRFX_CLOCK_EVT_HFCLK_STARTED); } if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_LFCLKSTARTED)); nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK); m_clock_cb.event_handler(NRFX_CLOCK_EVT_LFCLK_STARTED); } #if CALIBRATION_SUPPORT if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_CTTO)); nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK); m_clock_cb.event_handler(NRFX_CLOCK_EVT_CTTO); } if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_CLOCK_EVENT_DONE)); nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK); m_clock_cb.cal_state = CAL_STATE_IDLE; m_clock_cb.event_handler(NRFX_CLOCK_EVT_CAL_DONE); } #endif // CALIBRATION_SUPPORT }
void nrfx_qdec_irq_handler(void) { nrfx_qdec_event_t event; if ( nrf_qdec_event_check(NRF_QDEC_EVENT_SAMPLERDY) && nrf_qdec_int_enable_check(NRF_QDEC_INT_SAMPLERDY_MASK) ) { nrf_qdec_event_clear(NRF_QDEC_EVENT_SAMPLERDY); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_SAMPLERDY)); event.type = NRF_QDEC_EVENT_SAMPLERDY; event.data.sample.value = (int8_t)nrf_qdec_sample_get(); m_qdec_event_handler(event); } if ( nrf_qdec_event_check(NRF_QDEC_EVENT_REPORTRDY) && nrf_qdec_int_enable_check(NRF_QDEC_INT_REPORTRDY_MASK) ) { nrf_qdec_event_clear(NRF_QDEC_EVENT_REPORTRDY); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_REPORTRDY)); event.type = NRF_QDEC_EVENT_REPORTRDY; event.data.report.acc = (int16_t)nrf_qdec_accread_get(); event.data.report.accdbl = (uint16_t)nrf_qdec_accdblread_get(); m_qdec_event_handler(event); } if ( nrf_qdec_event_check(NRF_QDEC_EVENT_ACCOF) && nrf_qdec_int_enable_check(NRF_QDEC_INT_ACCOF_MASK) ) { nrf_qdec_event_clear(NRF_QDEC_EVENT_ACCOF); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_QDEC_EVENT_ACCOF)); event.type = NRF_QDEC_EVENT_ACCOF; m_qdec_event_handler(event); } }
uint32_t nrfx_pwm_simple_playback(nrfx_pwm_t const * const p_instance, nrf_pwm_sequence_t const * p_sequence, uint16_t playback_count, uint32_t flags) { pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; NRFX_ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED); NRFX_ASSERT(playback_count > 0); NRFX_ASSERT(nrfx_is_in_ram(p_sequence->values.p_raw)); // To take advantage of the looping mechanism, we need to use both sequences // (single sequence can be played back only once). nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence); nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence); bool odd = (playback_count & 1); nrf_pwm_loop_set(p_instance->p_registers, (playback_count / 2) + (odd ? 1 : 0)); uint32_t shorts_mask; if (flags & NRFX_PWM_FLAG_STOP) { shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK; } else if (flags & NRFX_PWM_FLAG_LOOP) { shorts_mask = odd ? NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK : NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; } else { shorts_mask = 0; } nrf_pwm_shorts_set(p_instance->p_registers, shorts_mask); NRFX_LOG_INFO("Function: %s, sequence length: %d.", __func__, p_sequence->length); NRFX_LOG_DEBUG("Sequence data:"); NRFX_LOG_HEXDUMP_DEBUG((uint8_t *)p_sequence->values.p_raw, p_sequence->length * sizeof(uint16_t)); return start_playback(p_instance, p_cb, flags, odd ? NRF_PWM_TASK_SEQSTART1 : NRF_PWM_TASK_SEQSTART0); }
static void uart_irq_handler(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) { if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) && nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR)) { nrfx_uart_event_t event; nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_UART_EVENT_ERROR)); nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); if (!p_cb->rx_enabled) { nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX); } event.type = NRFX_UART_EVT_ERROR; event.data.error.error_mask = nrf_uart_errorsrc_get_and_clear(p_uart); event.data.error.rxtx.bytes = p_cb->rx_buffer_length; event.data.error.rxtx.p_data = p_cb->p_rx_buffer; // Abort transfer. p_cb->rx_buffer_length = 0; p_cb->rx_secondary_buffer_length = 0; p_cb->handler(&event,p_cb->p_context); } else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) && nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY)) { rx_byte(p_uart, p_cb); if (p_cb->rx_buffer_length == p_cb->rx_counter) { if (p_cb->rx_secondary_buffer_length) { uint8_t * p_data = p_cb->p_rx_buffer; size_t rx_counter = p_cb->rx_counter; // Switch to secondary buffer. p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length; p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer; p_cb->rx_secondary_buffer_length = 0; p_cb->rx_counter = 0; rx_done_event(p_cb, rx_counter, p_data); } else { if (!p_cb->rx_enabled) { nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX); } nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); p_cb->rx_buffer_length = 0; rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer); } } } if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY)) { if (p_cb->tx_counter < p_cb->tx_buffer_length && !p_cb->tx_abort) { tx_byte(p_uart, p_cb); } else { nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY); if (p_cb->tx_buffer_length) { tx_done_event(p_cb, p_cb->tx_buffer_length); } } } if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO)) { nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO); // RXTO event may be triggered as a result of abort call. In th if (p_cb->rx_enabled) { nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX); } if (p_cb->rx_buffer_length) { p_cb->rx_buffer_length = 0; rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer); } } }
nrfx_err_t nrfx_uarte_tx(nrfx_uarte_t const * p_instance, uint8_t const * p_data, size_t length) { uarte_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED); NRFX_ASSERT(p_data); NRFX_ASSERT(length > 0); NRFX_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length)); nrfx_err_t err_code; // EasyDMA requires that transfer buffers are placed in DataRAM, // signal error if the are not. if (!nrfx_is_in_ram(p_data)) { err_code = NRFX_ERROR_INVALID_ADDR; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } if (nrfx_uarte_tx_in_progress(p_instance)) { err_code = NRFX_ERROR_BUSY; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } p_cb->tx_buffer_length = length; p_cb->p_tx_buffer = p_data; NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length); NRFX_LOG_DEBUG("Tx data:"); NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer, p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0])); err_code = NRFX_SUCCESS; nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX); nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED); nrf_uarte_tx_buffer_set(p_instance->p_reg, p_cb->p_tx_buffer, p_cb->tx_buffer_length); nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTTX); if (p_cb->handler == NULL) { bool endtx; bool txstopped; do { endtx = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDTX); txstopped = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_TXSTOPPED); } while ((!endtx) && (!txstopped)); if (txstopped) { err_code = NRFX_ERROR_FORBIDDEN; } p_cb->tx_buffer_length = 0; } NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; }
static void twim_irq_handler(NRF_TWIM_Type * p_twim, twim_control_block_t * p_cb) { #if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED) /* Handle only workaround case. Can be used without TWIM handler in IRQs. */ if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED)) { nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); nrf_twim_int_disable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK); if (p_twim->FREQUENCY == 0) { // Set enable to zero to reset TWIM internal state. nrf_twim_disable(p_twim); nrf_twim_enable(p_twim); // Set proper frequency. nrf_twim_frequency_set(p_twim, p_cb->bus_frequency); twim_list_enable_handle(p_twim, p_cb->flags); // Start proper transmission. nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); return; } } #endif NRFX_ASSERT(p_cb->handler); if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR)) { nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR)); if (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED)) { nrf_twim_int_disable(p_twim, p_cb->int_mask); p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK; nrf_twim_int_enable(p_twim, p_cb->int_mask); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); return; } } nrfx_twim_evt_t event; if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED)) { NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED)); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED); event.xfer_desc = p_cb->xfer_desc; if (p_cb->error) { event.xfer_desc.primary_length = (p_cb->xfer_desc.type == NRFX_TWIM_XFER_RX) ? nrf_twim_rxd_amount_get(p_twim) : nrf_twim_txd_amount_get(p_twim); event.xfer_desc.secondary_length = (p_cb->xfer_desc.type == NRFX_TWIM_XFER_TXRX) ? nrf_twim_rxd_amount_get(p_twim) : nrf_twim_txd_amount_get(p_twim); } nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX); if (!p_cb->repeated || p_cb->error) { nrf_twim_shorts_set(p_twim, 0); p_cb->int_mask = 0; nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK); } } else { nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED)); if (p_cb->xfer_desc.type == NRFX_TWIM_XFER_TX) { event.xfer_desc = p_cb->xfer_desc; if (!p_cb->repeated) { nrf_twim_shorts_set(p_twim, 0); p_cb->int_mask = 0; nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK); } } else { nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK); nrf_twim_int_enable(p_twim, p_cb->int_mask); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); return; } } uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim); if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK) { event.type = NRFX_TWIM_EVT_ADDRESS_NACK; NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_ADDRESS_NACK)); } else if (errorsrc & NRF_TWIM_ERROR_DATA_NACK) { event.type = NRFX_TWIM_EVT_DATA_NACK; NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DATA_NACK)); } else { event.type = NRFX_TWIM_EVT_DONE; NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRFX_TWIM_EVT_DONE)); } if (!p_cb->repeated) { p_cb->busy = false; } p_cb->handler(&event, p_cb->p_context); }
__STATIC_INLINE nrfx_err_t twim_xfer(twim_control_block_t * p_cb, NRF_TWIM_Type * p_twim, nrfx_twim_xfer_desc_t const * p_xfer_desc, uint32_t flags) { nrfx_err_t err_code = NRFX_SUCCESS; nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX; nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED; if (!nrfx_is_in_ram(p_xfer_desc->p_primary_buf)) { err_code = NRFX_ERROR_INVALID_ADDR; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */ nrf_twim_int_disable(p_twim, NRF_TWIM_ALL_INTS_MASK); if (p_cb->busy) { nrf_twim_int_enable(p_twim, p_cb->int_mask); err_code = NRFX_ERROR_BUSY; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } else { p_cb->busy = ((NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER & flags) || (NRFX_TWIM_FLAG_REPEATED_XFER & flags)) ? false: true; } p_cb->xfer_desc = *p_xfer_desc; p_cb->repeated = (flags & NRFX_TWIM_FLAG_REPEATED_XFER) ? true : false; nrf_twim_address_set(p_twim, p_xfer_desc->address); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); twim_list_enable_handle(p_twim, flags); switch (p_xfer_desc->type) { case NRFX_TWIM_XFER_TXTX: NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_REPEATED_XFER)); NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_HOLD_XFER)); NRFX_ASSERT(!(flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER)); if (!nrfx_is_in_ram(p_xfer_desc->p_secondary_buf)) { err_code = NRFX_ERROR_INVALID_ADDR; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED)) {} NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED)); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length); p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK; break; case NRFX_TWIM_XFER_TXRX: nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); if (!nrfx_is_in_ram(p_xfer_desc->p_secondary_buf)) { err_code = NRFX_ERROR_INVALID_ADDR; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length); nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK | NRF_TWIM_SHORT_LASTRX_STOP_MASK); p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; break; case NRFX_TWIM_XFER_TX: nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); if (NRFX_TWIM_FLAG_TX_NO_STOP & flags) { nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK; nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); evt_to_wait = NRF_TWIM_EVENT_SUSPENDED; } else { nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; } nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); break; case NRFX_TWIM_XFER_RX: nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK); p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; start_task = NRF_TWIM_TASK_STARTRX; nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); break; default: err_code = NRFX_ERROR_INVALID_PARAM; break; } if (!(flags & NRFX_TWIM_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRFX_TWIM_XFER_TXTX)) { nrf_twim_task_trigger(p_twim, start_task); } if (p_cb->handler) { if (flags & NRFX_TWIM_FLAG_NO_XFER_EVT_HANDLER) { p_cb->int_mask = NRF_TWIM_INT_ERROR_MASK; } nrf_twim_int_enable(p_twim, p_cb->int_mask); #if NRFX_CHECK(NRFX_TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED) if ((flags & NRFX_TWIM_FLAG_HOLD_XFER) && ((p_xfer_desc->type == NRFX_TWIM_XFER_TX) || (p_xfer_desc->type == NRFX_TWIM_XFER_TXRX))) { p_cb->flags = flags; twim_list_enable_handle(p_twim, 0); p_twim->FREQUENCY = 0; nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); nrf_twim_int_enable(p_twim, NRF_TWIM_INT_TXSTARTED_MASK); } #endif } else { while (!nrf_twim_event_check(p_twim, evt_to_wait)) { if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR)) { NRFX_LOG_DEBUG("TWIM: Event: %s.", EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR)); nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); evt_to_wait = NRF_TWIM_EVENT_STOPPED; } } uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim); p_cb->busy = false; if (errorsrc) { err_code = twi_process_error(errorsrc); } } return err_code; }