Beispiel #1
0
int wbsio_check_for_spi(void)
{
	if (0 == (wbsio_spibase = wbsio_get_spibase(WBSIO_PORT1)))
		if (0 == (wbsio_spibase = wbsio_get_spibase(WBSIO_PORT2)))
			return 1;

	msg_pspew("\nwbsio_spibase = 0x%x\n", wbsio_spibase);

	msg_pdbg("%s: Winbond saved on 4 register bits so max chip size is "
		 "1024 kB!\n", __func__);
	max_rom_decode.spi = 1024 * 1024;
	register_spi_master(&spi_master_wbsio);

	return 0;
}
Beispiel #2
0
int jlink_spi_init(void)
{
	char *arg;
	unsigned long speed = 0;

	register_shutdown(jlink_spi_shutdown, NULL);

	arg = extract_programmer_param("spispeed");

	if (arg) {
		char *endptr;

		errno = 0;
		speed = strtoul(arg, &endptr, 10);

		if (*endptr != '\0' || errno != 0) {
			msg_perr("Invalid SPI speed specified: %s.\n", arg);
			free(arg);
			return 1;
		}

		if (speed < 1) {
			msg_perr("SPI speed must be at least 1 kHz.\n");
			free(arg);
			return 1;
		}
	}

	free(arg);

	int ret;
	bool use_serial_number;
	uint32_t serial_number;

	arg = extract_programmer_param("serial");

	if (arg) {
		if (!strlen(arg)) {
			msg_perr("Emptpy serial number specified.\n");
			free(arg);
			return 1;
		}

		ret = jaylink_parse_serial_number(arg, &serial_number);

		if (ret == JAYLINK_ERR) {
			msg_perr("Invalid serial number specified: %s.\n", arg);
			free(arg);
			return 1;
		} if (ret != JAYLINK_OK) {
			msg_perr("jaylink_parse_serial_number() failed: %s.\n", jaylink_strerror(ret));
			free(arg);
			return 1;
		}

		use_serial_number = true;
	} else {
		use_serial_number = false;
	}

	free(arg);

	reset_cs = true;
	arg = extract_programmer_param("cs");

	if (arg) {
		if (!strcasecmp(arg, "reset")) {
			reset_cs = true;
		} else if (!strcasecmp(arg, "trst")) {
			reset_cs = false;
		} else {
			msg_perr("Invalid chip select pin specified: '%s'.\n", arg);
			free(arg);
			return 1;
		}
	}

	free(arg);

	if (reset_cs)
		msg_pdbg("Using RESET as chip select signal.\n");
	else
		msg_pdbg("Using TRST as chip select signal.\n");

	ret = jaylink_init(&jaylink_ctx);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_init() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	ret = jaylink_discovery_scan(jaylink_ctx, 0);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_discover_scan() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	struct jaylink_device **devs;

	ret = jaylink_get_devices(jaylink_ctx, &devs, NULL);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_devices() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	if (!use_serial_number)
		msg_pdbg("No device selected, using first device.\n");

	size_t i;
	struct jaylink_device *dev;
	bool device_found = false;

	for (i = 0; devs[i]; i++) {
		if (use_serial_number) {
			uint32_t tmp;

			ret = jaylink_device_get_serial_number(devs[i], &tmp);

			if (ret == JAYLINK_ERR_NOT_AVAILABLE) {
				continue;
			} else if (ret != JAYLINK_OK) {
				msg_pwarn("jaylink_device_get_serial_number() failed: %s.\n",
					jaylink_strerror(ret));
				continue;
			}

			if (serial_number != tmp)
				continue;
		}

		ret = jaylink_open(devs[i], &jaylink_devh);

		if (ret == JAYLINK_OK) {
			dev = devs[i];
			device_found = true;
			break;
		}

		jaylink_devh = NULL;
	}

	jaylink_free_devices(devs, true);

	if (!device_found) {
		msg_perr("No J-Link device found.\n");
		return 1;
	}

	size_t length;
	char *firmware_version;

	ret = jaylink_get_firmware_version(jaylink_devh, &firmware_version,
		&length);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_firmware_version() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	} else if (length > 0) {
		msg_pdbg("Firmware: %s\n", firmware_version);
		free(firmware_version);
	}

	ret = jaylink_device_get_serial_number(dev, &serial_number);

	if (ret == JAYLINK_OK) {
		msg_pdbg("S/N: %" PRIu32 "\n", serial_number);
	} else if (ret == JAYLINK_ERR_NOT_AVAILABLE) {
		msg_pdbg("S/N: N/A\n");
	} else {
		msg_perr("jaylink_device_get_serial_number() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	uint8_t caps[JAYLINK_DEV_EXT_CAPS_SIZE];

	memset(caps, 0, sizeof(caps));
	ret = jaylink_get_caps(jaylink_devh, caps);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_caps() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_EXT_CAPS)) {
		ret = jaylink_get_extended_caps(jaylink_devh, caps);

		if (ret != JAYLINK_OK) {
			msg_perr("jaylink_get_available_interfaces() failed: %s.\n", jaylink_strerror(ret));
			return 1;
		}
	}

	uint32_t ifaces;

	ret = jaylink_get_available_interfaces(jaylink_devh, &ifaces);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_available_interfaces() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	if (!(ifaces & (1 << JAYLINK_TIF_JTAG))) {
		msg_perr("Device does not support JTAG interface.\n");
		return 1;
	}

	ret = jaylink_select_interface(jaylink_devh, JAYLINK_TIF_JTAG, NULL);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_select_interface() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	struct jaylink_hardware_status hwstat;

	ret = jaylink_get_hardware_status(jaylink_devh, &hwstat);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_hardware_status() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	msg_pdbg("VTarget: %u.%03u V\n", hwstat.target_voltage / 1000,
		hwstat.target_voltage % 1000);

	if (hwstat.target_voltage < MIN_TARGET_VOLTAGE) {
		msg_perr("Target voltage is below %u.%03u V. You need to attach VTref to the I/O voltage of "
			"the chip.\n", MIN_TARGET_VOLTAGE / 1000, MIN_TARGET_VOLTAGE % 1000);
		return 1;
	}

	struct jaylink_speed device_speeds;

	device_speeds.freq = DEFAULT_FREQ;
	device_speeds.div = DEFAULT_FREQ_DIV;

	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) {
		ret = jaylink_get_speeds(jaylink_devh, &device_speeds);

		if (ret != JAYLINK_OK) {
			msg_perr("jaylink_get_speeds() failed: %s.\n", jaylink_strerror(ret));
			return 1;
		}
	}

	device_speeds.freq /= 1000;

	msg_pdbg("Maximum SPI speed: %" PRIu32 " kHz\n", device_speeds.freq / device_speeds.div);

	if (!speed) {
		speed = device_speeds.freq / device_speeds.div;
		msg_pdbg("SPI speed not specified, using %lu kHz.\n", speed);
	}

	if (speed > (device_speeds.freq / device_speeds.div)) {
		msg_perr("Specified SPI speed of %lu kHz is too high. Maximum is %" PRIu32 " kHz.\n", speed,
			device_speeds.freq / device_speeds.div);
		return 1;
	}

	ret = jaylink_set_speed(jaylink_devh, speed);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_set_speed() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	msg_pdbg("SPI speed: %lu kHz\n", speed);

	/* Ensure that the CS signal is not active initially. */
	if (!deassert_cs())
		return 1;

	register_spi_master(&spi_master_jlink_spi);

	return 0;
}
Beispiel #3
0
int pickit2_spi_init(void)
{
	unsigned int usedevice = 0; // FIXME: allow to select one of multiple devices

	uint8_t buf[CMD_LENGTH] = {
		CMD_EXEC_SCRIPT,
		10,			/* Script length */
		SCR_SET_PINS,
		2, /* Bit-0=0(PDC Out), Bit-1=1(PGD In), Bit-2=0(PDC LL), Bit-3=0(PGD LL) */
		SCR_SET_AUX,
		0, /* Bit-0=0(Aux Out), Bit-1=0(Aux LL) */
		SCR_VDD_ON,
		SCR_MCLR_GND_OFF,	/* Let CS# float */
		SCR_VPP_PWM_ON,
		SCR_VPP_ON,		/* Pull CS# high */
		SCR_BUSY_LED_ON,
		CMD_CLR_DLOAD_BUFF,
		CMD_CLR_ULOAD_BUFF,
		CMD_END_OF_BUFFER
	};


	int spispeed_idx = 0;
	char *spispeed = extract_programmer_param("spispeed");
	if (spispeed != NULL) {
		int i = 0;
		for (; spispeeds[i].name; i++) {
			if (strcasecmp(spispeeds[i].name, spispeed) == 0) {
				spispeed_idx = i;
				break;
			}
		}
		if (spispeeds[i].name == NULL) {
			msg_perr("Error: Invalid 'spispeed' value.\n");
			free(spispeed);
			return 1;
		}
		free(spispeed);
	}

	int millivolt = 3500;
	char *voltage = extract_programmer_param("voltage");
	if (voltage != NULL) {
		millivolt = parse_voltage(voltage);
		free(voltage);
		if (millivolt < 0)
			return 1;
	}

	/* Here comes the USB stuff */
	usb_init();
	(void)usb_find_busses();
	(void)usb_find_devices();
	struct usb_device *dev = get_device_by_vid_pid(PICKIT2_VID, PICKIT2_PID, usedevice);
	if (dev == NULL) {
		msg_perr("Could not find a PICkit2 on USB!\n");
		return 1;
	}
	msg_pdbg("Found USB device (%04x:%04x).\n", dev->descriptor.idVendor, dev->descriptor.idProduct);

	pickit2_handle = usb_open(dev);
	int ret = usb_set_configuration(pickit2_handle, 1);
	if (ret != 0) {
		msg_perr("Could not set USB device configuration: %i %s\n", ret, usb_strerror());
		if (usb_close(pickit2_handle) != 0)
			msg_perr("Could not close USB device!\n");
		return 1;
	}
	ret = usb_claim_interface(pickit2_handle, 0);
	if (ret != 0) {
		msg_perr("Could not claim USB device interface %i: %i %s\n", 0, ret, usb_strerror());
		if (usb_close(pickit2_handle) != 0)
			msg_perr("Could not close USB device!\n");
		return 1;
	}

	if (register_shutdown(pickit2_shutdown, NULL) != 0) {
		return 1;
	}

	if (pickit2_get_firmware_version()) {
		return 1;
	}

	/* Command Set SPI Speed */
	if (pickit2_set_spi_speed(spispeed_idx)) {
		return 1;
	}

	/* Command Set SPI Voltage */
	msg_pdbg("Setting voltage to %i mV.\n", millivolt);
	if (pickit2_set_spi_voltage(millivolt) != 0) {
		return 1;
	}

	/* Perform basic setup.
	 * Configure pin directions and logic levels, turn Vdd on, turn busy LED on and clear buffers. */
	ret = usb_interrupt_write(pickit2_handle, ENDPOINT_OUT, (char *)buf, CMD_LENGTH, DFLT_TIMEOUT);
	if (ret != CMD_LENGTH) {
		msg_perr("Command Setup failed (%s)!\n", usb_strerror());
		return 1;
	}

	register_spi_master(&spi_master_pickit2);

	return 0;
}
Beispiel #4
0
/* Returns 0 upon success, a negative number upon errors. */
int mstarddc_spi_init(void)
{
	int ret = 0;

	// Get device, address from command-line
	char *i2c_device = extract_programmer_param("dev");
	if (i2c_device != NULL && strlen(i2c_device) > 0) {
		char *i2c_address = strchr(i2c_device, ':');
		if (i2c_address != NULL) {
			*i2c_address = '\0';
			i2c_address++;
		}
		if (i2c_address == NULL || strlen(i2c_address) == 0) {
			msg_perr("Error: no address specified.\n"
				 "Use flashrom -p mstarddc_spi:dev=/dev/device:address.\n");
			ret = -1;
			goto out;
		}
		mstarddc_addr = strtol(i2c_address, NULL, 16); // FIXME: error handling
	} else {
		msg_perr("Error: no device specified.\n"
			 "Use flashrom -p mstarddc_spi:dev=/dev/device:address.\n");
		ret = -1;
		goto out;
	}
	msg_pinfo("Info: Will try to use device %s and address 0x%02x.\n", i2c_device, mstarddc_addr);

	// Get noreset=1 option from command-line
	char *noreset = extract_programmer_param("noreset");
	if (noreset != NULL && noreset[0] == '1')
		mstarddc_doreset = 0;
	free(noreset);
	msg_pinfo("Info: Will %sreset the device at the end.\n", mstarddc_doreset ? "" : "NOT ");
	// Open device
	if ((mstarddc_fd = open(i2c_device, O_RDWR)) < 0) {
		switch (errno) {
		case EACCES:
			msg_perr("Error opening %s: Permission denied.\n"
				 "Please use sudo or run as root.\n",
				 i2c_device);
			break;
		case ENOENT:
			msg_perr("Error opening %s: No such file.\n"
				 "Please check you specified the correct device.\n",
				 i2c_device);
			break;
		default:
			msg_perr("Error opening %s: %s.\n", i2c_device, strerror(errno));
		}
		ret = -1;
		goto out;
	}
	// Set slave address
	if (ioctl(mstarddc_fd, I2C_SLAVE, mstarddc_addr) < 0) {
		msg_perr("Error setting slave address 0x%02x: errno %d.\n",
			 mstarddc_addr, errno);
		ret = -1;
		goto out;
	}
	// Enable ISP mode
	uint8_t cmd[5] = { 'M', 'S', 'T', 'A', 'R' };
	if (write(mstarddc_fd, cmd, 5) < 0) {
		int enable_err = errno;
		uint8_t end_cmd = MSTARDDC_SPI_END;

		// Assume device is already in ISP mode, try to send END command
		if (write(mstarddc_fd, &end_cmd, 1) < 0) {
			msg_perr("Error enabling ISP mode: errno %d & %d.\n"
				 "Please check that device (%s) and address (0x%02x) are correct.\n",
				 enable_err, errno, i2c_device, mstarddc_addr);
			ret = -1;
			goto out;
		}
	}
	// Register shutdown function
	register_shutdown(mstarddc_spi_shutdown, NULL);

	// Register programmer
	register_spi_master(&spi_master_mstarddc);
out:
	free(i2c_device);
	return ret;
}