mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.3.6 AD985X
This commit is contained in:
parent
1ffebd886c
commit
3188e13658
@ -1,19 +1,17 @@
|
||||
//
|
||||
// FILE: AD985X.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.3.4
|
||||
// VERSION: 0.3.6
|
||||
// DATE: 2019-02-08
|
||||
// PURPOSE: Class for AD9850 and AD9851 function generator
|
||||
// URL: https://github.com/RobTillaart/AD985X
|
||||
//
|
||||
// HISTORY: see changelog.md
|
||||
|
||||
|
||||
#include "AD985X.h"
|
||||
|
||||
|
||||
// UNO HARDWARE SPI PINS
|
||||
#define SPI_CLOCK 13 // not portable...
|
||||
#define SPI_CLOCK 13 // not portable.
|
||||
#define SPI_MISO 12
|
||||
#define SPI_MOSI 11
|
||||
|
||||
@ -58,13 +56,13 @@ void AD9850::begin(uint8_t select, uint8_t resetPin, uint8_t FQUDPin, uint8_t da
|
||||
{
|
||||
mySPI = new SPIClass(HSPI);
|
||||
mySPI->end();
|
||||
mySPI->begin(14, 12, 13, select); // CLK=14 MISO=12 MOSI=13
|
||||
mySPI->begin(14, 12, 13, select); // CLK = 14 MISO = 12 MOSI = 13
|
||||
}
|
||||
else // VSPI
|
||||
{
|
||||
mySPI = new SPIClass(VSPI);
|
||||
mySPI->end();
|
||||
mySPI->begin(18, 19, 23, select); // CLK=18 MISO=19 MOSI=23
|
||||
mySPI->begin(18, 19, 23, select); // CLK = 18 MISO = 19 MOSI = 23
|
||||
}
|
||||
#else // generic hardware SPI
|
||||
mySPI = &SPI;
|
||||
@ -143,8 +141,8 @@ void AD9850::powerUp()
|
||||
bool AD9850::setPhase(uint8_t phase)
|
||||
{
|
||||
if (phase > 31) return false;
|
||||
_config &= 0x07;
|
||||
_config |= (phase << 3);
|
||||
_config &= 0x07; // keep last three bits
|
||||
_config |= (phase << 3); // set new phase
|
||||
writeData();
|
||||
return true;
|
||||
}
|
||||
@ -176,7 +174,8 @@ void AD9850::writeData()
|
||||
// Serial.println(_config, HEX);
|
||||
uint32_t data = _factor;
|
||||
|
||||
// used for multi device configuration only - https://github.com/RobTillaart/AD985X/issues/13
|
||||
// used for multi device configuration only
|
||||
// see https://github.com/RobTillaart/AD985X/issues/13
|
||||
digitalWrite(_select, HIGH);
|
||||
if (_hwSPI)
|
||||
{
|
||||
@ -233,7 +232,7 @@ bool AD9850::setFrequency(uint32_t freq)
|
||||
rv = false;
|
||||
freq = AD9850_MAX_FREQ;
|
||||
}
|
||||
// _factor = round(freq * 34.359738368); // 4294967296 / 125000000
|
||||
// _factor = round(freq * 34.359738368); // 4294967296 / 125000000
|
||||
_factor = (147573952589ULL * freq) >> 32;
|
||||
_freq = freq;
|
||||
_factor += _offset;
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: AD985X.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.3.5
|
||||
// VERSION: 0.3.6
|
||||
// DATE: 2019-02-08
|
||||
// PURPOSE: Class for AD9850 and AD9851 function generator
|
||||
// URL: https://github.com/RobTillaart/AD985X
|
||||
@ -12,13 +12,19 @@
|
||||
#include "SPI.h"
|
||||
|
||||
|
||||
#define AD985X_LIB_VERSION (F("0.3.5"))
|
||||
#define AD985X_LIB_VERSION (F("0.3.6"))
|
||||
|
||||
|
||||
#define AD9850_MAX_FREQ (40UL * 1000UL * 1000UL)
|
||||
#define AD9851_MAX_FREQ (70UL * 1000UL * 1000UL)
|
||||
#define AD9850_MAX_FREQ (40UL * 1000UL * 1000UL)
|
||||
#define AD9851_MAX_FREQ (70UL * 1000UL * 1000UL)
|
||||
|
||||
#define AD9851_ARC_CUTOFF_FREQ (10000000UL)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BASE CLASS AD9850
|
||||
//
|
||||
class AD9850
|
||||
{
|
||||
public:
|
||||
@ -46,12 +52,12 @@ public:
|
||||
// offset to calibrate the frequency (internal counter)
|
||||
// offset must be stored by the user.
|
||||
void setCalibration(int32_t offset = 0) { _offset = offset; };
|
||||
int32_t getCalibration() { return _offset; };
|
||||
int32_t getCalibration() { return _offset; };
|
||||
|
||||
|
||||
// autoUpdate is default true;
|
||||
void setAutoUpdate(bool update = true) { _autoUpdate = update; };
|
||||
bool getAutoUpdate() { return _autoUpdate; };
|
||||
bool getAutoUpdate() { return _autoUpdate; };
|
||||
void update();
|
||||
|
||||
|
||||
@ -62,7 +68,7 @@ public:
|
||||
// debugging
|
||||
bool usesHWSPI() { return _hwSPI; };
|
||||
// internal chip factor used for frequency. (debugging only)
|
||||
uint32_t getFactor() { return _factor; };
|
||||
uint32_t getFactor() { return _factor; };
|
||||
|
||||
|
||||
// ESP32 specific
|
||||
@ -110,7 +116,7 @@ protected:
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DERIVED CLASS
|
||||
// DERIVED CLASS AD9851
|
||||
//
|
||||
class AD9851 : public AD9850
|
||||
{
|
||||
@ -132,16 +138,17 @@ public:
|
||||
|
||||
// 10 MHz is default, set in Hz.
|
||||
// will be kept <= 30 MHz as that is the freq of LOW mode.
|
||||
void setARCCutOffFreq(uint32_t Hz = 10000000UL );
|
||||
// ARC = AutoRefClock
|
||||
void setARCCutOffFreq(uint32_t Hz = AD9851_ARC_CUTOFF_FREQ);
|
||||
uint32_t getARCCutOffFreq();
|
||||
|
||||
|
||||
protected:
|
||||
bool _autoRefClock = false;
|
||||
uint32_t _ARCCutOffFreq = 10000000UL;
|
||||
uint32_t _ARCCutOffFreq = AD9851_ARC_CUTOFF_FREQ;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
// -- END OF FILE --
|
||||
|
||||
|
@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.3.6] - 2023-10-15
|
||||
- add ESP32 HSPI example
|
||||
- add unit tests for setFrequency setFrequencyF
|
||||
- update readme.md
|
||||
- fix version number in .cpp
|
||||
- minor edits
|
||||
|
||||
|
||||
## [0.3.5] - 2023-01-11
|
||||
- update GitHub actions
|
||||
- update license
|
||||
@ -13,7 +21,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- add bool return value to setPhase()
|
||||
- add test_constants in unit test
|
||||
|
||||
|
||||
## [0.3.4] - 2022-10-25
|
||||
- add changelog.md
|
||||
- add RP2040 in build-CI
|
||||
|
@ -1,9 +1,12 @@
|
||||
|
||||
[![Arduino CI](https://github.com/RobTillaart/AD985X/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
||||
[![JSON check](https://github.com/RobTillaart/AD985X/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/AD985X/actions/workflows/jsoncheck.ym)l
|
||||
[![Arduino-lint](https://github.com/RobTillaart/AD985X/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/AD985X/actions/workflows/arduino-lint.yml)
|
||||
[![JSON check](https://github.com/RobTillaart/AD985X/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/AD985X/actions/workflows/jsoncheck.yml)
|
||||
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/AD985X.svg)](https://github.com/RobTillaart/AD985X/issues)
|
||||
|
||||
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/AD985X/blob/master/LICENSE)
|
||||
[![GitHub release](https://img.shields.io/github/release/RobTillaart/AD985X.svg?maxAge=3600)](https://github.com/RobTillaart/AD985X/releases)
|
||||
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/AD985X.svg)](https://registry.platformio.org/libraries/robtillaart/AD985X)
|
||||
|
||||
|
||||
# AD985X
|
||||
@ -16,13 +19,13 @@ Arduino library for AD9850 and AD9851 function generators.
|
||||
Library for the AD9850 and AD9851 function generators.
|
||||
These devices can produce a square and a sine wave
|
||||
|
||||
| type | max frequency | phase (stepsize) |
|
||||
|:---------|---------------:|-------------------:|
|
||||
| AD9850 | 40 MHz | 0..31 x 11.25° |
|
||||
| AD9851 | 70 MHz | 0..31 x 11.25° |
|
||||
| type | max frequency | phase (step size) |
|
||||
|:--------:|:--------------:|:-------------------:|
|
||||
| AD9850 | 40 MHz | 0..31 x 11.25° |
|
||||
| AD9851 | 70 MHz | 0..31 x 11.25° |
|
||||
|
||||
|
||||
Note that at the max frequency the devices do not give a nice sine anymore.
|
||||
Note that at the max frequency the devices do not give a nice sine any more.
|
||||
You need to check what is acceptable for your project.
|
||||
|
||||
The library has a AD9850 as base class that implements the commonalities.
|
||||
@ -64,7 +67,6 @@ Schema break-out
|
||||
L = LED
|
||||
C = chip
|
||||
P = potentiometer => for duty cycle square wave
|
||||
|
||||
```
|
||||
|
||||
|
||||
@ -191,13 +193,17 @@ For the AD9850 => 40 MHz, for the AD9851 => 70 MHz.
|
||||
- Note setFrequencyF is affected by the autoUpdateFlag.
|
||||
The frequency is limited by the MaxFrequency of the class used.
|
||||
Returns false if limited.
|
||||
- **uint32_t getMaxFrequency()** returns the maximum frequency that can be set. For the AD9850 this is 20 MHz.
|
||||
For the AD9851 this is 70 MHz.
|
||||
- **float getFrequency()** returns the frequency set. As it returns a float it might loose some accuracy at higher frequencies.
|
||||
- **uint32_t getMaxFrequency()** returns the maximum frequency that can be set.
|
||||
- For the AD9850 this is 20 MHz.
|
||||
- For the AD9851 this is 70 MHz.
|
||||
- **float getFrequency()** returns the frequency set.
|
||||
As it returns a float it might loose some accuracy at higher frequencies.
|
||||
- **bool setPhase(uint8_t phase = 0)** set the phase in units of 11.25° 0..31 allowed.
|
||||
Default it sets the phase to 0.
|
||||
Returns false if phase > 31, no change to phase in that case.
|
||||
- **uint8_t getPhase()** returns the phase set, 0 by default. One need to multiply by 11.25° to get the actual angle.
|
||||
- **uint8_t getPhase()** returns the phase set, 0 by default.
|
||||
- multiply by 11.25° to get the actual phase angle in degrees.
|
||||
- multiply by (PI \* 0.0625) to get actual phase angle in radians.
|
||||
|
||||
|
||||
### Calibration
|
||||
@ -313,20 +319,28 @@ The user is also responsible to store it e.g. in EEPROM to make it persistent.
|
||||
|
||||
#### Should
|
||||
|
||||
- examples for ESP32 HWSPI interface
|
||||
- do tests on ESP32
|
||||
- performance measurements
|
||||
- unit tests for
|
||||
- bool setFrequency
|
||||
- bool setPhase
|
||||
|
||||
|
||||
#### Could
|
||||
|
||||
- move code to .cpp
|
||||
- create defines for MAGIC numbers (defaults)
|
||||
- should other void function return bool?
|
||||
- setARCCutOffFreq() ?
|
||||
- should **setSPIspeed(uint32_t speed)** return bool?
|
||||
- out of range?
|
||||
|
||||
|
||||
#### Wont
|
||||
|
||||
- **bool setARCCutOffFreq()** no need
|
||||
|
||||
|
||||
## Support
|
||||
|
||||
If you appreciate my libraries, you can support the development and maintenance.
|
||||
Improve the quality of the libraries by providing issues and Pull Requests, or
|
||||
donate through PayPal or GitHub sponsors.
|
||||
|
||||
Thank you,
|
||||
|
||||
|
27
libraries/AD985X/examples/AD9850_ESP32_HWSPI/.arduino-ci.yml
Normal file
27
libraries/AD985X/examples/AD9850_ESP32_HWSPI/.arduino-ci.yml
Normal file
@ -0,0 +1,27 @@
|
||||
platforms:
|
||||
rpipico:
|
||||
board: rp2040:rp2040:rpipico
|
||||
package: rp2040:rp2040
|
||||
gcc:
|
||||
features:
|
||||
defines:
|
||||
- ARDUINO_ARCH_RP2040
|
||||
warnings:
|
||||
flags:
|
||||
|
||||
packages:
|
||||
rp2040:rp2040:
|
||||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
|
||||
|
||||
compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
platforms:
|
||||
# - uno
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
# - m4
|
||||
- esp32
|
||||
# - esp8266
|
||||
# - mega2560
|
||||
# - rpipico
|
@ -0,0 +1,96 @@
|
||||
//
|
||||
// FILE: AD9850_ESP32_HWSPI.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo ESP32 hardware SPI
|
||||
// URL: https://github.com/RobTillaart/AD985X
|
||||
|
||||
|
||||
#include "AD985X.h"
|
||||
|
||||
AD9850 freqGen;
|
||||
|
||||
uint32_t freq = 0;
|
||||
uint32_t prev = 0;
|
||||
uint32_t maxFreq;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("AD985X_LIB_VERSION: \t");
|
||||
Serial.println(AD985X_LIB_VERSION);
|
||||
|
||||
help();
|
||||
|
||||
// Select HW SPI for ESP32
|
||||
freqGen.selectHSPI();
|
||||
freqGen.begin(15, 16, 17); // selectPin, resetPin, FQUDPin
|
||||
|
||||
freqGen.powerUp();
|
||||
maxFreq = freqGen.getMaxFrequency();
|
||||
Serial.println(maxFreq);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (Serial.available() > 0)
|
||||
{
|
||||
int c = Serial.read();
|
||||
switch (c)
|
||||
{
|
||||
case '?' :
|
||||
help();
|
||||
break;
|
||||
case 'R' :
|
||||
freqGen.reset();
|
||||
freq = freqGen.getFrequency();
|
||||
break;
|
||||
case 'P' :
|
||||
freqGen.powerDown();
|
||||
break;
|
||||
case 'U' :
|
||||
freqGen.powerUp();
|
||||
break;
|
||||
case '+' :
|
||||
freq += 1;
|
||||
break;
|
||||
case '-' :
|
||||
freq -= 1;
|
||||
break;
|
||||
case '*' :
|
||||
freq *= 10;
|
||||
break;
|
||||
case '/' :
|
||||
freq /= 10;
|
||||
break;
|
||||
}
|
||||
if (freq > maxFreq) freq = maxFreq;
|
||||
}
|
||||
|
||||
// UPDATE AD985X IF NEW VALUE
|
||||
if (prev != freq)
|
||||
{
|
||||
prev = freq;
|
||||
freqGen.setFrequency(freq);
|
||||
Serial.println(freq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void help()
|
||||
{
|
||||
Serial.println();
|
||||
Serial.println("+ : f = f + 1");
|
||||
Serial.println("- : f = f - 1");
|
||||
Serial.println("* : f = f * 10");
|
||||
Serial.println("/ : f = f / 10");
|
||||
Serial.println("? : help");
|
||||
Serial.println("R : AD9850 reset");
|
||||
Serial.println("P : AD9850 power down");
|
||||
Serial.println("U : AD9850 power up");
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// -- END OF FILE --
|
@ -15,9 +15,9 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/AD985X.git"
|
||||
},
|
||||
"version": "0.3.5",
|
||||
"version": "0.3.6",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
"headers": "AD985X.h"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=AD985X
|
||||
version=0.3.5
|
||||
version=0.3.6
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for AD9850 and AD9851 function generators. Supports both hardware SPI as software SPI.
|
||||
|
@ -74,7 +74,59 @@ unittest(test_auto_update)
|
||||
}
|
||||
|
||||
|
||||
unittest(test_ad9850)
|
||||
unittest(test_ad9850_frequency)
|
||||
{
|
||||
AD9850 funcgen;
|
||||
funcgen.begin(4, 5, 6);
|
||||
|
||||
for (uint32_t freq = 500; freq <= 10000; freq += 500)
|
||||
{
|
||||
funcgen.setFrequency(freq);
|
||||
assertEqual(freq, funcgen.getFrequency());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unittest(test_ad9851_frequency)
|
||||
{
|
||||
AD9851 funcgen;
|
||||
funcgen.begin(4, 5, 6);
|
||||
|
||||
for (uint32_t freq = 500; freq <= 10000; freq += 500)
|
||||
{
|
||||
funcgen.setFrequency(freq);
|
||||
assertEqual(freq, funcgen.getFrequency());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unittest(test_ad9850_frequency_float)
|
||||
{
|
||||
AD9850 funcgen;
|
||||
funcgen.begin(4, 5, 6);
|
||||
|
||||
for (float freq = 1; freq <= 5; freq += 0.31415)
|
||||
{
|
||||
funcgen.setFrequencyF(freq);
|
||||
assertEqualFloat(freq, funcgen.getFrequency(), 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unittest(test_ad9851_frequency_float)
|
||||
{
|
||||
AD9851 funcgen;
|
||||
funcgen.begin(4, 5, 6);
|
||||
|
||||
for (float freq = 1; freq <= 5; freq += 0.31415)
|
||||
{
|
||||
funcgen.setFrequencyF(freq);
|
||||
assertEqualFloat(freq, funcgen.getFrequency(), 0.01);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unittest(test_ad9850_phase)
|
||||
{
|
||||
AD9850 funcgen;
|
||||
funcgen.begin(4, 5, 6);
|
||||
@ -92,7 +144,7 @@ unittest(test_ad9850)
|
||||
}
|
||||
|
||||
|
||||
unittest(test_ad9851)
|
||||
unittest(test_ad9851_phase)
|
||||
{
|
||||
AD9851 funcgen;
|
||||
funcgen.begin(4, 5, 6);
|
||||
@ -215,4 +267,4 @@ unittest(test_ad9851_float_freq)
|
||||
|
||||
unittest_main()
|
||||
|
||||
// --------
|
||||
// END OF FILE --
|
||||
|
Loading…
Reference in New Issue
Block a user