1 #include "max2871.h"
2 #include "max2871_regs.h"
3
4 #if (defined DEBUG)
5 #include <stdio.h>
6 #define LOG printf
7 #else
8 #define LOG(x,...)
9 #include <libopencm3/lpc43xx/ssp.h>
10 #include <libopencm3/lpc43xx/scu.h>
11 #include "hackrf_core.h"
12 #endif
13
14 #include <stdint.h>
15 #include <string.h>
16
17 static void max2871_spi_write(max2871_driver_t* const drv, uint8_t r, uint32_t v);
18 static void max2871_write_registers(max2871_driver_t* const drv);
19 static void delay_ms(int ms);
20
max2871_setup(max2871_driver_t * const drv)21 void max2871_setup(max2871_driver_t* const drv)
22 {
23 /* Configure GPIO pins. */
24 scu_pinmux(SCU_VCO_CE, SCU_GPIO_FAST);
25 scu_pinmux(SCU_VCO_SCLK, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
26 /* Only used for the debug pin config: scu_pinmux(SCU_VCO_SCLK, SCU_GPIO_FAST); */
27 scu_pinmux(SCU_VCO_SDATA, SCU_GPIO_FAST);
28 scu_pinmux(SCU_VCO_LE, SCU_GPIO_FAST);
29 scu_pinmux(SCU_VCO_MUX, SCU_GPIO_FAST | SCU_CONF_FUNCTION4);
30 scu_pinmux(SCU_SYNT_RFOUT_EN, SCU_GPIO_FAST);
31
32 /* Set GPIO pins as outputs. */
33 gpio_output(drv->gpio_vco_ce);
34 gpio_output(drv->gpio_vco_sclk);
35 gpio_output(drv->gpio_vco_sdata);
36 gpio_output(drv->gpio_vco_le);
37 gpio_output(drv->gpio_synt_rfout_en);
38
39 /* MUX is an input */
40 gpio_input(drv->gpio_vco_mux);
41
42 /* set to known state */
43 gpio_set(drv->gpio_vco_ce); /* active high */
44 gpio_clear(drv->gpio_vco_sclk);
45 gpio_clear(drv->gpio_vco_sdata);
46 gpio_set(drv->gpio_vco_le); /* active low */
47 gpio_set(drv->gpio_synt_rfout_en); /* active high */
48
49 max2871_regs_init();
50 int i;
51 for(i = 5; i >= 0; i--) {
52 max2871_spi_write(drv, i, max2871_get_register(i));
53 delay_ms(20);
54 }
55
56 max2871_set_INT(1);
57 max2871_set_N(4500);
58 max2871_set_FRAC(0);
59 max2871_set_CPL(0);
60 max2871_set_CPT(0);
61 max2871_set_P(1);
62 max2871_set_M(0);
63 max2871_set_LDS(0);
64 max2871_set_SDN(0);
65 max2871_set_MUX(0x0C); /* Register 6 readback */
66 max2871_set_DBR(0);
67 max2871_set_RDIV2(0);
68 max2871_set_R(1); /* 40 MHz f_PFD */
69 max2871_set_REG4DB(1);
70 max2871_set_CP(15); /* ?: CP charge pump current 0-15 */
71 max2871_set_LDF(1); /* INT-N */
72 max2871_set_LDP(0); /* ?: Lock-Detect Precision */
73 max2871_set_PDP(1);
74 max2871_set_SHDN(0);
75 max2871_set_TRI(0);
76 max2871_set_RST(0);
77 max2871_set_VCO(0);
78 max2871_set_VAS_SHDN(0);
79 max2871_set_VAS_TEMP(1);
80 max2871_set_CSM(0);
81 max2871_set_MUTEDEL(1);
82 max2871_set_CDM(0);
83 max2871_set_CDIV(0);
84 max2871_set_SDLDO(0);
85 max2871_set_SDDIV(0);
86 max2871_set_SDREF(0);
87 max2871_set_BS(20*40); /* For 40 MHz f_PFD */
88 max2871_set_FB(1); /* Do not put DIVA into the feedback loop */
89 max2871_set_DIVA(0);
90 max2871_set_SDVCO(0);
91 max2871_set_MTLD(1);
92 max2871_set_BDIV(0);
93 max2871_set_RFB_EN(0);
94 max2871_set_BPWR(0);
95 max2871_set_RFA_EN(0);
96 max2871_set_APWR(3);
97 max2871_set_SDPLL(0);
98 max2871_set_F01(1);
99 max2871_set_LD(1);
100 max2871_set_ADCS(0);
101 max2871_set_ADCM(0);
102
103 max2871_write_registers(drv);
104
105 max2871_set_frequency(drv, 3500);
106 }
107
delay_ms(int ms)108 static void delay_ms(int ms)
109 {
110 uint32_t i;
111 while(ms--) {
112 for (i = 0; i < 20000; i++) {
113 __asm__("nop");
114 }
115 }
116 }
117
118
serial_delay(void)119 static void serial_delay(void)
120 {
121 uint32_t i;
122
123 for (i = 0; i < 2; i++)
124 __asm__("nop");
125 }
126
127
128 /* SPI register write
129 *
130 * Send 32 bits:
131 * First 29 bits are data
132 * Last 3 bits are register number */
max2871_spi_write(max2871_driver_t * const drv,uint8_t r,uint32_t v)133 static void max2871_spi_write(max2871_driver_t* const drv, uint8_t r, uint32_t v) {
134 #if DEBUG
135 LOG("0x%04x -> reg%d\n", v, r);
136 #else
137
138 uint32_t bits = 32;
139 uint32_t msb = 1 << (bits -1);
140 uint32_t data = v | r;
141
142 /* make sure everything is starting in the correct state */
143 gpio_set(drv->gpio_vco_le);
144 gpio_clear(drv->gpio_vco_sclk);
145 gpio_clear(drv->gpio_vco_sdata);
146
147 /* start transaction by bringing LE low */
148 gpio_clear(drv->gpio_vco_le);
149
150 while (bits--) {
151 if (data & msb)
152 gpio_set(drv->gpio_vco_sdata);
153 else
154 gpio_clear(drv->gpio_vco_sdata);
155 data <<= 1;
156
157 serial_delay();
158 gpio_set(drv->gpio_vco_sclk);
159
160 serial_delay();
161 gpio_clear(drv->gpio_vco_sclk);
162 }
163
164 gpio_set(drv->gpio_vco_le);
165 #endif
166 }
167
max2871_spi_read(max2871_driver_t * const drv)168 static uint32_t max2871_spi_read(max2871_driver_t* const drv)
169 {
170 uint32_t bits = 32;
171 uint32_t data = 0;
172
173 max2871_spi_write(drv, 0x06, 0x0);
174
175 serial_delay();
176 gpio_set(drv->gpio_vco_sclk);
177 serial_delay();
178 gpio_clear(drv->gpio_vco_sclk);
179 serial_delay();
180
181 while (bits--) {
182 gpio_set(drv->gpio_vco_sclk);
183 serial_delay();
184
185 gpio_clear(drv->gpio_vco_sclk);
186 serial_delay();
187
188 data <<= 1;
189 data |= gpio_read(drv->gpio_vco_mux) ? 1 : 0;
190 }
191 return data;
192 }
193
max2871_write_registers(max2871_driver_t * const drv)194 static void max2871_write_registers(max2871_driver_t* const drv)
195 {
196 int i;
197 for(i = 5; i >= 0; i--) {
198 max2871_spi_write(drv, i, max2871_get_register(i));
199 }
200 }
201
202 /* Set frequency (MHz). */
max2871_set_frequency(max2871_driver_t * const drv,uint16_t mhz)203 uint64_t max2871_set_frequency(max2871_driver_t* const drv, uint16_t mhz)
204 {
205 int n = mhz / 40;
206 int diva = 0;
207
208 while(n * 40 < 3000) {
209 n *= 2;
210 diva += 1;
211 }
212
213 max2871_set_RFA_EN(0);
214 max2871_write_registers(drv);
215
216 max2871_set_N(n);
217 max2871_set_DIVA(diva);
218 max2871_write_registers(drv);
219
220 while(max2871_spi_read(drv) & MAX2871_VASA);
221
222 max2871_set_RFA_EN(1);
223 max2871_write_registers(drv);
224
225 return (mhz/40)*40 * 1000000;
226 }
227
max2871_enable(max2871_driver_t * const drv)228 void max2871_enable(max2871_driver_t* const drv)
229 {
230 gpio_set(drv->gpio_vco_ce);
231 }
max2871_disable(max2871_driver_t * const drv)232 void max2871_disable(max2871_driver_t* const drv)
233 {
234 gpio_clear(drv->gpio_vco_ce);
235 }
236
237