Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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);
	}
}
Ejemplo n.º 5
0
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);
  }
}
Ejemplo n.º 6
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);
	}
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
/**
  @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);
}
Ejemplo n.º 10
0
bool stream_isclosed(struct _libstream_stream* stream) {
  return !stream->running && queue_space(&stream->buffer, QUEUE_SPACE_GET) == 0;
}
Ejemplo n.º 11
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)));
}