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: platform_drivers LTC26X6 AD77681
main.cpp
- Committer:
- jngarlitos
- Date:
- 2021-12-06
- Revision:
- 1:9dd7c64b4a64
- Parent:
- 0:b9debc14d077
File content as of revision 1:9dd7c64b4a64:
/****************************************************************************** *Copyright (c)2020 Analog Devices, Inc. * * Licensed under the 2020-04-27-CN0540EC License(the "License"); * you may not use this file except in compliance with the License. * ****************************************************************************/ #include <mbed.h> #include "platform_drivers.h" #include <assert.h> #include "main.h" #include "cn0540_app_config.h" #include "platform_drivers.h" #include "cn0540_init_params.h" extern "C"{ #include "ad77681.h" #include "cn0540_adi_fft.h" #include "ltc26x6.h" } // Descriptor of the main device - the ADC AD7768-1 ad77681_dev *device_adc; // Structure carying measured data, sampled by the ADC adc_data measured_data; // AD7768-1's status register structure, carying all the error flags ad77681_status_registers *current_status; // Initialize the interrupt event variable volatile bool int_event= false; // Descriptor of the DAC LTC2606 ltc26x6_dev *device_dac; // Structure carying data, the FFT module works with fft_entry *FFT_data; // Structure carying measuremtns from the FFT module fft_measurements *FFT_meas; // Initialize the serial object with TX and RX pins Serial pc(USBTX, USBRX); // Initialize the drdy pin as interrupt input InterruptIn drdy(DRDY_PIN, PullNone); // Initialize the adc_rst_pin pin as digital output DigitalOut adc_reset(ADC_RST_PIN); // Initialize the buffer enable control pin as digital output DigitalOut buffer_en(ARD_BUF_EN_PIN); // Initialize the red LED control pin as digital output DigitalOut led_red(ARD_RED_LED_PIN); // Initialize the blue LED pin as digital output DigitalOut led_blue(ARD_BLUE_LED_PIN); /** * ADC data recteption interrupt from DRDY * * Data reception from the ADC using interrupt generated by the ADC's DRDY (Data Ready) pin * Interrupt triggers falling edge of the active-high DRDY pulse * DRDY pulse is generated by the ADC and frequency of the DRDY pulse depends on the ADC settings: * * DRDY frequency = MCLK / ( MCLK_DIV * FILTER_OSR ) */ void drdy_interrupt() { int_event = true; if (measured_data.count == measured_data.samples) { // Desired numer of samples has been taken, set everything back drdy.disable_irq(); // Disable interrupt on DRDY pin measured_data.finish = true; // Desired number of samples has been taken measured_data.count = 0; // Set measured data counter to 0 } } /** *================================================================================================================================= * * ////////////////////////////////////////////////// MAIN function \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ * *================================================================================================================================== */ int main() { int32_t connected = FAILURE; uint32_t menu; sdpk1_gpio_setup(); // Setup SDP-K1 GPIOs adc_hard_reset(); // Perform ADC hard reset connected = ad77681_setup(&device_adc, init_params, ¤t_status); // SETUP and check connection if(connected == FAILURE) go_to_error(); ltc26x6_init(&device_dac, init_params_dac); // Initialize DAC #ifdef CN0540_ADI_FFT_H_ // if the adi_fft.h is included , initialize it FFT_init_params(&FFT_data, &FFT_meas); // Initialize FFT structure and allocate space update_FFT_enviroment(device_adc->vref, device_adc->mclk, device_adc->sample_rate, FFT_data); // Update the Vref, Mclk, Sampling rate measured_data.samples = 4096; // Initialize FFT with 4096 samples FFT_init(measured_data.samples, FFT_data); // Update sample count for FFT #endif // CN0540_ADI_FFT_H_ // FFT module is initializedd with 4096 samples and 7-term BH window print_title(); print_prompt(); //============ MAIN WHILE ====================// while(1) { if (pc.readable()) { // Settings menu SWITCH getUserInput(&menu); switch (menu) { case 1: menu_1_set_adc_powermode(); // Set ADC power mode break; case 2: menu_2_set_adc_clock_divider(); // Set ADC clock divider break; case 3: menu_3_set_adc_filter_type(); // Set ad7768-1 filter type break; case 4: menu_4_adc_buffers_controll(); // Set ADC AIN & Reference buffers break; case 5: menu_5_set_default_settings(); // Set ADC default value break; case 6: menu_6_set_adc_vcm(); // Set ADC VCM break; case 7: menu_7_adc_read_register(); // Read ADC register break; case 8: menu_8_adc_cont_read_data(); // Perform continuous ADC read break; case 9: menu_9_reset_ADC(); // Reset ADC break; case 10: menu_10_power_down(); // ADC Wake up and sleep break; case 11: menu_11_ADC_GPIO(); // Set ADC GPIOs break; case 12: menu_12_read_master_status(); // Read ADC master status break; case 13: menu_13_mclk_vref(); // Set ADC MCLK / Vref break; case 14: menu_14_print_measured_data(); // Print continouos ADC read data break; case 15: menu_15_set_adc_data_output_mode(); // Set ADC data output mode break; case 16: menu_16_set_adc_diagnostic_mode(); // Set ADC to diagnostic mode break; case 17: menu_17_do_the_fft(); // Perform FFT break; case 18: menu_18_fft_settings(); // Change FFT settins break; case 19: menu_19_gains_offsets(); // Set ADC gain and offset break; case 20: menu_20_check_scratchpad(); // Perform scratchpad check break; case 21: menu_21_piezo_offset(); // Compensate piezo offset break; case 22: menu_22_set_DAC_output(); // Set DAC output mode break; default: pc.printf("Invalid option"); print_prompt(); break; } } } } /** * Error warning, in case of unsuccessfull SPI connection * */ void static go_to_error() { int32_t connected = FAILURE; uint8_t scratchpad_sequence = 0xAD; while (1) { pc.printf("ERROR: NOT CONNECTED\nCHECK YOUR PHYSICAL CONNECTION\n\n"); // When not connected, keep showing error message wait(5); connected = ad77681_setup(&device_adc, init_params, ¤t_status); // Keep trying to connect if (connected == SUCCESS) { pc.printf("SUCCESSFULLY RECONNECTED\n\n"); // If successfull reading from scratchpad, init the ADC and go back break; } } } /** * Print title * */ void static print_title() { pc.printf("\n\r"); pc.printf("****************************************************************\n"); pc.printf("* EVAL-CN0540-PMDZ Demonstration Program -- (mbed) *\n"); pc.printf("* *\n"); pc.printf("* This program demonstrates IEPE / ICP piezo accelerometer *\n"); pc.printf("* interfacing and FFT measurements using AD7768-1 *\n"); pc.printf("* Precision 24-bit sigma-delta AD converter *\n"); pc.printf("* *\n"); pc.printf("* Set the baud rate to 115200 select the newline terminator. *\n"); pc.printf("****************************************************************\n"); } /** * Print main menu to console * */ void static print_prompt() { pc.printf("\n\nCommand Summary:\n\n"); pc.printf(" 1 - Set ADC power mode\n"); pc.printf(" 2 - Set ADC MCLK divider\n"); pc.printf(" 3 - Set ADC filter type\n"); pc.printf(" 4 - Set ADC AIN and REF buffers\n"); pc.printf(" 5 - Set ADC to default config\n"); pc.printf(" 6 - Set ADC VCM output\n"); pc.printf(" 7 - Read desired ADC register\n"); pc.printf(" 8 - Read continuous ADC data\n"); pc.printf(" 9 - Reset ADC\n"); pc.printf(" 10 - ADC Power-down\n"); pc.printf(" 11 - Set ADC GPIOs\n"); pc.printf(" 12 - Read ADC master status\n"); pc.printf(" 13 - Set ADC Vref and MCLK\n"); pc.printf(" 14 - Print ADC measured data\n"); pc.printf(" 15 - Set ADC data output mode\n"); pc.printf(" 16 - Set ADC diagnostic mode\n"); pc.printf(" 17 - Do the FFT\n"); pc.printf(" 18 - FFT settings\n"); pc.printf(" 19 - Set ADC Gains, Offsets\n"); pc.printf(" 20 - ADC Scratchpad Check\n"); pc.printf(" 21 - Compenzate Piezo sensor offset\n"); pc.printf(" 22 - Set DAC output\n"); pc.printf("\n\r"); } /** * Read user input from uart * *UserInput = 0 if failure * */ int32_t static getUserInput(uint32_t *UserInput) { long uart_val; int32_t ret; ret = pc.scanf("%ld", &uart_val); // Return 1 = OK, Return 0 = Fail if((ret == 0) || (uart_val < 0)) { // Failure if uart_val is negative, or non-digit *UserInput = 0; return FAILURE; } *UserInput = (uint32_t)(uart_val); return SUCCESS; } /** * Set power mode * */ void static menu_1_set_adc_powermode(void) { uint32_t new_pwr_mode; pc.printf(" Avaliable power modes: \n"); pc.printf(" 1 - Low power mode\n"); pc.printf(" 2 - Median power mode\n"); pc.printf(" 3 - Fast power mode\n"); pc.printf(" Select an option: \n"); getUserInput(&new_pwr_mode); pc.putc('\n'); switch (new_pwr_mode) { case 1: ad77681_set_power_mode(device_adc, AD77681_ECO); pc.printf(" Low power mode selected\n"); break; case 2: ad77681_set_power_mode(device_adc, AD77681_MEDIAN); pc.printf(" Median power mode selected\n"); break; case 3: ad77681_set_power_mode(device_adc, AD77681_FAST); pc.printf(" Fast power mode selected\n"); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Set clock divider * */ void static menu_2_set_adc_clock_divider(void) { uint32_t new_mclk_div; pc.printf(" Avaliable MCLK divide options: \n"); pc.printf(" 1 - MCLK/16\n"); pc.printf(" 2 - MCLK/8\n"); pc.printf(" 3 - MCLK/4\n"); pc.printf(" 4 - MCLK/2\n"); pc.printf(" Select an option: \n"); getUserInput(&new_mclk_div); pc.putc('\n'); switch (new_mclk_div) { case 1: ad77681_set_mclk_div(device_adc, AD77681_MCLK_DIV_16); pc.printf(" MCLK/16 selected\n"); break; case 2: ad77681_set_mclk_div(device_adc, AD77681_MCLK_DIV_8); pc.printf(" MCLK/8 selected\n"); break; case 3: ad77681_set_mclk_div(device_adc, AD77681_MCLK_DIV_4); pc.printf(" MCLK/4 selected\n"); break; case 4: ad77681_set_mclk_div(device_adc, AD77681_MCLK_DIV_2); pc.printf(" MCLK/2 selected\n"); break; default: pc.printf(" Invalid option\n"); break; } // Update the sample rate after changing the MCLK divider ad77681_update_sample_rate(device_adc); print_prompt(); } /** * Set filter type * */ void static menu_3_set_adc_filter_type(void) { uint32_t new_filter = 0; int32_t ret; pc.printf(" Avaliable clock divide options: \n"); pc.printf(" 1 - SINC3 Fileter\n"); pc.printf(" 2 - SINC5 Filter\n"); pc.printf(" 3 - Low ripple FIR Filter\n"); pc.printf(" 4 - SINC3 50/60Hz rejection\n"); pc.printf(" 5 - User-defined FIR filter\n"); pc.printf(" Select an option: \n"); getUserInput(&new_filter); pc.putc('\n'); switch (new_filter) { case 1: set_adc_SINC3_filter(); break; case 2: set_adc_SINC5_filter(); break; case 3: set_adc_FIR_filter(); break; case 4: set_adc_50HZ_rej(); break; case 5: set_adc_user_defined_FIR(); break; default: pc.printf(" Invalid option\n"); break; } // Update the sample rate after changing the Filter type ad77681_update_sample_rate(device_adc); print_prompt(); } /** * Set SINC3 filter * */ void static set_adc_SINC3_filter(void) { uint32_t new_sinc3 = 0, new_sinc5 = 0; int32_t ret; pc.printf(" SINC3 filter Oversampling ratios: \n"); pc.printf(" OSR is calculated as (x + 1)*32\n"); pc.printf(" x is SINC3 OSR register value\n"); pc.printf(" Please input a value from 0 to 8192 = 2^13\n :"); ret = getUserInput(&new_sinc3); if ((new_sinc3 >= 0) && (new_sinc3 <= 8192) && (ret == SUCCESS)) { pc.printf("%d\n", new_sinc3); ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx32, AD77681_SINC3, new_sinc3); pc.printf(" SINC3 OSR is set to %d\n", (new_sinc3 + 1) * 32); } else { pc.printf("%d\n", new_sinc3); pc.printf(" Invalid option - too large number\n"); } } /** * Set SINC5 filter * */ void static set_adc_SINC5_filter(void) { uint32_t new_sinc5; pc.printf(" SINC5 filter Oversampling ratios: \n"); pc.printf(" 1 - Oversampled by 8\n"); pc.printf(" 2 - Oversampled by 16\n"); pc.printf(" 3 - Oversampled by 32\n"); pc.printf(" 4 - Oversampled by 64\n"); pc.printf(" 5 - Oversampled by 128\n"); pc.printf(" 6 - Oversampled by 256\n"); pc.printf(" 7 - Oversampled by 512\n"); pc.printf(" 8 - Oversampled by 1024\n"); pc.printf(" Select an option: \n"); getUserInput(&new_sinc5); pc.putc('\n'); switch (new_sinc5) { case 1: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx32, AD77681_SINC5_DECx8, 0); pc.printf(" SINC5 with OSRx8 set\n"); break; case 2: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx32, AD77681_SINC5_DECx16, 0); pc.printf(" SINC5 with OSRx16 set\n"); break; case 3: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx32, AD77681_SINC5, 0); pc.printf(" SINC5 with OSRx32 set\n"); break; case 4: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx64, AD77681_SINC5, 0); pc.printf(" SINC5 with OSRx64 set\n"); break; case 5: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx128, AD77681_SINC5, 0); pc.printf(" SINC5 with OSRx128 set\n"); break; case 6: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx256, AD77681_SINC5, 0); pc.printf(" SINC5 with OSRx256 set\n"); break; case 7: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx512, AD77681_SINC5, 0); pc.printf(" SINC5 with OSRx512 set\n"); break; case 8: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx1024, AD77681_SINC5, 0); pc.printf(" SINC5 with OSRx1024 set\n"); break; default: pc.printf(" Invalid option\n"); break; } } /** * Set FIR filter * */ void static set_adc_FIR_filter(void) { uint32_t new_fir; pc.printf(" FIR filter Oversampling ratios: \n"); pc.printf(" 1 - Oversampled by 32\n"); pc.printf(" 2 - Oversampled by 64\n"); pc.printf(" 3 - Oversampled by 128\n"); pc.printf(" 4 - Oversampled by 256\n"); pc.printf(" 5 - Oversampled by 512\n"); pc.printf(" 6 - Oversampled by 1024\n"); pc.printf(" Select an option: \n"); getUserInput(&new_fir); pc.putc('\n'); switch (new_fir) { case 1: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx32, AD77681_FIR, 0); pc.printf(" FIR with OSRx32 set\n"); break; case 2: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx64, AD77681_FIR, 0); pc.printf(" FIR with OSRx64 set\n"); break; case 3: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx128, AD77681_FIR, 0); pc.printf(" FIR with OSRx128 set\n"); break; case 4: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx256, AD77681_FIR, 0); pc.printf(" FIR with OSRx256 set\n"); break; case 5: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx512, AD77681_FIR, 0); pc.printf(" FIR with OSRx512 set\n"); break; case 6: ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx1024, AD77681_FIR, 0); pc.printf(" FIR with OSRx1024 set\n"); break; default: pc.printf(" Invalid option\n"); break; } } /** * Set 50HZ rejection bit when SINC3 is being used * */ void static set_adc_50HZ_rej(void) { uint32_t new_50Hz; pc.printf(" SINC3 50/60Hz rejection: \n"); pc.printf(" 1 - 50/60Hz rejection enable \n"); pc.printf(" 2 - 50/60Hz rejection disable \n"); pc.printf(" Select an option: \n"); getUserInput(&new_50Hz); pc.putc('\n'); switch (new_50Hz) { case 1: ad77681_set_50HZ_rejection(device_adc, ENABLE); pc.printf(" SINC3 50/60Hz rejection enabled\n"); break; case 2: ad77681_set_50HZ_rejection(device_adc, DISABLE); pc.printf(" SINC3 50/60Hz rejection disabled\n"); break; default: pc.printf(" Invalid option\n"); break; } } /** * Insert user-defined FIR filter coeffs * */ void static set_adc_user_defined_FIR(void) { const uint8_t coeff_reg_length = 56; // Maximum allowed number of coefficients in the coeff register pc.printf(" User Defined FIR filter\n"); if ((ARRAY_SIZE(programmable_FIR) <= coeff_reg_length) && (count_of_active_coeffs <= coeff_reg_length)) { pc.printf(" Aplying user-defined FIR filter coefficients from 'FIR_user_coeffs.h'\n"); ad77681_programmable_filter(device_adc, programmable_FIR, count_of_active_coeffs); pc.printf(" Coeffs inserted successfully\n"); } else pc.printf(" Incorrect count of coefficients in 'FIR_user_coeffs.h'\n"); } /** * AIN and REF buffers controll * */ void static menu_4_adc_buffers_controll(void) { uint32_t new_AIN_buffer = 0, new_REF_buffer = 0, new_buffer = 0; pc.printf(" Buffers settings: \n"); pc.printf(" 1 - Set AIN precharge buffers\n"); pc.printf(" 2 - Set REF buffers\n"); pc.printf(" Select an option: \n"); getUserInput(&new_buffer); pc.putc('\n'); switch (new_buffer) { case 1: pc.printf(" Analog IN precharge buffers settings: \n"); pc.printf(" 1 - Turn ON both precharge buffers\n"); pc.printf(" 2 - Turn OFF both precharge buffers\n"); pc.printf(" 3 - Turn ON AIN- precharge buffer\n"); pc.printf(" 4 - Turn OFF AIN- precharge buffer\n"); pc.printf(" 5 - Turn ON AIN+ precharge buffer\n"); pc.printf(" 6 - Turn OFF AIN+ precharge buffer\n"); pc.printf(" Select an option: \n"); getUserInput(&new_AIN_buffer); pc.putc('\n'); switch (new_AIN_buffer) { case 1: ad77681_set_AINn_buffer(device_adc, AD77681_AINn_ENABLED); ad77681_set_AINp_buffer(device_adc, AD77681_AINp_ENABLED); pc.printf(" AIN+ and AIN- enabled\n"); break; case 2: ad77681_set_AINn_buffer(device_adc, AD77681_AINn_DISABLED); ad77681_set_AINp_buffer(device_adc, AD77681_AINp_DISABLED); pc.printf(" AIN+ and AIN- disabled\n"); break; case 3: ad77681_set_AINn_buffer(device_adc, AD77681_AINn_ENABLED); pc.printf(" AIN- Enabled\n"); break; case 4: ad77681_set_AINn_buffer(device_adc, AD77681_AINn_DISABLED); pc.printf(" AIN- Disabled\n"); break; case 5: ad77681_set_AINp_buffer(device_adc, AD77681_AINp_ENABLED); pc.printf(" AIN+ Enabled\n"); break; case 6: ad77681_set_AINp_buffer(device_adc, AD77681_AINp_DISABLED); pc.printf(" AIN+ Disabled\n"); break; default: pc.printf(" Invalid option\n"); break; } break; case 2: pc.printf(" REF buffers settings: \n"); pc.printf(" 1 - Full REF- reference buffer\n"); pc.printf(" 2 - Full REF+ reference buffer\n"); pc.printf(" 3 - Unbuffered REF- reference buffer\n"); pc.printf(" 4 - Unbuffered REF+ reference buffer\n"); pc.printf(" 5 - Precharge REF- reference buffer\n"); pc.printf(" 6 - Precharge REF+ reference buffer\n"); pc.printf(" Select an option: \n"); getUserInput(&new_REF_buffer); pc.putc('\n'); switch (new_REF_buffer) { case 1: ad77681_set_REFn_buffer(device_adc, AD77681_BUFn_FULL_BUFFER_ON); pc.printf(" Fully buffered REF-\n"); break; case 2: ad77681_set_REFp_buffer(device_adc, AD77681_BUFp_FULL_BUFFER_ON); pc.printf(" Fully buffered REF+\n"); break; case 3: ad77681_set_REFn_buffer(device_adc, AD77681_BUFn_DISABLED); pc.printf(" Unbuffered REF-\n"); break; case 4: ad77681_set_REFp_buffer(device_adc, AD77681_BUFp_DISABLED); pc.printf(" Unbuffered REF+\n"); break; case 5: ad77681_set_REFn_buffer(device_adc, AD77681_BUFn_ENABLED); pc.printf(" Precharge buffer on REF-\n"); break; case 6: ad77681_set_REFp_buffer(device_adc, AD77681_BUFp_ENABLED); pc.printf(" Precharge buffer on REF+\n"); break; default: pc.printf(" Invalid option\n"); break; } break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Default ADC Settings * */ void static menu_5_set_default_settings(void) { int32_t default_settings_flag = ad77681_setup(&device_adc, init_params, ¤t_status); if (default_settings_flag == SUCCESS) pc.printf("\n Default ADC settings successfull\n"); else pc.printf("\n Error in settings, please reset the ADC\n"); print_prompt(); } /** * VCM output controll * */ void static menu_6_set_adc_vcm(void) { uint32_t new_vcm = 0; pc.printf(" Avaliable VCM output voltage levels: \n"); pc.printf(" 1 - VCM = (AVDD1-AVSS)/2\n"); pc.printf(" 2 - VCM = 2.5V\n"); pc.printf(" 3 - VCM = 2.05V\n"); pc.printf(" 4 - VCM = 1.9V\n"); pc.printf(" 5 - VCM = 1.65V\n"); pc.printf(" 6 - VCM = 1.1V\n"); pc.printf(" 7 - VCM = 0.9V\n"); pc.printf(" 8 - VCM off\n"); pc.printf(" Select an option: \n"); getUserInput(&new_vcm); pc.putc('\n'); switch (new_vcm) { case 1: ad77681_set_VCM_output(device_adc, AD77681_VCM_HALF_VCC); pc.printf(" VCM set to half of the Vcc\n"); break; case 2: ad77681_set_VCM_output(device_adc, AD77681_VCM_2_5V); pc.printf(" VCM set to 2.5V\n"); break; case 3: ad77681_set_VCM_output(device_adc, AD77681_VCM_2_05V); pc.printf(" VCM set to 2.05V\n"); break; case 4: ad77681_set_VCM_output(device_adc, AD77681_VCM_1_9V); pc.printf(" VCM set to 1.9V\n"); break; case 5: ad77681_set_VCM_output(device_adc, AD77681_VCM_1_65V); pc.printf(" VCM set to 1.65V\n"); break; case 6: ad77681_set_VCM_output(device_adc, AD77681_VCM_1_1V); pc.printf(" VCM set to 1.1V\n"); break; case 7: ad77681_set_VCM_output(device_adc, AD77681_VCM_0_9V); pc.printf(" VCM set to 0.9V\n"); break; case 8: ad77681_set_VCM_output(device_adc, AD77681_VCM_OFF); pc.printf(" VCM OFF\n"); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Register read * */ void static menu_7_adc_read_register(void) { uint32_t new_reg_to_read = 0; uint8_t reg_read_buf[3], read_adc_data[6], hex_number = 0; uint8_t HI = 0, MID = 0, LO = 0; char binary_number[8], other_register[2] = ""; double voltage; pc.printf(" Read desired register: \n"); pc.printf(" 1 - 0x03 - Chip type\n"); pc.printf(" 2 - 0x14 - Interface format\n"); pc.printf(" 3 - 0x15 - Power clock\n"); pc.printf(" 4 - 0x16 - Analog\n"); pc.printf(" 5 - 0x17 - Analog2\n"); pc.printf(" 6 - 0x18 - Conversion\n"); pc.printf(" 7 - 0x19 - Digital filter\n"); pc.printf(" 8 - 0x1A - SINC3 Dec. rate MSB\n"); pc.printf(" 9 - 0x1B - SINC3 Dec. rate LSB\n"); pc.printf(" 10 - 0x1C - Duty cycle ratio\n"); pc.printf(" 11 - 0x1D - Sync, Reset\n"); pc.printf(" 12 - 0x1E - GPIO Controll\n"); pc.printf(" 13 - 0x1F - GPIO Write\n"); pc.printf(" 14 - 0x20 - GPIO Read\n"); pc.printf(" 15 - 0x21 - 0x23 - Offset register\n"); pc.printf(" 16 - 0x24 - 0x26 - Gain register\n"); pc.printf(" 17 - 0x2C - ADC Data\n"); pc.printf(" Select an option: \n"); getUserInput(&new_reg_to_read); pc.putc('\n'); switch (new_reg_to_read) { case 1: ad77681_spi_reg_read(device_adc, AD77681_REG_CHIP_TYPE, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x03 - Chip type register is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 2: ad77681_spi_reg_read(device_adc, AD77681_REG_INTERFACE_FORMAT, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x14 - Interface format register is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 3: ad77681_spi_reg_read(device_adc, AD77681_REG_POWER_CLOCK, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x15 - Power clock register is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 4: ad77681_spi_reg_read(device_adc, AD77681_REG_ANALOG, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x16 - Anlaog register is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 5: ad77681_spi_reg_read(device_adc, AD77681_REG_ANALOG2, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x17 - Analog2 regster is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 6: ad77681_spi_reg_read(device_adc, AD77681_REG_CONVERSION, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x18 - Conversion register is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 7: ad77681_spi_reg_read(device_adc, AD77681_REG_DIGITAL_FILTER, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x19 - Digital filter register is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 8: ad77681_spi_reg_read(device_adc, AD77681_REG_SINC3_DEC_RATE_MSB, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x1A - SINC3 Dec. rate MSB is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 9: ad77681_spi_reg_read(device_adc, AD77681_REG_SINC3_DEC_RATE_LSB, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x1B - SINC3 Dec. rate LSB is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 10: ad77681_spi_reg_read(device_adc, AD77681_REG_DUTY_CYCLE_RATIO, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x1C - Duty cycle ratio 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 11: ad77681_spi_reg_read(device_adc, AD77681_REG_SYNC_RESET, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x1D - Sync, Reset 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 12: ad77681_spi_reg_read(device_adc, AD77681_REG_GPIO_CONTROL, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x1E - GPIO Controll is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 13: ad77681_spi_reg_read(device_adc, AD77681_REG_GPIO_WRITE, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x1F - GPIO Write is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 14: ad77681_spi_reg_read(device_adc, AD77681_REG_GPIO_READ, reg_read_buf); print_binary(reg_read_buf[1], binary_number); pc.printf(" Value of 0x20 - GPIO Read is: 0x%x 0b%s\n", reg_read_buf[1], binary_number); break; case 15: ad77681_spi_reg_read(device_adc, AD77681_REG_OFFSET_HI, reg_read_buf); HI = reg_read_buf[1]; ad77681_spi_reg_read(device_adc, AD77681_REG_OFFSET_MID, reg_read_buf); MID = reg_read_buf[1]; ad77681_spi_reg_read(device_adc, AD77681_REG_OFFSET_LO, reg_read_buf); LO = reg_read_buf[1]; pc.printf(" Value of 0x21 - 0x23 - Offset register is: 0x%x %x %x\n", HI, MID, LO); break; case 16: ad77681_spi_reg_read(device_adc, AD77681_REG_GAIN_HI, reg_read_buf); HI = reg_read_buf[1]; ad77681_spi_reg_read(device_adc, AD77681_REG_GAIN_MID, reg_read_buf); MID = reg_read_buf[1]; ad77681_spi_reg_read(device_adc, AD77681_REG_GAIN_LO, reg_read_buf); LO = reg_read_buf[1]; pc.printf(" Value of 0x24 - 0x26 - Gain register is: 0x%x %x %x\n", HI, MID, LO); break; case 17: ad77681_spi_read_adc_data(device_adc, read_adc_data, AD77681_REGISTER_DATA_READ); pc.printf(" Value of 0x2C - ADC data is: 0x%x 0x%x 0x%x\n", read_adc_data[1], read_adc_data[2], read_adc_data[3]); break; default : pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Read ADC data * */ void static menu_8_adc_cont_read_data(void) { uint32_t new_sample_count = 0; int32_t ret; pc.printf(" Read Continuous ADC Data"); pc.printf(" Input number of samples (1 to 4096): \n"); ret = getUserInput(&new_sample_count); // Get user input if ((new_sample_count <= 4096) && (ret == SUCCESS) ) { pc.printf("\n%d of samples\n", new_sample_count); // Print Desired Measurement Count measured_data.samples = (uint16_t)(new_sample_count); measured_data.finish = false; measured_data.count = 0; pc.printf("Sampling....\n"); cont_sampling(); pc.printf("Done Sampling....\n"); } else { pc.printf(" Invalid option\n"); } print_prompt(); } /** * ADC Continuous read * */ void static cont_sampling() { uint8_t buf[6]; ad77681_set_continuos_read(device_adc, AD77681_CONTINUOUS_READ_ENABLE); __enable_irq(); // Enable all interupts drdy.enable_irq(); // Enable interrupt on DRDY pin drdy.fall(&drdy_interrupt); // Interrupt on falling edne of DRDY while (!measured_data.finish) { // While loop. Waiting for the measurements to be completed if (int_event==true) { // Checks if Interrupt Occurred ad77681_spi_read_adc_data(device_adc, buf, AD77681_CONTINUOUS_DATA_READ); // Read the continuous read data if (device_adc->conv_len == AD77681_CONV_24BIT) // 24bit format measured_data.raw_data[measured_data.count] = (buf[0] << 16 | buf[1] << 8 | buf[2]<< 0); // Combining the SPI buffers else // 16bit format measured_data.raw_data[measured_data.count] = (buf[0] << 8 | buf[1]<< 0); // Combining the SPI buffers measured_data.count++; // Increment Measured Data Counter int_event=false; // Set int event flag after reading the Data } } ad77681_set_continuos_read(device_adc, AD77681_CONTINUOUS_READ_DISABLE); // Disable continuous ADC read } /** * Reset ADC * */ void static menu_9_reset_ADC(void) { uint32_t new_reset_option = 0; pc.printf(" ADC reset opportunities: \n"); pc.printf(" 1 - Soft reset - over SPI\n"); pc.printf(" 2 - Hard reset - uing RESET pin\n"); pc.printf(" Select an option: \n"); getUserInput(&new_reset_option); pc.putc('\n'); switch (new_reset_option) { case 1: ad77681_soft_reset(device_adc); // Perform soft reset thru SPI write pc.printf(" ADC after soft reset\n"); break; case 2: adc_hard_reset(); pc.printf(" ADC after hard reset\n"); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Reset ADC thru SDP-K1 GPIO * * */ void static adc_hard_reset() { adc_reset = 0; // Set ADC reset pin to Low mdelay(100); // Delay 100ms adc_reset = 1; // Set ADC reset pin to High mdelay(100); // Delay 100ms } /** * Sleep mode / Wake up ADC * */ void static menu_10_power_down(void) { uint32_t new_sleep = 0; pc.printf(" Controll sleep mode of the ADC: \n"); pc.printf(" 1 - Put ADC to sleep mode\n"); pc.printf(" 2 - Wake up ADC\n"); pc.printf(" Select an option: \n"); getUserInput(&new_sleep); pc.putc('\n'); switch (new_sleep) { case 1: ad77681_power_down(device_adc, AD77681_SLEEP); pc.printf(" ADC put to sleep mode\n"); break; case 2: ad77681_power_down(device_adc, AD77681_WAKE); pc.printf(" ADC powered\n"); break; default: pc.printf("Invalid option\n"); break; } print_prompt(); } /** * ADC's GPIO Controll * */ void static menu_11_ADC_GPIO(void) { uint8_t GPIO_state; uint32_t new_gpio_sel = 0; char binary_number[8]; int32_t ret_val = FAILURE, ret; pc.printf(" ADC GPIO Controll: \n"); pc.printf(" 1 - Read from GPIO\n"); pc.printf(" 2 - Write to GPIO\n"); pc.printf(" 3 - Set GPIO as input / output\n"); pc.printf(" 4 - Change GPIO settings\n"); pc.printf(" Select an option: \n"); getUserInput(&new_gpio_sel); pc.putc('\n'); switch (new_gpio_sel) { case 1: ad77681_gpio_read(device_adc, &GPIO_state, AD77681_ALL_GPIOS); print_binary(GPIO_state, binary_number); pc.printf(" Current GPIO Values:\n GPIO0: %c\n GPIO1: %c\n GPIO2: %c\n GPIO3: %c\n", binary_number[7], binary_number[6], binary_number[5], binary_number[4]); break; case 2: adc_GPIO_write(); break; case 3: adc_GPIO_inout(); break; case 4: adc_GPIO_settings(); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Write to GPIOs, part of the ADC_GPIO function * */ void static adc_GPIO_write(void) { uint32_t new_gpio_write = 0, new_value = 0; int32_t ret, ret_val; pc.printf(" Write to GPIO: \n"); pc.printf(" 1 - Write to all GPIOs\n"); pc.printf(" 2 - Write to GPIO0\n"); pc.printf(" 3 - Write to GPIO1\n"); pc.printf(" 4 - Write to GPIO2\n"); pc.printf(" 5 - Write to GPIO3\n"); pc.printf(" Select an option: \n"); getUserInput(&new_gpio_write); pc.putc('\n'); switch (new_gpio_write) { case 1: pc.printf("Insert value to be writen into all GPIOs, same value for all GPIOs: "); ret = getUserInput(&new_value); if (((new_value == GPIO_HIGH) || (new_value == GPIO_LOW)) && (ret == SUCCESS)) { new_value *= 0xF; ret_val = ad77681_gpio_write(device_adc, new_value, AD77681_ALL_GPIOS); pc.printf("\n Value %d successully written to all GPOIs\n", new_value); } else pc.printf("\nInvalid value\n"); break; case 2: pc.printf("Insert value to be written into GPIO0: "); ret = getUserInput(&new_value); if (((new_value == GPIO_HIGH) || (new_value == GPIO_LOW)) && (ret == SUCCESS)) { ret_val = ad77681_gpio_write(device_adc, new_value, AD77681_GPIO0); pc.printf("\n Value %d successully written to GPIO0\n", new_value); } else pc.printf("\nInvalid value\n"); break; case 3: pc.printf("Insert value to be written into GPIO1: "); ret = getUserInput(&new_value); if (((new_value == GPIO_HIGH) || (new_value == GPIO_LOW)) && (ret == SUCCESS)) { ret_val = ad77681_gpio_write(device_adc, new_value, AD77681_GPIO1); pc.printf("\n Value %d successully written to GPIO1\n", new_value); } else pc.printf("\nInvalid value\n"); break; case 4: pc.printf("Insert value to be written into GPIO2: "); ret = getUserInput(&new_value); if (((new_value == GPIO_HIGH) || (new_value == GPIO_LOW)) && (ret == SUCCESS)) { ret_val = ad77681_gpio_write(device_adc, new_value, AD77681_GPIO2); pc.printf("\n Value %d successully written to GPIO2\n", new_value); } else pc.printf("\nInvalid value\n"); break; case 5: pc.printf("Insert value to be written into GPIO3: "); ret = getUserInput(&new_value); if (((new_value == GPIO_HIGH) || (new_value == GPIO_LOW)) && (ret == SUCCESS)) { ret_val = ad77681_gpio_write(device_adc, new_value, AD77681_GPIO3); pc.printf("\n Value %d successully written to GPIO3\n", new_value); } else pc.printf("\nInvalid value\n"); break; default: pc.printf(" Invalid option\n"); break; } } /** * GPIO direction, part of the ADC_GPIO function * */ void static adc_GPIO_inout(void) { uint32_t new_gpio_inout = 0, new_gpio_inout_set = 0; int32_t ret_val; pc.printf(" Set GPIOs as input or output: \n"); pc.printf(" 1 - Set all GPIOs\n"); pc.printf(" 2 - Set GPIO0\n"); pc.printf(" 3 - Set GPIO1\n"); pc.printf(" 4 - Set GIPO2\n"); pc.printf(" 5 - Set GPIO3\n"); pc.printf(" Select an option: \n"); getUserInput(&new_gpio_inout); pc.putc('\n'); switch (new_gpio_inout) { case 1: pc.printf(" 1 - Set all GPIOS as inputs\n"); pc.printf(" 2 - Set all GPIOS as outputs\n"); getUserInput(&new_gpio_inout_set); pc.putc('\n'); if ((new_gpio_inout_set == 1) || (new_gpio_inout_set == 2)) { new_gpio_inout_set -= 1; new_gpio_inout_set *= 0xF; ret_val = ad77681_gpio_inout(device_adc, new_gpio_inout_set, AD77681_ALL_GPIOS); pc.printf("All GPIOs successfully set"); } else pc.printf("\nInvalid value\n"); break; case 2: pc.printf(" 1 - Set GPIO0 as input\n"); pc.printf(" 2 - Set GPIO0 as output\n"); getUserInput(&new_gpio_inout_set); pc.putc('\n'); if ((new_gpio_inout_set == 1) || (new_gpio_inout_set == 2)) { new_gpio_inout_set -= 1; ret_val = ad77681_gpio_inout(device_adc, new_gpio_inout_set, AD77681_GPIO0); pc.printf("GPIO0 successfully set"); } else pc.printf("\nInvalid value\n"); break; case 3: pc.printf(" 1 - Set GPIO1 as input\n"); pc.printf(" 2 - Set GPIO1 as output\n"); getUserInput(&new_gpio_inout_set); pc.putc('\n'); if ((new_gpio_inout_set == 1) || (new_gpio_inout_set == 2)) { new_gpio_inout_set -= 1; ret_val = ad77681_gpio_inout(device_adc, new_gpio_inout_set, AD77681_GPIO1); pc.printf("GPIO1 successfully set"); } else pc.printf("\nInvalid value\n"); break; case 4: pc.printf(" 1 - Set GPIO2 as input\n"); pc.printf(" 2 - Set GPIO2 as output\n"); getUserInput(&new_gpio_inout_set); pc.putc('\n'); if ((new_gpio_inout_set == 1) || (new_gpio_inout_set == 2)) { new_gpio_inout_set -= 1; ret_val = ad77681_gpio_inout(device_adc, new_gpio_inout_set, AD77681_GPIO2); pc.printf("GPIO2 successfully set"); } else pc.printf("\nInvalid value\n"); break; case 5: pc.printf(" 1 - Set GPIO3 as input\n"); pc.printf(" 2 - Set GPIO3 as output\n"); getUserInput(&new_gpio_inout_set); pc.putc('\n'); if ((new_gpio_inout_set == 1) || (new_gpio_inout_set == 2)) { new_gpio_inout_set -= 1; ret_val = ad77681_gpio_inout(device_adc, new_gpio_inout_set, AD77681_GPIO3); pc.printf("GPIO3 successfully set"); } else pc.printf("\nInvalid value\n"); break; default: pc.printf(" Invalid option\n"); break; } } /** * Additional GPIO settings, part of the ADC_GPIO function * */ void static adc_GPIO_settings(void) { uint32_t new_gpio_settings = 0; pc.printf(" GPIO Settings: \n"); pc.printf(" 1 - Enable all GPIOs (Global enble)\n"); pc.printf(" 2 - Disable all GPIOs (Global disable)\n"); pc.printf(" 3 - Set GPIO0 - GPIO2 as open drain\n"); pc.printf(" 4 - Set GPIO0 - GPIO2 as strong driver\n"); pc.printf(" Select an option: \n"); getUserInput(&new_gpio_settings); pc.putc('\n'); switch (new_gpio_settings) { case 1: ad77681_global_gpio(device_adc, AD77681_GLOBAL_GPIO_ENABLE); pc.printf(" Global GPIO enalbe bit enabled"); break; case 2: ad77681_global_gpio(device_adc, AD77681_GLOBAL_GPIO_DISABLE); pc.printf(" Global GPIO enalbe bit disabled"); break; default: pc.printf(" Invalid option\n"); break; } } /** * Read ADC status from status registers * */ void static menu_12_read_master_status(void) { uint8_t reg_read_buf[3]; char binary_number[8]; char ok[3] = { 'O', 'K' }, fault[6] = { 'F', 'A', 'U', 'L', 'T' }; ad77681_status(device_adc, current_status); pc.putc('\n'); pc.printf("== MASTER STATUS REGISER\n"); pc.printf("Master error: %s\n", ((current_status->master_error == 0) ? (ok) : (fault))); pc.printf("ADC error: %s\n", ((current_status->adc_error == 0) ? (ok) : (fault))); pc.printf("Dig error: %s\n", ((current_status->dig_error == 0) ? (ok) : (fault))); pc.printf("Ext. clock: %s\n", ((current_status->adc_err_ext_clk_qual == 0) ? (ok) : (fault))); pc.printf("Filter saturated: %s\n", ((current_status->adc_filt_saturated == 0) ? (ok) : (fault))); pc.printf("Filter not settled: %s\n", ((current_status->adc_filt_not_settled == 0) ? (ok) : (fault))); pc.printf("SPI error: %s\n", ((current_status->spi_error == 0) ? (ok) : (fault))); pc.printf("POR Flag: %s\n", ((current_status->por_flag == 0) ? (ok) : (fault))); if (current_status->spi_error == 1) { pc.printf("\n== SPI DIAG STATUS REGISER\n"); pc.printf("SPI ignore error: %s\n", ((current_status->spi_ignore == 0) ? (ok) : (fault))); pc.printf("SPI clock count error: %s\n", ((current_status->spi_clock_count == 0) ? (ok) : (fault))); pc.printf("SPI read error: %s\n", ((current_status->spi_read_error == 0) ? (ok) : (fault))); pc.printf("SPI write error: %s\n", ((current_status->spi_write_error == 0) ? (ok) : (fault))); pc.printf("SPI CRC error: %s\n", ((current_status->spi_crc_error == 0) ? (ok) : (fault))); } if (current_status->adc_error == 1) { pc.printf("\n== ADC DIAG STATUS REGISER\n"); pc.printf("DLDO PSM error: %s\n", ((current_status->dldo_psm_error == 0) ? (ok) : (fault))); pc.printf("ALDO PSM error: %s\n", ((current_status->aldo_psm_error == 0) ? (ok) : (fault))); pc.printf("REF DET error: %s\n", ((current_status->ref_det_error == 0) ? (ok) : (fault))); pc.printf("FILT SAT error: %s\n", ((current_status->filt_sat_error == 0) ? (ok) : (fault))); pc.printf("FILT NOT SET error: %s\n", ((current_status->filt_not_set_error == 0) ? (ok) : (fault))); pc.printf("EXT CLK QUAL error: %s\n", ((current_status->ext_clk_qual_error == 0) ? (ok) : (fault))); } if (current_status->dig_error == 1) { pc.printf("\n== DIGITAL DIAG STATUS REGISER\n"); pc.printf("Memory map CRC error: %s\n", ((current_status->memoy_map_crc_error == 0) ? (ok) : (fault))); pc.printf("RAM CRC error: %s\n", ((current_status->ram_crc_error == 0) ? (ok) : (fault))); pc.printf("FUSE CRC error: %s\n", ((current_status->fuse_crc_error == 0) ? (ok) : (fault))); } pc.putc('\n'); print_prompt(); } /** * Set Vref anc MCLK as "exteranl" values, depending on you setup * */ void static menu_13_mclk_vref(void) { uint32_t input = 0, new_settings = 0; int32_t ret; pc.printf(" Set Vref and Mclk: \n"); pc.printf(" 1 - Change Vref\n"); pc.printf(" 2 - Change MCLK\n"); pc.printf(" Select an option: \n"); getUserInput(&new_settings); pc.putc('\n'); switch (new_settings) { case 1: pc.printf(" Change Vref from %d mV to [mV]: ", device_adc->vref); // Vref change ret = getUserInput(&input); if ((input >= 1000) && (input <= 5000) && (ret == SUCCESS)) { pc.printf("\n New Vref value is %d mV", input); device_adc->vref = input; #ifdef CN0540_ADI_FFT_H_ // Update the Vref, Mclk and sampling rate update_FFT_enviroment(device_adc->vref, device_adc->mclk, device_adc->sample_rate, FFT_data); #endif //CN0540_ADI_FFT_H_ } else pc.printf(" Invalid option\n"); pc.putc('\n'); break; case 2: pc.printf(" Change MCLK from %d kHz to [kHz]: ", device_adc->mclk); // MCLK change ret = getUserInput(&input); if ((input >= 10000) && (input <= 50000) && (ret == SUCCESS)){ pc.printf("\n New MCLK value is %d kHz\n", input); device_adc->vref = input; ad77681_update_sample_rate(device_adc); // Update the sample rate after changinig the MCLK #ifdef CN0540_ADI_FFT_H_ // Update the Vref, Mclk and sampling rate update_FFT_enviroment(device_adc->vref, device_adc->mclk, device_adc->sample_rate, FFT_data); #endif //CN0540_ADI_FFT_H_ } else pc.printf(" Invalid option\n"); pc.putc('\n'); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Print measured data and transfered to voltage * */ void static menu_14_print_measured_data(void) { double voltage; int32_t shifted_data; uint16_t i; char buf[15]; if (measured_data.finish) { // Printing Voltage pc.printf("\n\nVoltage\n"); for ( i = 0; i < measured_data.samples; i++) { ad77681_data_to_voltage(device_adc, &measured_data.raw_data[i], &voltage); pc.printf("%.9f \n",voltage); } // Printing Codes pc.printf("\n\nCodes\n"); for(i = 0 ; i < measured_data.samples ; i++) { if (measured_data.raw_data[i] & 0x800000) shifted_data = (int32_t)((0xFF << 24) | measured_data.raw_data[i]); else shifted_data = (int32_t)((0x00 << 24) | measured_data.raw_data[i]); pc.printf("%d\n", shifted_data + AD7768_HALF_SCALE); } // Printing Raw Date pc.printf("\n\nRaw data\n"); for (i = 0; i < measured_data.samples; i++) pc.printf("%d\n", measured_data.raw_data[i]); // Set measured_data.finish to false after Printing measured_data.finish = false; } else pc.printf("Data not prepared\n"); print_prompt(); } /** * Set data output mode * */ void static menu_15_set_adc_data_output_mode(void) { uint32_t new_data_mode = 0, new_length = 0, new_status = 0, new_crc = 0, ret; pc.printf(" ADC data outpup modes: \n"); pc.printf(" 1 - Continuous: waiting for DRDY\n"); pc.printf(" 2 - Continuous one shot: waiting for SYNC_IN\n"); pc.printf(" 3 - Single-conversion standby\n"); pc.printf(" 4 - Periodic standby\n"); pc.printf(" 5 - Standby mode\n"); pc.printf(" 6 - 16bit or 24bit data format\n"); pc.printf(" 7 - Status bit output\n"); pc.printf(" 8 - Switch form diag mode to measure\n"); pc.printf(" 9 - Switch form measure to diag mode\n"); pc.printf(" 10 - Set CRC type\n"); pc.printf(" Select an option: \n"); getUserInput(&new_data_mode); pc.putc('\n'); switch (new_data_mode) { case 1: ad77681_set_conv_mode(device_adc, AD77681_CONV_CONTINUOUS, device_adc->diag_mux_sel, device_adc->conv_diag_sel);// DIAG MUX NOT SELECTED pc.printf(" Continuous mode set\n"); break; case 2: ad77681_set_conv_mode(device_adc, AD77681_CONV_ONE_SHOT, device_adc->diag_mux_sel, device_adc->conv_diag_sel); pc.printf(" Continuous one shot conversion set\n"); break; case 3: ad77681_set_conv_mode(device_adc, AD77681_CONV_SINGLE, device_adc->diag_mux_sel, device_adc->conv_diag_sel); pc.printf(" Single conversion standby mode set\n"); break; case 4: ad77681_set_conv_mode(device_adc, AD77681_CONV_PERIODIC, device_adc->diag_mux_sel, device_adc->conv_diag_sel); pc.printf(" Periodiec standby mode set\n"); break; case 5: ad77681_set_conv_mode(device_adc, AD77681_CONV_STANDBY, device_adc->diag_mux_sel, device_adc->conv_diag_sel); pc.printf(" Standby mode set\n"); break; case 6: pc.printf(" Conversion length select: \n"); pc.printf(" 1 - 24bit length\n"); pc.printf(" 2 - 16bit length\n"); getUserInput(&new_length); pc.putc('\n'); switch (new_length) { case 1: ad77681_set_convlen(device_adc, AD77681_CONV_24BIT); pc.printf(" 24bit data output format selected\n"); break; case 2: ad77681_set_convlen(device_adc, AD77681_CONV_16BIT); pc.printf(" 16bit data output format selected\n"); break; default: pc.printf(" Invalid option\n"); break; } break; case 7: pc.printf(" Status bit output: \n"); pc.printf(" 1 - Enable status bit after each ADC conversion\n"); pc.printf(" 2 - Disable status bit after each ADC conversion\n"); getUserInput(&new_status); pc.putc('\n'); switch (new_status) { case 1: ad77681_set_status_bit(device_adc, true); pc.printf(" Status bit enabled\n"); break; case 2: ad77681_set_status_bit(device_adc, false); pc.printf(" Status bit disabled\n"); break; default: pc.printf(" Invalid option\n"); break; } break; case 8: ad77681_set_conv_mode(device_adc, device_adc->conv_mode, device_adc->diag_mux_sel, false);// DIAG MUX NOT SELECTED pc.printf(" Measure mode selected\n"); break; case 9: ad77681_set_conv_mode(device_adc, device_adc->conv_mode, device_adc->diag_mux_sel, true); // DIAG MUX SELECTED pc.printf(" Diagnostic mode selected\n"); break; case 10: pc.printf(" CRC settings \n"); pc.printf(" 1 - Disable CRC\n"); pc.printf(" 2 - 8-bit polynomial CRC\n"); pc.printf(" 3 - XOR based CRC\n"); getUserInput(&new_crc); pc.putc('\n'); switch (new_crc) { case 1: ad77681_set_crc_sel(device_adc, AD77681_NO_CRC); pc.printf(" CRC disabled\n"); break; case 2: ad77681_set_crc_sel(device_adc, AD77681_CRC); pc.printf(" 8-bit polynomial CRC method selected\n"); break; case 3: ad77681_set_crc_sel(device_adc, AD77681_XOR); pc.printf(" XOR based CRC method selected\n"); break; default: pc.printf(" Invalid option\n"); break; } break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Set diagnostic mode * */ void static menu_16_set_adc_diagnostic_mode(void) { uint32_t new_diag_mode = 0; pc.printf(" ADC diagnostic modes: \n"); pc.printf(" 1 - Internal temperature sensor\n"); pc.printf(" 2 - AIN shorted\n"); pc.printf(" 3 - Positive full-scale\n"); pc.printf(" 4 - Negative full-scale\n"); pc.printf(" Select an option: \n"); getUserInput(&new_diag_mode); pc.putc('\n'); switch (new_diag_mode) { case 1: ad77681_set_conv_mode(device_adc, device_adc->conv_mode, AD77681_TEMP_SENSOR, true); pc.printf(" Diagnostic mode: Internal temperature sensor selected\n"); break; case 2: ad77681_set_conv_mode(device_adc, device_adc->conv_mode, AD77681_AIN_SHORT, true); pc.printf(" Diagnostic mode: AIN shorted selected\n"); break; case 3: ad77681_set_conv_mode(device_adc, device_adc->conv_mode, AD77681_POSITIVE_FS, true); pc.printf(" Diagnostic mode: Positive full-scale selected\n"); break; case 4: ad77681_set_conv_mode(device_adc, device_adc->conv_mode, AD77681_NEGATIVE_FS, true); pc.printf(" Diagnostic mode: Negative full-scale selected\n"); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Do the FFT * */ void static menu_17_do_the_fft(void) { pc.printf(" FFT in progress...\n"); measured_data.samples = FFT_data->fft_length * 2; measured_data.samples = 4096; measured_data.finish = false; measured_data.count = 0; pc.printf("Sampling....\n"); cont_sampling(); perform_FFT(measured_data.raw_data, FFT_data, FFT_meas, device_adc->sample_rate); pc.printf(" FFT Done!\n"); measured_data.finish = false; pc.printf("\n THD:\t\t%.3f dB", FFT_meas->THD); pc.printf("\n SNR:\t\t%.3f dB", FFT_meas->SNR); pc.printf("\n DR:\t\t%.3f dB", FFT_meas->DR); pc.printf("\n Fundamental:\t%.3f dBFS", FFT_meas->harmonics_mag_dbfs[0]); pc.printf("\n Fundamental:\t%.3f Hz", FFT_meas->harmonics_freq[0]*FFT_data->bin_width); pc.printf("\n RMS noise:\t%.6f uV", FFT_meas->RMS_noise * 1000000.0); pc.printf("\n LSB noise:\t%.3f", FFT_meas->transition_noise_LSB); print_prompt(); } /** * Setting of the FFT module * */ void static menu_18_fft_settings(void) { uint32_t new_menu_select, new_window, new_sample_count; pc.printf(" FFT settings: \n"); pc.printf(" 1 - Set window type\n"); pc.printf(" 2 - Set sample count\n"); pc.printf(" 3 - Print FFT plot\n"); pc.printf(" Select an option: \n\n"); getUserInput(&new_menu_select); switch (new_menu_select) { case 1: pc.printf(" Choose window type:\n"); pc.printf(" 1 - 7-term Blackman-Harris\n"); pc.printf(" 2 - Rectangular\n"); getUserInput(&new_window); switch (new_window) { case 1: pc.printf(" 7-7-term Blackman-Harris window selected\n"); FFT_data->window = BLACKMAN_HARRIS_7TERM; break; case 2: pc.printf(" Rectalngular window selected\n"); FFT_data->window = RECTANGULAR; break; default: pc.printf(" Invalid option\n"); break; } break; case 2: pc.printf(" Set sample count:\n"); pc.printf(" 1 - 4096 samples\n"); pc.printf(" 2 - 1024 samples\n"); pc.printf(" 3 - 256 samples\n"); pc.printf(" 4 - 64 samples\n"); pc.printf(" 5 - 16 samples\n"); getUserInput(&new_sample_count); switch (new_sample_count) { case 1: pc.printf(" 4096 samples selected\n"); FFT_init(4096, FFT_data); // Update the FFT module with a new sample count break; case 2: pc.printf(" 1024 samples selected\n"); FFT_init(1024, FFT_data); break; case 3: pc.printf(" 256 samples selected\n"); FFT_init(256, FFT_data); break; case 4: pc.printf(" 64 samples selected\n"); FFT_init(64, FFT_data); break; case 5: pc.printf(" 16 samples selected\n"); FFT_init(16, FFT_data); break; default: pc.printf(" Invalid option\n"); break; } break; case 3: if (FFT_data->fft_done == true) { pc.printf(" Printing FFT plot in dB:\n"); for (uint16_t i = 0; i < FFT_data->fft_length; i++) pc.printf("%.4f\n", FFT_data->fft_dB[i]); } else pc.printf(" Data not prepared\n"); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Set Gains and Offsets * */ void static menu_19_gains_offsets(void) { uint32_t gain_offset, new_menu_select; int32_t ret; pc.printf(" Gains and Offsets settings: \n"); pc.printf(" 1 - Set gain\n"); pc.printf(" 2 - Set offset\n"); pc.printf(" Select an option: \n"); getUserInput(&new_menu_select); switch (new_menu_select) { case 1: pc.printf(" Insert new Gain value in decimal form\n"); ret = getUserInput(&gain_offset); if ((gain_offset <= 0xFFFFFF) && (ret == SUCCESS)) { ad77681_apply_gain(device_adc, gain_offset); pc.printf(" Value %d has been successfully inserted to the Gain register\n", gain_offset); } else pc.printf(" Invalid value\n"); break; case 2: pc.printf(" Insert new Offset value in decimal form\n"); ret = getUserInput(&gain_offset); if ((gain_offset <= 0xFFFFFF) && (ret == SUCCESS)) { ad77681_apply_offset(device_adc, gain_offset); pc.printf(" Value %d has been successfully inserted to the Offset register\n", gain_offset); } else pc.printf(" Invalid value\n"); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Chceck read and write functionaity by writing to and reading from scratchpad register * */ void static menu_20_check_scratchpad(void) { int32_t ret; uint32_t ret_val; uint32_t new_menu_select; uint8_t chceck_sequence; pc.printf(" Scratchpad check\n"); pc.printf(" Insert 8bit number for scratchpad check: \n"); ret = getUserInput(&new_menu_select); if ((new_menu_select <= 0xFF) && (new_menu_select >= 0) && (ret == SUCCESS)) { chceck_sequence = (uint8_t)(new_menu_select); ret_val = ad77681_scratchpad(device_adc, &chceck_sequence); pc.printf(" Insered sequence: %d\n Returned sequence: %d\n", new_menu_select, chceck_sequence); if (ret_val == SUCCESS) pc.printf(" SUCCESS!\n"); else pc.printf(" FAILURE!\n"); } else pc.printf(" Invalid value\n"); print_prompt(); } /** * Start with the piezo accelerometer offset compensation * The offset compenzation process uses a successive approximation model * There is lot of averaging going on, because of quite noisy piezo accelerometer * It will take some time */ void static menu_21_piezo_offset(void) { uint8_t ltc2606_res = 16; uint32_t dac_code = 0; uint32_t dac_code_arr[16]; double mean_voltage = 0.0, min_voltage; double mean_voltage_arr[16]; int8_t sar_loop, min_find, min_index; uint16_t SINC3_odr; // Low power mode and MCLK/16 ad77681_set_power_mode(device_adc, AD77681_ECO); ad77681_set_mclk_div(device_adc, AD77681_MCLK_DIV_16); // 4SPS = 7999 SINC3, 10SPS = 3199 SINC3, 50SPS = 639 SINC3 ad77681_SINC3_ODR(device_adc, &SINC3_odr, 4); // Set the oversamplig ratio to high value, to extract DC ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx32, AD77681_SINC3, SINC3_odr); // successive approximation algorithm pc.printf("\nInitialize SAR loop (DAC MSB set to high)\n"); // Set DAC code to half scale dac_code = (1 << (ltc2606_res - 1 )); // Update output of the DAC ltc26x6_write_code(device_dac, write_update_command, dac_code); // Wait for DAC output to settle wait_ms(500); // Set desired number of samples for every iteration measured_data.samples = 100; measured_data.finish = false; measured_data.count = 0; // Take X number of samples cont_sampling(); // Get the mean voltage of taken samples stroed in the measured_data strucutre get_mean_voltage(&measured_data, &mean_voltage); // Print the mean ADC read voltage for a given DAC code pc.printf("DAC code:%x\t\tMean Voltage: %.6f\n", dac_code, mean_voltage); // Store the initial DAC code in the array dac_code_arr[ltc2606_res - 1] = dac_code; // Store the initial mean voltage in the array mean_voltage_arr[ltc2606_res - 1] = mean_voltage; for ( sar_loop = ltc2606_res - 1; sar_loop > 0; sar_loop--) { // Check if the mean voltage is positive or negative if (mean_voltage > 0) { dac_code = dac_code + (1 << (sar_loop - 1)); pc.printf("UP\n\n"); } else { dac_code = dac_code - (1 << (sar_loop)) + (1 << (sar_loop-1)); pc.printf("DOWN\n\n"); } // Print loop coard pc.printf("SAR loop #: %d\n",sar_loop); // Update output of the DAC ltc26x6_write_code(device_dac, write_update_command, dac_code); // Wait for DAC output to settle wait_ms(500); // Clear data finish flag measured_data.finish = false; measured_data.count = 0; // Take X number of samples cont_sampling(); // Get the mean voltage of taken samples stroed in the measured_data strucutre get_mean_voltage(&measured_data, &mean_voltage); pc.printf("DAC code:%x\t\tMean Voltage: %.6f\n", dac_code, mean_voltage); dac_code_arr[sar_loop - 1] = dac_code; mean_voltage_arr[sar_loop - 1] = mean_voltage; } min_voltage = abs(mean_voltage_arr[0]); for (min_find = 0; min_find < 16; min_find++) { if (min_voltage > abs(mean_voltage_arr[min_find])) { min_voltage = abs(mean_voltage_arr[min_find]); min_index = min_find; } } ltc26x6_write_code(device_dac, write_update_command, dac_code_arr[min_index]); // Wait for DAC output to settle wait_ms(500); // Print the final DAC code pc.printf("\nFinal DAC code set to:%x\t\tFinal Mean Voltage: %.6f\n", dac_code_arr[min_index], mean_voltage_arr[min_index]); // Set to original filter ad77681_set_filter_type(device_adc, AD77681_SINC5_FIR_DECx32, AD77681_FIR, 0); ad77681_update_sample_rate(device_adc); pc.printf("\nOffset compenzation done!\n"); print_prompt(); } /** * Get mean from sampled data * @param mean_voltage Mean Voltage * @param measured_data The structure carying measured data */ void static get_mean_voltage(struct adc_data *measured_data, double *mean_voltage) { int32_t shifted_data; double sum = 0, voltage = 0; uint16_t i; for ( i = 0; i < measured_data->samples; i++) { ad77681_data_to_voltage(device_adc, &measured_data->raw_data[i], &voltage); sum += voltage; } *mean_voltage = (double)(sum / (double)(measured_data->samples)); } /** * Set output of the on-board DAC in codes or in voltage * */ void static menu_22_set_DAC_output(void) { int16_t dac_status; uint16_t code ; uint32_t new_menu_select, new_dac; float dac_voltage; // Gain factor of the on-board DAC buffer, to have full 5V range(ADA4807-1ARJZ) // Non-inverting op-amp resistor ratio => 1 + (2.7 k ohm / 2.7 k ohm) float buffer_gain = 2; pc.printf(" Set DAC output: \n"); pc.printf(" 1 - Voltage\n"); pc.printf(" 2 - Codes\n"); pc.printf(" Select an option: \n"); getUserInput(&new_menu_select); switch (new_menu_select) { case 1: pc.printf(" Set DAC output in mV: "); getUserInput(&new_dac); dac_voltage = ((float)(new_dac) / 1000.0) / buffer_gain; ltc26x6_voltage_to_code(device_dac, dac_voltage, &code); ltc26x6_write_code(device_dac, write_update_command, code); if (dac_status == SUCCESS) pc.printf("%.3f V at Shift output\n\n", dac_voltage * buffer_gain); else if (dac_status == LTC26X6_CODE_OVERFLOW) pc.printf("%.3f V at Shift output, OVERFLOW!\n\n", dac_voltage * buffer_gain); else if (dac_status == LTC26X6_CODE_UNDERFLOW) pc.printf("%.3f V at Shift output, UNDERFLOW!\n\n", dac_voltage * buffer_gain); break; case 2: pc.printf(" Set DAC codes in decimal form: "); getUserInput(&new_dac); ltc26x6_write_code(device_dac, write_update_command, new_dac); pc.printf("%x at DAC output\n\n", new_dac); break; default: pc.printf(" Invalid option\n"); break; } print_prompt(); } /** * Prints out an array in binary form * */ void static print_binary(uint8_t number, char *binary_number) { for (int8_t i = 7; i >= 0; i--) { if (number & 1) binary_number[i] = '1'; else binary_number[i] = '0'; number >>= 1; } } /** * Setup SDP-K1 GPIOs * * */ void static sdpk1_gpio_setup(void) { // Enable DAC buffer & other buffer buffer_en = GPIO_HIGH; // Turn on onboard red LED led_red = GPIO_HIGH; // Turn on onboard blue LED led_blue = GPIO_HIGH; }