Maxim Integrated MAX5719 20-bit, 0.05nV-sec DAC Test program running on MAX32625MBED.
Dependencies: FunctionGenerator MAX5719
Revision 27:56e5a3ca9207, committed 2021-01-03
- Comitter:
- whismanoid
- Date:
- Sun Jan 03 06:16:54 2021 +0000
- Parent:
- 26:b89783422715
- Commit message:
- Initial Commit MAX5719BOB_FunctionGen
Changed in this revision
FunctionGenerator.h | Show diff for this revision Revisions of this file |
FunctionGenerator.lib | Show annotated file Show diff for this revision Revisions of this file |
--- a/FunctionGenerator.h Sun Jan 03 05:11:44 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,455 +0,0 @@ -// /******************************************************************************* -// * Copyright (C) 2019 Maxim Integrated Products, Inc., All Rights Reserved. -// * -// * Permission is hereby granted, free of charge, to any person obtaining a -// * copy of this software and associated documentation files (the "Software"), -// * to deal in the Software without restriction, including without limitation -// * the rights to use, copy, modify, merge, publish, distribute, sublicense, -// * and/or sell copies of the Software, and to permit persons to whom the -// * Software is furnished to do so, subject to the following conditions: -// * -// * The above copyright notice and this permission notice shall be included -// * in all copies or substantial portions of the Software. -// * -// * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES -// * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// * OTHER DEALINGS IN THE SOFTWARE. -// * -// * Except as contained in this notice, the name of Maxim Integrated -// * Products, Inc. shall not be used except as stated in the Maxim Integrated -// * Products, Inc. Branding Policy. -// * -// * The mere transfer of this software does not imply any licenses -// * of trade secrets, proprietary technology, copyrights, patents, -// * trademarks, maskwork rights, or any other form of intellectual -// * property whatsoever. Maxim Integrated Products, Inc. retains all -// * ownership rights. -// ******************************************************************************* -// */ -// ********************************************************************* -// @file FunctionGenerator.h -// ********************************************************************* - -// Prevent multiple declaration -#ifndef __FunctionGenerator_H__ -#define __FunctionGenerator_H__ - -//-------------------------------------------------- -// Option to support Sine waveform; requires floating point -// -// Triangle Ramp: Ramp Up then Ramp Down -#ifndef USE_FunctionGenerator_TriangleRampUpDown -#define USE_FunctionGenerator_TriangleRampUpDown 0 -#endif // USE_FunctionGenerator_TriangleRampUpDown -// -// Ramp Up from m_code_limit_L to m_code_limit_H by m_code_increment -#ifndef USE_FunctionGenerator_RampUp -#define USE_FunctionGenerator_RampUp 0 -#endif // USE_FunctionGenerator_RampUp -// -// Ramp Down from m_code_limit_H to m_code_limit_L by m_code_increment -#ifndef USE_FunctionGenerator_RampDown -#define USE_FunctionGenerator_RampDown 0 -#endif // USE_FunctionGenerator_RampDown -// -// Computed Sinusoid (Sine wave) m_code_amplitude * sin(m_phase_accumulator) + m_code_offset; m_phase_increment determines frequency -#ifndef USE_FunctionGenerator_Sine -#define USE_FunctionGenerator_Sine 0 -#endif // USE_FunctionGenerator_Sine -// -// Arbitrary Waveform Generation by table lookup; m_table_index_increment determines frequency -#ifndef USE_FunctionGenerator_Table -#define USE_FunctionGenerator_Table 0 -#endif // USE_FunctionGenerator_Table -// -// Sinusoid using Arbitrary Waveform Generation table lookup -#ifndef USE_FunctionGenerator_Sine_Table -#define USE_FunctionGenerator_Sine_Table 1 -#endif // USE_FunctionGenerator_Sine_Table -// - -// standard include for target platform -#include "mbed.h" -// TODO: error: 'PI' was not declared -- use M_PI instead of PI - -/** - @brief DACFunctionGenerator class is a Function Generator for DAC output - */ -// -class DACFunctionGenerator -{ -public: - enum shape_t { - // Constant DC output - Constant = 0, - // -#if USE_FunctionGenerator_TriangleRampUpDown - // Triangle Ramp: Ramp Up then Ramp Down - TriangleRampUpDown, -#endif // USE_FunctionGenerator_TriangleRampUpDown - // -#if USE_FunctionGenerator_RampUp - // Ramp Up from m_code_limit_L to m_code_limit_H by m_code_increment - RampUp, -#endif // USE_FunctionGenerator_RampUp - // -#if USE_FunctionGenerator_RampDown - // Ramp Down from m_code_limit_H to m_code_limit_L by m_code_increment - RampDown, -#endif // USE_FunctionGenerator_RampDown - // -#if USE_FunctionGenerator_Sine - // Computed Sinusoid (Sine wave) m_code_amplitude * sin(m_phase_accumulator) + m_code_offset; m_phase_increment determines frequency - Sine, -#endif // USE_FunctionGenerator_Sine - // -#if (USE_FunctionGenerator_Table) || (USE_FunctionGenerator_Sine_Table) - // Arbitrary Waveform Generation by table lookup; m_table_index_increment determines frequency - Table, -#endif // USE_FunctionGenerator_Table - // - } m_shape; //!< shape of the generated waveform -private: - uint32_t m_code; //!< DAC output code value (unsigned value) -public: - uint32_t m_code_limit_H; //!< high limit of code (unsigned value) - uint32_t m_code_limit_L; //!< low limit of code (unsigned value) -#if (USE_FunctionGenerator_TriangleRampUpDown) || (USE_FunctionGenerator_RampUp) || (USE_FunctionGenerator_RampDown) - int32_t m_code_increment; //!< amount to be added to code (signed value) (Ramp) -#endif -#if (USE_FunctionGenerator_Sine) || (USE_FunctionGenerator_Sine_Table) - uint32_t m_code_offset; //!< (Sine) - uint32_t m_code_amplitude; //!< (Sine) -#endif // USE_FunctionGenerator_Sine -#if (USE_FunctionGenerator_Sine) - float m_phase_accumulator; //!< phase angle in radians (Sine) - float m_phase_increment; //!< increment in phase angle in radians, per sample period (Sine) - const float m_phase_accumulator_limit_H = (2 * M_PI); //!< high limit of phase angle in radians (Sine) -#endif // USE_FunctionGenerator_Sine -#if (USE_FunctionGenerator_Table) || (USE_FunctionGenerator_Sine_Table) - uint32_t* m_table_data; //!< (Table) - uint32_t m_table_index; //!< (Table) - int32_t m_table_index_increment; //!< (Table) - uint32_t m_table_length; //!< (Table) -#endif // USE_FunctionGenerator_Table -public: - DACFunctionGenerator() //!< #ctor - { // ............0xFFFFF for 20-bit - m_code_limit_H = 0xFFFFF; - m_code_limit_L = 0x00000; -#if (USE_FunctionGenerator_TriangleRampUpDown) || (USE_FunctionGenerator_RampUp) || (USE_FunctionGenerator_RampDown) - m_code_increment = 0x00001; -#endif - m_code = (m_code_limit_L/4 + m_code_limit_H/4) * 2; // approx (code_limit_H+code_limit_L)/2 but avoid overflow -#if USE_FunctionGenerator_TriangleRampUpDown - m_shape = TriangleRampUpDown; -#else // USE_FunctionGenerator_TriangleRampUpDown - m_shape = Constant; -#endif // USE_FunctionGenerator_TriangleRampUpDown - }; - void Configure_Constant(uint32_t code = 0x5555) - { - m_code = code; - m_shape = Constant; - } -#if USE_FunctionGenerator_TriangleRampUpDown - void Configure_TriangleRampUpDown( - uint32_t code_limit_L = 0x00000, - uint32_t code_limit_H = 0xFFFFF, - int32_t increment = 0x00001 - ) - { - m_code_limit_H = code_limit_H; - m_code_limit_L = code_limit_L; - m_code_increment = increment; - m_code = (m_code_limit_L/4 + m_code_limit_H/4) * 2; // approx (code_limit_H+code_limit_L)/2 but avoid overflow - m_shape = TriangleRampUpDown; - } -#endif // USE_FunctionGenerator_TriangleRampUpDown -#if USE_FunctionGenerator_RampUp - void Configure_RampUp( - uint32_t code_limit_L = 0x00000, - uint32_t code_limit_H = 0xFFFFF, - int32_t increment = 0x00001 - ) - { - m_code_limit_H = code_limit_H; - m_code_limit_L = code_limit_L; - m_code_increment = increment; - m_code = code_limit_L; - m_shape = RampUp; - } -#endif // USE_FunctionGenerator_RampUp -#if USE_FunctionGenerator_RampDown - void Configure_RampDown( - uint32_t code_limit_L = 0x00000, - uint32_t code_limit_H = 0xFFFFF, - int32_t increment = 0x00001 - ) - { - m_code_limit_H = code_limit_H; - m_code_limit_L = code_limit_L; - m_code_increment = increment; - m_code = code_limit_H; - m_shape = RampDown; - } -#endif // USE_FunctionGenerator_RampDown -#if USE_FunctionGenerator_Sine - void Configure_Sine( // TODO WIP Sine - uint32_t code_limit_L = 0x00000, - uint32_t code_limit_H = 0xFFFFF, - float num_samples_per_tone_cycle = 10.0 - ) - { - m_code_limit_H = code_limit_H; - m_code_limit_L = code_limit_L; - //~ m_code_increment = increment; - m_code = (m_code_limit_L/4 + m_code_limit_H/4) * 2; // approx (code_limit_H+code_limit_L)/2 but avoid overflow - m_code_offset = (m_code_limit_L/4 + m_code_limit_H/4) * 2; // approx (code_limit_H+code_limit_L)/2 but avoid overflow - m_code_amplitude = m_code_limit_H - m_code_offset; - m_phase_accumulator = 0; - //~ m_phase_accumulator_limit_H = (2 * M_PI); - m_phase_increment = m_phase_accumulator_limit_H / num_samples_per_tone_cycle; - //~ m_phase_increment = (2 * M_PI) / num_samples_per_tone_cycle; - m_shape = Sine; - } -#endif // USE_FunctionGenerator_Sine -#if USE_FunctionGenerator_Table - void Configure_Table( // TODO WIP Table - uint32_t* table_data, - uint32_t table_length, - int32_t increment = 0x00001 - ) - { - m_table_data = table_data; - m_table_length = table_length; - m_code = table_data[0]; - //~ m_phase_accumulator = 0; - //~ m_phase_increment = (2 * M_PI) / num_samples_per_tone_cycle; - m_table_index_increment = increment; - m_shape = Table; - } -#endif // USE_FunctionGenerator_Table -#if USE_FunctionGenerator_Sine_Table - // TODO: implement Configure_Sine_Table(uint32_t code_limit_L, uint32_t code_limit_H, float num_samples_per_tone_cycle, uint32_t* table_data_out, uint32_t table_length) - void Configure_Sine_Table( - uint32_t* table_data_buffer, - uint32_t table_length, - uint32_t code_limit_L = 0x00000, - uint32_t code_limit_H = 0xFFFFF, - float num_tone_cycles_in_table = 7 - ) - { - m_code_limit_H = code_limit_H; - m_code_limit_L = code_limit_L; - //~ m_code_increment = increment; - m_code = (m_code_limit_L/4 + m_code_limit_H/4) * 2; // approx (code_limit_H+code_limit_L)/2 but avoid overflow - m_code_offset = (m_code_limit_L/4 + m_code_limit_H/4) * 2; // approx (code_limit_H+code_limit_L)/2 but avoid overflow - m_code_amplitude = m_code_limit_H - m_code_offset; - m_table_data = table_data_buffer; - m_table_length = table_length; - // - // DIAGNOSTIC: initialize table to midscale - //~ for (m_table_index = 0; m_table_index < m_table_length; m_table_index++) - //~ { - //~ m_table_data[m_table_index] = m_code_offset - 0.75 * m_code_amplitude; - //~ } - //~ m_code_amplitude = 0.5 * m_code_amplitude; // DIAGNOSTIC - //~ m_table_data[0] = m_code_limit_L; // DIAGNOSTIC - //~ m_table_data[1] = m_code_limit_H; - //~ m_table_data[3] = m_code_limit_L; - //~ m_table_data[m_table_length-1] = m_code_limit_H; - // - // write a sine wave table into caller-provided buffer table_data_buffer[table_length] - // float num_tone_cycles_in_table = 7; // num_samples_per_tone_cycle; // ???? - // TODO: is m_table_data[m_table_length-1] not being initialized? - for (m_table_index = 0; m_table_index < /* DIAGNOSTIC */ m_table_length+0; m_table_index++) - { - // calculate phase angle from m_table_index - // m_table_index = m_table_length * m_phase_accumulator / (2 * M_PI); - // m_phase_accumulator = m_phase_accumulator + m_phase_increment - // m_phase_increment = m_phase_accumulator_limit_H / num_samples_per_tone_cycle; - float phase_accumulator = num_tone_cycles_in_table * ((((float)m_table_index + 0.5) / (float)m_table_length) * (2.0 * M_PI)); - // - // calculate code from sine(phase angle) - float code = m_code_amplitude * sin(phase_accumulator) + m_code_offset; - m_code = code; - if (code > m_code_limit_H) { - m_code = m_code_limit_H; - } - if (code < m_code_limit_L) { - m_code = m_code_limit_L; - } - //~ m_code = m_code_offset - m_code_amplitude + m_table_index * 0.1 * m_code_amplitude; // DIAGNOSITC override sine with a ramp - // - // store code into table_data[m_table_index] - m_table_data[m_table_index] = m_code; - // - } - // - m_table_index = 0; - m_code = m_table_data[m_table_index]; - //~ m_phase_accumulator = 0; - //~ m_phase_increment = (2 * M_PI) / num_samples_per_tone_cycle; - m_table_index_increment = 1; - m_shape = Table; - } -#endif // USE_FunctionGenerator_Sine_Table -public: - uint32_t Code() const { return m_code; }; //!< get DAC output code value -public: - uint32_t Next() //!< determine next code value - { - switch(m_shape) - { - // Constant DC output - case Constant: - break; -#if USE_FunctionGenerator_TriangleRampUpDown - // Triangle Ramp: Ramp Up then Ramp Down - case TriangleRampUpDown: - if (m_code_increment >= 0) { - // increment is positive or zero: rising ramp - // avoid (code + increment) overflow maxint - // avoid (code + increment) > code_limit_H - if ((m_code + m_code_increment) < m_code) { // arithmetic overflow - m_code_increment = -m_code_increment; // change the slope - m_code = m_code + m_code_increment; // note: increment is negative - } - else if ((m_code + m_code_increment) > m_code_limit_H) { - m_code_increment = -m_code_increment; // change the slope - m_code = m_code + m_code_increment; // note: increment is negative - } - else { - m_code = m_code + m_code_increment; // note: increment is positive - } - } - else { - // increment is negative: falling ramp - // avoid (code + increment) underflow minint - // avoid (code + increment) < code_limit_L which might be 0U - if (m_code < (m_code + m_code_increment)) { // arithmetic underflow - m_code_increment = -m_code_increment; // change the slope - m_code = m_code + m_code_increment; // note: increment is positive - } - else if (m_code_limit_L > (m_code + m_code_increment)) { - m_code_increment = -m_code_increment; // change the slope - m_code = m_code + m_code_increment; // note: increment is positive - } - else { - m_code = m_code + m_code_increment; // note: increment is negative - } - } - break; // case TriangleRampUpDown -#endif // TriangleRampUpDown -#if USE_FunctionGenerator_RampUp - // Ramp Up from m_code_limit_L to m_code_limit_H by m_code_increment - case RampUp: - // increment must be positive or zero: rising ramp - if (m_code_increment < 0) { - m_code_increment = -m_code_increment; // change the slope - } - // increment is positive or zero: rising ramp - // avoid (code + increment) overflow maxint - // avoid (code + increment) > code_limit_H - if ((m_code + m_code_increment) < m_code) { // arithmetic overflow - m_code = m_code + m_code_increment; // note: increment is negative - } - else if ((m_code + m_code_increment) > m_code_limit_H) { - m_code = m_code_limit_L; - } - else { - m_code = m_code + m_code_increment; // note: increment is positive - } - break; // case RampUp -#endif // USE_FunctionGenerator_RampUp -#if USE_FunctionGenerator_RampDown - // Ramp Down from m_code_limit_H to m_code_limit_L by m_code_increment - case RampDown: - // increment must be negative: falling ramp - if (m_code_increment >= 0) { - m_code_increment = -m_code_increment; // change the slope - } - // increment is negative: falling ramp - // avoid (code + increment) underflow minint - // avoid (code + increment) < code_limit_L which might be 0U - if (m_code < (m_code + m_code_increment)) { // arithmetic underflow - m_code = m_code + m_code_increment; // note: increment is positive - } - else if (m_code_limit_L > (m_code + m_code_increment)) { - m_code = m_code_limit_H; - } - else { - m_code = m_code + m_code_increment; // note: increment is negative - } - break; // case RampDown -#endif // RampDown -#if USE_FunctionGenerator_Sine - // Computed Sinusoid (Sine wave) m_code_amplitude * sin(m_phase_accumulator) + m_code_offset; m_phase_increment determines frequency - case Sine: - { - // - // DIAGNOSTIC: scope trigger - // ARDUINO - //~ pinMode (8, OUTPUT); - //~ digitalWrite(8, 0); // output logic low - // ARDUINO - // - // DIAGNOSTIC: this line is likely compute heavy on soft float systems - // ARDUINO UNO 16MHz: this line takes 132.0 to 154.0us, limiting sample update rate - float code = m_code_amplitude * sin(m_phase_accumulator) + m_code_offset; - // - // DIAGNOSTIC: scope trigger - // ARDUINO - //~ pinMode (8, OUTPUT); - //~ digitalWrite(8, 1); // output logic high -- initial value in constructor - // ARDUINO - // - m_code = code; - if (code > m_code_limit_H) { - m_code = m_code_limit_H; - } - if (code < m_code_limit_L) { - m_code = m_code_limit_L; - } - m_phase_accumulator = m_phase_accumulator + m_phase_increment; - if (m_phase_accumulator > m_phase_accumulator_limit_H) { - m_phase_accumulator = m_phase_accumulator - m_phase_accumulator_limit_H; - } - } - break; // case Sine -#endif // USE_FunctionGenerator_Sine -#if (USE_FunctionGenerator_Table) || (USE_FunctionGenerator_Sine_Table) - // Arbitrary Waveform Generation by table lookup; m_phase_increment determines frequency - case Table: - if (m_table_index >= m_table_length) { - m_table_index = m_table_length; - } - m_code = m_table_data[m_table_index]; - //~ m_phase_accumulator = m_phase_accumulator + m_phase_increment; - //~ if (m_phase_accumulator > m_phase_accumulator_limit_H) { - //~ m_phase_accumulator = m_phase_accumulator - m_phase_accumulator_limit_H; - //~ } - //~ m_table_index = m_table_length * m_phase_accumulator / m_phase_accumulator_limit_H; - m_table_index = m_table_index + m_table_index_increment; - // if (m_table_index < 0) { // m_table_index is unsigned so no underflow - // m_table_index = 0; - // } - if (m_table_index >= m_table_length) { - m_table_index = 0; // wrap to 0, assuming increment is 1 - } - break; // case Table -#endif // USE_FunctionGenerator_Table - } // switch(shape) - return m_code; - }; -}; - -#endif // __FunctionGenerator_H__ - -// End of file -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FunctionGenerator.lib Sun Jan 03 06:16:54 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/whismanoid/code/FunctionGenerator/#1c31998b91c6