コード例 #1
0
ファイル: uart.c プロジェクト: heyuanjie87/rt-thread
void UART0_IRQHandler(void)
{
    if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR)
        && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR))
    {
        nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR);
    }

    if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_RXDRDY)
        && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY))
    {
        rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_RX_IND);
    }

    if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_TXDRDY)
        && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY))
    {
        rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_TX_DONE);
    }

    if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXTO))
    {
        rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_RX_TIMEOUT);
    }
}
コード例 #2
0
ファイル: uart_nrfx_uart.c プロジェクト: agatti/zephyr
/**
 * @brief Output a character in polled mode.
 *
 * @param dev UART device struct
 * @param c Character to send
 *
 * @return Sent character
 */
static unsigned char uart_nrfx_poll_out(struct device *dev,
					unsigned char c)
{
	/* The UART API dictates that poll_out should wait for the transmitter
	 * to be empty before sending a character. However, without locking,
	 * this introduces a rare yet possible race condition if the thread is
	 * preempted between sending the byte and checking for completion.

	 * Because of this race condition, the while loop has to be placed
	 * after the write to TXD, and we can't wait for an empty transmitter
	 * before writing. This is a trade-off between losing a byte once in a
	 * blue moon against hanging up the whole thread permanently
	 */

	/* reset transmitter ready state */
	nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY);

	/* send a character */
	nrf_uart_txd_set(NRF_UART0, (u8_t)c);

	/* Wait for transmitter to be ready */
	while (!nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY)) {
	}

	return c;
}
コード例 #3
0
ファイル: uart.c プロジェクト: nodish/openthread
/**
 * Interrupt handler of UART0 peripherial.
 */
void UARTE0_UART0_IRQHandler(void)
{
    // Check if any error has been detected.
    if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_ERROR))
    {
        // Clear error event and ignore erronous byte in RXD register.
        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR);
        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);
    }
    else if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_RXDRDY))
    {
        // Clear RXDRDY event.
        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY);

        // Read byte from the UART buffer.
        uint8_t byte = nrf_uart_rxd_get(UART_INSTANCE);

        if (!isRxBufferFull())
        {
            sReceiveBuffer[sReceiveHead] = byte;
            sReceiveHead                 = (sReceiveHead + 1) % UART_RX_BUFFER_SIZE;
            otSysEventSignalPending();
        }
    }

    if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY))
    {
        // Clear TXDRDY event.
        nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY);

        // Send any more bytes if available or call application about TX done.
        if (sTransmitLength)
        {
            nrf_uart_txd_set(UART_INSTANCE, *sTransmitBuffer++);
            sTransmitLength--;
        }
        else
        {
            sTransmitDone = true;
            nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STOPTX);
            otSysEventSignalPending();
        }
    }
}
コード例 #4
0
ファイル: nrfx_uart.c プロジェクト: abtink/openthread
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;
}
コード例 #5
0
ファイル: uart_nrfx_uart.c プロジェクト: agatti/zephyr
/** Console I/O function */
static int uart_nrfx_err_check(struct device *dev)
{
	u32_t error = 0;

	if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR)) {
		/* register bitfields maps to the defines in uart.h */
		error = nrf_uart_errorsrc_get_and_clear(NRF_UART0);
	}

	return error;
}
コード例 #6
0
ファイル: uart_nrfx_uart.c プロジェクト: agatti/zephyr
static int uart_nrfx_poll_in(struct device *dev, unsigned char *c)
{
	if (!nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY)) {
		return -1;
	}

	/* Clear the interrupt */
	nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXDRDY);

	/* got a character */
	*c = nrf_uart_rxd_get(NRF_UART0);

	return 0;
}
コード例 #7
0
ファイル: uart_nrfx_uart.c プロジェクト: agatti/zephyr
/** Interrupt driven FIFO read function */
static int uart_nrfx_fifo_read(struct device *dev,
			       u8_t *rx_data,
			       const int size)
{
	u8_t num_rx = 0;

	while ((size - num_rx > 0) &&
	       nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY)) {
		/* Clear the interrupt */
		nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXDRDY);

		/* Receive a character */
		rx_data[num_rx++] = (u8_t)nrf_uart_rxd_get(NRF_UART0);
	}

	return num_rx;
}
コード例 #8
0
ファイル: uart_nrfx_uart.c プロジェクト: agatti/zephyr
/** Interrupt driven FIFO fill function */
static int uart_nrfx_fifo_fill(struct device *dev,
			       const u8_t *tx_data,
			       int len)
{
	u8_t num_tx = 0;

	while ((len - num_tx > 0) &&
	       nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY)) {
		/* Clear the interrupt */
		nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY);

		/* Send a character */
		nrf_uart_txd_set(NRF_UART0, (u8_t)tx_data[num_tx++]);
	}

	return (int)num_tx;
}
コード例 #9
0
ファイル: nrfx_uart.c プロジェクト: abtink/openthread
static bool tx_blocking(NRF_UART_Type * p_uart, uart_control_block_t * p_cb)
{
    while (p_cb->tx_counter < p_cb->tx_buffer_length)
    {
        // Wait until the transmitter is ready to accept a new byte.
        // Exit immediately if the transfer has been aborted.
        while (!nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY))
        {
            if (p_cb->tx_abort)
            {
                return false;
            }
        }

        tx_byte(p_uart, p_cb);
    }

    return true;
}
コード例 #10
0
ファイル: uart.c プロジェクト: heyuanjie87/rt-thread
static int _uart_getc(struct rt_serial_device *serial)
{
    int ch = -1;
    UART_CFG_T *instance = working_cfg;

    RT_ASSERT(serial != RT_NULL);

    if (serial->parent.user_data != RT_NULL)
    {
        instance = (UART_CFG_T*)serial->parent.user_data;
    }

    if (nrf_uart_event_check(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY))
    {
        nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY);
        ch = (int)(nrf_uart_rxd_get(instance->uart.reg.p_uart));
    }

    return ch;
}
コード例 #11
0
ファイル: uart.c プロジェクト: heyuanjie87/rt-thread
static int _uart_putc(struct rt_serial_device *serial, char c)
{
    UART_CFG_T *instance = working_cfg;

    RT_ASSERT(serial != RT_NULL);

    if (serial->parent.user_data != RT_NULL)
    {
        instance = (UART_CFG_T*)serial->parent.user_data;
    }

    nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_TXDRDY);
    nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTTX);
    nrf_uart_txd_set(instance->uart.reg.p_uart, (uint8_t)c);
    while (!nrf_uart_event_check(instance->uart.reg.p_uart, NRF_UART_EVENT_TXDRDY))
    {
    }

    return 1;
}
コード例 #12
0
ファイル: nrfx_uart.c プロジェクト: abtink/openthread
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);
        }
    }
}
コード例 #13
0
ファイル: nrfx_uart.c プロジェクト: abtink/openthread
bool nrfx_uart_rx_ready(nrfx_uart_t const * p_instance)
{
    return nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
}
コード例 #14
0
ファイル: nrfx_uart.c プロジェクト: abtink/openthread
nrfx_err_t nrfx_uart_rx(nrfx_uart_t const * p_instance,
                        uint8_t *           p_data,
                        size_t              length)
{
    uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx];

    NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_INITIALIZED);
    NRFX_ASSERT(p_data);
    NRFX_ASSERT(length > 0);

    nrfx_err_t err_code;

    bool second_buffer = false;

    if (p_cb->handler)
    {
        nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
                                                NRF_UART_INT_MASK_ERROR);
    }
    if (p_cb->rx_buffer_length != 0)
    {
        if (p_cb->rx_secondary_buffer_length != 0)
        {
            if (p_cb->handler)
            {
                nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
                                                       NRF_UART_INT_MASK_ERROR);
            }
            err_code = NRFX_ERROR_BUSY;
            NRFX_LOG_WARNING("Function: %s, error code: %s.",
                             __func__,
                             NRFX_LOG_ERROR_STRING_GET(err_code));
            return err_code;
        }
        second_buffer = true;
    }

    if (!second_buffer)
    {
        p_cb->rx_buffer_length = length;
        p_cb->p_rx_buffer      = p_data;
        p_cb->rx_counter       = 0;
        p_cb->rx_secondary_buffer_length = 0;
    }
    else
    {
        p_cb->p_rx_secondary_buffer = p_data;
        p_cb->rx_secondary_buffer_length = length;
    }

    NRFX_LOG_INFO("Transfer rx_len: %d.", length);

    if ((!p_cb->rx_enabled) && (!second_buffer))
    {
        rx_enable(p_instance);
    }

    if (p_cb->handler == NULL)
    {
        nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXTO);

        bool rxrdy;
        bool rxto;
        bool error;
        do
        {
            do
            {
                error = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_ERROR);
                rxrdy = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY);
                rxto  = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXTO);
            } while ((!rxrdy) && (!rxto) && (!error));

            if (error || rxto)
            {
                break;
            }
            rx_byte(p_instance->p_reg, p_cb);
        } while (p_cb->rx_buffer_length > p_cb->rx_counter);

        p_cb->rx_buffer_length = 0;
        if (error)
        {
            err_code = NRFX_ERROR_INTERNAL;
            NRFX_LOG_WARNING("Function: %s, error code: %s.",
                             __func__,
                             NRFX_LOG_ERROR_STRING_GET(err_code));
            return err_code;
        }

        if (rxto)
        {
            err_code = NRFX_ERROR_FORBIDDEN;
            NRFX_LOG_WARNING("Function: %s, error code: %s.",
                             __func__,
                             NRFX_LOG_ERROR_STRING_GET(err_code));
            return err_code;
        }

        if (p_cb->rx_enabled)
        {
            nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX);
        }
        else
        {
            // Skip stopping RX if driver is forced to be enabled.
            nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX);
        }
    }
    else
    {
        nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY |
                                               NRF_UART_INT_MASK_ERROR);
    }
    err_code = NRFX_SUCCESS;
    NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code));
    return err_code;
}
コード例 #15
0
ファイル: uart_nrfx_uart.c プロジェクト: agatti/zephyr
/** Interrupt driven receiver ready function */
static int uart_nrfx_irq_rx_ready(struct device *dev)
{
	return nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY);
}
コード例 #16
0
ファイル: uart_nrfx_uart.c プロジェクト: agatti/zephyr
/** Interrupt driven transfer empty function */
static int uart_nrfx_irq_tx_complete(struct device *dev)
{
	return !nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY);
}