11//
22// FILE: AD985X.cpp
33// AUTHOR: Rob Tillaart
4- // VERSION: 0.3.0
4+ // VERSION: 0.3.1
55// DATE: 2019-02-08
66// PURPOSE: Class for AD9850 and AD9851 function generator
77//
1616// inverted SELECT line as preparation for multidevice.
1717// 0.3.0 2021-06-06 fix factory bit mask + new examples + some refactor
1818// added multi device document
19+ // 0.3.1 2021-08-25 VSPI / HSPI support for ESP32
20+ // faster software SPI
21+ // minor optimizations / refactor
1922
2023
2124#include " AD985X.h"
@@ -42,47 +45,82 @@ AD9850::AD9850()
4245
4346void AD9850::begin (uint8_t select, uint8_t resetPin, uint8_t FQUDPin, uint8_t dataOut , uint8_t clock)
4447{
45- _select = select;
46- _reset = resetPin;
47- _fqud = FQUDPin;
48+ _select = select;
49+ _reset = resetPin;
50+ _fqud = FQUDPin;
51+ _dataOut = dataOut;
52+ _clock = clock;
53+ // following 3 are always set.
4854 pinMode (_select, OUTPUT);
4955 pinMode (_reset, OUTPUT);
5056 pinMode (_fqud, OUTPUT);
51- digitalWrite (_select, LOW); // device select = HIGH See - https://github.com/RobTillaart/AD985X/issues/13
57+ // device select = HIGH See - https://github.com/RobTillaart/AD985X/issues/13
58+ digitalWrite (_select, LOW);
5259 digitalWrite (_reset, LOW);
5360 digitalWrite (_fqud, LOW);
54- _useHW = true ;
5561
56- // SW SPI
57- if ((dataOut != 0 ) && (clock != 0 ))
62+ _hwSPI = ((dataOut == 0 ) || (clock == 0 ));
63+
64+ _spi_settings = SPISettings (2000000 , LSBFIRST, SPI_MODE0);
65+
66+ if (_hwSPI)
5867 {
59- _dataOut = dataOut;
60- _clock = clock;
61- pinMode (_dataOut, OUTPUT);
62- pinMode (_clock, OUTPUT);
63- digitalWrite (_dataOut, LOW);
64- digitalWrite (_clock, LOW);
65- _useHW = false ;
68+ #if defined(ESP32)
69+ if (_useHSPI) // HSPI
70+ {
71+ mySPI = new SPIClass (HSPI);
72+ mySPI->end ();
73+ mySPI->begin (14 , 12 , 13 , select); // CLK=14 MISO=12 MOSI=13
74+ }
75+ else // VSPI
76+ {
77+ mySPI = new SPIClass (VSPI);
78+ mySPI->end ();
79+ mySPI->begin (18 , 19 , 23 , select); // CLK=18 MISO=19 MOSI=23
80+ }
81+ #else // generic hardware SPI
82+ mySPI = &SPI;
83+ mySPI->end ();
84+ mySPI->begin ();
85+ #endif
6686 }
67-
68- if (_useHW)
87+ else // software SPI
6988 {
70- SPI.begin (); // set MOSI & MISO pin right.
89+ pinMode (_dataOut, OUTPUT);
90+ pinMode (_clock, OUTPUT);
91+ digitalWrite (_dataOut, LOW);
92+ digitalWrite (_clock, LOW);
7193 }
7294
7395 reset ();
7496}
7597
7698
99+ #if defined(ESP32)
100+ void AD9850::setGPIOpins (uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select)
101+ {
102+ _clock = clk;
103+ _dataOut = mosi;
104+ _select = select;
105+ pinMode (_select, OUTPUT);
106+ digitalWrite (_select, LOW);
107+
108+ mySPI->end (); // disable SPI
109+ mySPI->begin (clk, miso, mosi, select);
110+ }
111+ #endif
112+
113+
77114void AD9850::reset ()
78115{
79- digitalWrite (_select, HIGH); // be sure to select the correct device
116+ // be sure to select the correct device
117+ digitalWrite (_select, HIGH);
80118 pulsePin (_reset);
81- if (_useHW ) pulsePin (SPI_CLOCK);
119+ if (_hwSPI ) pulsePin (SPI_CLOCK);
82120 else pulsePin (_clock);
83121 digitalWrite (_select, LOW);
84122
85- _config = 0 ; // 0 phase no powerdown
123+ _config = 0 ; // 0 phase no power down
86124 _freq = 0 ;
87125 _factor = 0 ;
88126 _offset = 0 ;
@@ -121,6 +159,13 @@ void AD9850::pulsePin(uint8_t pin)
121159}
122160
123161
162+ void AD9850::setSPIspeed (uint32_t speed)
163+ {
164+ _SPIspeed = speed;
165+ _spi_settings = SPISettings (_SPIspeed, LSBFIRST, SPI_MODE0);
166+ };
167+
168+
124169void AD9850::writeData ()
125170{
126171 // Serial.println(_factor, HEX);
@@ -129,17 +174,17 @@ void AD9850::writeData()
129174
130175 // used for multidevice config only - https://github.com/RobTillaart/AD985X/issues/13
131176 digitalWrite (_select, HIGH);
132- if (_useHW )
177+ if (_hwSPI )
133178 {
134- SPI. beginTransaction (SPISettings ( 2000000 , LSBFIRST, SPI_MODE0) );
135- SPI. transfer (data & 0xFF );
179+ mySPI-> beginTransaction (_spi_settings );
180+ mySPI-> transfer (data & 0xFF );
136181 data >>= 8 ;
137- SPI. transfer (data & 0xFF );
182+ mySPI-> transfer (data & 0xFF );
138183 data >>= 8 ;
139- SPI. transfer (data & 0xFF );
140- SPI. transfer (data >> 8 );
141- SPI. transfer (_config & 0xFC ); // mask factory test bit
142- SPI. endTransaction ();
184+ mySPI-> transfer (data & 0xFF );
185+ mySPI-> transfer (data >> 8 );
186+ mySPI-> transfer (_config & 0xFC ); // mask factory test bit
187+ mySPI-> endTransaction ();
143188 }
144189 else
145190 {
@@ -160,14 +205,16 @@ void AD9850::writeData()
160205
161206
162207// simple one mode version
163- void AD9850::swSPI_transfer (uint8_t value )
208+ void AD9850::swSPI_transfer (uint8_t val )
164209{
210+ uint8_t clk = _clock;
211+ uint8_t dao = _dataOut;
165212 // for (uint8_t mask = 0x80; mask; mask >>= 1) // MSBFIRST
166213 for (uint8_t mask = 0x01 ; mask; mask <<= 1 ) // LSBFIRST
167214 {
168- digitalWrite (_dataOut,(value & mask) != 0 );
169- digitalWrite (_clock , HIGH);
170- digitalWrite (_clock , LOW);
215+ digitalWrite (dao, (val & mask));
216+ digitalWrite (clk , HIGH);
217+ digitalWrite (clk , LOW);
171218 }
172219}
173220
0 commit comments