Beispiel #1
0
void show_story(display &disp, const std::string &scenario_name,
	const config::const_child_itors &story)
{
	const int total_segments = count_segments(story);
	int segment_count = 0;
	config::const_child_iterator itor = story.first;
	storyscreen::START_POSITION startpos = storyscreen::START_BEGINNING;
	while (itor != story.second)
	{
		storyscreen::controller ctl(disp, vconfig(*itor, true),
			scenario_name, segment_count, total_segments);
		storyscreen::STORY_RESULT result = ctl.show(startpos);

		switch(result) {
		case storyscreen::NEXT:
			if(itor != story.second) {
				++itor;
				++segment_count;
				startpos = storyscreen::START_BEGINNING;
			}
			break;
		case storyscreen::BACK:
			if(itor != story.first) {
				--itor;
				--segment_count;
				startpos = storyscreen::START_END;
			}
			break;
		case storyscreen::QUIT:
			return;
		}
	}
	return;
}
void show_story(display& disp, const std::string& scenario_name, const config::const_child_itors& story)
{
	const int total_segments = count_segments(story);
	int segment_count = 0;
	config::const_child_iterator itor = story.first;
	// storyscreen::START_POSITION startpos = storyscreen::START_BEGINNING;
	while (itor != story.second) {
		gui2::tstory_screen dlg(*itor);
		dlg.show(disp.video());

		tstory_screen::legacy_result result = dlg.get_legacy_result();

		switch (result) {
		case tstory_screen::NEXT:
			if (itor != story.second) {
				++ itor;
				++ segment_count;
				// startpos = storyscreen::START_BEGINNING;
			}
			break;
		case tstory_screen::BACK:
			if (itor != story.first) {
				-- itor;
				-- segment_count;
				// startpos = storyscreen::START_END;
			}
			break;
		case tstory_screen::QUIT:
			return;
		}
	}
}
Beispiel #3
0
/*
  Sends a command/data sequence that can include restarts, writes and reads. Every transmission begins with a START,
  and ends with a STOP so you do not have to specify that.

  sequence is the I2C operation sequence that should be performed. It can include any number of writes, restarts and
  reads. Note that the sequence is composed of uint16_t, not uint8_t. This is because we have to support out-of-band
  signalling of I2C_RESTART and I2C_READ operations, while still passing through 8-bit data.

  sequence_length is the number of sequence elements (not bytes). Sequences of arbitrary length are supported, but
  there is an upper limit on the number of segments (restarts): no more than 42. The minimum sequence length is
  (rather obviously) 2.

  received_data should point to a buffer that can hold as many bytes as there are I2C_READ operations in the
  sequence. If there are no reads, 0 can be passed, as this parameter will not be used.
*/
int i2c_send_sequence(int handle, uint16_t *sequence, uint32_t sequence_length, uint8_t *received_data) {
  struct i2c_rdwr_ioctl_data message_sequence;
  uint32_t number_of_segments = count_segments(sequence, sequence_length);
  struct i2c_msg *messages = malloc(number_of_segments * sizeof(struct i2c_msg));
  struct i2c_msg *current_message = messages;
  /* msg_buf needs to hold all *bytes written* in the entire sequence. Since it is difficult to estimate that number
     without processing the sequence, we make an upper-bound guess: sequence_length. Yes, this is inefficient, but
     optimizing this doesn't seem to be worth the effort. */
  uint8_t *msg_buf = malloc(sequence_length); /* certainly no more than that */
  uint8_t *msg_cur_buf_ptr = msg_buf;
  uint8_t *msg_cur_buf_base;
  uint32_t msg_cur_buf_size;
  uint8_t address;
  uint8_t rw;
  uint32_t i;
  int result = -1;

  if(sequence_length < 2) goto i2c_send_sequence_cleanup;
  if((number_of_segments > I2C_RDRW_IOCTL_MAX_MSGS)) goto i2c_send_sequence_cleanup;

  address = sequence[0];        /* the first byte is always an address */
  rw = address & 1;
  msg_cur_buf_size = 0;
  msg_cur_buf_base = msg_cur_buf_ptr;
  i = 1;

  while(i < sequence_length) {
    if(sequence[i] != I2C_RESTART) {
      /* if we are writing, the only thing in the sequence are bytes to be written */
      if(rw == WRITING) *msg_cur_buf_ptr++ = (uint8_t)(sequence[i]);
      /* for reads, there is nothing to be done, as the only possible thing in the sequence is I2C_READ */
      msg_cur_buf_size++;
    }

    if((sequence[i] == I2C_RESTART) || (i == (sequence_length - 1))) {
      /* segment is complete, fill out the message structure */
      current_message->addr = address >> 1; /* Linux uses 7-bit addresses */
      current_message->flags = rw ? I2C_M_RD : 0;
      current_message->len = msg_cur_buf_size;
      /* buf needs to point to either the buffer that will receive data, or buffer that holds bytes to be written */
      current_message->buf = rw ? received_data : msg_cur_buf_base;
      current_message++;

      if(rw == READING) received_data += msg_cur_buf_size;

      /* do we have another transaction coming? */
      if(i < (sequence_length - 2)) { /* every I2C transaction is at least two bytes long */
        address = sequence[++i];
        rw = address & 1;
        msg_cur_buf_size = 0;
        msg_cur_buf_base = msg_cur_buf_ptr;
      }
    }
    i++;
  }