Пример #1
0
static int
ow_send_command(device_t ndev, device_t pdev, struct ow_cmd *cmd)
{
	int present, i, bit, tries;
	device_t lldev;
	struct ow_timing *t;

	lldev = device_get_parent(ndev);

	/*
	 * Retry the reset a couple of times before giving up.
	 */
	tries = 4;
	do {
		OWLL_RESET_AND_PRESENCE(lldev, &timing_regular, &present);
		if (present == 1)
			device_printf(ndev, "Reset said no device on bus?.\n");
	} while (present == 1 && tries-- > 0);
	if (present == 1) {
		device_printf(ndev, "Reset said the device wasn't there.\n");
		return ENOENT;		/* No devices acked the RESET */
	}
	if (present == -1) {
		device_printf(ndev, "Reset discovered bus wired wrong.\n");
		return ENOENT;
	}

	for (i = 0; i < cmd->rom_len; i++)
		ow_send_byte(lldev, &timing_regular, cmd->rom_cmd[i]);
	for (i = 0; i < cmd->rom_read_len; i++)
		ow_read_byte(lldev, &timing_regular, cmd->rom_read + i);
	if (cmd->xpt_len) {
		/*
		 * Per AN937, the reset pulse and ROM level are always
		 * done with the regular timings. Certain ROM commands
		 * put the device into overdrive mode for the remainder
		 * of the data transfer, which is why we have to pass the
		 * timings here. Commands that need to be handled like this
		 * are expected to be flagged by the client.
		 */
		t = (cmd->flags & OW_FLAG_OVERDRIVE) ?
		    &timing_overdrive : &timing_regular;
		for (i = 0; i < cmd->xpt_len; i++)
			ow_send_byte(lldev, t, cmd->xpt_cmd[i]);
		if (cmd->flags & OW_FLAG_READ_BIT) {
			memset(cmd->xpt_read, 0, (cmd->xpt_read_len + 7) / 8);
			for (i = 0; i < cmd->xpt_read_len; i++) {
				OWLL_READ_DATA(lldev, t, &bit);
				cmd->xpt_read[i / 8] |= bit << (i % 8);
			}
		} else {
			for (i = 0; i < cmd->xpt_read_len; i++)
				ow_read_byte(lldev, t, cmd->xpt_read + i);
		}
	}
	return 0;
}
Пример #2
0
void ow_match_rom(uint8_t *rom_value, uint8_t pin) {
  uint8_t bytes_left = 8;

  ow_send_byte(OW_ROM_MATCH, pin);

  while(bytes_left-- > 0) {
    ow_send_byte(*rom_value++, pin);
  }
}
Пример #3
0
uint8_t ow_search_rom(uint8_t *bit_pattern, uint8_t last_deviation, uint8_t pin) {

  uint8_t current_bit   = 1;
  uint8_t new_deviation = 0;
  uint8_t bit_mask      = 0x01;
  uint8_t bit_a;
  uint8_t bit_b;

  ow_send_byte(OW_ROM_SEARCH, pin);

  while(current_bit <= 64) {
    bit_a = ow_read_bit(pin);
    bit_b = ow_read_bit(pin);

    if(bit_a && bit_b) {
      return SEARCH_ERROR;
    } else if(bit_a ^ bit_b) {
      if(bit_a) {
        (*bit_pattern) |= bit_mask;
      } else {
        (*bit_pattern) &= ~bit_mask;
      }
    } else {
      if(current_bit == last_deviation) {
        (*bit_pattern) |= bit_mask;
      } else if(current_bit > last_deviation) {
        (*bit_pattern) &= ~bit_mask;
        new_deviation = current_bit;
      } else if(!(*bit_pattern & bit_mask)) {
        new_deviation = current_bit;
      } else {
      }
    }

    if((*bit_pattern) & bit_mask) {
      ow_write_bit1(pin);
    } else {
      ow_write_bit0(pin);
    }

    current_bit++;

    bit_mask <<= 1;
    if(!bit_mask) {
      bit_mask = 0x01;
      bit_pattern++;
    }
  }
  return new_deviation;
}