Ejemplo n.º 1
0
static ssize_t IRAM_ATTR uart_read(int fd, void* data, size_t size)
{
    assert(fd >=0 && fd < 3);
    uint8_t *data_c = (uint8_t *) data;
    uart_dev_t* uart = s_uarts[fd];
    size_t received = 0;
    _lock_acquire_recursive(&s_uart_locks[fd]);
    while (uart->status.rxfifo_cnt > 0 && received < size) {
        uint8_t c = uart->fifo.rw_byte;
#if CONFIG_NEWLIB_STDOUT_ADDCR
        /* Convert \r\n sequences to \n.
         * If \r is received, it is put into 'buffered_char' until the next
         * character is received. Then depending on the character, we either
         * drop \r (if the next one is \n) or output \r and then proceed to output
         * the new character.
         */
        const int NONE = -1;
        static int buffered_char = NONE;
        if (buffered_char != NONE) {
            if (buffered_char == '\r' && c == '\n') {
                buffered_char = NONE;
            } else {
                data_c[received] = buffered_char;
                buffered_char = NONE;
                ++received;
                if (received == size) {
                    /* We have placed the buffered character into the output buffer
                     * but there won't be enough space for the newly received one.
                     * Keep the new character in buffered_char until read is called
                     * again.
                     */
                    buffered_char = c;
                    break;
                }
            }
        }
        if (c == '\r') {
            buffered_char = c;
            continue;
        }
#endif //CONFIG_NEWLIB_STDOUT_ADDCR
        data_c[received] = c;
        ++received;
    }
    _lock_release_recursive(&s_uart_locks[fd]);
    if (received > 0) {
        return received;
    }
    errno = EWOULDBLOCK;
    return -1;
}
Ejemplo n.º 2
0
esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr_alloc_flags)
{
    RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
    RMT_CHECK((s_rmt_driver_channels & BIT(channel)) == 0, "RMT driver already installed for channel", ESP_ERR_INVALID_STATE);

    esp_err_t err = ESP_OK;

    if(p_rmt_obj[channel] != NULL) {
        ESP_LOGD(RMT_TAG, "RMT driver already installed");
        return ESP_ERR_INVALID_STATE;
    }

    p_rmt_obj[channel] = (rmt_obj_t*) malloc(sizeof(rmt_obj_t));

    if(p_rmt_obj[channel] == NULL) {
        ESP_LOGE(RMT_TAG, "RMT driver malloc error");
        return ESP_ERR_NO_MEM;
    }
    memset(p_rmt_obj[channel], 0, sizeof(rmt_obj_t));

    p_rmt_obj[channel]->tx_len_rem = 0;
    p_rmt_obj[channel]->tx_data = NULL;
    p_rmt_obj[channel]->channel = channel;
    p_rmt_obj[channel]->tx_offset = 0;
    p_rmt_obj[channel]->tx_sub_len = 0;

    if(p_rmt_obj[channel]->tx_sem == NULL) {
        p_rmt_obj[channel]->tx_sem = xSemaphoreCreateBinary();
        xSemaphoreGive(p_rmt_obj[channel]->tx_sem);
    }
    if(p_rmt_obj[channel]->rx_buf == NULL && rx_buf_size > 0) {
        p_rmt_obj[channel]->rx_buf = xRingbufferCreate(rx_buf_size, RINGBUF_TYPE_NOSPLIT);
        rmt_set_rx_intr_en(channel, 1);
        rmt_set_err_intr_en(channel, 1);
    }

    _lock_acquire_recursive(&rmt_driver_isr_lock);

    if(s_rmt_driver_channels == 0) { // first RMT channel using driver
        err = rmt_isr_register(rmt_driver_isr_default, NULL, intr_alloc_flags, &s_rmt_driver_intr_handle);
    }
    if (err == ESP_OK) {
        s_rmt_driver_channels |= BIT(channel);
        rmt_set_tx_intr_en(channel, 1);
    }

    _lock_release_recursive(&rmt_driver_isr_lock);

    return err;
}
Ejemplo n.º 3
0
esp_err_t rmt_driver_uninstall(rmt_channel_t channel)
{
    esp_err_t err = ESP_OK;
    RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG);
    RMT_CHECK((s_rmt_driver_channels & BIT(channel)) != 0, "No RMT driver for this channel", ESP_ERR_INVALID_STATE);
    if(p_rmt_obj[channel] == NULL) {
        return ESP_OK;
    }
    xSemaphoreTake(p_rmt_obj[channel]->tx_sem, portMAX_DELAY);

    rmt_set_rx_intr_en(channel, 0);
    rmt_set_err_intr_en(channel, 0);
    rmt_set_tx_intr_en(channel, 0);
    rmt_set_tx_thr_intr_en(channel, 0, 0xffff);

    _lock_acquire_recursive(&rmt_driver_isr_lock);

    s_rmt_driver_channels &= ~BIT(channel);
    if (s_rmt_driver_channels == 0) { // all channels have driver disabled
        err = rmt_isr_deregister(s_rmt_driver_intr_handle);
        s_rmt_driver_intr_handle = NULL;
    }

    _lock_release_recursive(&rmt_driver_isr_lock);

    if (err != ESP_OK) {
        return err;
    }

    if(p_rmt_obj[channel]->tx_sem) {
        vSemaphoreDelete(p_rmt_obj[channel]->tx_sem);
        p_rmt_obj[channel]->tx_sem = NULL;
    }
    if(p_rmt_obj[channel]->rx_buf) {
        vRingbufferDelete(p_rmt_obj[channel]->rx_buf);
        p_rmt_obj[channel]->rx_buf = NULL;
    }

    free(p_rmt_obj[channel]);
    p_rmt_obj[channel] = NULL;
    return ESP_OK;
}
Ejemplo n.º 4
0
static size_t IRAM_ATTR uart_write(int fd, const void * data, size_t size)
{
    assert(fd >=0 && fd < 3);
    const char *data_c = (const char *)data;
    uart_dev_t* uart = s_uarts[fd];
    /*
     *  Even though newlib does stream locking on each individual stream, we need
     *  a dedicated UART lock if two streams (stdout and stderr) point to the
     *  same UART.
     */
    _lock_acquire_recursive(&s_uart_locks[fd]);
    for (size_t i = 0; i < size; i++) {
#if CONFIG_NEWLIB_STDOUT_ADDCR
        if (data_c[i]=='\n') {
            uart_tx_char(uart, '\r');
        }
#endif
        uart_tx_char(uart, data_c[i]);
    }
    _lock_release_recursive(&s_uart_locks[fd]);
    return size;
}