void *uart_monitor_stdin(void *d) { struct termios org_settings, new_settings; char buf[INPUT_BUFFER_SIZE]; int rv; tcgetattr(0, &org_settings); new_settings = org_settings; new_settings.c_lflag &= ~(ECHO | ICANON); new_settings.c_cc[VTIME] = 0; new_settings.c_cc[VMIN] = 1; printf("Console input initialized\n"); while (1) { tcsetattr(0, TCSANOW, &new_settings); rv = read(0, buf, INPUT_BUFFER_SIZE); if (queue_space(&cached_char) >= rv) { queue_add_units(&cached_char, buf, rv); char_available = rv; } tcsetattr(0, TCSANOW, &org_settings); /* * Trigger emulated interrupt to process input. Keyboard * input while interrupt handler runs is queued by the * system. */ task_trigger_test_interrupt(uart_interrupt); } return 0; }
size_t queue_get(struct _queue *queue, char *buf, size_t size) { int block, read = 0; while (read < size) { pthread_mutex_lock(&queue->lock); // How much space we have in the buffer. // Update in case other thread put some while we were busy. int bufleft = queue_space(queue, QUEUE_SPACE_GET); // If there's no more space, return. if (bufleft != 0) { // How much we can transfer with memcpy. block = MIN(queue->size - queue->get, MIN(bufleft, size - read)); // Perform the copy and update variables. memcpy(buf + read, queue->buffer + queue->get, block); queue->get = queue->get + block; #ifdef DEBUG assert(queue->get <= queue->size); #endif if (queue->get == queue->size) { queue->get = 0; queue->get_parity = ~queue->get_parity; } read = read + block; } pthread_mutex_unlock(&queue->lock); if (bufleft == 0) break; } return read; }
size_t queue_flush(struct _queue *queue) { pthread_mutex_lock(&queue->lock); // Fast-forward the get pointer and set its parity. size_t ret = queue_space(queue, QUEUE_SPACE_GET); queue->get = queue->put; queue->get_parity = queue->put_parity; pthread_mutex_unlock(&queue->lock); return ret; }
void send_data_to_usb(struct usart_config const *config) { struct queue const *uart_in = config->producer.queue; /* Copy input from buffer until RX fifo empty or the queue is full */ while (uartn_rx_available(config->uart) && queue_space(uart_in)) { int c = uartn_read_char(config->uart); QUEUE_ADD_UNITS(uart_in, &c, 1); } }
bool stream_read(struct _libstream_stream *stream, void* buf, size_t* bytes) { // Get what we can from the buffer. *bytes = queue_get(&stream->buffer, buf, *bytes); // In bg thread, fill buffer for next read. if (stream->running) { sem_post(&stream->download); return true; } else { // Indicate closed stream. return (queue_space(&stream->buffer, QUEUE_SPACE_GET) != 0); } }
void uart_inject_char(char *s, int sz) { int i; int num_char; for (i = 0; i < sz; i += INPUT_BUFFER_SIZE - 1) { num_char = MIN(INPUT_BUFFER_SIZE - 1, sz - i); if (queue_space(&cached_char) < num_char) return; queue_add_units(&cached_char, s + i, num_char); char_available = num_char; task_trigger_test_interrupt(uart_interrupt); } }
static int usb_wait_console(void) { timestamp_t deadline = get_time(); int wait_time_us = 1; if (!is_enabled || !tx_fifo_is_ready()) return EC_SUCCESS; deadline.val += USB_CONSOLE_TIMEOUT_US; /* * If the USB console is not used, Tx buffer would never free up. * In this case, let's drop characters immediately instead of sitting * for some time just to time out. On the other hand, if the last * Tx is good, it's likely the host is there to receive data, and * we should wait so that we don't clobber the buffer. */ if (last_tx_ok) { while (queue_space(&tx_q) < USB_MAX_PACKET_SIZE || !is_reset) { if (timestamp_expired(deadline, NULL) || in_interrupt_context()) { last_tx_ok = 0; return EC_ERROR_TIMEOUT; } if (wait_time_us < MSEC) udelay(wait_time_us); else usleep(wait_time_us); wait_time_us *= 2; } return EC_SUCCESS; } last_tx_ok = queue_space(&tx_q); return EC_SUCCESS; }
void motion_sense_fifo_add_unit(struct ec_response_motion_sensor_data *data, struct motion_sensor_t *sensor, int valid_data) { struct ec_response_motion_sensor_data vector; int i; data->sensor_num = sensor - motion_sensors; mutex_lock(&g_sensor_mutex); if (queue_space(&motion_sense_fifo) == 0) { queue_remove_unit(&motion_sense_fifo, &vector); motion_sense_fifo_lost++; motion_sensors[vector.sensor_num].lost++; if (vector.flags & MOTIONSENSE_SENSOR_FLAG_FLUSH) CPRINTS("Lost flush for sensor %d", vector.sensor_num); } for (i = 0; i < valid_data; i++) sensor->xyz[i] = data->data[i]; mutex_unlock(&g_sensor_mutex); if (valid_data) { int ap_odr = sensor->config[SENSOR_CONFIG_AP].odr & ~ROUND_UP_FLAG; int rate = INT_TO_FP(sensor->drv->get_data_rate(sensor)); /* If the AP does not want sensor info, skip */ if (ap_odr == 0) return; /* Skip if EC is oversampling */ if (sensor->oversampling < 0) { sensor->oversampling += fp_div(INT_TO_FP(1000), rate); return; } sensor->oversampling += fp_div(INT_TO_FP(1000), rate) - fp_div(INT_TO_FP(1000), INT_TO_FP(ap_odr)); } queue_add_unit(&motion_sense_fifo, data); }
/** @brief Network receive callback function @param[in] *arg: unused @param[in] *data: Data received @param[in] length: Length of data received @return void */ MEMSPACE static void tcp_data_receive_callback(void *arg, char *data, uint16_t length) { uint16_t current; uint8_t byte; // Echo debug #if 0 for(current = 0; current < length; current++) uart0_putc(data[current]); #endif // FIXME NOT WORKING // for(current = 0; (current < length) && queue_space(uart_send_queue); current++) { byte = (uint8_t)data[current]; queue_pushc(uart_send_queue, byte); } if(queue_empty(uart_send_queue) && tx_fifo_empty(0)) uart_tx_disable(0); else uart_tx_enable(0); }
bool stream_isclosed(struct _libstream_stream* stream) { return !stream->running && queue_space(&stream->buffer, QUEUE_SPACE_GET) == 0; }
/* * Motion Sense Task * Requirement: motion_sensors[] are defined in board.c file. * Two (minimium) Accelerometers: * 1 in the A/B(lid, display) and 1 in the C/D(base, keyboard) * Gyro Sensor (optional) */ void motion_sense_task(void) { int i, ret, wait_us, fifo_flush_needed = 0; timestamp_t ts_begin_task, ts_end_task; uint32_t event = 0; uint16_t ready_status; struct motion_sensor_t *sensor; #ifdef CONFIG_LID_ANGLE const uint16_t lid_angle_sensors = ((1 << CONFIG_LID_ANGLE_SENSOR_BASE)| (1 << CONFIG_LID_ANGLE_SENSOR_LID)); #endif #ifdef CONFIG_ACCEL_FIFO timestamp_t ts_last_int; #endif #ifdef CONFIG_LPC int sample_id = 0; uint8_t *lpc_status; uint16_t *lpc_data; lpc_status = host_get_memmap(EC_MEMMAP_ACC_STATUS); lpc_data = (uint16_t *)host_get_memmap(EC_MEMMAP_ACC_DATA); set_present(lpc_status); #endif #ifdef CONFIG_ACCEL_FIFO ts_last_int = get_time(); #endif do { ts_begin_task = get_time(); ready_status = 0; for (i = 0; i < motion_sensor_count; ++i) { sensor = &motion_sensors[i]; /* if the sensor is active in the current power state */ if (SENSOR_ACTIVE(sensor)) { if (sensor->state != SENSOR_INITIALIZED) { continue; } ts_begin_task = get_time(); ret = motion_sense_process(sensor, event, &ts_begin_task, &fifo_flush_needed); if (ret != EC_SUCCESS) continue; ready_status |= (1 << i); } } #ifdef CONFIG_GESTURE_DETECTION /* Run gesture recognition engine */ gesture_calc(); #endif #ifdef CONFIG_LID_ANGLE /* * Check to see that the sensors required for lid angle * calculation are ready. */ ready_status &= lid_angle_sensors; if (ready_status == lid_angle_sensors) motion_lid_calc(); #endif #ifdef CONFIG_CMD_ACCEL_INFO if (accel_disp) { CPRINTF("[%T event 0x%08x ", event); for (i = 0; i < motion_sensor_count; ++i) { sensor = &motion_sensors[i]; CPRINTF("%s=%-5d, %-5d, %-5d ", sensor->name, sensor->xyz[X], sensor->xyz[Y], sensor->xyz[Z]); } #ifdef CONFIG_LID_ANGLE CPRINTF("a=%-4d", motion_lid_get_angle()); #endif CPRINTF("]\n"); } #endif #ifdef CONFIG_LPC update_sense_data(lpc_status, lpc_data, &sample_id); #endif ts_end_task = get_time(); #ifdef CONFIG_ACCEL_FIFO /* * Ask the host to flush the queue if * - a flush event has been queued. * - the queue is almost full, * - we haven't done it for a while. */ if (fifo_flush_needed || event & TASK_EVENT_MOTION_ODR_CHANGE || queue_space(&motion_sense_fifo) < CONFIG_ACCEL_FIFO_THRES || (accel_interval > 0 && (ts_end_task.val - ts_last_int.val) > accel_interval)) { if (!fifo_flush_needed) motion_sense_insert_timestamp(); fifo_flush_needed = 0; ts_last_int = ts_end_task; #ifdef CONFIG_MKBP_EVENT /* * We don't currently support wake up sensor. * When we do, add per sensor test to know * when sending the event. */ if (sensor_active == SENSOR_ACTIVE_S0) mkbp_send_event(EC_MKBP_EVENT_SENSOR_FIFO); #endif } #endif if (accel_interval > 0) { /* * Delay appropriately to keep sampling time * consistent. */ wait_us = accel_interval - (ts_end_task.val - ts_begin_task.val); /* * Guarantee some minimum delay to allow other lower * priority tasks to run. */ if (wait_us < MIN_MOTION_SENSE_WAIT_TIME) wait_us = MIN_MOTION_SENSE_WAIT_TIME; } else { wait_us = -1; } } while ((event = task_wait_event(wait_us))); }