Beispiel #1
0
void menu_i2c_fm75_set_resolution_func(const struct menu_item *m, bool checked)
{
        uint8_t conf = 0;
        static const uint8_t res_mask = 0x60;

        resource_acquire(RES_MASK(RES_ID_I2C1), RES_WAIT_FOREVER);

        /*
         * First we need to read currently configuration of FM75.
         */
        fm75_read_reg(FM75_REG_CONF, &conf, sizeof(conf));

        /*
         * Set the new resolution in configuration register of FM75.
         */
        conf &= ~res_mask;
        conf |= ((int) m->param << 5) & res_mask;

        /*
         * Then we set the new value of resolution and send it to sensor.
         */
        fm75_write_reg(FM75_REG_CONF, &conf, sizeof(conf));

        resource_release(RES_MASK(RES_ID_I2C1));
}
Beispiel #2
0
void menu_i2c_write_to_eeprom_func(const struct menu_item *m, bool checked)
{
        int i;
        size_t wr_status = 0;
        HW_I2C_ABORT_SOURCE abrt_src = HW_I2C_ABORT_NONE;
        uint8_t addr[2] = {0x00, 0x00};
        static uint8_t write_buffer[65];        // 64 bytes of data + '\0'

        set_target_address(EEPROM_ADDRESS);
        /*
         * Generate random data (some pattern).
         */
        for (i = 0; i < sizeof(write_buffer) - 1; i++) {
                write_buffer[i] = rand() % 96 + 32;
        }

        /*
         * Acquire I2C resource and write data to EEPROM. First two bytes determine memory address
         * from which data will be written. First byte is high byte address and the second one is
         * low byte address. In that case data will be stored starting from address 0. Next bytes
         * are data. Despite 2 separate write calls below, writing is still goes as one transfer
         * on the bus because it is done via FIFO and as long as FIFO is non-empty controller will
         * continue to send data and will generate stop condition only when FIFO is empty. Notice
         * also the use of flags between the 2 calls that ensure that no STOP condition will be
         * generated between them.
         * After writing operation release I2C resource.
         */
        resource_acquire(RES_MASK(RES_ID_I2C1), RES_WAIT_FOREVER);

        wr_status = hw_i2c_write_buffer_sync(HW_I2C1, addr, sizeof(addr), &abrt_src, HW_I2C_F_NONE);
        if ((wr_status < sizeof(addr)) || (abrt_src != HW_I2C_ABORT_NONE)) {
                printf("EEPROM address write during write failed: %u" NEWLINE, abrt_src);
        }
        else {
                wr_status = hw_i2c_write_buffer_sync(HW_I2C1, write_buffer, sizeof(write_buffer) - 1, NULL,
                                                     HW_I2C_F_WAIT_FOR_STOP);
                if ((wr_status < (ssize_t)sizeof(write_buffer)) || (abrt_src != HW_I2C_ABORT_NONE)) {
                        printf("EEPROM write failure: %u" NEWLINE, abrt_src);
                }
                else {
                        /*
                         * Wait for ACK from EEPROM.
                         */
                        eeprom_poll_ack(HW_I2C1);

                        /*
                         * Print on UART what was generated and written in EEPROM.
                         */
                        printf("written to EEPROM: %s" NEWLINE, write_buffer);
                }
        }


        resource_release(RES_MASK(RES_ID_I2C1));
}
Beispiel #3
0
static inline uint32_t dma_resource_mask(int num)
{
        static const uint32_t res_mask[] = {
                RES_MASK(RES_ID_DMA_MUX01), RES_MASK(RES_ID_DMA_MUX01),
                RES_MASK(RES_ID_DMA_MUX23), RES_MASK(RES_ID_DMA_MUX23),
                RES_MASK(RES_ID_DMA_MUX45), RES_MASK(RES_ID_DMA_MUX45),
                RES_MASK(RES_ID_DMA_MUX67), RES_MASK(RES_ID_DMA_MUX67)
        };
        return res_mask[num];
}
Beispiel #4
0
void ad_spi_bus_release(spi_device dev)
{
        const spi_device_config *device = (spi_device_config *) dev;

        if (--device->data->bus_acquire_count == 0) {
                if (device->hw_init.use_dma) {
                        resource_release(dma_resource_mask(device->hw_init.rx_dma_channel));
                }
#if !CONFIG_SPI_ONE_DEVICE_ON_BUS
                resource_release(RES_MASK(device->bus_res_id));
#endif
        }
}
Beispiel #5
0
void task_i2c_get_temp_func(const struct task_item *task)
{
        uint8_t temp[2];
        int t_out, fract;

        /*
         * Wait in OS friendly way for request to run.
         */
        if (!read_temp_enabled) {
                OS_EVENT_WAIT(event, OS_EVENT_FOREVER);
        }

        /*
         * Require I2C for exclusively reading temperature from FM75 and release it after operation.
         */
        resource_acquire(RES_MASK(RES_ID_I2C1), RES_WAIT_FOREVER);

        set_target_address(FM75_ADDRESS);

        /*
         * Read actual temperature values from FM75.
         */
        fm75_read_reg(FM75_REG_TEMP, temp, sizeof(temp));

        resource_release(RES_MASK(RES_ID_I2C1));

        /*
         * Send results to UART.
         */
        t_out = convert_temp(temp, &fract);
        printf("current temperature: %d.%04d C" NEWLINE, t_out, fract);

        /*
         * Wait 1 second to get temperature again.
         */
        OS_DELAY(1000);
}
Beispiel #6
0
void menu_i2c_read_from_eeprom_func(const struct menu_item *m, bool checked)
{
        size_t rd_status, wr_status;
        HW_I2C_ABORT_SOURCE abrt_src = HW_I2C_ABORT_NONE;
        uint8_t addr[2] = {0x00, 0x00};
        static uint8_t read_buffer[65];        // 64 bytes of data + '\0'

        set_target_address(EEPROM_ADDRESS);
        /*
         * Acquire I2C resource and read data back from EEPROM and release it after operation.
         * Before reading data we need to set address from which reading will start. This is done
         * by writing two bytes indicating address in EEPROM before reading from it. I2C controller
         * will automatically generate proper write and read commands on I2C bus.
         */
        resource_acquire(RES_MASK(RES_ID_I2C1), RES_WAIT_FOREVER);

        wr_status = hw_i2c_write_buffer_sync(HW_I2C1, addr, sizeof(addr), &abrt_src, HW_I2C_F_NONE);
        if ((wr_status < sizeof(addr)) || (abrt_src != HW_I2C_ABORT_NONE)) {
                printf("EEPROM address write during read failed: %u" NEWLINE, abrt_src);
        }
        else {
                rd_status = hw_i2c_read_buffer_sync(HW_I2C1, read_buffer, sizeof(read_buffer) - 1, &abrt_src, HW_I2C_F_NONE);

                /*
                 * Print on UART what was read from EEPROM.
                 */
                if ((rd_status < sizeof(read_buffer)) || (abrt_src != HW_I2C_ABORT_NONE)) {
                        printf("EEPROM read failure: %u" NEWLINE, abrt_src);
                }
                else {
                        printf("read from EEPROM:  %s" NEWLINE, read_buffer);
                }
        }

        resource_release(RES_MASK(RES_ID_I2C1));
}
Beispiel #7
0
static int ad7298_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val,
			   int *val2,
			   long m)
{
	int ret;
	struct ad7298_state *st = iio_priv(indio_dev);

	switch (m) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&indio_dev->mlock);
		if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
			ret = -EBUSY;
		} else {
			if (chan->address == AD7298_CH_TEMP)
				ret = ad7298_scan_temp(st, val);
			else
				ret = ad7298_scan_direct(st, chan->address);
		}
		mutex_unlock(&indio_dev->mlock);

		if (ret < 0)
			return ret;

		if (chan->address != AD7298_CH_TEMP)
			*val = ret & RES_MASK(AD7298_BITS);

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_VOLTAGE:
			*val = ad7298_get_ref_voltage(st);
			*val2 = chan->scan_type.realbits;
			return IIO_VAL_FRACTIONAL_LOG2;
		case IIO_TEMP:
			*val = ad7298_get_ref_voltage(st);
			*val2 = 10;
			return IIO_VAL_FRACTIONAL;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OFFSET:
		*val = 1093 - 2732500 / ad7298_get_ref_voltage(st);
		return IIO_VAL_INT;
	}
	return -EINVAL;
}
static int ad7298_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val,
			   int *val2,
			   long m)
{
	int ret;
	struct ad7298_state *st = iio_priv(indio_dev);
	unsigned int scale_uv;

	switch (m) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&indio_dev->mlock);
		if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
			ret = -EBUSY;
		} else {
			if (chan->address == AD7298_CH_TEMP)
				ret = ad7298_scan_temp(st, val);
			else
				ret = ad7298_scan_direct(st, chan->address);
		}
		mutex_unlock(&indio_dev->mlock);

		if (ret < 0)
			return ret;

		if (chan->address != AD7298_CH_TEMP)
			*val = ret & RES_MASK(AD7298_BITS);

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_VOLTAGE:
			scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
			*val =  scale_uv / 1000;
			*val2 = (scale_uv % 1000) * 1000;
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_TEMP:
			*val =  1;
			*val2 = 0;
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
	}
	return -EINVAL;
}
Beispiel #9
0
static int ad7298_read_raw(struct iio_dev *dev_info,
                           struct iio_chan_spec const *chan,
                           int *val,
                           int *val2,
                           long m)
{
    int ret;
    struct ad7298_state *st = iio_priv(dev_info);
    unsigned int scale_uv;

    switch (m) {
    case 0:
        mutex_lock(&dev_info->mlock);
        if (iio_ring_enabled(dev_info)) {
            if (chan->address == AD7298_CH_TEMP)
                ret = -ENODEV;
            else
                ret = ad7298_scan_from_ring(dev_info,
                                            chan->address);
        } else {
            if (chan->address == AD7298_CH_TEMP)
                ret = ad7298_scan_temp(st, val);
            else
                ret = ad7298_scan_direct(st, chan->address);
        }
        mutex_unlock(&dev_info->mlock);

        if (ret < 0)
            return ret;

        if (chan->address != AD7298_CH_TEMP)
            *val = ret & RES_MASK(AD7298_BITS);

        return IIO_VAL_INT;
    case (1 << IIO_CHAN_INFO_SCALE_SHARED):
        scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
        *val =  scale_uv / 1000;
        *val2 = (scale_uv % 1000) * 1000;
        return IIO_VAL_INT_PLUS_MICRO;
    case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
        *val =  1;
        *val2 = 0;
        return IIO_VAL_INT_PLUS_MICRO;
    }
    return -EINVAL;
}
Beispiel #10
0
void ad_spi_bus_acquire(spi_device dev)
{
        spi_device_config *device = (spi_device_config *) dev;

        if (device->data->bus_acquire_count++ == 0) {
#if !CONFIG_SPI_ONE_DEVICE_ON_BUS
                resource_acquire(RES_MASK(device->bus_res_id), RES_WAIT_FOREVER);
#endif
                if (device->bus_data->current_device != device) {
                        ad_spi_bus_apply_config(device);
                }

                if (device->hw_init.use_dma) {
                        resource_acquire(dma_resource_mask(device->hw_init.rx_dma_channel),
                                                                                RES_WAIT_FOREVER);
                }
        }
}
static int ad9834_write_frequency(struct ad9834_state *st,
				  unsigned long addr, unsigned long fout)
{
	unsigned long regval;

	if (fout > (st->mclk / 2))
		return -EINVAL;

	regval = ad9834_calc_freqreg(st->mclk, fout);

	st->freq_data[0] = cpu_to_be16(addr | (regval &
				       RES_MASK(AD9834_FREQ_BITS / 2)));
	st->freq_data[1] = cpu_to_be16(addr | ((regval >>
				       (AD9834_FREQ_BITS / 2)) &
				       RES_MASK(AD9834_FREQ_BITS / 2)));

	return spi_sync(st->spi, &st->freq_msg);
}
static int ad7298_scan_temp(struct ad7298_state *st, int *val)
{
	int tmp, ret;
	__be16 buf;

	buf = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
			  AD7298_TAVG | st->ext_ref);

	ret = spi_write(st->spi, (u8 *)&buf, 2);
	if (ret)
		return ret;

	buf = cpu_to_be16(0);

	ret = spi_write(st->spi, (u8 *)&buf, 2);
	if (ret)
		return ret;

	usleep_range(101, 1000); /* sleep > 100us */

	ret = spi_read(st->spi, (u8 *)&buf, 2);
	if (ret)
		return ret;

	tmp = be16_to_cpu(buf) & RES_MASK(AD7298_BITS);

	/*
	 * One LSB of the ADC corresponds to 0.25 deg C.
	 * The temperature reading is in 12-bit twos complement format
	 */

	if (tmp & (1 << (AD7298_BITS - 1))) {
		tmp = (4096 - tmp) * 250;
		tmp -= (2 * tmp);

	} else {
		tmp *= 250; /* temperature in milli degrees Celsius */
	}

	*val = tmp;

	return 0;
}