コード例 #1
0
ファイル: uart.c プロジェクト: nklabs/nuttx-gpep
/**
 * @brief Callback for data receiving
 *
 * The callback function provided to device driver for being notified when
 * driver received a data stream.
 *
 * This function Must be called from interrupt context.
 *
 * It put the current operation to received queue and gets another operation to
 * continue receiving. Then notifies rx thread to process.
 *
 * @param buffer Data buffer.
 * @param length Received data length.
 * @param error Error code when driver receiving.
 * @return None.
 */
static void uart_rx_callback(uint8_t *buffer, int length, int error)
{
    struct op_node *node;
    int ret;

    *info->rx_node->data_size = cpu_to_le16(length);
    put_node_back(&info->data_queue, info->rx_node);
    /* notify rx thread to process this data*/
    sem_post(&info->rx_sem);

    node = get_node_from(&info->free_queue);

    if (!node) {
        /*
         * there is no free buffer, inform the rx thread to engage another uart
         * receiver.
         */
        info->require_node = 1;
        return;
    }

    info->rx_node = node;
    ret = device_uart_start_receiver(info->dev, node->buffer, info->rx_buf_size,
                                     NULL, NULL, uart_rx_callback);
    if (ret) {
        uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__);
    }
}
コード例 #2
0
ファイル: uart.c プロジェクト: nklabs/nuttx-gpep
/**
 * @brief Allocate operations for receiver buffers
 *
 * This function is allocating operation and use them as receiving buffers.
 *
 * @param max_nodes Maximum nodes.
 * @param buf_size Buffer size in operation.
 * @param queue Target queue.
 * @return 0 for success, -errno for failures.
 */
static int uart_alloc_op(int max_nodes, int buf_size, sq_queue_t *queue)
{
    struct gb_operation *operation = NULL;
    struct gb_uart_receive_data_request *request = NULL;
    struct op_node *node = NULL;
    int i = 0;

    for (i = 0; i < max_nodes; i++) {
        operation = gb_operation_create(info->cport,
                                        GB_UART_PROTOCOL_RECEIVE_DATA,
                                        sizeof(*request) + buf_size);
        if (!operation) {
            goto err_free_op;
        }

        node = malloc(sizeof(struct op_node));
        if (!node) {
            gb_operation_destroy(operation);
            goto err_free_op;
        }
        node->operation = operation;

        request = gb_operation_get_request_payload(operation);
        node->data_size = &request->size;
        node->buffer = request->data;
        put_node_back(queue, node);
    }

    return 0;

err_free_op:
    uart_free_op(queue);

    return -ENOMEM;
}
コード例 #3
0
ファイル: uart.c プロジェクト: haywoodspartan/nuttx
/**
 * @brief Data receiving process thread
 *
 * This function is the thread for processing data receiving tasks. When
 * it wake up, it checks the receiving queue for processing the come in data.
 * If protocol is running out of buffer, as soon as it gets a free buffer,
 * it passes to driver for continuing the receiving.
 *
 * @param data The regular thread data.
 * @return None.
 */
static void *uart_rx_thread(void *data)
{
    struct gb_operation *operation = NULL;
    struct gb_uart_receive_data_request *request = NULL;
    struct buf_node *node = NULL;
    struct gb_bundle *bundle = data;
    struct gb_uart_info *info = bundle->priv;
    struct device *dev = bundle->dev;
    int ret;

    while (1) {
        sem_wait(&info->rx_sem);

        if (info->thread_stop) {
            break;
        }

        node = get_node_from(&info->data_queue);
        if (node) {
            operation = gb_operation_create(info->cport,
                                           GB_UART_PROTOCOL_RECEIVE_DATA,
                                           sizeof(*request) + node->data_size);
            if (!operation) {
                uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__);
            } else {
                request = gb_operation_get_request_payload(operation);
                request->size = cpu_to_le16(node->data_size);
                request->flags = node->data_flags;
                memcpy(request->data, node->buffer, node->data_size);

                ret = gb_operation_send_request(operation, NULL, false);
                if (ret) {
                    uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__);
                }
                gb_operation_destroy(operation);
            }
            put_node_back(&info->free_queue, node);
        }

        /*
         * In case there is no free node in callback.
         */
        if (info->require_node) {
            node = get_node_from(&info->free_queue);
            info->rx_node = node;
            ret = device_uart_start_receiver(dev, node->buffer,
                                             info->rx_buf_size, NULL,
                                             NULL, uart_rx_callback);
            if (ret) {
                uart_report_error(GB_UART_EVENT_DEVICE_ERROR, __func__);
            }
            info->require_node = 0;
        }
    }

    return NULL;
}
コード例 #4
0
ファイル: uart.c プロジェクト: haywoodspartan/nuttx
/**
 * @brief Callback for data receiving
 *
 * The callback function provided to device driver for being notified when
 * driver received a data stream.
 *
 * This function Must be called from interrupt context.
 *
 * It put the current buffer to received queue and gets another buffer to
 * continue receiving. Then notifies rx thread to process.
 *
 * @param dev Pointer to the UART device controller
 * @param data Pointer to struct gb_uart_info.
 * @param buffer Data buffer.
 * @param length Received data length.
 * @param error Error code when driver receiving.
 * @return None.
 */
static void uart_rx_callback(struct device *dev, void *data, uint8_t *buffer,
                             int length, int error)
{
    struct gb_uart_info *info;
    struct buf_node *node;
    int ret;
    uint8_t flags = 0;

    DEBUGASSERT(data);
    info = data;

    info->rx_node->data_size = length;

    if (error & LSR_OE) {
        flags |= GB_UART_RECV_FLAG_OVERRUN;
    }
    if (error & LSR_PE) {
        flags |= GB_UART_RECV_FLAG_PARITY;
    }
    if (error & LSR_FE) {
        flags |= GB_UART_RECV_FLAG_FRAMING;
    }
    if (error & LSR_BI) {
        flags |= GB_UART_RECV_FLAG_BREAK;
    }
    info->rx_node->data_flags = flags;

    put_node_back(&info->data_queue, info->rx_node);
    /* notify rx thread to process this data*/
    sem_post(&info->rx_sem);

    node = get_node_from(&info->free_queue);

    if (!node) {
        /*
         * there is no free buffer, inform the rx thread to engage another uart
         * receiver.
         */
        info->require_node = 1;
        return;
    }

    info->rx_node = node;
    ret = device_uart_start_receiver(dev, node->buffer,
                                     info->rx_buf_size,
                                     NULL, NULL, uart_rx_callback);
    if (ret) {
        uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__);
    }
}
コード例 #5
0
ファイル: uart.c プロジェクト: haywoodspartan/nuttx
/**
 * @brief Allocate receiver buffers
 *
 * This function is allocating receiving buffers.
 *
 * @param max_nodes Maximum nodes.
 * @param buf_size Buffer size in operation.
 * @param queue Target queue.
 * @return 0 for success, errno for failures.
 */
static int uart_alloc_buf(int max_nodes, int buf_size, sq_queue_t *queue)
{
    struct buf_node *node = NULL;
    int i = 0;

    for (i = 0; i < max_nodes; i++) {
        node = malloc(sizeof(*node) + buf_size);
        if (!node) {
            /*
             * It may have some buffers already be allocated, caller should
             * free them.
             */
            return ENOMEM;
            /* Keeping consistency with Nuttx APIs, so returns positive num */
        }
        put_node_back(queue, node);
    }

    return 0;
}
コード例 #6
0
ファイル: uart.c プロジェクト: nklabs/nuttx-gpep
/**
 * @brief Data receiving process thread
 *
 * This function is the thread for processing data receiving tasks. When
 * it wake up, it checks the receiving queue for processing the come in data.
 * If protocol is running out of operation, once it gets a free operation,
 * it passes to driver for continuing the receiving.
 *
 * @param data The regular thread data.
 * @return None.
 */
static void *uart_rx_thread(void *data)
{
    struct op_node *node = NULL;
    int ret;

    while (1) {
        sem_wait(&info->rx_sem);

        if (info->thread_stop) {
            break;
        }

        node = get_node_from(&info->data_queue);
        if (node) {
            ret = gb_operation_send_request(node->operation, NULL, false);
            if (ret) {
                uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__);
            }
            put_node_back(&info->free_queue, node);
        }

        /*
         * In case there is no free node in callback.
         */
        if (info->require_node) {
            node = get_node_from(&info->free_queue);
            info->rx_node = node;
            ret = device_uart_start_receiver(info->dev, node->buffer,
                                             info->rx_buf_size, NULL, NULL,
                                             uart_rx_callback);
            if (ret) {
                uart_report_error(GB_UART_EVENT_DEVICE_ERROR, __func__);
            }
            info->require_node = 0;
        }
    }

    return NULL;
}