├── .gitignore
├── ADF4350.cpp
├── ADF4350.h
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | desktop.ini
3 | *.swp
4 |
--------------------------------------------------------------------------------
/ADF4350.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | ADF4350.cpp - ADF4350 PLL Communication Library
3 | Created by Neal Pisenti, 2013.
4 | JQI - Strontium - UMD
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | aunsigned long with this program. If not, see .
18 |
19 |
20 | */
21 |
22 | #include "Arduino.h"
23 | #include "SPI.h"
24 | #include
25 |
26 |
27 |
28 | // NOTE: Currently, set up for channel spacing of 10Mhz; might ammend later if needed,
29 | // but this was easy and takes care of forseeable applications...
30 | // This means we'll be operating in int-N mode.
31 | //
32 | // Currently, keep frequency between 140Mhz and 3Ghz.
33 |
34 | /* CONSTRUCTOR */
35 |
36 | // Constructor function; initializes communication pinouts
37 |
38 | ADF4350::ADF4350(byte ssPin) {
39 | _ssPin = ssPin;
40 | pinMode(_ssPin, OUTPUT);
41 | digitalWrite(_ssPin, HIGH);
42 | }
43 |
44 |
45 |
46 |
47 |
48 | // Initializes a new ADF4350 object, with refClk (in Mhz), and initial frequency.
49 | void ADF4350::initialize(int freq, int refClk = 10){
50 | _refClk = refClk;
51 | _phase = 1;
52 |
53 | _feedbackType = 0;
54 | _powerdown = 0;
55 | _auxEnabled = 0;
56 | _rfEnabled = 1;
57 |
58 | // default power = 5dbm
59 | _auxPower = 3;
60 | _rfPower = 3;
61 |
62 | // sets register values which don't have dynamic values...
63 | ADF4350::setR1();
64 | ADF4350::setR3();
65 | ADF4350::setR5();
66 |
67 |
68 | ADF4350::setFreq(freq);
69 | // ADF4350::update();
70 | }
71 |
72 | // gets current frequency setting
73 | int ADF4350::getFreq(){
74 | return _freq;
75 | }
76 |
77 | void ADF4350::setFreq(int freq){
78 | _freq = freq;
79 | int multiplier;
80 |
81 | // selects the right divider range (ie, output divider is 2^(_divider))
82 | // the multiplier is required if you're using fundamental feedback to N-counter
83 | if (_freq <= 270 && _freq >= 140){
84 | _divider = 4;
85 | multiplier = 16;
86 | } else if (_freq >= 280 && _freq <= 540){
87 | _divider = 3;
88 | multiplier = 8;
89 | } else if (_freq >= 550 && _freq <= 1090){
90 | _divider = 2;
91 | multiplier = 4;
92 | } else if (_freq >= 1100 && _freq <= 2190){
93 | _divider = 1;
94 | multiplier = 2;
95 | } else{
96 | _divider = 0;
97 | multiplier = 1;
98 | }
99 |
100 | if (_feedbackType == 0){
101 | _int = _freq/_refClk;
102 | } else{
103 | _int = _freq*multiplier/_refClk;
104 | }
105 | ADF4350::update();
106 | }
107 |
108 |
109 |
110 | // updates dynamic registers, and writes values to PLL board
111 | void ADF4350::update(){
112 | // updates registers with dynamic values...
113 | ADF4350::setR0();
114 | ADF4350::setR2();
115 | ADF4350::setR4();
116 |
117 | // writes registers to device
118 | ADF4350::writeRegister(_r5);
119 | ADF4350::writeRegister(_r4);
120 | ADF4350::writeRegister(_r3);
121 | ADF4350::writeRegister(_r2);
122 | ADF4350::writeRegister(_r1);
123 | ADF4350::writeRegister(_r0);
124 | }
125 |
126 | void ADF4350::setFeedbackType(bool feedback){
127 | _feedbackType = feedback;
128 | }
129 |
130 | void ADF4350::powerDown(bool pd){
131 | _powerdown = pd;
132 | ADF4350::setR2();
133 | ADF4350::update();
134 |
135 | }
136 |
137 | void ADF4350::rfEnable(bool rf){
138 | _rfEnabled = rf;
139 | ADF4350::setR4();
140 | ADF4350::update();
141 | }
142 |
143 | // CAREFUL!!!! pow must be 0, 1, 2, or 3... corresponding to -4, -1, 3, 5 dbm.
144 | void ADF4350::setRfPower(int pow){
145 | _rfPower = pow;
146 | ADF4350::setR4();
147 | ADF4350::update();
148 | }
149 |
150 | void ADF4350::auxEnable(bool aux){
151 | _auxEnabled = aux;
152 | ADF4350::setR4();
153 | ADF4350::update();
154 | }
155 |
156 | // CAREFUL!!!! pow must be 0, 1, 2, or 3... corresponding to -4, -1, 3, 5 dbm.
157 | void ADF4350::setAuxPower(int pow){
158 | _auxPower = pow;
159 | ADF4350::setR4();
160 | ADF4350::update();
161 | }
162 |
163 | // REGISTER UPDATE FUNCTIONS
164 |
165 | void ADF4350::setR0(){
166 | unsigned long r0 = (_int << 15); // sets int value...
167 | byte r0Ary[] = { lowByte(r0 >> 24), lowByte(r0 >> 16), lowByte(r0 >> 8), lowByte(r0) };
168 | memcpy(&_r0, &r0Ary, sizeof(r0Ary));
169 | }
170 |
171 | void ADF4350::setR1(){
172 | unsigned long r1 = (_phase << 15) + // phase value = 1
173 | (2 << 3) + // modulus value = 1
174 | 1; // register value
175 | byte r1Ary[] = { lowByte(r1 >> 24), lowByte(r1 >> 16), lowByte(r1 >> 8), lowByte(r1) };
176 | memcpy(&_r1, &r1Ary, sizeof(r1Ary));
177 | }
178 |
179 | void ADF4350::setR2(){
180 | unsigned long r2 = (6 << 26) + // muxout
181 | (1 << 14) + // r-counter = 1
182 | (7 << 9) + // charge pump = 2.5
183 | (5 << 6) + // digital lock detect + polarity
184 | (_powerdown << 5) + // powerdown 0 = false; 1 = true
185 | 2; // register value
186 |
187 | byte r2Ary[] = { lowByte(r2 >> 24), lowByte(r2 >> 16), lowByte(r2 >> 8), lowByte(r2) };
188 | memcpy(&_r2, &r2Ary, sizeof(r2Ary));
189 | }
190 |
191 | void ADF4350::setR3(){
192 | unsigned long r3 = 3; // (all zero, except register control value = 3);
193 | byte r3Ary[] = { lowByte(r3 >> 24), lowByte(r3 >> 16), lowByte(r3 >> 8), lowByte(r3) };
194 | memcpy(&_r3, &r3Ary, sizeof(r3Ary));
195 | }
196 |
197 | void ADF4350::setR4(){
198 |
199 | unsigned long r4 = (_feedbackType << 23) + // divided/fundamental feedback
200 | (_divider << 20) +
201 | (80 << 12) + // band select clock divider
202 | (0 << 9) + // vco powerdown = false; MTLD = 1; aux output = divided;
203 | (_auxEnabled << 8) + // AUX OUTPUT enable/disable
204 | (_auxPower << 6) + // aux output power = {-4, -1, 2, 5dbm}
205 | (_rfEnabled << 5) + // RF OUTPUT ENABLED
206 | (_rfPower << 3) + // RF output power = 5dbm
207 | 4; // register select
208 |
209 | byte r4Ary[] = { lowByte(r4 >> 24), lowByte(r4 >> 16), lowByte(r4 >> 8), lowByte(r4) };
210 | memcpy(&_r4, &r4Ary, sizeof(r4Ary));
211 |
212 |
213 | }
214 |
215 | void ADF4350::setR5(){
216 |
217 | unsigned long r5 = (1 << 22) + (3<<19) + 5; // lock detect pin mode = digital lock detect
218 | byte r5Ary[] = { lowByte(r5 >> 24), lowByte(r5 >> 16), lowByte(r5 >> 8), lowByte(r5) };
219 | memcpy(&_r5, &r5Ary, sizeof(r5Ary));
220 |
221 | }
222 | // Writes SPI to particular register.
223 | // registerInfo is a 2-element array which contains [register, number of bytes]
224 | void ADF4350::writeRegister(byte data[]){
225 |
226 |
227 | digitalWrite(_ssPin, LOW);
228 |
229 | // Writes the data
230 | for(int i = 0; i < 4 ; i++){
231 | SPI.transfer(data[i]);
232 | }
233 |
234 | digitalWrite(_ssPin, HIGH);
235 |
236 | }
237 |
238 |
--------------------------------------------------------------------------------
/ADF4350.h:
--------------------------------------------------------------------------------
1 | /*
2 | ADF4350.h - ADF4350 PLL Communication Library
3 | Created by Neal Pisenti, 2013.
4 | JQI - Strontium - UMD
5 |
6 | This program is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | This program is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | aunsigned long with this program. If not, see .
18 |
19 |
20 | */
21 |
22 | #ifndef ADF4350_h
23 | #define ADF4350_h
24 |
25 | #include "Arduino.h"
26 |
27 | class ADF4350
28 | {
29 | public:
30 | // Constructor function.
31 | // Creates PLL object, with given SS pin
32 | ADF4350(byte);
33 |
34 | // Initialize with initial frequency, refClk (defaults to 10Mhz);
35 | void initialize(int, int);
36 |
37 |
38 | // powers down the PLL/VCO
39 | void powerDown(bool);
40 | void setRfPower(int);
41 | void setAuxPower(int);
42 | void auxEnable(bool);
43 | void rfEnable(bool);
44 |
45 | // Gets current frequency
46 | int getFreq();
47 |
48 | // Sets frequency
49 | void setFreq(int);
50 |
51 | void setInt(int);
52 |
53 | void setFeedbackType(bool);
54 |
55 | void update();
56 |
57 | unsigned long _phase;
58 | unsigned long _freq, _int, _divider, _refClk, _auxPower, _rfPower;
59 | private:
60 | // Instance variables that hold pinout mapping
61 | byte _ssPin;
62 |
63 | // Instance variables for ...
64 | bool _powerdown, _auxEnabled, _rfEnabled, _feedbackType;
65 |
66 | // register values
67 | byte _r0[4], _r1[4], _r2[4], _r3[4], _r4[4], _r5[4];
68 |
69 |
70 |
71 | // function to write data to register.
72 | void setR0();
73 | void setR1();
74 | void setR2();
75 | void setR3();
76 | void setR4();
77 | void setR5();
78 | void writeRegister(byte[4]);
79 |
80 |
81 |
82 | };
83 |
84 |
85 | #endif
86 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ADF4350
2 |
3 | Communication library to interface with Analog Devices ADF4350 PLL IC. Designed
4 | with the ADF4350 evaluation board in mind.
5 |
6 | ## Getting started
7 |
8 | In your Arduino sketch, you'll want to include the SPI library in addition to this code:
9 |
10 | #include
11 | #include
12 |
13 | #define COM_PIN 32 // sets pin 32 to be the slave-select pin for PLL
14 | ADF4350 PLL(COM_PIN); // declares object PLL of type ADF4350. Will initialize it below.
15 |
16 | void setup(){
17 | SPI.begin(); // for communicating with DDS/PLLs
18 | SPI.setClockDivider(4);
19 | SPI.setDataMode(SPI_MODE0);
20 | delay(500); // give it a sec to warm up
21 |
22 |
23 | PLL.initialize(400, 10); // initialize the PLL to output 400 Mhz, using an
24 | // onboard reference of 10Mhz
25 |
26 | }
27 |
28 |
29 | ### Important note
30 |
31 | The ADF4350 works with 3.3V logic levels, not 5V. Be careful if you're using an Arduino Uno or similar!
32 |
33 | ## Implemented features
34 |
35 | Self-explanatory functions...
36 |
37 | * `ADF4350::initialize(int frequency, int refClk)` -- initializes PLL with given frequency (Mhz) and reference clock frequency (also in Mhz).
38 | * `ADF4350::getFreq()` -- returns current frequency
39 | * `ADF4350::setFreq(int freq)` -- sets PLL to output new frequency `freq` (in MHz).
40 |
41 | Functions you should use after consulting datasheet:
42 |
43 | * `ADF4350::setFeedbackType(bool feedback)` -- fundamental vs. divided feedback
44 | * `ADF4350::powerDown(bool pd)` -- power down the VCO (or not).
45 | * `ADF4350::rfEnable(bool rf)` -- enable/disable output on the main RF output.
46 | * `ADF4350::setRfPower(int pow)` -- `pow` should be 0, 1, 2, or 3, corresponding to -4, -1, 3, or 5 dBm.
47 | * `ADF4350::auxEnable(bool aux)` -- enable/disable output on the auxilary output.
48 | * `ADF4350::setAuxPower(int pow)` -- set auxiliary power output. Again, `pow` should be 0, 1, 2, or 3, corresponding to -4, -1, 3, or 5 dBm.
49 |
--------------------------------------------------------------------------------