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)); }
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)); }
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]; }
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 } }
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); }
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)); }
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; }
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; }
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; }