Beispiel #1
0
/**
 * @brief Opens a flink device file
 * @param file_name: Device file (null terminated array).
 * @return flink_dev*: Pointer to the opened flink device or NULL in case of error.
 */
flink_dev* flink_open(const char* file_name) {
	flink_dev* dev = NULL;
	
	// Allocate memory for flink_t
	dev = malloc(sizeof(flink_dev));
	if(dev == NULL) { // allocation failed
		libc_error();
		return NULL;
	}
	
	// Open device file
	dev->fd = open(file_name, O_RDWR);
	if(dev->fd < 0) { // failed to open device
		free(dev);
		libc_error();
		return NULL;
	}
	
	if(get_subdevices(dev) < 0) { // reading subdevices failed
		close(dev->fd);
		free(dev);
		return NULL;
	}
	
	return dev;
}
Beispiel #2
0
/**
 * @brief Read header of all subdevices and update flink device.
 * 
 * @param dev: flink device to update
 * @return int: number of subdevices read, or -1 in case of error.
 */
static int get_subdevices(flink_dev* dev) {
	flink_subdev* subdev = NULL;
	int i = 0, ret = 0;
	
	if(!validate_flink_dev(dev)) {
		flink_error(FLINK_EINVALDEV);
		return EXIT_ERROR;
	}
	
	// Read nof subdevices
	dev->nof_subdevices = read_nof_subdevices(dev);
	
	// Allocate memory
	dev->subdevices = calloc(dev->nof_subdevices, sizeof(flink_subdev));
	if(dev->subdevices == NULL) { // allocation failed
		libc_error();
		dev->nof_subdevices = 0;
		return EXIT_ERROR;
	}
	
	// Fillup all information
	for(i = 0; i < dev->nof_subdevices; i++) { // for each subdevice
		subdev = dev->subdevices + i;
		subdev->id = i;
		ret = flink_ioctl(dev, READ_SUBDEVICE_INFO, subdev);
		subdev->parent = dev;
	}
	
	return ret;
}
void FileDescriptor::RaiseError(const char* msg)
{
	if (ignoreErrors.size() == 0) {
		// Ignore none
		throw libc_error(msg);
	}

	ErrorSet * curIgnore = ignoreErrors.back().get();
	if (!curIgnore) {
		// Ignore all
		return;
	}

	if (!curIgnore->count(errno)) {
		// Don't ignore this one
		throw libc_error(msg);
	}
}
Beispiel #4
0
/**
 * @brief Select a flink subdevice for further operations.
 * @param subdev: Subdevice to select.
 * @param exclusive: Block access to this subdevice for other processes.
 * @return int: 0 on success, else -1.
 */
int flink_subdevice_select(flink_subdev* subdev, uint8_t exclusive) {
	ioctl_cmd_t cmd = SELECT_SUBDEVICE;
	if(exclusive) cmd = SELECT_SUBDEVICE_EXCL;
	
	if(flink_ioctl(subdev->parent, cmd, &(subdev->id)) < 0) {
		libc_error();
		return EXIT_ERROR;
	}
	return EXIT_SUCCESS;
}
Beispiel #5
0
/**
 * @brief Read number of subdevices from flink device.
 * 
 * @param dev: Device to read
 * @return int: Number of flink devices or -1 in case of error.
 */
static int read_nof_subdevices(flink_dev* dev) {
	uint8_t n = 0;
	
	dbg_print("reading number of subdevices...\n");
	
	if(flink_ioctl(dev, READ_NOF_SUBDEVICES, &n) < 0) {
		dbg_print("   --> failed!\n");
		libc_error();
		return EXIT_ERROR;
	}
	dbg_print("  --> %u\n", n);
	return n;
}
Beispiel #6
0
/**
 * @brief Reset a flink subdevice.
 * @param subdev: Subdevice to reset
 * @return int: 0 on success, else -1.
 */
int flink_subdevice_reset(flink_subdev* subdev) {
	uint32_t offset = CONFIG_OFFSET;
	uint8_t reset = 1;
	
	if(!validate_flink_subdev(subdev)) {
		flink_error(FLINK_EINVALSUBDEV);
		return EXIT_ERROR;
	}
	
	if(flink_write_bit(subdev, offset, RESET_BIT, &reset)) {
		libc_error();
		return EXIT_ERROR;
	}
	return EXIT_SUCCESS;
}
Beispiel #7
0
/**
 * @brief Configures a channel as input or output
 * @param subdev: Subdevice containing the channel.
 * @param channel: Channel number.
 * @param output: Value, a value of nonzero configures the channel as output.
 * @return int: 0 on success, -1 in case of failure.
 */
int flink_dio_set_direction(flink_subdev* subdev, uint32_t channel, uint8_t output) {
	uint32_t offset;
	uint8_t bit;
	
	dbg_print("Setting digital I/O direction for channel %d on subdevice %d\n", channel, subdev->id);
	
	offset = HEADER_SIZE + SUBHEADER_SIZE + (channel / (REGISTER_WITH * 8)) * REGISTER_WITH;
	bit = channel % (REGISTER_WITH * 8);
	
	dbg_print("   --> calculated offset is 0x%x\n", offset);
	dbg_print("   --> calculated bit is %u\n", bit);
	
	if(flink_write_bit(subdev, offset, bit, &output)) {
		libc_error();
		return EXIT_ERROR;
	}
	return EXIT_SUCCESS;
}
Beispiel #8
0
/**
 * @brief Reads an input channel
 * @param subdev: Subdevice containing the channel.
 * @param channel: Channel number.
 * @param value: Contains a value of nonzero if the input is set.
 * @return int: 0 on success, -1 in case of failure.
 */
int flink_dio_get_value(flink_subdev* subdev, uint32_t channel, uint8_t* value) {
	uint32_t offset;
	uint8_t bit;
	
	dbg_print("Reading digital input value from channel %d on subdevice %d\n", channel, subdev->id);
	
	offset = HEADER_SIZE + SUBHEADER_SIZE + subdev->nof_channels / (REGISTER_WITH * 8) + channel / (REGISTER_WITH * 8);
	if(subdev->nof_channels % (REGISTER_WITH * 8) != 0) offset += 4;
	bit = channel % (REGISTER_WITH * 8);
	
	dbg_print("[DEBUG]   --> calculated offset is 0x%x\n", offset);
	dbg_print("[DEBUG]   --> calculated bit is %u\n", bit);
	
	if(flink_read_bit(subdev, offset, bit, value)) {
		libc_error();
		return EXIT_ERROR;
	}
	return EXIT_SUCCESS;
}
Beispiel #9
0
/**
 * @brief Sets a output channel to a value
 * @param subdev: Subdevice containing the channel.
 * @param channel: Channel number.
 * @param output: A value of nonzero sets the channel.
 * @return int: 0 on success, -1 in case of failure.
 */
int flink_dio_set_value(flink_subdev* subdev, uint32_t channel, uint8_t value) {
	uint32_t offset;
	uint8_t bit;
	uint8_t val = (value != 0);
	
	dbg_print("Setting digital output value to %u...\n", val);
	
	offset = HEADER_SIZE + SUBHEADER_SIZE + subdev->nof_channels / (REGISTER_WITH * 8) + channel / (REGISTER_WITH * 8);
	if(subdev->nof_channels % (REGISTER_WITH * 8) != 0) offset += 4;
	bit = channel % (REGISTER_WITH * 8);
	
	dbg_print("   --> calculated offset is 0x%x\n", offset);
	dbg_print("   --> calculated bit is %u\n", bit);
	
	if(flink_write_bit(subdev, offset, bit, &val)) {
		libc_error();
		return EXIT_ERROR;
	}
	return EXIT_SUCCESS;
}