22// FILE: AD520X.cpp
33// AUTHOR: Rob Tillaart
44// DATE: 2020-07-24
5- // VERSION: 0.1.1
5+ // VERSION: 0.1.2
66// PURPOSE: Arduino library for AD5204 and AD5206 digital potentiometers (+ older AD8400, AD8402, AD8403)
77// URL: https://github.com/RobTillaart/AD520X
88//
99// HISTORY:
10- // 0.0.1 2020-07-24 initial version
11- // 0.0.2 2020-07-25 support for AD8400 series in documentation.
12- // 0.1.0 2020-07-26 refactor, fix #2 select pin for HW SPI; add shutdown.
13- // 0.1.1 2020-12-08 Arduino-CI + unit test + isPowerOn()
10+ // 0.0.1 2020-07-24 initial version
11+ // 0.0.2 2020-07-25 support for AD8400 series in documentation.
12+ // 0.1.0 2020-07-26 refactor, fix #2 select pin for HW SPI; add shutdown.
13+ // 0.1.1 2020-12-08 Arduino-CI + unit test + isPowerOn()
14+ // 0.1.2 2021-08-19 VSPI / HSPI support for ESP32 only
15+ // add setGPIOpins for ESP32 only
16+ // add SetSPIspeed (generic)
1417
1518
1619#include " AD520X.h"
@@ -20,13 +23,14 @@ AD520X::AD520X(uint8_t select, uint8_t reset, uint8_t shutdown, uint8_t dataOut,
2023{
2124 _pmCount = 6 ;
2225 _select = select;
23- _data = dataOut;
26+ _dataOut = dataOut;
2427 _clock = clock;
2528 _reset = reset;
2629 _shutdown = shutdown;
2730 _hwSPI = (dataOut == 255 ) && (clock == 255 );
2831}
2932
33+
3034// initializes the pins and starts SPI in case of hardware SPI
3135void AD520X::begin (uint8_t value)
3236{
@@ -37,29 +41,65 @@ void AD520X::begin(uint8_t value)
3741 pinMode (_shutdown, OUTPUT);
3842 digitalWrite (_shutdown, LOW);
3943
44+ _spi_settings = SPISettings (_SPIspeed, MSBFIRST, SPI_MODE1);
45+
4046 if (_hwSPI)
4147 {
42- SPI.begin ();
48+ #if defined(ESP32)
49+ if (_useHSPI) // HSPI
50+ {
51+ mySPI = new SPIClass (HSPI);
52+ mySPI->end ();
53+ mySPI->begin (14 , 12 , 13 , _select); // CLK=14 MISO=12 MOSI=13
54+ }
55+ else // VSPI
56+ {
57+ mySPI = new SPIClass (VSPI);
58+ mySPI->end ();
59+ mySPI->begin (18 , 19 , 23 , _select); // CLK=18 MISO=19 MOSI=23
60+ }
61+ #else // generic hardware SPI
62+ mySPI = &SPI;
63+ mySPI->end ();
64+ mySPI->begin ();
65+ #endif
4366 delay (1 );
4467 }
4568 else
4669 {
47- pinMode (_data , OUTPUT);
48- pinMode (_clock, OUTPUT);
49- digitalWrite (_data , LOW);
50- digitalWrite (_clock, LOW);
70+ pinMode (_dataOut , OUTPUT);
71+ pinMode (_clock, OUTPUT);
72+ digitalWrite (_dataOut , LOW);
73+ digitalWrite (_clock, LOW);
5174 }
5275
5376 setAll (value);
5477}
5578
79+
80+ #if defined(ESP32)
81+ void AD520X::setGPIOpins (uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select)
82+ {
83+ _clock = clk;
84+ _dataOut = mosi;
85+ _select = select;
86+ pinMode (_select, OUTPUT);
87+ digitalWrite (_select, HIGH);
88+
89+ mySPI->end (); // disable SPI and restart
90+ mySPI->begin (clk, miso, mosi, select);
91+ }
92+ #endif
93+
94+
5695void AD520X::setValue (uint8_t pm, uint8_t value)
5796{
5897 if (pm >= _pmCount) return ;
5998 _value[pm] = value;
6099 updateDevice (pm);
61100}
62101
102+
63103void AD520X::setAll (uint8_t value)
64104{
65105 for (uint8_t pm = 0 ; pm < _pmCount; pm++)
@@ -68,77 +108,98 @@ void AD520X::setAll(uint8_t value)
68108 }
69109}
70110
111+
71112uint8_t AD520X::getValue (uint8_t pm)
72113{
73114 if (pm >= _pmCount) return 0 ;
74115 return _value[pm];
75116}
76117
118+
77119void AD520X::reset (uint8_t value)
78120{
79121 digitalWrite (_reset, HIGH);
80122 digitalWrite (_reset, LOW);
81123 setAll (value);
82124}
83125
126+
127+ void AD520X::setSPIspeed (uint32_t speed)
128+ {
129+ _SPIspeed = speed;
130+ _spi_settings = SPISettings (_SPIspeed, MSBFIRST, SPI_MODE1);
131+ };
132+
133+
134+ // ///////////////////////////////////////////////////////////////////////////
135+ //
136+ // PROTECTED
137+ //
84138void AD520X::updateDevice (uint8_t pm)
85139{
140+ digitalWrite (_select, LOW);
86141 if (_hwSPI)
87142 {
88- SPI.beginTransaction (SPISettings (16000000 , MSBFIRST, SPI_MODE1));
89- digitalWrite (_select, LOW);
90- SPI.transfer (pm);
91- SPI.transfer (_value[pm]);
92- digitalWrite (_select, HIGH);
93- SPI.endTransaction ();
143+ mySPI->beginTransaction (_spi_settings);
144+ mySPI->transfer (pm);
145+ mySPI->transfer (_value[pm]);
146+ mySPI->endTransaction ();
94147 }
95148 else // Software SPI
96149 {
97- digitalWrite (_select, LOW);
98150 swSPI_transfer (pm);
99151 swSPI_transfer (_value[pm]);
100- digitalWrite (_select, HIGH);
101152 }
153+ digitalWrite (_select, HIGH);
102154}
103155
156+
104157// simple one mode version
105- void AD520X::swSPI_transfer (uint8_t value )
158+ void AD520X::swSPI_transfer (uint8_t val )
106159{
160+ uint8_t clk = _clock;
161+ uint8_t dao = _dataOut;
107162 for (uint8_t mask = 0x80 ; mask; mask >>= 1 )
108163 {
109- digitalWrite (_data,(value & mask) != 0 );
110- digitalWrite (_clock , HIGH);
111- digitalWrite (_clock , LOW);
164+ digitalWrite (dao,(val & mask));
165+ digitalWrite (clk , HIGH);
166+ digitalWrite (clk , LOW);
112167 }
113168}
114169
115170
116171// ///////////////////////////////////////////////////////////////////////////
117-
172+ //
173+ // DERIVED CLASSES
174+ //
118175AD5206::AD5206 (uint8_t select, uint8_t reset, uint8_t shutdown, uint8_t dataOut, uint8_t clock)
119176 : AD520X(select, reset, shutdown, dataOut, clock)
120177{
121178 _pmCount = 6 ;
122179}
123180
181+
124182AD5204::AD5204 (uint8_t select, uint8_t reset, uint8_t shutdown, uint8_t dataOut, uint8_t clock)
125183 : AD520X(select, reset, shutdown, dataOut, clock)
126184{
127185 _pmCount = 4 ;
128186}
129187
188+
130189AD8403::AD8403 (uint8_t select, uint8_t reset, uint8_t shutdown, uint8_t dataOut, uint8_t clock)
131190 : AD520X(select, reset, shutdown, dataOut, clock)
132191{
133192 _pmCount = 4 ;
134193}
135194
195+
136196AD8402::AD8402 (uint8_t select, uint8_t reset, uint8_t shutdown, uint8_t dataOut, uint8_t clock)
137197 : AD520X(select, reset, shutdown, dataOut, clock)
138198{
139199 _pmCount = 2 ;
140200}
141201
202+
142203AD8400::AD8400 (uint8_t select, uint8_t reset, uint8_t shutdown, uint8_t dataOut, uint8_t clock)
143204 : AD520X(select, reset, shutdown, dataOut, clock)
144205{
0 commit comments