Beispiel #1
0
/**
 * @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;
}
Beispiel #2
0
/**
 * @brief Modem and line status process thread
 *
 * This function is the thread for processing modem and line status change. It
 * uses the operation to send the event to the peer. It only sends the required
 * status for protocol, not the all status in UART.
 *
 * @param data The regular thread data.
 * @return None.
 */
static void *uart_status_thread(void *data)
{
    uint16_t updated_status = 0;
    struct gb_uart_serial_state_request *request;
    struct gb_uart_info *info = data;
    int ret = 0;

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

        if (info->thread_stop) {
            break;
        }

        updated_status = parse_ms_ls_registers(info->updated_ms,
                                               info->updated_ls);
        /*
         * Only send the status bits which protocol need to know to peer
         */
        if (info->last_serial_state ^ updated_status) {
            info->last_serial_state = updated_status;
            request = gb_operation_get_request_payload(info->ms_ls_operation);
            request->control = updated_status;
            ret = gb_operation_send_request(info->ms_ls_operation, NULL, false);
            if (ret) {
                uart_report_error(GB_UART_EVENT_PROTOCOL_ERROR, __func__);
            }
        }
    }

    return NULL;
}
Beispiel #3
0
/**
 * @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__);
    }
}
Beispiel #4
0
/**
 * @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;
}
Beispiel #5
0
/**
 * @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__);
    }
}