Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: sdp_k1_sdram
ad717x_iio.c
00001 /***************************************************************************//** 00002 * @file ad717x_iio.c 00003 * @brief Source file for the AD717x IIO Application 00004 ******************************************************************************** 00005 * Copyright (c) 2021-22 Analog Devices, Inc. 00006 * All rights reserved. 00007 * 00008 * This software is proprietary to Analog Devices, Inc. and its licensors. 00009 * By using this software you agree to the terms of the associated 00010 * Analog Devices Software License Agreement. 00011 *******************************************************************************/ 00012 00013 /******************************************************************************/ 00014 /***************************** Include Files **********************************/ 00015 /******************************************************************************/ 00016 00017 #include <stdio.h> 00018 #include "ad717x_user_config.h" 00019 #include "app_config.h" 00020 #include "ad717x_iio.h" 00021 #include "ad717x.h" 00022 #include "iio.h" 00023 #include "no_os_util.h" 00024 #include "ad717x_data_capture.h" 00025 #include "no_os_error.h" 00026 00027 /******************************************************************************/ 00028 /********************* Macros and Constants Definition ************************/ 00029 /******************************************************************************/ 00030 00031 /* Define ADC Resolution in Bits */ 00032 #if defined (DEV_AD7177_2) 00033 #define AD717x_RESOLUTION 32 00034 #else 00035 #define AD717x_RESOLUTION 24 00036 #endif 00037 00038 /* ADC max count (full scale value) for unipolar inputs */ 00039 #define ADC_MAX_COUNT_UNIPOLAR (uint32_t)((1 << AD717x_RESOLUTION) - 1) 00040 00041 /* ADC max count (full scale value) for bipolar inputs */ 00042 #define ADC_MAX_COUNT_BIPOLAR (uint32_t)(1 << (AD717x_RESOLUTION-1)) 00043 00044 /* Bytes per sample (*Note: 4 bytes needed per sample for data range 00045 * of 0 to 32-bit) */ 00046 #define BYTES_PER_SAMPLE sizeof(uint32_t) 00047 00048 /* Number of data storage bits (needed for IIO client) */ 00049 #define CHN_STORAGE_BITS (BYTES_PER_SAMPLE * 8) 00050 00051 /* Private IDs for IIO attributes */ 00052 #define AD717x_RAW_ATTR_ID 0 00053 #define AD717x_SCALE_ATTR_ID 1 00054 #define AD717x_OFFSET_ATTR_ID 2 00055 #define AD717x_SAMPLING_FREQUENCY_ID 3 00056 00057 /* Data Buffer for burst mode data capture */ 00058 #define AD717x_DATA_BUFFER_SIZE (8192) 00059 00060 /* Scan type definition */ 00061 #define AD717x_SCAN {\ 00062 .sign = 'u',\ 00063 .realbits = AD717x_RESOLUTION,\ 00064 .storagebits = CHN_STORAGE_BITS,\ 00065 .shift = 0,\ 00066 .is_big_endian = false\ 00067 } 00068 00069 /* Channel attribute definition */ 00070 #define AD717x_CHANNEL(_name, _priv) {\ 00071 .name = _name,\ 00072 .priv = _priv,\ 00073 .show = get_adc_attribute,\ 00074 .store = set_adc_attribute\ 00075 } 00076 00077 /* AD717x Channel Definition */ 00078 #define IIO_AD717x_CHANNEL(_idx) {\ 00079 .name = "ch" # _idx,\ 00080 .ch_type = IIO_VOLTAGE,\ 00081 .channel = _idx,\ 00082 .scan_index = _idx,\ 00083 .indexed = true,\ 00084 .scan_type = &ad717x_scan_type[_idx],\ 00085 .ch_out = false,\ 00086 .attributes = ad717x_channel_attributes,\ 00087 } 00088 00089 /******************************************************************************/ 00090 /******************** Variables and User Defined Data Types *******************/ 00091 /******************************************************************************/ 00092 00093 /* IIO interface descriptor */ 00094 static struct iio_desc *p_ad717x_iio_desc; 00095 00096 /* Pointer to the struct representing the AD717x IIO device */ 00097 ad717x_dev *p_ad717x_dev_inst = NULL; 00098 00099 /* Device Name */ 00100 static const char dev_name[] = ACTIVE_DEVICE_NAME; 00101 00102 /* Variable to hold the number of active channels*/ 00103 uint8_t num_active_channels = 0; 00104 00105 /* Channel scale values */ 00106 static float attr_scale_val[NUMBER_OF_CHANNELS]; 00107 00108 /* Channel offset values */ 00109 static int attr_offset_val[NUMBER_OF_CHANNELS]; 00110 00111 /* AD717x channel scan type */ 00112 static struct scan_type ad717x_scan_type[] = { 00113 AD717x_SCAN, 00114 AD717x_SCAN, 00115 AD717x_SCAN, 00116 AD717x_SCAN, 00117 #if (NUMBER_OF_CHANNELS != 4) 00118 AD717x_SCAN, 00119 AD717x_SCAN, 00120 AD717x_SCAN, 00121 AD717x_SCAN, 00122 #if (NUMBER_OF_CHANNELS != 4) && (NUMBER_OF_CHANNELS !=8 ) 00123 AD717x_SCAN, 00124 AD717x_SCAN, 00125 AD717x_SCAN, 00126 AD717x_SCAN, 00127 AD717x_SCAN, 00128 AD717x_SCAN, 00129 AD717x_SCAN, 00130 AD717x_SCAN 00131 #endif 00132 #endif 00133 }; 00134 00135 /******************************************************************************/ 00136 /************************** Functions Declaration *****************************/ 00137 /******************************************************************************/ 00138 00139 /******************************************************************************/ 00140 /************************** Functions Definition ******************************/ 00141 /******************************************************************************/ 00142 00143 /*! 00144 * @brief Getter/Setter for the attribute value 00145 * @param device[in]- pointer to IIO device structure 00146 * @param buf[in]- pointer to buffer holding attribute value 00147 * @param len[in]- length of buffer string data 00148 * @param channel[in]- pointer to IIO channel structure 00149 * @param id[in]- Attribute ID 00150 * @return Number of characters read/written in case of success, negative error code otherwise 00151 */ 00152 static int32_t get_adc_attribute(void *device, 00153 char *buf, 00154 uint32_t len, 00155 const struct iio_ch_info *channel, 00156 intptr_t id) 00157 { 00158 int32_t adc_raw_data = 0; 00159 int32_t adc_offset = 0; 00160 00161 switch (id) { 00162 case AD717x_RAW_ATTR_ID: 00163 if (ad717x_single_read(device, channel->ch_num, &adc_raw_data) < 0) 00164 return -EINVAL; 00165 00166 return sprintf(buf, "%d", adc_raw_data); 00167 00168 case AD717x_SCALE_ATTR_ID: 00169 return sprintf(buf, "%f", attr_scale_val[channel->ch_num]); 00170 00171 case AD717x_OFFSET_ATTR_ID: 00172 return sprintf(buf, "%d", attr_offset_val[channel->ch_num]); 00173 00174 case AD717x_SAMPLING_FREQUENCY_ID: 00175 return sprintf(buf, "%d", AD717x_SAMPLING_RATE/NUMBER_OF_CHANNELS); 00176 00177 default: 00178 break; 00179 } 00180 00181 return -EINVAL; 00182 } 00183 00184 00185 static int32_t set_adc_attribute(void *device, 00186 char *buf, 00187 uint32_t len, 00188 const struct iio_ch_info *channel, 00189 intptr_t id) 00190 { 00191 switch (id) { 00192 00193 /* ADC Raw, Scale, Offset factors are constant for the firmware configuration */ 00194 case AD717x_RAW_ATTR_ID: 00195 case AD717x_SCALE_ATTR_ID: 00196 case AD717x_OFFSET_ATTR_ID: 00197 case AD717x_SAMPLING_FREQUENCY_ID: 00198 default: 00199 break; 00200 } 00201 00202 return len; 00203 } 00204 00205 /* AD717X Channel Attributes */ 00206 static struct iio_attribute ad717x_channel_attributes[] = { 00207 AD717x_CHANNEL("raw", AD717x_RAW_ATTR_ID), 00208 AD717x_CHANNEL("scale", AD717x_SCALE_ATTR_ID), 00209 AD717x_CHANNEL("offset", AD717x_OFFSET_ATTR_ID), 00210 END_ATTRIBUTES_ARRAY 00211 }; 00212 00213 /* AD717x Global Attributes */ 00214 static struct iio_attribute iio_ad717x_global_attributes[] = { 00215 AD717x_CHANNEL("sampling_frequency", AD717x_SAMPLING_FREQUENCY_ID), 00216 END_ATTRIBUTES_ARRAY 00217 }; 00218 00219 /* IIO Attributes */ 00220 static struct iio_channel iio_adc_channels[] = { 00221 IIO_AD717x_CHANNEL(0), 00222 IIO_AD717x_CHANNEL(1), 00223 IIO_AD717x_CHANNEL(2), 00224 IIO_AD717x_CHANNEL(3), 00225 #if (NUMBER_OF_CHANNELS != 4) 00226 IIO_AD717x_CHANNEL(4), 00227 IIO_AD717x_CHANNEL(5), 00228 IIO_AD717x_CHANNEL(6), 00229 IIO_AD717x_CHANNEL(7), 00230 #if (NUMBER_OF_CHANNELS != 4) && (NUMBER_OF_CHANNELS != 8) 00231 IIO_AD717x_CHANNEL(8), 00232 IIO_AD717x_CHANNEL(9), 00233 IIO_AD717x_CHANNEL(10), 00234 IIO_AD717x_CHANNEL(11), 00235 IIO_AD717x_CHANNEL(12), 00236 IIO_AD717x_CHANNEL(13), 00237 IIO_AD717x_CHANNEL(14), 00238 IIO_AD717x_CHANNEL(15) 00239 #endif 00240 #endif 00241 }; 00242 00243 /** 00244 * @brief Read the debug register value 00245 * @param desc[in,out] - Pointer to IIO device descriptor 00246 * @param reg[in]- Address of the register to be read 00247 * @param readval[out]- Pointer to the register data variable 00248 * @return 0 in case of success, negative error code 00249 */ 00250 static int32_t iio_ad717x_debug_reg_read(void *dev, 00251 uint32_t reg, 00252 uint32_t *readval) 00253 { 00254 int32_t debug_read_status; // Status check variable 00255 00256 /* Retrieve the pointer to the requested register */ 00257 ad717x_st_reg *read_register = AD717X_GetReg(p_ad717x_dev_inst, reg); 00258 if (!read_register) { 00259 return -EINVAL; 00260 } 00261 00262 /* Read the register data, extract the value */ 00263 debug_read_status = AD717X_ReadRegister(p_ad717x_dev_inst, reg); 00264 if (debug_read_status) { 00265 return debug_read_status; 00266 } 00267 *readval = read_register->value; 00268 00269 return 0; 00270 } 00271 00272 00273 /** 00274 * @brief Write value to the debug register 00275 * @param desc[in,out] Pointer to IIO device descriptor 00276 * @param reg[in] Address of the register where the data is to be written 00277 * @param write_val[out] Pointer to the register data variable 00278 * @return 0 in case of success, negative error code otherwise 00279 */ 00280 static int32_t iio_ad717x_debug_reg_write(void *dev, 00281 uint32_t reg, 00282 uint32_t write_val) 00283 { 00284 int32_t debug_write_status; // Status check variable 00285 ad717x_st_reg *device_data_reg; // Pointer to data register 00286 00287 /* Retrieve the pointer to the requested registrer */ 00288 device_data_reg = AD717X_GetReg(p_ad717x_dev_inst, reg); 00289 device_data_reg->value = write_val; 00290 00291 /* Write value to the register */ 00292 debug_write_status = AD717X_WriteRegister(p_ad717x_dev_inst, reg); 00293 if (debug_write_status) { 00294 return debug_write_status; 00295 } 00296 00297 return 0; 00298 } 00299 00300 00301 /** 00302 * @brief Transfer the device data into memory (optional) 00303 * @param dev_instance[in] - IIO device instance 00304 * @param ch_mask[in] - Channels select mask 00305 * @return 0 in case of success or negative value otherwise 00306 */ 00307 static int32_t iio_ad717x_pre_enable(void *dev_instance, uint32_t chn_mask) 00308 { 00309 return prepare_data_transfer(chn_mask, NUMBER_OF_CHANNELS, BYTES_PER_SAMPLE); 00310 } 00311 00312 00313 /** 00314 * @brief Read buffer data corresponding to AD4170 IIO device 00315 * @param iio_dev_data[in] - Pointer to IIO device data structure 00316 * @return 0 in case of success or negative value otherwise 00317 */ 00318 static int32_t iio_ad717x_submit_buffer(struct iio_device_data *iio_dev_data) 00319 { 00320 int32_t ret; 00321 00322 /* Read the samples counts equal to buffer size/block */ 00323 ret = read_buffered_data(&iio_dev_data->buffer->buf->buff, 00324 iio_dev_data->buffer->size); 00325 00326 /* Increment the write spin count as buffer reads all 'n' samples 00327 * in one go which is also the size of buffer block for a given instance. 00328 * The read spin count is incremented from IIO library during buffer 00329 * write/offloading into transmit buffer */ 00330 if (iio_dev_data->buffer->buf->write.spin_count >= UINT32_MAX) { 00331 iio_dev_data->buffer->buf->write.spin_count = 0; 00332 } 00333 00334 iio_dev_data->buffer->buf->write.spin_count += 1; 00335 00336 return ret; 00337 } 00338 00339 00340 /** 00341 * @brief Perform tasks before end of current data transfer 00342 * @param dev[in] - IIO device instance 00343 * @return 0 in case of success or negative value otherwise 00344 */ 00345 static int32_t iio_ad717x_post_disable(void *dev) 00346 { 00347 return end_data_transfer(); 00348 } 00349 00350 00351 /** 00352 * @brief Init for reading/writing and parameterization of a AD717x IIO device 00353 * @param desc[in,out] IIO device descriptor 00354 * @return 0 in case of success, negative error code otherwise 00355 */ 00356 int32_t iio_ad717x_init(struct iio_device **desc) 00357 { 00358 struct iio_device *iio_ad717x_inst; // IIO Device Descriptor for AD717x 00359 00360 iio_ad717x_inst = calloc(1, sizeof(struct iio_device)); 00361 if (!iio_ad717x_inst) { 00362 return -EINVAL; 00363 } 00364 00365 iio_ad717x_inst->num_ch = NO_OS_ARRAY_SIZE(iio_adc_channels); 00366 iio_ad717x_inst->channels = iio_adc_channels; 00367 iio_ad717x_inst->attributes = iio_ad717x_global_attributes; 00368 iio_ad717x_inst->buffer_attributes = NULL; 00369 iio_ad717x_inst->write_dev = NULL; 00370 iio_ad717x_inst->pre_enable = iio_ad717x_pre_enable; 00371 iio_ad717x_inst->post_disable = iio_ad717x_post_disable; 00372 iio_ad717x_inst->submit = iio_ad717x_submit_buffer; 00373 iio_ad717x_inst->debug_reg_read = iio_ad717x_debug_reg_read; 00374 iio_ad717x_inst->debug_reg_write = iio_ad717x_debug_reg_write; 00375 00376 *desc = iio_ad717x_inst; 00377 00378 return 0; 00379 } 00380 00381 00382 /** 00383 * @brief Function to update scale and offset values based on user selection 00384 * @param device[in] AD717x device descriptor 00385 * @return 0 in case of success, negative error code otherwise 00386 */ 00387 static int32_t ad717x_update_attr_parameters(ad717x_dev *device) 00388 { 00389 float reference_value = 0; // Variable to hold the updated reference value 00390 uint8_t i; 00391 00392 for (i = 0; i < NUMBER_OF_CHANNELS; i++) { 00393 /* Update reference value */ 00394 switch (device->setups[device->chan_map[i].setup_sel].ref_source) { 00395 case INTERNAL_REF: 00396 reference_value = AD717X_INTERNAL_REFERENCE; 00397 break; 00398 case EXTERNAL_REF: 00399 reference_value = AD717x_EXTERNAL_REFERENCE; 00400 break; 00401 case AVDD_AVSS: 00402 reference_value = AD717X_AVDD_AVSS_REFERENCE; 00403 break; 00404 default: 00405 return -EINVAL; 00406 } 00407 00408 /* Update channel attribute parameters */ 00409 if (!(device->setups[device->chan_map[i].setup_sel].bi_unipolar)) { 00410 /* Settings for Unipolar mode */ 00411 attr_scale_val[i] = ((reference_value / ADC_MAX_COUNT_UNIPOLAR) * 1000) / 00412 SCALE_FACTOR_DR; 00413 attr_offset_val[i] = 0; 00414 ad717x_scan_type[i].sign = 'u'; 00415 ad717x_scan_type[i].realbits = AD717x_RESOLUTION; 00416 } else { 00417 /* Settings for Bipolar mode */ 00418 attr_scale_val[i] = ((reference_value / (ADC_MAX_COUNT_BIPOLAR)) * 1000) / 00419 SCALE_FACTOR_DR; 00420 attr_offset_val[i] = -(1 << (AD717x_RESOLUTION - 1)); 00421 ad717x_scan_type[i].sign = 's'; 00422 ad717x_scan_type[i].realbits = CHN_STORAGE_BITS; 00423 } 00424 } 00425 00426 return 0; 00427 } 00428 00429 00430 /** 00431 * @brief Initialize the AD717x IIO Interface 00432 * @return 0 in case of success, negative error code otherwise 00433 */ 00434 int32_t ad717x_iio_initialize(void) 00435 { 00436 int32_t iio_init_status; // Status check variable 00437 struct iio_init_param iio_init_params; // IIO Init Parameters 00438 struct iio_device *ad717x_iio_desc; // aD717x IIO Descriptor 00439 00440 /* Init the system peripheral- UART */ 00441 iio_init_status = init_system(); 00442 if (iio_init_status) { 00443 return iio_init_status; 00444 } 00445 00446 /* IIO Initialization Parameters */ 00447 iio_init_params.phy_type = USE_UART; 00448 iio_init_params.nb_devs = 1; 00449 00450 /* IIOD init parameters */ 00451 struct iio_device_init iio_device_init_params = { 00452 .name = (char*)dev_name, 00453 .raw_buf = adc_data_buffer, 00454 .raw_buf_len = DATA_BUFFER_SIZE 00455 }; 00456 00457 /* Initialize AD717x device */ 00458 iio_init_status = AD717X_Init(&p_ad717x_dev_inst, ad717x_init_params); 00459 if (iio_init_status) { 00460 return iio_init_status; 00461 } 00462 00463 /* Update the ADC scale respective to the device settings */ 00464 iio_init_status = ad717x_update_attr_parameters(p_ad717x_dev_inst); 00465 if (iio_init_status) { 00466 return iio_init_status; 00467 } 00468 00469 /* Initialize the AD717x IIO Interface */ 00470 iio_init_status = iio_ad717x_init(&ad717x_iio_desc); 00471 if (iio_init_status) { 00472 return iio_init_status; 00473 } 00474 00475 /* Initialize the IIO Interface */ 00476 iio_init_params.uart_desc = uart_desc; 00477 iio_device_init_params.dev = p_ad717x_dev_inst; 00478 iio_device_init_params.dev_descriptor = ad717x_iio_desc; 00479 iio_init_params.devs = &iio_device_init_params; 00480 iio_init_params.nb_trigs = 0; 00481 iio_init_status = iio_init(&p_ad717x_iio_desc, &iio_init_params); 00482 if (iio_init_status) { 00483 return iio_init_status; 00484 } 00485 00486 return 0; 00487 } 00488 00489 00490 /** 00491 * @brief Run the AD717x IIO event handler 00492 * @return None 00493 */ 00494 void ad717x_iio_event_handler(void) 00495 { 00496 (void)iio_step(p_ad717x_iio_desc); 00497 }
Generated on Tue Nov 15 2022 11:39:51 by
