0.1.0 AD9833

This commit is contained in:
Rob Tillaart 2023-08-27 20:28:30 +02:00
parent 5dd75883af
commit cd94d589b2
19 changed files with 1084 additions and 0 deletions

View File

@ -0,0 +1,28 @@
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

4
libraries/AD9833/.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
github: RobTillaart

View File

@ -0,0 +1,13 @@
name: Arduino-lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: arduino/arduino-lint-action@v1
with:
library-manager: update
compliance: strict

View File

@ -0,0 +1,17 @@
---
name: Arduino CI
on: [push, pull_request]
jobs:
runTest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- run: |
gem install arduino_ci
arduino_ci.rb

View File

@ -0,0 +1,18 @@
name: JSON check
on:
push:
paths:
- '**.json'
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: json-syntax-check
uses: limitusus/json-syntax-check@v1
with:
pattern: "\\.json$"

303
libraries/AD9833/AD9833.cpp Normal file
View File

@ -0,0 +1,303 @@
//
// FILE: AD9833.cpp
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for AD9833 function generator
// VERSION: 0.1.0
// URL: https://github.com/RobTillaart/AD9833
//
#include "AD9833.h"
// CONTROL REGISTER BITS
#define AD9833_B28 (1 << 13)
#define AD9833_HLB (1 << 12)
#define AD9833_FSELECT (1 << 11)
#define AD9833_PSELECT (1 << 10)
#define AD9833_RESET (1 << 8)
#define AD9833_SLEEP1 (1 << 7)
#define AD9833_SLEEP12 (1 << 6)
#define AD9833_OPBITEN (1 << 5)
#define AD9833_DIV2 (1 << 3)
#define AD9833_MODE (1 << 1)
AD9833::AD9833()
{
}
void AD9833::begin(uint8_t selectPin, uint8_t dataPin, uint8_t clockPin)
{
_selectPin = selectPin;
_dataPin = dataPin;
_clockPin = clockPin;
pinMode(_selectPin, OUTPUT);
digitalWrite(_selectPin, HIGH);
_hwSPI = ((dataPin == 0) || (clockPin == 0));
_spi_settings = SPISettings(8000000, MSBFIRST, SPI_MODE2);
if (_hwSPI)
{
#if defined(ESP32)
if (_useHSPI) // HSPI
{
mySPI = new SPIClass(HSPI);
mySPI->end();
mySPI->begin(14, 12, 13, selectPin); // CLK = 14 MISO = 12 MOSI = 13
}
else // VSPI
{
mySPI = new SPIClass(VSPI);
mySPI->end();
mySPI->begin(18, 19, 23, selectPin); // CLK = 18 MISO = 19 MOSI = 23
}
#else // generic hardware SPI
mySPI = &SPI;
mySPI->end();
mySPI->begin();
#endif
}
else // software SPI
{
pinMode(_dataPin, OUTPUT);
pinMode(_clockPin, OUTPUT);
digitalWrite(_dataPin, LOW);
digitalWrite(_clockPin, LOW);
}
reset();
}
void AD9833::begin(uint8_t selectPin, SPIClass * spi)
{
_selectPin = selectPin;
pinMode(_selectPin, OUTPUT);
digitalWrite(_selectPin, HIGH);
_hwSPI = true;
_spi_settings = SPISettings(8000000, MSBFIRST, SPI_MODE2);
mySPI = spi;
mySPI->end();
mySPI->begin();
reset();
}
void AD9833::reset()
{
setWave(AD9833_OFF);
setFrequency(1000, 0);
setFrequency(1000, 1);
setPhase(0, 0);
setPhase(0, 1);
}
void AD9833::setWave(uint8_t waveType)
{
if (waveType > 4) return;
// store wave type
_waveType = waveType;
// clear bits in control register
_control &= ~(AD9833_SLEEP1 | AD9833_SLEEP12 | AD9833_OPBITEN | AD9833_MODE);
// set bits in control register
switch(_waveType)
{
case AD9833_OFF:
_control |= (AD9833_SLEEP1 | AD9833_SLEEP12);
break;
case AD9833_SINE:
// no bits need to set
break;
case AD9833_SQUARE1:
_control |= (AD9833_DIV2 | AD9833_OPBITEN);
break;
case AD9833_SQUARE2:
_control |= (AD9833_OPBITEN);
break;
case AD9833_TRIANGLE:
_control |= (AD9833_MODE);
break;
}
writeControlRegister(_control);
}
uint8_t AD9833::getWave()
{
return _waveType;
}
float AD9833::setFrequency(float freq, uint8_t channel)
{
if (channel > 1) return -1;
_freq[channel] = freq;
if (_freq[channel] > AD9833_MAX_FREQ) _freq[channel] = AD9833_MAX_FREQ;
if (_freq[channel] < 0) _freq[channel] = 0;
// convert to bit pattern
// fr = round(freq * pow(2, 28) / 25 MHz));
// rounding
uint32_t fr = (_freq[channel] * (268435456.0 / 25000000.0) + 0.5);
_control |= AD9833_B28;
writeControlRegister(_control);
writeFreqRegister(channel, fr);
return _freq[channel];
}
float AD9833::getFrequency(uint8_t channel)
{
return _freq[channel];
}
float AD9833::getMaxFrequency()
{
return AD9833_MAX_FREQ;
}
void AD9833::setFrequencyChannel(uint8_t channel)
{
if (channel > 1) return;
if (channel == 0) _control &= ~AD9833_FSELECT;
if (channel == 1) _control |= AD9833_FSELECT;
writeControlRegister(_control);
}
float AD9833::setPhase(float phase, uint8_t channel)
{
if (channel > 1) return -1;
_phase[channel] = phase;
while (_phase[channel] >= AD9833_MAX_PHASE) _phase[channel] -= AD9833_MAX_PHASE;
while (_phase[channel] < 0) _phase[channel] += AD9833_MAX_PHASE;
uint16_t ph = _phase[channel] * (4095.0 / 360.0);
writePhaseRegister(channel, ph);
return _phase[channel];
}
float AD9833::getPhase(uint8_t channel)
{
return _phase[channel];
}
float AD9833::getMaxPhase()
{
return AD9833_MAX_PHASE;
}
void AD9833::setPhaseChannel(uint8_t channel)
{
if (channel > 1) return;
if (channel == 0) _control &= ~AD9833_PSELECT;
if (channel == 1) _control |= AD9833_PSELECT;
writeControlRegister(_control);
}
void AD9833::setSPIspeed(uint32_t speed)
{
_SPIspeed = speed;
_spi_settings = SPISettings(_SPIspeed, MSBFIRST, SPI_MODE2);
}
uint32_t AD9833::getSPIspeed()
{
return _SPIspeed;
}
bool AD9833::usesHWSPI()
{
return _hwSPI;
}
////////////////////////////////////////////////////////////////
//
// PRIVATE
//
void AD9833::writeControlRegister(uint16_t value)
{
uint16_t data = value & 0x3FFF; // bit 15 and 14 == 00
writeData(data);
}
void AD9833::writeFreqRegister(uint8_t reg, uint32_t freq)
{
uint16_t data = 0;
if (reg > 1) return;
if (reg == 0) data = 0x4000; // bit 15 and 14 01
if (reg == 1) data = 0x8000; // bit 15 and 14 10
// 28 bits in two sets of 14
data |= (freq & 0x3FFF);
writeData(data);
data &= 0xC000;
data |= (freq >> 14);
writeData(data);
}
void AD9833::writePhaseRegister(uint8_t reg, uint16_t value)
{
uint16_t data = 0;
if (reg > 1) return;
if (reg == 0) data = 0xC000; // bit 15 and 14 and 13 110
if (reg == 1) data = 0xE000; // bit 15 and 14 and 13 111
data |= (value & 0x0FFF);
writeData(data);
}
void AD9833::writeData(uint16_t data)
{
digitalWrite(_selectPin, LOW);
if (_hwSPI)
{
mySPI->beginTransaction(_spi_settings);
mySPI->transfer16(data);
mySPI->endTransaction();
}
else
{
// local variables is fast.
uint8_t clk = _clockPin;
uint8_t dao = _dataPin;
// MSBFIRST
for (uint16_t mask = 0x8000; mask; mask >>= 1)
{
digitalWrite(dao, (data & mask));
digitalWrite(clk, LOW);
digitalWrite(clk, HIGH);
}
digitalWrite(dao, LOW);
}
digitalWrite(_selectPin, HIGH);
}
// -- END OF FILE --

111
libraries/AD9833/AD9833.h Normal file
View File

@ -0,0 +1,111 @@
#pragma once
//
// FILE: AD9833.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for AD9833 function generator.
// VERSION: 0.1.0
// URL: https://github.com/RobTillaart/AD9833
#include "Arduino.h"
#include "SPI.h"
#define AD9833_LIB_VERSION (F("0.1.0"))
#define AD9833_MAX_FREQ (12500000UL) // 12.5 MHz.
#define AD9833_MAX_PHASE (360.0)
// MODE OPERANDI
#define AD9833_OFF 0
#define AD9833_SINE 1
#define AD9833_SQUARE1 2
#define AD9833_SQUARE2 3
#define AD9833_TRIANGLE 4
class AD9833
{
public:
AD9833();
// selectPin == fsyncPin
void begin(uint8_t selectPin, uint8_t dataPin = 0, uint8_t clockPin = 0);
void begin(uint8_t selectPin, SPIClass * spi);
void reset();
void setWave(uint8_t wave = AD9833_OFF);
uint8_t getWave();
// returns frequency set
// 0 .. 12.5 MHz == AD9833_MAX_FREQ
float setFrequency(float freq, uint8_t channel = 0);
float getFrequency(uint8_t channel = 0);
float getMaxFrequency();
void setFrequencyChannel(uint8_t channel);
// returns phase set
// [0 .. 360>
float setPhase(float phase, uint8_t channel = 0);
float getPhase(uint8_t channel = 0);
float getMaxPhase();
void setPhaseChannel(uint8_t channel);
// Hardware SPI settings
void setSPIspeed(uint32_t speed); // speed in Hz
uint32_t getSPIspeed();
bool usesHWSPI();
// ESP32 specific
#if defined(ESP32)
void selectHSPI() { _useHSPI = true; };
void selectVSPI() { _useHSPI = false; };
bool usesHSPI() { return _useHSPI; };
bool usesVSPI() { return !_useHSPI; };
// to overrule ESP32 default hardware pins
void setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select);
#endif
private:
void writeControlRegister(uint16_t value);
void writeFreqRegister(uint8_t reg, uint32_t freq);
void writePhaseRegister(uint8_t reg, uint16_t value);
void writeData(uint16_t data);
bool _hwSPI = true;
uint32_t _SPIspeed = 8000000;
SPIClass * mySPI;
SPISettings _spi_settings;
#if defined(ESP32)
bool _useHSPI = true;
#endif
// PINS
uint8_t _dataPin = 0;
uint8_t _clockPin = 0;
uint8_t _selectPin = 0;
// SIGNAL
uint16_t _control = 0;
uint8_t _waveType = AD9833_OFF;
float _freq[2] = { 1000, 1000 }; // Hz
float _phase[2] = { 0, 0 }; // angle
};
// -- END OF FILE --

View File

@ -0,0 +1,11 @@
# Change Log AD9833
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.1.0] - 2023-08-25
- initial version

21
libraries/AD9833/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023-2023 Rob Tillaart
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 THE
AUTHORS OR COPYRIGHT HOLDERS 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.

209
libraries/AD9833/README.md Normal file
View File

@ -0,0 +1,209 @@
[![Arduino CI](https://github.com/RobTillaart/AD9833/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/AD9833/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/AD9833/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/AD9833/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/AD9833/actions/workflows/jsoncheck.yml)
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/AD9833.svg)](https://github.com/RobTillaart/AD9833/issues)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/AD9833/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/AD9833.svg?maxAge=3600)](https://github.com/RobTillaart/AD9833/releases)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/AD9833.svg)](https://registry.platformio.org/libraries/robtillaart/AD9833)
# AD9833
Arduino library for AD9833 function generator.
## Description
Experimental library for the AD9833 function generator.
The library supports both hardware SPI and software SPI.
TODO: test with hardware.
The AD9833 is a signal generator that has two channels for frequency and
two channels for the phase. These channels can be set separately to give
maximum flexibility.
The AD9833 can generate three types of wave: sine, square (2x) and triangle.
The frequency of the waves cover a range from 0 to 12.5 MHz.
The step size for frequency is ~0.1 Hz (using 25 MHz reference clock).
The library also can set the phase of each wave from 0° to 360°.
The step size for phase is ~0.1°.
| type | freq max | freq step | phase | phase step |
|:--------:|:----------:|:-----------:|:--------:|:-----------:|
| AD9833 | 12.5 MHz | 0.1 Hz | 0..360 | 0.1° |
#### Related
- https://github.com/RobTillaart/AD985X
- https://github.com/RobTillaart/functionGenerator
## Connection
Schema AD9833 chip, breakout will have different pins.
```
TOP VIEW
+-----------+
COMP | 1 10 | VOUT
VDD | 2 9 | A-GND
CAP / 2.5 V | 3 8 | FSYNC (select)
D-GND | 4 7 | SCLK
MCLK | 5 6 | SDATA
+-----------+
```
| PIN | Description |
|:--------------|:---------------------|
| COMP | DAC Bias Pin |
| VDD | Power supply |
| CAP / 2.5 V | (datasheet) |
| D-GND | Digital Ground |
| MCLK | Digital Clock Input |
| SDATA | Serial Data In |
| SCLK | Serial Clock In |
| FSYNC | Select |
| A-GND | Analog Ground |
| VOUT | Analog Out |
Read datasheet for detailed description of the pins.
## Interface
```cpp
#include "AD9833.h"
```
#### Constructor
- **AD9833()** 12.5 MHz signal generator
- **void begin(uint8_t selectPin, uint8_t dataPin = 0, uint8_t clockPin = 0)**
For hardware SPI only use the first two parameters,
for SW SPI you need to define the data and clock pin too.
- selectPin = chip select.
- **void begin(uint8_t selectPin, SPIClass \* spi)**
For hardware SPI only, to select a specific hardware SPI port e.g. SPI2.
- **void reset()** resets the function generator.
#### Wave
- **void setWave(uint8_t wave)**
- **uint8_t getWave()**
| wave type | define name | value | notes |
|:-----------:|:-----------------:|:-------:|:--------|
| No output | AD9833_OFF | 0 |
| Sine | AD9833_SINE | 1 |
| Square | AD9833_SQUARE1 | 2 |
| Square2 | AD9833_SQUARE2 | 3 | half frequency
| Triangle | AD9833_TRIANGLE | 4 |
#### Frequency
Default channel is 0, which makes the function calls simpler
when only using one channel.
- **float setFrequency(float freq, uint8_t channel = 0)**
SetFrequency sets the frequency and is limited by the MaxFrequency of 12.5 MHz.
Returns the frequency set.
- **float getFrequency(uint8_t channel = 0)** returns the frequency set.
- **float getMaxFrequency()** returns the maximum frequency to set (convenience).
- **void selectFreqChannel(uint8_t channel)** select the active frequency channel (0 or 1).
#### Phase
Default channel is 0, which makes the function calls simpler
when only using one channel.
- **float setPhase(float phase, uint8_t channel = 0)**
setPhase sets the phase and is limited to 0° - 360°.
Returns the phase set.
- **float getPhase(uint8_t channel = 0)** returns the phase set.
- **float getMaxPhase()** returns the maximum phase to set (convenience).
- **void selectPhaseChannel(uint8_t channel)** select the active phase channel (0 or 1).
#### Hardware SPI
To be used only if one needs a specific speed.
- **void setSPIspeed(uint32_t speed)** set SPI transfer rate.
- **uint32_t getSPIspeed()** returns SPI transfer rate.
- **bool usesHWSPI()** returns true if HW SPI is used.
#### ESP32 specific
- **void selectHSPI()** in case hardware SPI, the ESP32 has two options HSPI and VSPI.
- **void selectVSPI()** see above.
- **bool usesHSPI()** returns true if HSPI is used.
- **bool usesVSPI()** returns true if VSPI is used.
The **selectVSPI()** or the **selectHSPI()** needs to be called
BEFORE the **begin()** function.
- **void setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select)**
to overrule ESP32 default hardware pins (to be tested).
Needs to be called AFTER the **begin()** function.
In code, something like this (TODO write example)
```cpp
void setup()
{
freqGen.selectVSPI();
freqGen.begin(15);
freqGen.setGPIOpins(CLK, MISO, MOSI, SELECT); // SELECT should match the parameter of begin()
...
}
```
## Future
#### Must
- test with hardware
- update documentation
#### Should
- examples
- for ESP32 HWSPI interface
- use of channels (freq & phase)
- do tests on ESP32
- performance measurements
#### Could
- extend unit tests
- move code to .cpp
- solve MAGIC numbers (defaults)
- setting half freq register for performance mode.
- investigate different power down / sleep modi (page 16)
- investigate hardware reset (page 16)
#### Wont
## 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,

View File

@ -0,0 +1,35 @@
//
// FILE: AD9833_1000_Hz.ino
// AUTHOR: Rob Tillaart
// DATE: 2023-08-25
// PURPOSE: create a 1000 Hz reference signal
#include "AD9833.h"
AD9833 AD;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
AD.begin(10);
AD.setFrequency(1000, 0);
Serial.println(AD.getFrequency(0));
AD.setFrequencyChannel(0);
AD.setPhase(0, 0);
Serial.println(AD.getPhase(0));
AD.setPhaseChannel(0);
AD.setWave(AD9833_SINE);
Serial.println(AD.getWave());
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,29 @@
//
// FILE: AD9833_minimal.ino
// AUTHOR: Rob Tillaart
// DATE: 2023-08-25
// PURPOSE: demo AD9833 wave form generator
#include "AD9833.h"
AD9833 AD;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
AD.begin(10); // HW SPI, select pin 10
AD.setFrequency(1000, 0);
AD.setWave(AD9833_SQUARE1);
Serial.println(AD.getWave());
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,55 @@
//
// FILE: AD9833_performance.ino
// AUTHOR: Rob Tillaart
// DATE: 2023-08-25
// PURPOSE: demo AD9833 wave form generator
#include "AD9833.h"
AD9833 AD;
uint32_t start, stop;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
delay(10);
AD.begin(7, 8, 9); // software SPI
// AD.begin(10); // hardware SPI
Serial.print("hardware:\t");
Serial.println(AD.usesHWSPI());
delay(10);
start = micros();
AD.setFrequency(1000, 0);
stop = micros();
Serial.print("setFrequency:\t");
Serial.println(stop - start);
delay(10);
start = micros();
AD.setPhase(45, 0);
stop = micros();
Serial.print("setPhase:\t");
Serial.println(stop - start);
delay(10);
start = micros();
AD.setWave(AD9833_SQUARE1);
stop = micros();
Serial.print("setWave:\t");
Serial.println(stop - start);
delay(10);
}
void loop()
{
}
// -- END OF FILE --

View File

@ -0,0 +1,19 @@
Board: ESP32 (240 Mhz)
IDE: 1.8.19
AD9833_performance.ino
hardware: 1
setFrequency: 32
setPhase: 11
setWave: 13
hardware: 0 (software SPI)
setFrequency: 22
setPhase: 8
setWave: 10

View File

@ -0,0 +1,17 @@
Board: UNO
IDE: 1.8.19
AD9833_performance.ino
hardware: 1
setFrequency: 56
setPhase: 48
setWave: 20
hardware: 0 (software SPI)
setFrequency: 640
setPhase: 244
setWave: 212

View File

@ -0,0 +1,45 @@
# Syntax Colouring Map For AD9833
# Data types (KEYWORD1)
AD9833 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
reset KEYWORD2
setWave KEYWORD2
getWave KEYWORD2
setFrequency KEYWORD2
getFrequency KEYWORD2
getMaxFrequency KEYWORD2
setFrequencyChannel KEYWORD2
setPhase KEYWORD2
getPhase KEYWORD2
getMaxPhase KEYWORD2
setPhaseChannel KEYWORD2
setSPIspeed KEYWORD2
getSPIspeed KEYWORD2
usesHWSPI KEYWORD2
selectHSPI KEYWORD2
selectVSPI KEYWORD2
usesHSPI KEYWORD2
usesVSPI KEYWORD2
setGPIOpins KEYWORD2
# Constants (LITERAL1)
AD9833_LIB_VERSION LITERAL1
AD9833_MAX_FREQ LITERAL1
AD9833_MAX_PHASE LITERAL1
AD9833_OFF LITERAL1
AD9833_SINE LITERAL1
AD9833_SQUARE1 LITERAL1
AD9833_SQUARE2 LITERAL1
AD9833_TRIANGLE LITERAL1

View File

@ -0,0 +1,23 @@
{
"name": "AD9833",
"keywords": "wave,frequency,sinus,square,triangle,generator",
"description": "Arduino library for AD9833 function generator.",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/AD9833.git"
},
"version": "0.1.0",
"license": "MIT",
"frameworks": "*",
"platforms": "*",
"headers": "AD9833.h"
}

View File

@ -0,0 +1,11 @@
name=AD9833
version=0.1.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for AD9833 function generator. Supports both hardware SPI as software SPI.
paragraph=
category=Signal Input/Output
url=https://github.com/RobTillaart/AD9833
architectures=*
includes=AD9833.h
depends=

View File

@ -0,0 +1,115 @@
//
// FILE: unit_test_001.cpp
// AUTHOR: Rob Tillaart
// DATE: 2023-08-27
// PURPOSE: unit tests for the AD9833 function generator
// https://github.com/RobTillaart/AD9833
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
//
// supported assertions
// ----------------------------
// assertEqual(expected, actual)
// assertNotEqual(expected, actual)
// assertLess(expected, actual)
// assertMore(expected, actual)
// assertLessOrEqual(expected, actual)
// assertMoreOrEqual(expected, actual)
// assertTrue(actual)
// assertFalse(actual)
// assertNull(actual)
#include <ArduinoUnitTests.h>
#include "Arduino.h"
#include "AD9833.h"
unittest_setup()
{
fprintf(stderr, "AD9833_LIB_VERSION: %s\n", AD9833_LIB_VERSION);
}
unittest_teardown()
{
}
unittest(test_constants)
{
assertEqual(12500000UL, AD9833_MAX_FREQ);
assertEqual(360, AD9833_MAX_PHASE);
assertEqual(0, AD9833_OFF);
assertEqual(1, AD9833_SINE);
assertEqual(2, AD9833_SQUARE1);
assertEqual(3, AD9833_SQUARE2);
assertEqual(4, AD9833_TRIANGLE);
}
unittest(test_constructor)
{
AD9833 funcgen;
AD9833 fgsw;
funcgen.begin(10);
fgsw.begin(4,5,6);
assertEqual(AD9833_MAX_FREQ, funcgen.getMaxFrequency());
assertEqual(AD9833_MAX_PHASE, funcgen.getMaxPhase());
assertTrue(funcgen.usesHWSPI());
assertFalse(fgsw.usesHWSPI());
}
unittest(test_wave)
{
AD9833 funcgen;
funcgen.begin(4, 5, 6);
for (long wave = 0; wave < 5; wave++)
{
funcgen.setWave(wave);
int w = funcgen.getWave();
assertEqual(w, wave);
}
}
unittest(test_frequency)
{
AD9833 funcgen;
funcgen.begin(4, 5, 6);
for (long freq = 0; freq < 10000000; freq += 1000000)
{
funcgen.setFrequency(freq);
long fr = funcgen.getFrequency();
assertEqual(fr, freq);
}
}
unittest(test_phase)
{
AD9833 funcgen;
funcgen.begin(4, 5, 6);
for (int ph = 0; ph < 360; ph += 30)
{
funcgen.setPhase(ph);
int phase = funcgen.getPhase();
assertEqual(ph, phase);
}
}
unittest_main()
// -- END OF FILE --