diff --git a/.github/workflows/build-projects.yaml b/.github/workflows/build-projects.yaml index b51835d7..2d700bc0 100644 --- a/.github/workflows/build-projects.yaml +++ b/.github/workflows/build-projects.yaml @@ -12,6 +12,7 @@ jobs: strategy: matrix: project: + - ad2s1210_iio - ad4130_iio - ad559xr_console - ad5770r_console diff --git a/.mbedignore b/.mbedignore index 2761d26c..a5904125 100644 --- a/.mbedignore +++ b/.mbedignore @@ -27,4 +27,5 @@ projects/ad590_console/ projects/adt7420_console/ projects/ad559xr_console/ projects/ad5933_console/ +projects/ad2s1210_iio/ projects/evb_discovery_firmware/ diff --git a/libraries/no-OS b/libraries/no-OS index 3ade1be9..6b024163 160000 --- a/libraries/no-OS +++ b/libraries/no-OS @@ -1 +1 @@ -Subproject commit 3ade1be92427f544ccf3589eaba3f9e8cb1f2312 +Subproject commit 6b024163b1257dbd7c36a72bef693d4194cc1d5a diff --git a/libraries/no-OS.lib b/libraries/no-OS.lib index e9f3b26a..6f2cbf15 100644 --- a/libraries/no-OS.lib +++ b/libraries/no-OS.lib @@ -1 +1 @@ -https://github.com/analogdevicesinc/no-OS/#3ade1be92427f544ccf3589eaba3f9e8cb1f2312 +https://github.com/analogdevicesinc/no-OS/#6b024163b1257dbd7c36a72bef693d4194cc1d5a diff --git a/projects/ad2s1210_iio/.gitignore b/projects/ad2s1210_iio/.gitignore new file mode 100644 index 00000000..2199b24b --- /dev/null +++ b/projects/ad2s1210_iio/.gitignore @@ -0,0 +1,17 @@ +*.swp +*.profile* +build +app/no-OS +Visual* +Code* +.gitattributes +.vs/ +*.sln +*.vgdbproj +*.TMP +*.user +scripts/__pycache__ +tests/.pytest_cache +tests/__pycache__ +tests/func/__pycache__ +tests/output diff --git a/projects/ad2s1210_iio/Makefile b/projects/ad2s1210_iio/Makefile new file mode 100644 index 00000000..fc6ad458 --- /dev/null +++ b/projects/ad2s1210_iio/Makefile @@ -0,0 +1,7 @@ +include ../../tools/scripts/generic_variables.mk + +-include $(NO-OS)/tools/scripts/generic_variables.mk + +include src.mk + +-include $(NO-OS)/tools/scripts/generic.mk diff --git a/projects/ad2s1210_iio/README.txt b/projects/ad2s1210_iio/README.txt new file mode 100644 index 00000000..a164e4b9 --- /dev/null +++ b/projects/ad2s1210_iio/README.txt @@ -0,0 +1,65 @@ +Evaluation Boards/Products Supported +------------------------------------ +EVAL-AD2S1210 + + +Overview +-------- +This is an IIO firmware application to evaluate the AD2S1210 device. +This code was developed and tested on SDP-K1 controller board: https://os.mbed.com/platforms/SDP_K1/ +Use of the Mbed platform allows code to be ported to other Mbed supported target boards with little or no modifications. + +Product details: AD2S1210. +Product Evaluation board details: EVAL-AD2S1210SDZ +User Guide for this code: https://wiki.analog.com/resources/tools-software/product-support-software/AD2S1210_mbed_iio_support +Communication Protocol: SPI + + +Hardware Setup +-------------- +Required: SDP-K1, ADZS-BRKOUT, EVAL-AD2S1210 board and USB cable. +Plug in the EVAL-AD2S1210 board to the ADZS-BRKOUT, populate flywires to the +SDP-K1 board using the Arduino connector. + +The connections are as follows: + +SDPK1 BREAKOUT +DIGITAL-0 -> 96 A0 +DIGITAL-1 -> 25 A1 +DIGITAL-4 -> 48 SAMPLE +DIGITAL-5 -> 43 RES0 +DIGITAL-6 -> 78 RES1 +DIGITAL-10 -> 100 nWD +DIGITAL-11 -> 12 SDI +DIGITAL-12 -> 110 SDO +DIGITAL-13 -> 13 SCLK +POWER-GND -> 4 GIO +POWER-3v3 -> 116 VIO + +2S1210-EVAL +J3 CS -> J3 GND + + + +(refer to the software wiki page for connection setup). +Connect the SDP-K1 board to the PC using the USB cable and the AD2S1210 EVB to the +provided AC adapter. + + +How to Get Started +------------------ +Mbed web/online compiler: https://studio.keil.arm.com/auth/login/ +Import the code into the compiler and compile it to generate the executable binary file. +Drag and drop the binary file onto the USB drive hosted by the SDP-K1 controller board. +Find detailed instructions here: https://wiki.analog.com/resources/tools-software/product-support-software/pcg-fw-mbed-build-guide + + +Notes +----- +A detailed user guide on the SDP-K1 controller board is available here: +https://os.mbed.com/platforms/SDP_K1/ +https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/SDP-K1.html. + + +Copyright (c) 2023 Analog Devices, Inc. All rights reserved. +Copyright (c) 2023 BayLibre, SAS diff --git a/projects/ad2s1210_iio/app/ad2s1210_iio.c b/projects/ad2s1210_iio/app/ad2s1210_iio.c new file mode 100644 index 00000000..b14b45a1 --- /dev/null +++ b/projects/ad2s1210_iio/app/ad2s1210_iio.c @@ -0,0 +1,664 @@ +/***************************************************************************//** + * @file ad2s1210_iio.c + * @brief Implementation of AD2S1210 IIO application interfaces +******************************************************************************** + * Copyright (c) 2023 Analog Devices, Inc. + * Copyright (c) 2023 BayLibre, SAS. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include +#include +#include +#include + +#include "iio.h" +#include "iio_trigger.h" + +#include "ad2s1210_iio.h" +#include "app_config.h" +#include "ad2s1210_user_config.h" +#include "common.h" +#include "no_os_error.h" +#include "no_os_util.h" + +/******** Forward declaration of getter/setter functions ********/ +static int iio_ad2s1210_attr_get(void *device, char *buf, uint32_t len, + const struct iio_ch_info *channel, + intptr_t priv); + +static int iio_ad2s1210_attr_set(void *device, char *buf, uint32_t len, + const struct iio_ch_info *channel, + intptr_t priv); + +/******************************************************************************/ +/********************* Macros and Constants Definition ************************/ +/******************************************************************************/ +#define AD2S1210_CHN_ATTR(_name, _priv) {\ + .name = _name,\ + .priv = _priv,\ + .show = iio_ad2s1210_attr_get,\ + .store = iio_ad2s1210_attr_set\ +} + +#define AD2S1210_CH(_name, _idx, _type, _ch_out) {\ + .name = _name, \ + .ch_type = _type,\ + .ch_out = _ch_out,\ + .indexed = true,\ + .channel = 0,\ + .scan_index = _idx,\ + .scan_type = &chn_scan[_idx],\ + .attributes = &ad2s1210_iio_ch_attributes[_idx][0]\ +} + +/* Number of IIO devices */ +#define NUM_OF_IIO_DEVICES 1 + +#define BYTES_PER_SAMPLE 2 + +/* Number of data storage bits (needed for IIO client to plot RESOLVER data) */ +#define CHN_STORAGE_BITS (BYTES_PER_SAMPLE * 8) + +#define AD2S1210_IIO_TRIGGER_NAME "ad2s1210_iio_trigger" + +/* data buffer size */ +#if defined(USE_SDRAM) +#define data_buffer SDRAM_START_ADDRESS +#define DATA_BUFFER_SIZE SDRAM_SIZE_BYTES +#else +#define DATA_BUFFER_SIZE (32768) /* 32kbytes */ +static int8_t data_buffer[DATA_BUFFER_SIZE] = { 0 }; +#endif + +/******************************************************************************/ +/******************** Variables and User Defined Data Types *******************/ +/******************************************************************************/ + +/* Pointer to the struct representing the AD2S1210 IIO device */ +struct ad2s1210_dev *ad2s1210_dev_inst; + +/* IIO interface descriptor */ +static struct iio_desc *ad2s1210_iio_desc; + +uint32_t active_chn_count; + +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) +static struct iio_hw_trig *ad2s1210_hw_trig_desc; +#endif + +enum ad2s1210_attribute_id { + RAW_ATTR_ID, + SCALE_ATTR_ID, + SAMPLING_FREQ_ATTR_ID, + LABEL_ATTR_ID, + HYSTERESIS_ATTR_ID, + HYSTERESIS_AVAILABLE_ATTR_ID, + FREQ_ATTR_ID, + FREQ_AVAIL_ATTR_ID, +}; + +struct scan_type chn_scan[RESOLVER_CHANNELS] = { + { + .sign = 'u', + .realbits = CHN_STORAGE_BITS, + .storagebits = CHN_STORAGE_BITS, + .shift = 0, + .is_big_endian = true, + }, + { + .sign = 's', + .realbits = CHN_STORAGE_BITS, + .storagebits = CHN_STORAGE_BITS, + .shift = 0, + .is_big_endian = true, + }, + { + .sign = 'u', + .realbits = CHN_STORAGE_BITS, + .storagebits = CHN_STORAGE_BITS, + .shift = 0, + .is_big_endian = false, + }, +}; + +/* IIO channels attributes list */ +static struct iio_attribute + ad2s1210_iio_ch_attributes[RESOLVER_CHANNELS][RESOLVER_MAX_ATTR] = { + { + AD2S1210_CHN_ATTR("hysteresis", HYSTERESIS_ATTR_ID), + AD2S1210_CHN_ATTR("hysteresis_available", HYSTERESIS_AVAILABLE_ATTR_ID), + AD2S1210_CHN_ATTR("label", LABEL_ATTR_ID), + AD2S1210_CHN_ATTR("raw", RAW_ATTR_ID), + AD2S1210_CHN_ATTR("scale", SCALE_ATTR_ID), + END_ATTRIBUTES_ARRAY + }, + { + AD2S1210_CHN_ATTR("label", LABEL_ATTR_ID), + AD2S1210_CHN_ATTR("raw", RAW_ATTR_ID), + AD2S1210_CHN_ATTR("scale", SCALE_ATTR_ID), + END_ATTRIBUTES_ARRAY + }, + { + AD2S1210_CHN_ATTR("frequency", FREQ_ATTR_ID), + AD2S1210_CHN_ATTR("frequency_available", FREQ_AVAIL_ATTR_ID), + AD2S1210_CHN_ATTR("label", LABEL_ATTR_ID), + END_ATTRIBUTES_ARRAY + }, +}; + +/* IIO device (global) attributes list */ +static struct iio_attribute ad2s1210_iio_global_attributes[] = { + AD2S1210_CHN_ATTR("sampling_frequency", SAMPLING_FREQ_ATTR_ID), + END_ATTRIBUTES_ARRAY +}; + +/* IIO channels info */ +static struct iio_channel ad2s1210_iio_channels[RESOLVER_CHANNELS] = { + AD2S1210_CH("position", 0, IIO_ANGL, false), + AD2S1210_CH("velocity", 1, IIO_ANGL_VEL, false), + AD2S1210_CH("altvoltage", 2, IIO_ALTVOLTAGE, true) +}; + +/* Flag to indicate if size of the buffer is updated according to requested + * number of samples for the multi-channel IIO buffer data alignment + */ +static bool buf_size_updated; + +static const float ad2s1210_velocity_scale[] = { + AD2S1210_TRACKING_RATE_10BIT, + AD2S1210_TRACKING_RATE_12BIT, + AD2S1210_TRACKING_RATE_14BIT, + AD2S1210_TRACKING_RATE_16BIT, +}; + + +/*! + * @brief Getter functions for AD2S1210 attributes + * @param device[in]- Pointer to IIO device instance + * @param buf[in,out]- IIO input data buffer + * @param len[in]- Number of input bytes + * @param channel[in] - Input channel + * @param priv[in] - Attribute private ID + * @return string length in case of success, negative error code otherwise + */ +static int iio_ad2s1210_attr_get(void *device, char *buf, uint32_t len, + const struct iio_ch_info *channel, + intptr_t priv) +{ + uint16_t data[2]; + uint16_t data_cpu = 0; + struct ad2s1210_dev *dev = (struct ad2s1210_dev *) device; + uint32_t active_mask = AD2S1210_POS_MASK; + float rps_max; + float scale = AD2S1210_POS_IIO_SCALE; + int ret; + uint16_t fexcit; + + if (channel->type == IIO_ANGL_VEL) { + active_mask = AD2S1210_VEL_MASK; + } + + switch (priv) { + case RAW_ATTR_ID: + ret = ad2s1210_spi_single_conversion(device, active_mask, + data, sizeof(data)); + if (ret) { + return ret; + } + + data_cpu = data[0]; + no_os_memswap64(&data_cpu, 2, 2); + + if (channel->type == IIO_ANGL_VEL) { + return sprintf(buf, "%d", (int16_t)data_cpu); + } + + return sprintf(buf, "%u", data_cpu); + case SCALE_ATTR_ID: + if (channel->type == IIO_ANGL_VEL) { + rps_max = ad2s1210_velocity_scale[dev->resolution]; + scale = 2 * MATH_PI * rps_max / (SHRT_MAX + 1); + } + + return snprintf(buf, len, "%10f", scale); + + case SAMPLING_FREQ_ATTR_ID: + return snprintf(buf, len, "%d", SAMPLING_RATE); + case LABEL_ATTR_ID: + if (channel->type == IIO_ANGL_VEL) { + return snprintf(buf, len, "velocity"); + } else if (channel->type == IIO_ALTVOLTAGE) { + return snprintf(buf, len, "excitation"); + } + return snprintf(buf, len, "position"); + + case HYSTERESIS_ATTR_ID: + ret = ad2s1210_hysteresis_is_enabled(dev); + if (ret < 0) { + return ret; + } + return snprintf(buf, len, "%d", ret); + + case HYSTERESIS_AVAILABLE_ATTR_ID: + return snprintf(buf, len, "0 1"); + + case FREQ_ATTR_ID: + ret = ad2s1210_get_excitation_frequency(dev, &fexcit); + if (ret) { + return ret; + } + return snprintf(buf, len, "%hu", fexcit); + + case FREQ_AVAIL_ATTR_ID: + return snprintf(buf, len, "[%d %d %d]", AD2S1210_MIN_EXCIT, + AD2S1210_STEP_EXCIT, AD2S1210_MAX_EXCIT); + default: + + break; + } + + return len; +} + +/*! + * @brief Setter functions for AD738x attributes + * @param device[in]- Pointer to IIO device instance + * @param buf[in]- IIO input data buffer + * @param len[in]- Number of input bytes + * @param channel[in] - Input channel + * @param priv[in] - Attribute private ID + * @return Positive len in case of success, negative error code otherwise + */ +static int iio_ad2s1210_attr_set(void *device, char *buf, uint32_t len, + const struct iio_ch_info *channel, + intptr_t priv) +{ + struct ad2s1210_dev *dev = (struct ad2s1210_dev *) device; + uint16_t fexcit; + uint8_t hysteresis; + int ret; + + switch (priv) { + case RAW_ATTR_ID: + case SCALE_ATTR_ID: + case LABEL_ATTR_ID: + case HYSTERESIS_AVAILABLE_ATTR_ID: + case FREQ_AVAIL_ATTR_ID: + /* All read-only attributes */ + break; + case FREQ_ATTR_ID: + ret = sscanf(buf, "%hu", &fexcit); + if (ret != 1) { + return -EINVAL; + } + + ret = ad2s1210_reinit_excitation_frequency(dev, fexcit); + if (ret) { + return ret; + } + break; + + case HYSTERESIS_ATTR_ID: + ret = sscanf(buf, "%hhu", &hysteresis); + if (ret != 1) { + return -EINVAL; + } + + ret = ad2s1210_set_hysteresis(dev, hysteresis ? true : false); + if (ret) { + return ret; + } + + break; + default: + break; + } + + return len; +} + +/*! + * @brief Read the debug register value + * @param dev[in, out]- Pointer to IIO device instance + * @param reg[in]- Register address to read from + * @param readval[out]- Pointer to variable to read data into + * @return 0 in case of success, negative value otherwise + */ +static int32_t iio_ad2s1210_debug_reg_read(void *dev, uint32_t reg, + uint32_t *val) +{ + return ad2s1210_reg_read(dev, (uint8_t) reg, (uint8_t *)val); +} + +/*! + * @brief Write the debug register value + * @param dev[in, out]- Pointer to IIO device instance + * @param reg[in]- Register address to read from + * @param writeval[out]- Pointer to variable to write data into + * @return 0 in case of success, negative value otherwise + */ +static int32_t iio_ad2s1210_debug_reg_write(void *dev, uint32_t reg, + uint32_t val) +{ + return ad2s1210_reg_write(dev, (uint8_t)reg, (uint8_t)val); +} + +/** + * @brief Read buffer data corresponding to AD2S1210 IIO device + * @param iio_dev_data[in] - Pointer to IIO device data structure + * @return 0 in case of success, negative error code otherwise + */ +static int32_t iio_ad2s1210_submit_buffer(struct iio_device_data *iio_dev_data) +{ + + uint32_t sample_indx = 0; + uint32_t nb_of_samples; + int32_t ret; + uint16_t data[2]; + uint8_t i; + +#if (DATA_CAPTURE_MODE == BURST_DATA_CAPTURE) + nb_of_samples = iio_dev_data->buffer->size / BYTES_PER_SAMPLE; + + if (!buf_size_updated) { + iio_dev_data->buffer->buf->size = iio_dev_data->buffer->size; + buf_size_updated = true; + } + + /* Push into circular buffer */ + while (sample_indx < nb_of_samples) { + ret = ad2s1210_spi_single_conversion(ad2s1210_dev_inst, + iio_dev_data->buffer->active_mask, + data, sizeof(data)); + if (ret) { + return ret; + } + ret = no_os_cb_write(iio_dev_data->buffer->buf, data, + BYTES_PER_SAMPLE * active_chn_count); + if (ret) { + return ret; + } + sample_indx++; + } +#endif + return 0; +} + +/** + * @brief Prepare for RESOLVER data capture (from device to memory) + * @param dev_instance[in] - IIO device instance + * @param chn_mask[in] - Channels select mask + * @return 0 in case of success, negative error code otherwise + */ +static int32_t iio_ad2s1210_prepare_transfer(void *dev_instance, + uint32_t chn_mask) +{ + int32_t ret; + +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + ret = iio_trig_enable(ad2s1210_hw_trig_desc); + if (ret) { + return ret; + } +#endif + active_chn_count = __builtin_popcount(chn_mask); + + return 0; +} + +/** + * @brief Perform tasks before end of current data transfer + * @param dev[in] - IIO device instance + * @return 0 in case of success, negative error code otherwise + */ +static int32_t iio_ad2s1210_end_transfer(void *dev) +{ + int32_t ret; + +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + ret = iio_trig_disable(ad2s1210_hw_trig_desc); + if (ret) { + return ret; + } +#endif + return 0; +} + +/** + * @brief Push data into IIO buffer when trigger handler IRQ is invoked + * @param iio_dev_data[in] - IIO device data instance + * @return 0 in case of success or negative value otherwise + */ +int32_t ad2s1210_trigger_handler(struct iio_device_data *iio_dev_data) +{ + int32_t ret; + uint16_t data[2]; + + if (!buf_size_updated) { + /* Update total buffer size according to bytes per scan for + * proper alignment of multi-channel IIO buffer data + */ + iio_dev_data->buffer->buf->size = ((uint32_t)(DATA_BUFFER_SIZE / + iio_dev_data->buffer->bytes_per_scan)) + * iio_dev_data->buffer->bytes_per_scan; + buf_size_updated = true; + } + + ret = ad2s1210_spi_single_conversion(ad2s1210_dev_inst, + iio_dev_data->buffer->active_mask, + data, sizeof(data)); + if (ret) { + return ret; + } + + ret = no_os_cb_write(iio_dev_data->buffer->buf, data, + BYTES_PER_SAMPLE * active_chn_count); + if (ret) { + return ret; + } + + return 0; +} + +/** + * @brief Init for reading/writing and parameterization of a + * ad2s1210 IIO device + * @param desc[in,out] - IIO device descriptor + * @return 0 in case of success, negative error code otherwise + */ +static int32_t ad2s1210_iio_param_init(struct iio_device **desc) +{ + struct iio_device *iio_ad2s1210_inst; + + iio_ad2s1210_inst = calloc(1, sizeof(struct iio_device)); + if (!iio_ad2s1210_inst) { + return -ENOMEM; + } + + iio_ad2s1210_inst->num_ch = NO_OS_ARRAY_SIZE(ad2s1210_iio_channels); + iio_ad2s1210_inst->channels = ad2s1210_iio_channels; + iio_ad2s1210_inst->attributes = ad2s1210_iio_global_attributes; + + iio_ad2s1210_inst->submit = iio_ad2s1210_submit_buffer; + iio_ad2s1210_inst->pre_enable = iio_ad2s1210_prepare_transfer; + iio_ad2s1210_inst->post_disable = iio_ad2s1210_end_transfer; + iio_ad2s1210_inst->debug_reg_read = iio_ad2s1210_debug_reg_read; + iio_ad2s1210_inst->debug_reg_write = iio_ad2s1210_debug_reg_write; +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + iio_ad2s1210_inst->trigger_handler = ad2s1210_trigger_handler; +#endif + + *desc = iio_ad2s1210_inst; + + return 0; +} + +/** + * @brief Initialization of AD2S1210 IIO hardware trigger parameters + * @param desc[in,out] - IIO hardware trigger descriptor + * @return 0 in case of success, negative error code otherwise + */ +static int32_t ad2s1210_iio_trigger_param_init(struct iio_hw_trig **desc) +{ + int32_t ret; + struct iio_hw_trig_init_param ad2s1210_hw_trig_init_params; + struct iio_hw_trig *hw_trig_desc; + + hw_trig_desc = calloc(1, sizeof(struct iio_hw_trig)); + if (!hw_trig_desc) { + return -ENOMEM; + } + + ad2s1210_hw_trig_init_params.irq_id = TRIGGER_INT_ID; + ad2s1210_hw_trig_init_params.name = AD2S1210_IIO_TRIGGER_NAME; + ad2s1210_hw_trig_init_params.irq_trig_lvl = NO_OS_IRQ_EDGE_FALLING; + ad2s1210_hw_trig_init_params.irq_ctrl = trigger_irq_desc; + ad2s1210_hw_trig_init_params.cb_info.event = NO_OS_EVT_GPIO; + ad2s1210_hw_trig_init_params.cb_info.peripheral = NO_OS_GPIO_IRQ; + ad2s1210_hw_trig_init_params.cb_info.handle = trigger_gpio_handle; + ad2s1210_hw_trig_init_params.iio_desc = ad2s1210_iio_desc; + + /* Initialize hardware trigger */ + ret = iio_hw_trig_init(&hw_trig_desc, &ad2s1210_hw_trig_init_params); + if (ret) { + return ret; + } + + *desc = hw_trig_desc; + + return 0; +} + +/** + * @brief Initialize the IIO interface for AD2S1210 IIO device + * @return 0 in case of success, negative error code otherwise + */ +int32_t ad2s1210_iio_initialize(void) +{ + struct iio_ctx_attr *context_attributes; + int32_t init_status; + + /* IIO device descriptors */ + struct iio_device *iio_ad2s1210_dev; + +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + static struct iio_trigger ad2s1210_iio_trig_desc = { + .is_synchronous = true, + }; + + /* IIO trigger init parameters */ + static struct iio_trigger_init iio_trigger_init_params = { + .descriptor = &ad2s1210_iio_trig_desc, + .name = AD2S1210_IIO_TRIGGER_NAME, + }; +#endif + + /* IIO interface init parameters */ + static struct iio_init_param iio_init_params = { + .phy_type = USE_UART, +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + .trigs = &iio_trigger_init_params, +#endif + }; + + /* IIOD init parameters */ + struct iio_device_init iio_device_init_params[NUM_OF_IIO_DEVICES] = { + { +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + .trigger_id = "trigger0", +#endif + } + }; + + /* Init the system peripherals */ + init_status = init_system(); + if (init_status) { + return init_status; + } + + /* Initialize AD2S1210 device and peripheral interface */ + init_status = ad2s1210_init(&ad2s1210_dev_inst, &ad2s1210_init_params); + if (init_status) { + return init_status; + } + + init_status = ad2s1210_iio_param_init(&iio_ad2s1210_dev); + if (init_status) { + return init_status; + } + + /* The setup currently uses fly wires through the expanstion board + * that has its own eeprom. Becuase of the autodetect mechanism + * of eeprom we cannot choose which eeprom to read on the i2c bus. + * hardcode these context attributes until a proper board is + * available. + */ + context_attributes = (struct iio_ctx_attr *)calloc( + NUM_CTX_ATTR, sizeof(*context_attributes)); + context_attributes[0].name = "hw_carrier"; + context_attributes[0].value = STR(HW_CARRIER_NAME); + context_attributes[1].name = "hw_mezzanine"; + context_attributes[1].value = HW_MEZZANINE_NAME; + context_attributes[2].name = "hw_name"; + context_attributes[2].value = HW_NAME; + context_attributes[3].name = "hw_vendor"; + context_attributes[3].value = HW_VENDOR; + + + iio_init_params.ctx_attrs = context_attributes; + iio_init_params.nb_ctx_attr = NUM_CTX_ATTR; + + iio_device_init_params[0].name = ACTIVE_DEVICE_NAME; + iio_device_init_params[0].raw_buf = data_buffer; + iio_device_init_params[0].raw_buf_len = DATA_BUFFER_SIZE; + iio_device_init_params[0].dev = ad2s1210_dev_inst; + iio_device_init_params[0].dev_descriptor = iio_ad2s1210_dev; + + iio_init_params.nb_devs++; +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + iio_init_params.nb_trigs++; +#endif + + /* Initialize the IIO interface */ + iio_init_params.uart_desc = uart_desc; + iio_init_params.devs = iio_device_init_params; + init_status = iio_init(&ad2s1210_iio_desc, &iio_init_params); + if (init_status) { + return init_status; + } + +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + /* Initialize the AD2S1210 IIO trigger specific parameters */ + init_status = ad2s1210_iio_trigger_param_init(&ad2s1210_hw_trig_desc); + if (init_status) { + return init_status; + } + + /* Initialize the PWM trigger source for periodic RESOLVER sampling */ + init_status = init_pwm_trigger(); + if (init_status) { + return init_status; + } +#endif + return 0; +} + +/** + * @brief Run the AD2S1210 IIO event handler + * @return none + * @details This function monitors the new IIO client event + */ +void ad2s1210_iio_event_handler(void) +{ + (void)iio_step(ad2s1210_iio_desc); +} diff --git a/projects/ad2s1210_iio/app/ad2s1210_iio.h b/projects/ad2s1210_iio/app/ad2s1210_iio.h new file mode 100644 index 00000000..8afdcdbd --- /dev/null +++ b/projects/ad2s1210_iio/app/ad2s1210_iio.h @@ -0,0 +1,35 @@ +/***************************************************************************//** +* @file ad2s1210_iio.h +* @brief Header file for AD2S1210 IIO interface +******************************************************************************** +* Copyright (c) 2023 Analog Devices, Inc. +* Copyright (c) 2023 BayLibre, SAS. +* All rights reserved. +* +* This software is proprietary to Analog Devices, Inc. and its licensors. +* By using this software you agree to the terms of the associated +* Analog Devices Software License Agreement. +*******************************************************************************/ +#ifndef _AD2S1210_IIO_H_ +#define _AD2S1210_IIO_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "iio.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/******************************************************************************/ +/********************** Public/Extern Declarations ****************************/ +/******************************************************************************/ +/* Init the IIO interface */ +int32_t ad2s1210_iio_initialize(void); + +/* Run the IIO event handler */ +void ad2s1210_iio_event_handler(void); + +#endif /* _AD2S1210_IIO_H_ */ diff --git a/projects/ad2s1210_iio/app/ad2s1210_user_config.c b/projects/ad2s1210_iio/app/ad2s1210_user_config.c new file mode 100644 index 00000000..e6aade7f --- /dev/null +++ b/projects/ad2s1210_iio/app/ad2s1210_user_config.c @@ -0,0 +1,64 @@ +/***************************************************************************//** + * @file ad2s1210_user_config.c + * @brief User configurations for AD2S1210 No-OS driver +******************************************************************************** +* Copyright (c) 2023 Analog Devices, Inc. +* Copyright (c) 2023 BayLibre, SAS. +* All rights reserved. +* +* This software is proprietary to Analog Devices, Inc. and its licensors. +* By using this software you agree to the terms of the associated +* Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "ad2s1210_user_config.h" +#include "app_config.h" +/******************************************************************************/ +/********************* Macros and Constants Definition ************************/ +/******************************************************************************/ + +/******************************************************************************/ +/******************** Variables and User Defined Data Types *******************/ +/******************************************************************************/ + +/* AD2S1210 No-OS driver init parameters */ +struct ad2s1210_init_param ad2s1210_init_params = { + .spi_init = { /* TODO: move to spi_init_param */ + .max_speed_hz = 2000000, + .mode = NO_OS_SPI_MODE_1, + .chip_select = SPI_CSB, + .platform_ops = &spi_ops, + .extra = &spi_extra_init_params + }, + .gpio_a0 = { + .number = GPIO_A0, + .platform_ops = &gpio_ops, + .extra = NULL + }, + .gpio_a1 = { + .number = GPIO_A1, + .platform_ops = &gpio_ops, + .extra = NULL + }, + .gpio_res0 = { + .number = GPIO_RES0, + .platform_ops = &gpio_ops, + .extra = NULL + }, + .gpio_res1 = { + .number = GPIO_RES1, + .platform_ops = &gpio_ops, + .extra = NULL + }, + .gpio_sample = { + .number = GPIO_SAMPLE, + .platform_ops = &gpio_ops, + .extra = NULL + }, + .resolution = AD2S1210_RESOLUTION, + .clkin_hz = AD2S1210_FCLKIN, +}; diff --git a/projects/ad2s1210_iio/app/ad2s1210_user_config.h b/projects/ad2s1210_iio/app/ad2s1210_user_config.h new file mode 100644 index 00000000..d8d35651 --- /dev/null +++ b/projects/ad2s1210_iio/app/ad2s1210_user_config.h @@ -0,0 +1,33 @@ +/***************************************************************************//* + * @file ad2s1210_user_config.h + * @brief User configurations for AD2S1210 No-OS driver +****************************************************************************** + * Copyright (c) 2023 Analog Devices, Inc. + * Copyright (c) 2023 BayLibre, SAS. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +******************************************************************************/ + +#ifndef _AD2S1210_USER_CONFIG_H_ +#define _AD2S1210_USER_CONFIG_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "ad2s1210.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/******************************************************************************/ +/********************** Public/Extern Declarations ****************************/ +/******************************************************************************/ + +extern struct ad2s1210_init_param ad2s1210_init_params; + +#endif /* _AD2S1210_USER_CONFIG_H_ */ diff --git a/projects/ad2s1210_iio/app/app_config.c b/projects/ad2s1210_iio/app/app_config.c new file mode 100644 index 00000000..fc742f79 --- /dev/null +++ b/projects/ad2s1210_iio/app/app_config.c @@ -0,0 +1,208 @@ +/***************************************************************************//** + * @file app_config.c + * @brief Application configurations module (platform-agnostic) + * @details This module performs the system configurations +******************************************************************************** + * Copyright (c) 2023 Analog Devices, Inc. + * Copyright (c) 2023 BayLibre, SAS. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include + +#include "app_config.h" +#include "common.h" +#include "no_os_error.h" +#include "no_os_uart.h" +#include "no_os_gpio.h" +#include "no_os_irq.h" +#include "no_os_pwm.h" +#include "no_os_delay.h" + +/******************************************************************************/ +/************************ Macros/Constants ************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/******************** Variables and User Defined Data Types *******************/ +/******************************************************************************/ + + +/* Trigger IRQ parameters */ +struct no_os_irq_init_param trigger_irq_params = { + .irq_ctrl_id = 0, + .platform_ops = &trigger_gpio_irq_ops, + .extra = &trigger_gpio_irq_extra_params +}; + +/* PWM init parameters */ +static struct no_os_pwm_init_param pwm_init_params = { + .id = 0, + .period_ns = CONV_TRIGGER_PERIOD_NSEC, + .duty_cycle_ns = CONV_TRIGGER_DUTY_CYCLE_NSEC, + .extra = &pwm_extra_init_params, + .platform_ops = &pwm_ops +}; + +/* UART init parameters */ +static struct no_os_uart_init_param uart_init_params = { + .device_id = 0, + .baud_rate = IIO_UART_BAUD_RATE, + .size = NO_OS_UART_CS_8, + .parity = NO_OS_UART_PAR_NO, + .stop = NO_OS_UART_STOP_1_BIT, +#if defined(USE_VIRTUAL_COM_PORT) + .platform_ops = &vcom_ops, + .extra = &vcom_extra_init_params +#else + .platform_ops = &uart_ops, + .extra = &uart_extra_init_params +#endif +}; + +/* UART init parameters for console comm port */ +struct no_os_uart_init_param uart_console_stdio_init_params = { + .device_id = 0, + .asynchronous_rx = false, + .baud_rate = IIO_UART_BAUD_RATE, + .size = NO_OS_UART_CS_8, + .parity = NO_OS_UART_PAR_NO, + .stop = NO_OS_UART_STOP_1_BIT, +#if defined(USE_VIRTUAL_COM_PORT) + /* If virtual com port is primary IIO comm port, use physical port for stdio + * console. Applicatios which does not support VCOM, should not satisfy this + * condition */ + .platform_ops = &uart_ops, + .extra = &uart_extra_init_params +#else +#if defined(CONSOLE_STDIO_PORT_AVAILABLE) + /* Applications which uses phy COM port as primary IIO comm port, + * can use VCOM as console stdio port provided it is available. + * Else, alternative phy com port can be used for console stdio ops if available */ + .platform_ops = &vcom_ops, + .extra = &vcom_extra_init_params +#endif +#endif +}; + +/* UART descriptor */ +struct no_os_uart_desc *uart_desc; + +/* UART console descriptor */ +struct no_os_uart_desc *uart_console_stdio_desc; + +/* Trigger GPIO interrupt descriptor */ +struct no_os_irq_ctrl_desc *trigger_irq_desc; + +/* PWM descriptor */ +struct no_os_pwm_desc *pwm_desc; + +/******************************************************************************/ +/************************** Functions Declarations ****************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************** Functions Definitions *****************************/ +/******************************************************************************/ + +/** + * @brief Initialize the UART peripheral + * @return 0 in case of success, negative error code otherwise + */ +static int32_t init_uart(void) +{ + int32_t ret; + + ret = no_os_uart_init(&uart_desc, &uart_init_params); + if (ret) { + return ret; + } + +#if defined(CONSOLE_STDIO_PORT_AVAILABLE) + /* Initialize the serial link for console stdio communication */ + ret = no_os_uart_init(&uart_console_stdio_desc, + &uart_console_stdio_init_params); + if (ret) { + return ret; + } +#endif + return 0; +} + +/** + * @brief Initialize the trigger GPIO and associated IRQ event + * @return 0 in case of success, negative error code otherwise + */ +static int32_t gpio_trigger_Init(void) +{ + int32_t ret; + + /* Initialize the IRQ controller */ + ret = no_os_irq_ctrl_init(&trigger_irq_desc, &trigger_irq_params); + if (ret) { + return ret; + } + + return 0; +} + +/** + * @brief Initialize the PWM trigger contoller + * @return 0 in case of success, negative error code otherwise + */ +int32_t init_pwm_trigger(void) +{ + int32_t ret; + + /* Initialize the PWM interface to generate PWM signal + * on conversion trigger event pin + */ + ret = no_os_pwm_init(&pwm_desc, &pwm_init_params); + if (ret) { + return ret; + } + + ret = no_os_pwm_enable(pwm_desc); + if (ret) { + return ret; + } + + return 0; +} + +/** + * @brief Initialize the system peripherals + * @return 0 in case of success, negative error code otherwise + */ +int32_t init_system(void) +{ + int32_t ret; + + ret = init_uart(); + if (ret) { + return ret; + } + +#if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE) + ret = gpio_trigger_Init(); + if (ret) { + return ret; + } +#endif + +#if defined(USE_SDRAM) + ret = sdram_init(); + if (ret) { + return ret; + } +#endif + return 0; +} diff --git a/projects/ad2s1210_iio/app/app_config.h b/projects/ad2s1210_iio/app/app_config.h new file mode 100644 index 00000000..c8c7a4f1 --- /dev/null +++ b/projects/ad2s1210_iio/app/app_config.h @@ -0,0 +1,179 @@ +/***************************************************************************//* + * @file app_config.h + * @brief Header file for application configurations (platform-agnostic) +****************************************************************************** + * Copyright (c) 2023 Analog Devices, Inc. + * Copyright (c) 2023 BayLibre, SAS + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +******************************************************************************/ + +#ifndef _APP_CONFIG_H_ +#define _APP_CONFIG_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/* List of supported platforms */ +#define MBED_PLATFORM 1 + +/* List of data capture modes */ +#define CONTINUOUS_DATA_CAPTURE 0 +#define BURST_DATA_CAPTURE 1 + +/* Macros for stringification */ +#define XSTR(s) #s +#define STR(s) XSTR(s) + +/******************************************************************************/ + +/**** ACTIVE_DEVICE selection ***** +* Define the device type here from the available list of devices (one at a time) +* e.g. #define DEV_AD2S1210 -> This will make AD2S1210 as an ACTIVE_DEVICE. +**/ +/* #define DEV_AD2S1210 */ + +/* Name of the active device */ +#if !defined(DEV_AD2S1210) +#define DEV_AD2S1210 +#define ACTIVE_DEVICE ID_AD2S1210 +#define ACTIVE_DEVICE_NAME "ad2s1210" +#define DEVICE_NAME "DEV_AD2S1210" +#endif + +/* Select the active platform (default is Mbed) */ +#if !defined(ACTIVE_PLATFORM) +#define ACTIVE_PLATFORM MBED_PLATFORM +#endif + +/* Select the RESOLVER data capture mode (default is CC mode) */ +#if !defined(DATA_CAPTURE_MODE) +#define DATA_CAPTURE_MODE CONTINUOUS_DATA_CAPTURE +#endif + +/* Enable the UART/VirtualCOM port connection (default VCOM) */ +/* #define USE_PHY_COM_PORT // Uncomment to select UART */ + +#if !defined(USE_PHY_COM_PORT) +#define USE_VIRTUAL_COM_PORT +#endif + +#if (ACTIVE_PLATFORM == MBED_PLATFORM) +#include "app_config_mbed.h" + +#define HW_CARRIER_NAME TARGET_NAME + +/* Redefine the init params structure mapping w.r.t. platform */ +#define pwm_extra_init_params mbed_pwm_extra_init_params +#define uart_extra_init_params mbed_uart_extra_init_params +#define vcom_extra_init_params mbed_vcom_extra_init_params +#define spi_extra_init_params mbed_spi_extra_init_params +#define trigger_gpio_irq_extra_params mbed_trigger_gpio_irq_init_params +#define trigger_gpio_extra_init_params mbed_trigger_gpio_extra_init_params +#define trigger_gpio_ops mbed_gpio_ops +#define irq_ops mbed_gpio_irq_ops +#define gpio_ops mbed_gpio_ops +#define spi_ops mbed_spi_ops +#define uart_ops mbed_uart_ops +#define vcom_ops mbed_virtual_com_ops +#define pwm_ops mbed_pwm_ops +#define trigger_gpio_irq_ops mbed_gpio_irq_ops +#define trigger_gpio_handle 0 /* Unused macro */ +#define IRQ_INT_ID GPIO_IRQ_ID1 +#define TRIGGER_GPIO_PORT 0 /* Unused macro */ +#define TRIGGER_GPIO_PIN PWM_TRIGGER +#define TRIGGER_INT_ID GPIO_IRQ_ID1 +#else +#error "No/Invalid active platform selected" +#endif + +/* Expected HW ID */ +#define HW_MEZZANINE_NAME "EVAL-AD2S1210SDZ" +#define HW_NAME "ad2s1210" +#define HW_VENDOR "Analog Devices" +#define NUM_CTX_ATTR 4 + +#define RESOLVER_CHANNELS 3 +#define RESOLVER_MAX_ATTR 10 + +/* Max count is always 16 bit. LSBs are ignored in lower resolutions */ +#define RESOLVER_MAX_COUNT_UNIPOLAR (uint32_t)(USHRT_MAX) +#define RESOLVER_MAX_COUNT_BIPOLAR (uint32_t)(SHRT_MAX) + +/* Not all resolutions are supported use driver defined resolutions 10, 12, 14, 16 */ +#define AD2S1210_RESOLUTION AD2S1210_RES_16BIT + +#define AD2S1210_FCLKIN 8192000 + +#define MATH_PI 3.1415926f +/* velocity scale depends on resolution */ +#define AD2S1210_POS_IIO_SCALE (2 * MATH_PI / RESOLVER_MAX_COUNT_UNIPOLAR) + +#if (AD2S1210_FCLKIN == 8192000) +#define AD2S1210_TRACKING_RATE_10BIT 2500 +#define AD2S1210_TRACKING_RATE_12BIT 1000 +#define AD2S1210_TRACKING_RATE_14BIT 500 +#define AD2S1210_TRACKING_RATE_16BIT 125 +#elif (AD2S1210_FCLKIN == 10240000) +#define AD2S1210_TRACKING_RATE_10BIT 3125 +#define AD2S1210_TRACKING_RATE_12BIT 1250 +#define AD2S1210_TRACKING_RATE_14BIT 625 +#define AD2S1210_TRACKING_RATE_16BIT 156 +#if (AD2S1210_FCLKIN != 10240000) +#warn "unknown tracking rate" +#endif +#endif + +/****** Macros used to form a VCOM serial number ******/ +/* Used to form a VCOM serial number */ +#define FIRMWARE_NAME "ad2s1210_iio" + +#if !defined(PLATFORM_NAME) +#define PLATFORM_NAME HW_CARRIER_NAME +#endif + +/* Below USB configurations (VID and PID) are owned and assigned by ADI. + * If intended to distribute software further, use the VID and PID owned by your + * organization + */ +#define VIRTUAL_COM_PORT_VID 0x0456 +#define VIRTUAL_COM_PORT_PID 0xb66c +#define VIRTUAL_COM_SERIAL_NUM (FIRMWARE_NAME "_" DEVICE_NAME "_" STR(PLATFORM_NAME)) + +#if defined(USE_PHY_COM_PORT) +/* If PHY com is selected, VCOM or alternate PHY com port can act as a console stdio port */ +#if (ACTIVE_PLATFORM == MBED_PLATFORM) +#define CONSOLE_STDIO_PORT_AVAILABLE +#endif +#else +/* If VCOM is selected, PHY com port will/should act as a console stdio port */ +#define CONSOLE_STDIO_PORT_AVAILABLE +#endif + +/* Default baud rate for IIO UART interface */ +#define IIO_UART_BAUD_RATE (230400) + +/* Enable/Disable the use of SDRAM for RESOLVER data capture buffer */ +/* #define USE_SDRAM // Uncomment to use SDRAM for data buffer */ + +/******************************************************************************/ +/********************** Public/Extern Declarations ****************************/ +/******************************************************************************/ + +extern struct no_os_uart_desc *uart_desc; +extern struct no_os_irq_ctrl_desc *trigger_irq_desc; + +int32_t init_system(void); +int32_t init_pwm_trigger(void); + +#endif /* _APP_CONFIG_H_ */ diff --git a/projects/ad2s1210_iio/app/app_config_mbed.c b/projects/ad2s1210_iio/app/app_config_mbed.c new file mode 100644 index 00000000..c7936f7c --- /dev/null +++ b/projects/ad2s1210_iio/app/app_config_mbed.c @@ -0,0 +1,78 @@ +/***************************************************************************//** + * @file app_config_mbed.c + * @brief Application configurations module for Mbed platform +******************************************************************************** + * Copyright (c) 2023 Analog Devices, Inc. + * Copyright (c) 2023 BayLibre, SAS. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include "app_config.h" +#include "app_config_mbed.h" + +/******************************************************************************/ +/************************ Macros/Constants ************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/******************** Variables and User Defined Data Types *******************/ +/******************************************************************************/ + +/* UART Mbed platform specific init parameters */ +struct mbed_uart_init_param mbed_uart_extra_init_params = { + .uart_tx_pin = UART_TX, + .uart_rx_pin = UART_RX, +#if defined(USE_PHY_COM_PORT) + .is_console_stdio_port = false, +#else + .is_console_stdio_port = true, +#endif +}; + +/* VCOM Mbed platform specific init parameters */ +struct mbed_uart_init_param mbed_vcom_extra_init_params = { + .vendor_id = VIRTUAL_COM_PORT_VID, + .product_id = VIRTUAL_COM_PORT_PID, + .serial_number = VIRTUAL_COM_SERIAL_NUM, +#if defined(USE_VIRTUAL_COM_PORT) + .is_console_stdio_port = false, +#else + .is_console_stdio_port = true, +#endif +}; + +/* SPI Mbed platform specific parameters */ +struct mbed_spi_init_param mbed_spi_extra_init_params = { + .spi_clk_pin = SPI_SCK, + .spi_miso_pin = SPI_HOST_SDI, + .spi_mosi_pin = SPI_HOST_SDO, + .use_sw_csb = false +}; + +struct mbed_gpio_init_param mbed_trigger_gpio_extra_init_params = { + .pin_mode = 0 /* NA */ +}; + +struct mbed_gpio_irq_init_param mbed_trigger_gpio_irq_init_params = { + .gpio_irq_pin = PWM_TRIGGER +}; + +struct mbed_pwm_init_param mbed_pwm_extra_init_params = { + .pwm_pin = PWM_TRIGGER +}; +/******************************************************************************/ +/************************** Functions Declarations ****************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************** Functions Definitions *****************************/ +/******************************************************************************/ diff --git a/projects/ad2s1210_iio/app/app_config_mbed.h b/projects/ad2s1210_iio/app/app_config_mbed.h new file mode 100644 index 00000000..05dbc42d --- /dev/null +++ b/projects/ad2s1210_iio/app/app_config_mbed.h @@ -0,0 +1,71 @@ +/***************************************************************************//** + * @file app_config_mbed.h + * @brief Header file for Mbed platform configurations +******************************************************************************** + * Copyright (c) 2023 Analog Devices, Inc. + * Copyright (c) 2023 BayLibre, SAS. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +#ifndef APP_CONFIG_MBED_H_ +#define APP_CONFIG_MBED_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include +#include + +#include "mbed_uart.h" +#include "mbed_gpio_irq.h" +#include "mbed_spi.h" +#include "mbed_pwm.h" +#include "mbed_gpio.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ +#define SPI_CSB ARDUINO_UNO_D10 +#define SPI_HOST_SDO ARDUINO_UNO_D11 +#define SPI_HOST_SDI ARDUINO_UNO_D12 +#define SPI_SCK ARDUINO_UNO_D13 +#define PWM_TRIGGER ARDUINO_UNO_D3 + +#define GPIO_A0 ARDUINO_UNO_D0 +#define GPIO_A1 ARDUINO_UNO_D1 +#define GPIO_RES0 ARDUINO_UNO_D5 +#define GPIO_RES1 ARDUINO_UNO_D6 +#define GPIO_SAMPLE ARDUINO_UNO_D4 + +/* UART Common Pin Mapping on SDP-K1 */ +#define UART_TX CONSOLE_TX +#define UART_RX CONSOLE_RX + +/* Define a sampling rate for a given setup. + * This is used to find the time period to trigger a periodic conversion event. + * Currently the value was experimentally found by testing the firmware on SDP-K1 + * controller board @20Mhz SPI clock, with fly wires to breakout board. + * This can vary from board to board, the exact maximum value was not determined + * as 16k seems reasonable for this setup. + * */ +#define SAMPLING_RATE (16000) +#define CONV_TRIGGER_PERIOD_NSEC (((float)(1.0 / SAMPLING_RATE) * 1000000) * 1000) +#define CONV_TRIGGER_DUTY_CYCLE_NSEC (CONV_TRIGGER_PERIOD_NSEC / 2) + +/******************************************************************************/ +/********************** Public/Extern Declarations ****************************/ +/******************************************************************************/ + +extern struct mbed_uart_init_param mbed_uart_extra_init_params; +extern struct mbed_uart_init_param mbed_vcom_extra_init_params; +extern struct mbed_spi_init_param mbed_spi_extra_init_params; +extern struct mbed_gpio_init_param mbed_trigger_gpio_extra_init_params; +extern struct mbed_gpio_irq_init_param mbed_trigger_gpio_irq_init_params; +extern struct mbed_pwm_init_param mbed_pwm_extra_init_params; + +#endif /* APP_CONFIG_MBED_H_ */ diff --git a/projects/ad2s1210_iio/app/main.c b/projects/ad2s1210_iio/app/main.c new file mode 100644 index 00000000..b9061bb6 --- /dev/null +++ b/projects/ad2s1210_iio/app/main.c @@ -0,0 +1,52 @@ +/***************************************************************************//** + * @file main.c + * @brief Main interface for AD2S1210 IIO firmware application +******************************************************************************** +* Copyright (c) 2023 Analog Devices, Inc. +* Copyright (c) 2023 BayLibre, SAS. +* All rights reserved. +* +* This software is proprietary to Analog Devices, Inc. and its licensors. +* By using this software you agree to the terms of the associated +* Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include +#include + +#include "ad2s1210_iio.h" + +/******************************************************************************/ +/********************* Macros and Constants Definition ************************/ +/******************************************************************************/ + +/******************************************************************************/ +/******************** Variables and User Defined Data Types *******************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************** Functions Declarations ****************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************** Functions Definitions *****************************/ +/******************************************************************************/ + +/* @brief Main function + * @details This is a main entry function for AD2S1210 IIO application + */ +int main(void) +{ + /* Initialize the AD2S1210 IIO interface */ + if (ad2s1210_iio_initialize()) { + printf("IIO initialization failure!!\r\n"); + } + + while (1) { + ad2s1210_iio_event_handler(); + } + +} diff --git a/projects/ad2s1210_iio/src.mk b/projects/ad2s1210_iio/src.mk new file mode 100644 index 00000000..3205cac0 --- /dev/null +++ b/projects/ad2s1210_iio/src.mk @@ -0,0 +1,15 @@ +# All the .c and .cpp and .h Files in SRC_DIRS are used in Build (Recursive) +SRC_DIRS += $(PROJECT_APP_PATH) +SRC_DIRS += $(LIBRARIES_PATH)/no-OS/drivers/resolver/ad2s1210 +SRC_DIRS += $(LIBRARIES_PATH)/no-OS/drivers/eeprom/24xx32a +SRC_DIRS += $(LIBRARIES_PATH)/no-OS/drivers/api +SRC_DIRS += $(LIBRARIES_PATH)/no-OS/drivers/platform/mbed +SRC_DIRS += $(LIBRARIES_PATH)/no-OS/iio +SRC_DIRS += $(LIBRARIES_PATH)/no-OS/util +SRC_DIRS += $(LIBRARIES_PATH)/no-OS/include +SRC_DIRS += $(LIBRARIES_PATH)/precision-converters-library/common +SRC_DIRS += $(LIBRARIES_PATH)/precision-converters-library/board_info +SRC_DIRS += $(LIBRARIES_PATH)/precision-converters-library/sdp_k1_sdram + +# Extra Macros +override NEW_CFLAGS += -DACTIVE_PLATFORM=MBED_PLATFORM diff --git a/projects/ad2s1210_iio/tests/conftest.py b/projects/ad2s1210_iio/tests/conftest.py new file mode 100644 index 00000000..af1b1eba --- /dev/null +++ b/projects/ad2s1210_iio/tests/conftest.py @@ -0,0 +1,62 @@ +"""Define some fixtures to use in the project.""" +import pytest +import serial +from time import sleep +import serial.tools.list_ports + +ADI_USB_VID = 0x0456 +ADI_USB_PID = 0xb66c +firmware_name = 'ad2s1210_iio' + +def pytest_addoption(parser): + parser.addoption("--serialport", action="store", default=None) + parser.addoption("--serial_com_type", action="store", default=None) + parser.addoption("--device_name", action="store", default=None) + parser.addoption("--platform_name", action="store", default=None) + +@pytest.fixture(scope="session") +def serialport(pytestconfig): + return pytestconfig.getoption("serialport") + +@pytest.fixture(scope="session") +def serialcomtype(pytestconfig): + return pytestconfig.getoption("serial_com_type") + +@pytest.fixture(scope="session") +def devicename(pytestconfig): + return pytestconfig.getoption("device_name") + +@pytest.fixture(scope="session") +def platformname(pytestconfig): + return pytestconfig.getoption("platform_name") + +@pytest.fixture(scope="session") +def serial_port(serialport, serialcomtype, devicename, platformname): + sleep(3) + if (serialcomtype == 'USE_VIRTUAL_COM_PORT'): + vcom_serial_number = firmware_name + '_' + devicename + '_' + platformname + # Get the COM port number corresponding to virtualCOM port parameters + for vcom_serial_port in serial.tools.list_ports.comports(): + if (vcom_serial_port.vid == ADI_USB_VID and vcom_serial_port.pid == ADI_USB_PID and vcom_serial_port.serial_number == vcom_serial_number): + break + yield vcom_serial_port.device + else: + for uart_serial_port in serial.tools.list_ports.comports(): + if(uart_serial_port.device == serialport): + break + yield uart_serial_port.device + +@pytest.fixture(scope="session") +def device_name(devicename): + return devicename + +@pytest.fixture(scope="session") +def serial_com_type(serialcomtype): + return serialcomtype + +@pytest.fixture(scope="function") +def target_reset(serial_port): + # NA as serial port connection is opened through test example file + + # Allow time for system to reset before doing anything + sleep(0.1) diff --git a/projects/ad2s1210_iio/tests/func/test_ad2s1210_example.py b/projects/ad2s1210_iio/tests/func/test_ad2s1210_example.py new file mode 100644 index 00000000..039ddb44 --- /dev/null +++ b/projects/ad2s1210_iio/tests/func/test_ad2s1210_example.py @@ -0,0 +1,60 @@ +import numpy as np +import decimal +import pytest +import serial +from time import sleep +import csv +import os +from numpy import ndarray +from adi.ad2s1210 import * + +iio_device = { 'DEV_AD2S1210': 'ad2s1210',} +#max angle is 2pi radians +MAX_EXPECTED_ANGLE = 3.5 +MIN_EXPECTED_ANGLE = 2.5 + +def test_ad2s1210(serial_port, device_name, serial_com_type, target_reset): + uri_str = "serial:" + serial_port + ",230400" + + # Allow VCOM connection to establish upon power-up + sleep(3) + + # Create a new instance of AD2S1210 class which creates + # a device context as well for IIO interface + ad2s1210_dev = ad2s1210(uri_str) + + # *********** Perform data capture check *********** + + print("\nData capture test for channel 0 => \n") + ad2s1210_dev._rx_data_type = np.uint16 + ad2s1210_dev.rx_output_type = "SI" + ad2s1210_dev.rx_enabled_channels = ['angl0'] + ad2s1210_dev.rx_buffer_size = 100 + ad2s1210_dev._rx_stack_interleaved = True + + data = ad2s1210_dev.rx() + + # Write data into CSV file (tests/output directory) + current_dir = os.getcwd() + output_dir = os.path.join(current_dir, "output") + isdir = os.path.isdir(output_dir) + if not isdir: + # Create 'output' directory if doesn't exists + os.mkdir(output_dir) + + file_name = device_name + "_" + serial_com_type + "_RESULT" + ".csv" + output_file = os.path.join(output_dir, file_name) + + with open(output_file, 'w') as result_file: + # create the csv writer + writer = csv.writer(result_file) + + # Write data into first row + writer.writerow(data) + + # Validate the data + max_angle = max(data) + min_angle = min(data) + print("Max Angle: {0}".format(max_angle)) + print("Min Angle: {0}".format(min_angle)) + assert (max_angle < MAX_EXPECTED_ANGLE and min_angle > MIN_EXPECTED_ANGLE), "Error reading angle!!" diff --git a/projects/ad2s1210_iio/tests/pytest.ini b/projects/ad2s1210_iio/tests/pytest.ini new file mode 100644 index 00000000..fb0cf61f --- /dev/null +++ b/projects/ad2s1210_iio/tests/pytest.ini @@ -0,0 +1,18 @@ +;--- +; This file is used to control the output of the test results +; -v: increase verbosity. +; -rxXs: allow print statements to be seen also show more detail about xfail, xpass and skipped tests +; -l; display local variables in trace back +; +; --strict any misspelled markers will show up as an error +; --tb=short; only print the function which failed and what line it failed on +; --show-capture; Don't print the stdin/err for tests that fail +; --junitxml: Tell pytest to output results in junit xml format +; --setup-show; shows what test fixtures are being used +;--- + +[pytest] +addopts = -v -rxXs -l --tb=short --strict --show-capture=stdout --junitxml=output/junit.xml --setup-show +xfail_strict = true +filterwarnings = ignore::UserWarning +junit_family=xunit2 \ No newline at end of file