1 /******************************************************************************
2 *
3 * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4 * Analog Devices, Inc.),
5 * Copyright (C) 2023-2024 Analog Devices, Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************************/
20
21 #include <stdint.h>
22 #include <stdio.h>
23 #include "spi.h"
24 #include "afe.h"
25 #include "mxc_sys.h"
26 #include "hart_uart.h"
27 #include "gcr_regs.h"
28
29 #include "afe_gpio.h"
30 #include "afe_timer.h"
31 #include "gpio.h"
32 #include "gpio_reva.h"
33 #include "gpio_common.h"
34
35 // Known Device revision defines
36 #define MXC_REVISION_MASK (0x00FF)
37 #define MXC_MAX32675_REV_A1 (0x00A1)
38 #define MXC_MAX32675_REV_A2 (0x00A2)
39 #define MXC_MAX32675_REV_A3 (0x00A3)
40 #define MXC_MAX32675_REV_B2 (0x00B2)
41 #define MXC_MAX32675_REV_B3 (0x00B3)
42 #define MXC_MAX32675_REV_B4 (0x00B4)
43
44 #define MXC_MAX32680_REV_A1 (0x00A1)
45 #define MXC_MAX32680_REV_B1 (0x00B1)
46
47 #define MXC_AFE_VERSION_ORIGINAL 0
48 #define MXC_AFE_VERSION_PRE_RESET 1
49 #define MXC_AFE_VERSION_POST_RESET 2
50
51 // AFE SPI Port Configuration
52 #if (TARGET_NUM == 32675)
53 #define AFE_SPI_PORT MXC_SPI0
54 #elif (TARGET_NUM == 32680)
55 #define AFE_SPI_PORT MXC_SPI1
56 #endif
57
58 #define AFE_SPI_BAUD 1000000 // Can only run up to PCLK speed
59 #define AFE_SPI_BIT_WIDTH 8
60 #define AFE_SPI_SSEL_PIN 1
61 #define AFE_SPI_ADDRESS_LEN 1
62
63 // AFE Trim Storage Defines
64 //#define DUMP_TRIM_DATA
65
66 //
67 // Enabling this will use the afe timer to timeout polling of the AFE.
68 // This avoid any chance of the blocking function afe_spi_transceive from never returning.
69 // However, as this low level function can be called several times for even a single
70 // AFE register read, it decreases throughput to and from the AFE.
71 // When running at lower system clock frequencies this can be more of a concern.
72 //
73 //#define AFE_SPI_TRANSCEIVE_SAFE_BUT_SLOWER
74
75 #ifdef AFE_SPI_TRANSCEIVE_SAFE_BUT_SLOWER
76 //
77 // This timeout prevents infinite loop if AFE is not responsive via SPI
78 //
79 // Each read from AFE is 8 bits, unless CRC is enabled.
80 // maximum of 4 reads.
81 // 1/AFE_SPI_BAUD * 4 * 8 should be a reasonable timeout for this.
82 // 1/1000000 = 1us * 4 * 8 = 32us
83 //
84 // Since this is just for catastrophic lockup, lets round it up to 100
85 // this will also be a even multiple for MXC_AFE_SPI_RESET_TIMEOUT_ITERATES
86 //
87 #if (AFE_SPI_BAUD != 1000000)
88 #warning "Recalculate MXC_AFE_SPI_READ_TIMEOUT, since baud rate was modified.\n"
89 #endif
90 #endif // End of AFE_SPI_TRANSCEIVE_SAFE_BUT_SLOWER
91
92 #define MXC_AFE_SPI_READ_TIMEOUT USEC(100)
93
94 //
95 // Initial AFE RESET time, up to 10 milliseconds
96 // Due to nature of AFE_TIMER, it cannot support nested Timeouts
97 // Therefore, count a number of read timeouts instead.
98 //
99 #define MXC_AFE_SPI_RESET_TIMEOUT_ITERATES (MSEC(10) / MXC_AFE_SPI_READ_TIMEOUT)
100
101 #if (TARGET_NUM == 32675)
102 #define AFE_TRIM_OTP_OFFSET_LOW 0x280
103 #define AFE_TRIM_OTP_OFFSET_HIGH 0x288
104
105 #define AFE_SPI_MISO_GPIO_PORT MXC_GPIO0
106 #define AFE_SPI_MISO_GPIO_PIN MXC_GPIO_PIN_2
107
108 #define AFE_SPI_MOSI_GPIO_PORT MXC_GPIO0
109 #define AFE_SPI_MOSI_GPIO_PIN MXC_GPIO_PIN_3
110
111 #define AFE_SPI_SCK_GPIO_PORT MXC_GPIO0
112 #define AFE_SPI_SCK_GPIO_PIN MXC_GPIO_PIN_4
113
114 #define AFE_SPI_SSEL_GPIO_PORT MXC_GPIO0
115 #define AFE_SPI_SSEL_GPIO_PIN MXC_GPIO_PIN_5
116
117 #elif (TARGET_NUM == 32680)
118 #define AFE_TRIM_OTP_OFFSET_LOW 0x0E10
119 #define AFE_TRIM_OTP_OFFSET_HIGH 0x0E18
120
121 #define AFE_SPI_MISO_GPIO_PORT MXC_GPIO0
122 #define AFE_SPI_MISO_GPIO_PIN MXC_GPIO_PIN_20
123
124 #define AFE_SPI_MOSI_GPIO_PORT MXC_GPIO0
125 #define AFE_SPI_MOSI_GPIO_PIN MXC_GPIO_PIN_21
126
127 #define AFE_SPI_SCK_GPIO_PORT MXC_GPIO0
128 #define AFE_SPI_SCK_GPIO_PIN MXC_GPIO_PIN_22
129
130 #define AFE_SPI_SSEL_GPIO_PORT MXC_GPIO0
131 #define AFE_SPI_SSEL_GPIO_PIN MXC_GPIO_PIN_23
132
133 //
134 // Register defines for new AFE reset.
135 // TODO(ADI): This bit does not yet exist for MAX32680.
136 // This is just a placeholder for now to prevent compilation errors.
137 //
138 #define MXC_F_GCR_RST1_AFE_POS 26 /**< RST1_AFE Position */
139 #define MXC_F_GCR_RST1_AFE ((uint32_t)(0x1UL << MXC_F_GCR_RST1_AFE_POS)) /**< RST1_AFE Mask */
140 #endif
141
142 #define AFE_TRIM0_ADC0_MASK 0x7FFFF
143 #define AFE_TRIM0_ADC0_BIT_WIDTH 19
144
145 #define AFE_TRIM1_ADC0_MASK 0x3FFF
146 #define AFE_TRIM1_ADC0_BIT_WIDTH 14
147
148 #define AFE_TRIM_DAC_MASK 0x0FFFF
149 #define AFE_TRIM_DAC_BIT_WIDTH 16
150
151 #define AFE_TRIM_ANA_ADC0_MASK 0x7FFF
152 #define AFE_TRIM_ANA_ADC0_BIT_WIDTH 15
153
154 #define AFE_TRIM0_ADC1_MASK 0x7FFFF
155 #define AFE_TRIM0_ADC1_BIT_WIDTH 19
156
157 #define AFE_TRIM1_ADC1_MASK 0x3FFF
158 #define AFE_TRIM1_ADC1_BIT_WIDTH 14
159
160 #define AFE_TRIM_HART_MASK 0x0FFFFF
161 #define AFE_TRIM_HART_BIT_WIDTH 20
162
163 // NOTE: These two bits are embedded inside the HART trim
164 #define AFE_TRIM_ANA_ADC1_MASK 0x060
165 #define AFE_TRIM_ANA_ADC1_BIT_WIDTH 2
166 #define AFE_TRIM_ANA_ADC1_OFFSET_1 5 // bit position in HART trim
167 #define AFE_TRIM_ANA_ADC1_OFFSET_2 10 // bit position in ANA TRIM ADC1
168
169 #define AFE_TRIM_VREF_MASK 0x7FF
170 #define AFE_TRIM_VREF_BIT_WIDTH 11
171
172 // Largest Possible AFE SPI transaction (BYTES): Address 1, Max Data 4, CRC 2
173 #define AFE_SPI_MAX_DATA_LEN 7
174
175 //
176 // Masks and values used for validation of AFE SPI out of reset
177 // Uses entire bottom nibble match, AND por_flag
178 //
179 // Revisions AFTER Reset added to AFE
180 #define ME16_AFE_POST_RST_SYS_CTRL_TRUE_POR_MASK \
181 (MXC_F_AFE_ADC_ZERO_SYS_CTRL_ANA_SRC_SEL | MXC_F_AFE_ADC_ZERO_SYS_CTRL_CRC5 | \
182 MXC_F_AFE_ADC_ZERO_SYS_CTRL_ST_DIS | MXC_F_AFE_ADC_ZERO_SYS_CTRL_POR_FLAG)
183 #define ME16_AFE_POST_RST_SYS_CTRL_TRUE_POR_VALUE \
184 (MXC_F_AFE_ADC_ZERO_SYS_CTRL_ST_DIS | MXC_F_AFE_ADC_ZERO_SYS_CTRL_POR_FLAG)
185 #define ME16_AFE_POST_RST_SYS_CTRL_RESET_VALUE (MXC_F_AFE_ADC_ZERO_SYS_CTRL_ST_DIS)
186
187 // Revisions BEFORE Reset added to AFE
188 #define ME16_AFE_PRE_RST_SYS_CTRL_TRUE_POR_MASK (MXC_F_AFE_ADC_ZERO_SYS_CTRL_POR_FLAG)
189 #define ME16_AFE_PRE_RST_SYS_CTRL_TRUE_POR_VALUE (MXC_F_AFE_ADC_ZERO_SYS_CTRL_POR_FLAG)
190 #define ME16_AFE_PRE_RST_SYS_CTRL_RESET_VALUE (0)
191
192 /***** Globals *****/
193 uint8_t afe_data[AFE_SPI_MAX_DATA_LEN];
194 mxc_spi_regs_t *pSPIm = AFE_SPI_PORT;
195 int check_done = 0;
196
197 typedef struct {
198 uint32_t adc_trim0_adc0;
199 uint32_t adc_trim0_adc1;
200 uint32_t adc_trim1_adc0;
201 uint32_t adc_trim1_adc1;
202 uint32_t ana_trim_adc0;
203 uint32_t vref_trim;
204 uint32_t hart_trim;
205 uint32_t ana_trim_adc1;
206 uint32_t dac_trim;
207 } trim_data_t;
208
209 trim_data_t trim_data;
210
211 uint32_t current_register_bank = 0;
212 uint32_t adc0_conversion_active = 0;
213 uint32_t adc1_conversion_active = 0;
214 uint32_t device_version = 0;
215
216 #if (TARGET_NUM == 32675)
217
218 static mxc_gpio_cfg_t gpio_cfg_spi0 = {
219 MXC_GPIO0, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3 | MXC_GPIO_PIN_4 | MXC_GPIO_PIN_5),
220 MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE
221 };
222
223 #elif (TARGET_NUM == 32680)
224
225 static mxc_gpio_cfg_t gpio_cfg_spi1 = {
226 MXC_GPIO0, (MXC_GPIO_PIN_20 | MXC_GPIO_PIN_21 | MXC_GPIO_PIN_22 | MXC_GPIO_PIN_23),
227 MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE
228 };
229 #endif
230
231 /***** Private Prototypes *****/
232 static int raw_afe_write_register(uint8_t reg_address, uint32_t value, uint8_t reg_length);
233 static int raw_afe_read_register(uint8_t reg_address, uint32_t *value, uint8_t reg_length);
234
235 /***** Functions *****/
236
237 // Probe and determine silicon version of AFE micro
afe_micro_version_probe(void)238 static int afe_micro_version_probe(void)
239 {
240 // Due to changes in the latest AFE revision, different initialization procedures are required.
241
242 uint32_t rev = MXC_GCR->revision;
243
244 // Mask off metal option details, only care about revision here
245 rev &= MXC_REVISION_MASK;
246
247 //
248 // Decode AFE version from micro version
249 //
250 #if (TARGET_NUM == 32675)
251 switch (rev) {
252 // Known and supported versions
253 case MXC_MAX32675_REV_A1:
254 case MXC_MAX32675_REV_A2:
255 case MXC_MAX32675_REV_A3:
256 case MXC_MAX32675_REV_B2:
257 case MXC_MAX32675_REV_B3:
258 device_version = MXC_AFE_VERSION_PRE_RESET;
259 return E_NO_ERROR;
260
261 case MXC_MAX32675_REV_B4:
262 device_version = MXC_AFE_VERSION_POST_RESET;
263 return E_NO_ERROR;
264
265 default:
266 // Unknown or unsupported version
267 return E_INVALID;
268 }
269 #elif (TARGET_NUM == 32680)
270 switch (rev) {
271 // Known and supported versions
272 case MXC_MAX32680_REV_A1:
273 device_version = MXC_AFE_VERSION_PRE_RESET;
274 return E_NO_ERROR;
275
276 case MXC_MAX32680_REV_B1:
277 // TODO(ADI): Validate this revision is correct when updated MAX32680 is released
278 device_version = MXC_AFE_VERSION_POST_RESET;
279 return E_NO_ERROR;
280
281 default:
282 // Unknown or unsupported version
283 return E_INVALID;
284 }
285 #else
286 #error "Selected TARGET is not known to have an AFE\n"
287 #endif
288
289 return E_NO_ERROR;
290 }
291
292 // Puts the SPI interface to the AFE into controlled inactive state
afe_spi_idle_interface(void)293 static void afe_spi_idle_interface(void)
294 {
295 // Make sure SSEL is inactive first
296 // SSEL should output 1 (inactive)
297 AFE_SPI_SSEL_GPIO_PORT->out_set = AFE_SPI_SSEL_GPIO_PIN;
298 AFE_SPI_SSEL_GPIO_PORT->outen_set = AFE_SPI_SSEL_GPIO_PIN;
299 AFE_SPI_SSEL_GPIO_PORT->en0_set = AFE_SPI_SSEL_GPIO_PIN;
300
301 // SCK output 0
302 AFE_SPI_SCK_GPIO_PORT->out_clr = AFE_SPI_SCK_GPIO_PIN;
303 AFE_SPI_SCK_GPIO_PORT->outen_set = AFE_SPI_SCK_GPIO_PIN;
304 AFE_SPI_SCK_GPIO_PORT->en0_set = AFE_SPI_SCK_GPIO_PIN;
305
306 // MISO will always be strong driven from AFE.
307 // Therefore, put in tristate input mode
308 AFE_SPI_MISO_GPIO_PORT->outen_clr = AFE_SPI_MISO_GPIO_PIN;
309 AFE_SPI_MISO_GPIO_PORT->padctrl0 &= ~AFE_SPI_MISO_GPIO_PIN;
310 AFE_SPI_MISO_GPIO_PORT->padctrl1 &= ~AFE_SPI_MISO_GPIO_PIN;
311
312 // Only setting en0 here, to avoid any chance of glitch when set to AF mode later
313 AFE_SPI_MISO_GPIO_PORT->en0_set = AFE_SPI_MISO_GPIO_PIN;
314
315 // MOSI output 0
316 AFE_SPI_MOSI_GPIO_PORT->out_clr = AFE_SPI_MOSI_GPIO_PIN;
317 AFE_SPI_MOSI_GPIO_PORT->outen_set = AFE_SPI_MOSI_GPIO_PIN;
318 AFE_SPI_MOSI_GPIO_PORT->en0_set = AFE_SPI_MOSI_GPIO_PIN;
319
320 return;
321 }
322
afe_spi_setup(void)323 static int afe_spi_setup(void)
324 {
325 int retval = 0;
326
327 // Enable SPI Periph clock, and reset it
328 #if (TARGET_NUM == 32675)
329 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI0);
330 MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI0);
331
332 #elif (TARGET_NUM == 32680)
333 MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPI1);
334 MXC_SYS_Reset_Periph(MXC_SYS_RESET0_SPI1);
335 #endif
336
337 // Initialize global check for previous SPI transaction finished
338 check_done = 0;
339
340 // NOTE: AFE uses SPI Mode 0, which is reset default
341
342 // Use SDK SPI driver to set the baud rate, as these depends what periph clock we are at
343 retval = MXC_SPI_SetFrequency(AFE_SPI_PORT, AFE_SPI_BAUD);
344 if (retval != E_NO_ERROR) {
345 return retval;
346 }
347
348 pSPIm->ctrl2 |= ((AFE_SPI_BIT_WIDTH << MXC_F_SPI_CTRL2_NUMBITS_POS) & MXC_F_SPI_CTRL2_NUMBITS);
349
350 pSPIm->ctrl0 |= (AFE_SPI_SSEL_PIN << MXC_F_SPI_CTRL0_SS_ACTIVE_POS);
351
352 pSPIm->ctrl2 |= MXC_S_SPI_CTRL2_DATA_WIDTH_MONO;
353
354 pSPIm->sstime = ((1 << MXC_F_SPI_SSTIME_PRE_POS) | (1 << MXC_F_SPI_SSTIME_POST_POS) |
355 (1 << MXC_F_SPI_SSTIME_INACT_POS));
356
357 pSPIm->dma = (MXC_F_SPI_DMA_TX_FLUSH | MXC_F_SPI_DMA_RX_FLUSH);
358
359 // FIFO Threshold reset defaults are fine
360 pSPIm->dma |= MXC_F_SPI_DMA_TX_FIFO_EN;
361 pSPIm->dma |= MXC_F_SPI_DMA_RX_FIFO_EN;
362
363 // Don't enable the SPI block until the FIFOs are enabled, to avoid floating any of the SPI interface pins.
364 pSPIm->ctrl0 |= (MXC_F_SPI_CTRL0_EN | MXC_F_SPI_CTRL0_MST_MODE);
365
366 // Clear any existing interrupt status
367 pSPIm->intfl = pSPIm->intfl;
368
369 //
370 // Now that the ME15 side of SPI is setup, configure gpio pads.
371 // Doing this after turning on the SPI periph to avoid floating AFE inputs.
372 //
373 #if (TARGET_NUM == 32675)
374 retval = MXC_AFE_GPIO_Config(&gpio_cfg_spi0);
375 if (retval != E_NO_ERROR) {
376 return retval;
377 }
378
379 #elif (TARGET_NUM == 32680)
380 retval = MXC_AFE_GPIO_Config(&gpio_cfg_spi1);
381 if (retval != E_NO_ERROR) {
382 return retval;
383 }
384 #endif
385
386 if (device_version < MXC_AFE_VERSION_POST_RESET) {
387 //
388 // MISO needs a pull down when SPI interface is idle, (this is changed on new silicon)
389 //
390 AFE_SPI_MISO_GPIO_PORT->padctrl0 |= AFE_SPI_MISO_GPIO_PIN;
391
392 // Ensure the second pull enable is disabled, so we only have to write one register later
393 AFE_SPI_MISO_GPIO_PORT->padctrl1 &= ~AFE_SPI_MISO_GPIO_PIN;
394
395 // Pull down
396 AFE_SPI_MISO_GPIO_PORT->ps &= ~AFE_SPI_MISO_GPIO_PIN;
397 }
398
399 return E_NO_ERROR;
400 }
401
402 #ifdef AFE_SPI_TRANSCEIVE_SAFE_BUT_SLOWER
403 //
404 // This function blocks until transceive is completed, or times out
405 // To avoid possibility of getting stuck in a infinite loop, it uses the afe timer
406 // to timeout polling.
407 //
afe_spi_transceive(uint8_t * data,int byte_length)408 static int afe_spi_transceive(uint8_t *data, int byte_length)
409 {
410 int status = E_NO_ERROR;
411 int i = 0;
412
413 if (byte_length > AFE_SPI_MAX_DATA_LEN) {
414 return E_OVERFLOW;
415 }
416
417 //
418 // Ensure transmit FIFO is finished
419 // NOTE: if the AFE was reset during transaction this may not finish, so using a timeout
420 //
421
422 // Start timeout, wait for SPI TX to complete
423 afe_timer_delay_async(AFE_SPI_TIMER, MXC_AFE_SPI_READ_TIMEOUT, NULL);
424
425 do {
426 status = afe_timer_delay_check(AFE_SPI_TIMER);
427
428 if ((pSPIm->dma & MXC_F_SPI_DMA_TX_LVL) == 0) {
429 // TX completed
430 afe_timer_delay_abort(AFE_SPI_TIMER);
431 break;
432 }
433 } while (status == E_BUSY);
434
435 if (status != E_BUSY) {
436 return E_TIME_OUT;
437 }
438
439 //
440 // If a transaction has been started, verify it completed before continuing
441 //
442 if (check_done) {
443 // Start timeout, wait for SPI MST DONE to set
444 afe_timer_delay_async(AFE_SPI_TIMER, MXC_AFE_SPI_READ_TIMEOUT, NULL);
445
446 do {
447 status = afe_timer_delay_check(AFE_SPI_TIMER);
448
449 if (pSPIm->intfl & MXC_F_SPI_INTFL_MST_DONE) {
450 // MST Done
451 afe_timer_delay_abort(AFE_SPI_TIMER);
452 break;
453 }
454 } while (status == E_BUSY);
455
456 if (status != E_BUSY) {
457 return E_TIME_OUT;
458 }
459 }
460
461 check_done = 1;
462
463 pSPIm->intfl = pSPIm->intfl;
464 pSPIm->dma |= (MXC_F_SPI_DMA_TX_FLUSH | MXC_F_SPI_DMA_RX_FLUSH);
465
466 while (pSPIm->dma & (MXC_F_SPI_DMA_TX_FLUSH | MXC_F_SPI_DMA_RX_FLUSH)) {}
467
468 pSPIm->ctrl1 = ((((byte_length) << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS)) |
469 (byte_length << MXC_F_SPI_CTRL1_RX_NUM_CHAR_POS));
470
471 if (device_version < MXC_AFE_VERSION_POST_RESET) {
472 //
473 // Legacy: Disable pull down on MISO while transmitting.
474 //
475 AFE_SPI_MISO_GPIO_PORT->padctrl0 |= AFE_SPI_MISO_GPIO_PIN;
476 }
477
478 pSPIm->ctrl0 |= MXC_F_SPI_CTRL0_START;
479
480 // NOTE: At most we will read 32 bits before returning to processing, no streaming data
481
482 //
483 // Transmit the data
484 //
485 for (i = 0; i < byte_length; i++) {
486 pSPIm->fifo8[0] = data[i];
487 }
488
489 //
490 // Receive the data
491 //
492
493 // Reset byte counter
494 i = 0;
495
496 // Start timeout, wait for SPI receive to complete
497 afe_timer_delay_async(AFE_SPI_TIMER, MXC_AFE_SPI_READ_TIMEOUT, NULL);
498
499 do {
500 status = afe_timer_delay_check(AFE_SPI_TIMER);
501
502 if ((pSPIm->dma & MXC_F_SPI_DMA_RX_LVL)) {
503 data[i] = pSPIm->fifo8[0];
504 i++;
505 }
506 } while ((i < byte_length) && (status == E_BUSY));
507
508 afe_timer_delay_abort(AFE_SPI_TIMER);
509
510 if (device_version < MXC_AFE_VERSION_POST_RESET) {
511 //
512 // Legacy: Enable pull down on MISO while idle.
513 //
514 AFE_SPI_MISO_GPIO_PORT->padctrl0 |= AFE_SPI_MISO_GPIO_PIN;
515 }
516
517 if ((i < byte_length) || (status != E_BUSY)) {
518 return E_TIME_OUT;
519 }
520
521 // Got all bytes, and we did NOT timeout
522 return E_NO_ERROR;
523 }
524 #else // Not AFE_SPI_TRANSCEIVE_SAFE_BUT_SLOWER
525
526 //
527 // This function blocks until transceive is completed, or times out
528 // This version does not use the afe timer to interrupt potential infinite polling.
529 //
afe_spi_transceive(uint8_t * data,int byte_length)530 static int afe_spi_transceive(uint8_t *data, int byte_length)
531 {
532 int i = 0;
533
534 if (byte_length > AFE_SPI_MAX_DATA_LEN) {
535 return E_OVERFLOW;
536 }
537
538 //
539 // Ensure transmit FIFO is finished
540 // NOTE: if the AFE was reset during transaction this may not finish, so using a timeout
541 //
542 while ((pSPIm->dma & MXC_F_SPI_DMA_TX_LVL) != 0) {}
543
544 //
545 // If a transaction has been started, verify it completed before continuing
546 //
547 if (check_done) {
548 while (!(pSPIm->intfl & MXC_F_SPI_INTFL_MST_DONE)) {}
549 }
550
551 check_done = 1;
552
553 pSPIm->intfl = pSPIm->intfl;
554 pSPIm->dma |= (MXC_F_SPI_DMA_TX_FLUSH | MXC_F_SPI_DMA_RX_FLUSH);
555
556 while (pSPIm->dma & (MXC_F_SPI_DMA_TX_FLUSH | MXC_F_SPI_DMA_RX_FLUSH)) {}
557
558 pSPIm->ctrl1 = ((((byte_length) << MXC_F_SPI_CTRL1_TX_NUM_CHAR_POS)) |
559 (byte_length << MXC_F_SPI_CTRL1_RX_NUM_CHAR_POS));
560
561 if (device_version < MXC_AFE_VERSION_POST_RESET) {
562 //
563 // Legacy: Disable pull down on MISO while transmitting.
564 //
565 AFE_SPI_MISO_GPIO_PORT->padctrl0 |= AFE_SPI_MISO_GPIO_PIN;
566 }
567
568 pSPIm->ctrl0 |= MXC_F_SPI_CTRL0_START;
569
570 // NOTE: At most we will read 32 bits before returning to processing, no streaming data
571
572 //
573 // Transmit the data
574 //
575 for (i = 0; i < byte_length; i++) {
576 pSPIm->fifo8[0] = data[i];
577 }
578
579 //
580 // Receive the data
581 //
582
583 // Reset byte counter
584 i = 0;
585
586 do {
587 if ((pSPIm->dma & MXC_F_SPI_DMA_RX_LVL)) {
588 data[i] = pSPIm->fifo8[0];
589 i++;
590 }
591 } while (i < byte_length);
592
593 if (device_version < MXC_AFE_VERSION_POST_RESET) {
594 //
595 // Legacy: Enable pull down on MISO while idle.
596 //
597 AFE_SPI_MISO_GPIO_PORT->padctrl0 |= AFE_SPI_MISO_GPIO_PIN;
598 }
599
600 // Got all bytes, and we did NOT timeout
601 return E_NO_ERROR;
602 }
603 #endif // End of else not AFE_SPI_TRANSCEIVE_SAFE_BUT_SLOWER
604
afe_spi_poll_for_ready_post_reset_change(uint32_t * true_por)605 static int afe_spi_poll_for_ready_post_reset_change(uint32_t *true_por)
606 {
607 int retval = E_NO_ERROR;
608 int read_timeout_count = 0;
609 uint32_t read_val = 0;
610
611 //
612 // New for ME16A-0D, Validate that SPI interface on AFE is responding
613 // AFE will not correctly respond after a reset for up to 10ms.
614 //
615 // It is ASSUMED that during the time wih the SPI on AFE is in reset the read output will be 0xFF or 0x00.
616 //
617 // The sys_ctrl register is modified on this revision so that the following is true:
618 // On a true POR: por_flag (bit 6) and st_dis (bit 3) will BOTH be set to 1, all other bits will be 0
619 // That is 0x48 == POR
620 //
621 // Any other reset: por_flag (bit 6) will NOT be set ASSUMING user code has already cleared it to 0
622 // st_dis (bit 3) will be set, and hart_en (bit 4) maybe set or not. Other bits will be 0.
623 //
624
625 // NOTE: Only allow 10ms for reset init. raw_afe_read_register calls afe_spi_transceive
626 // which uses afe_timer, so we cannot also use it here. So we count calls to read_reg
627 // instead.
628 do {
629 retval = raw_afe_read_register(
630 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, &read_val,
631 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
632
633 // NOTE: Remember that reading sys_ctrl also SETS the SPI_ABORT_DIS bit
634
635 if (retval == E_TIME_OUT) {
636 // The low level read timed out. We are counting these if it happens
637 // to many times, will error out and return
638 continue;
639 }
640
641 if (retval != E_NO_ERROR) {
642 return retval;
643 }
644
645 // Test mask for TRUE POR
646 read_val &= ME16_AFE_POST_RST_SYS_CTRL_TRUE_POR_MASK;
647
648 // Check for True POR
649 if (read_val == ME16_AFE_POST_RST_SYS_CTRL_TRUE_POR_VALUE) {
650 // This appears to be a true POR
651 *true_por = 1;
652 break;
653 }
654
655 // Check for a normal reset
656 if (read_val == ME16_AFE_POST_RST_SYS_CTRL_RESET_VALUE) {
657 // This appears to be a normal reset
658 *true_por = 0;
659 break;
660 }
661 // Keep counting timeouts, if we get too many, bail out
662 } while (read_timeout_count++ < MXC_AFE_SPI_RESET_TIMEOUT_ITERATES);
663
664 if (read_timeout_count >= MXC_AFE_SPI_RESET_TIMEOUT_ITERATES) {
665 // Failed to initiate communications with AFE within time limit
666 return E_TIME_OUT;
667 }
668
669 return E_NO_ERROR;
670 }
671
afe_spi_poll_for_ready_pre_reset_change(uint32_t * true_por)672 static int afe_spi_poll_for_ready_pre_reset_change(uint32_t *true_por)
673 {
674 int retval = E_NO_ERROR;
675 int read_timeout_count = 0;
676 uint32_t read_val = 0;
677
678 // Legacy initialization method, in this case we can only detect true POR.
679 // Reset has no effect, we can only look at bit6 POR_FLAG
680
681 // NOTE: Only allow 10ms for reset init. raw_afe_read_register calls afe_spi_transceive
682 // which uses afe_timer, so we cannot also use it here. So we count calls to read_reg
683 // instead.
684 do {
685 retval = raw_afe_read_register(
686 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, &read_val,
687 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
688
689 // NOTE: Remember that reading sys_ctrl also SETS the SPI_ABORT_DIS bit
690
691 if (retval == E_TIME_OUT) {
692 // The low level read timed out. We are counting these if it happens
693 // to many times, will error out and return
694 continue;
695 }
696
697 if (retval != E_NO_ERROR) {
698 return retval;
699 }
700
701 // Test mask for TRUE POR
702 read_val &= ME16_AFE_PRE_RST_SYS_CTRL_TRUE_POR_MASK;
703
704 // Check for True POR
705 if (read_val == ME16_AFE_PRE_RST_SYS_CTRL_TRUE_POR_VALUE) {
706 // This appears to be a true POR
707 *true_por = 1;
708 break;
709 }
710
711 // Check for a normal reset
712 if (read_val == ME16_AFE_PRE_RST_SYS_CTRL_RESET_VALUE) {
713 // This appears to be a normal reset
714 *true_por = 0;
715 break;
716 }
717 } while (read_timeout_count++ < MXC_AFE_SPI_RESET_TIMEOUT_ITERATES);
718
719 if (read_timeout_count >= MXC_AFE_SPI_RESET_TIMEOUT_ITERATES) {
720 // Failed to initiate communications with AFE within time limit
721 return E_TIME_OUT;
722 }
723
724 return E_NO_ERROR;
725 }
726
afe_spi_poll_for_ready(uint32_t * true_por)727 static int afe_spi_poll_for_ready(uint32_t *true_por)
728 {
729 if (device_version >= MXC_AFE_VERSION_POST_RESET) {
730 return afe_spi_poll_for_ready_post_reset_change(true_por);
731 } else {
732 // Treat all earlier revs the same
733 return afe_spi_poll_for_ready_pre_reset_change(true_por);
734 }
735 }
736
afe_setup_true_por(void)737 static int afe_setup_true_por(void)
738 {
739 //
740 // If this is a true POR, then set state as expected
741 // Clear por_flag, st_dis, hart_en, crc_en
742 // Also sets crc_inv to normal aka non-inverted
743 // and forces selection of ADC0 register bank
744 //
745 // SYS_CTRL should be 0
746 //
747 int retval = 0;
748 uint32_t read_val = 0;
749
750 retval = raw_afe_write_register(
751 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, read_val,
752 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
753
754 // NOTE: Remember that reading sys_ctrl also SETS the SPI_ABORT_DIS bit
755
756 if (retval != E_NO_ERROR) {
757 return retval;
758 }
759
760 // Read it back as an additional validation of proper SPI operation
761 retval = raw_afe_read_register(
762 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, &read_val,
763 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
764
765 // NOTE: Remember that reading sys_ctrl also SETS the SPI_ABORT_DIS bit
766
767 if (retval != E_NO_ERROR) {
768 return retval;
769 }
770
771 // Mask SPI_ABORT_DIS bit to 0 for the following expected value comparison
772 read_val &= ~MXC_F_AFE_ADC_ZERO_SYS_CTRL_SPI_ABORT_DIS;
773
774 if (read_val != 0) {
775 // Response does NOT matches written and expected value
776 return E_COMM_ERR;
777 }
778
779 return retval;
780 }
781
afe_setup_non_por(void)782 static int afe_setup_non_por(void)
783 {
784 //
785 // This is a non POR reset
786 // Do NOT clear st_dis, or hart_en bits.
787 // Clear por_flag, crc_en
788 // Also sets crc_inv to normal aka non-inverted
789 // and forces selection of ADC0 register bank
790 //
791 // st_dis and hart_en must remain on to avoid disabling HART pin biases once enabled
792
793 int retval = 0;
794 uint32_t read_val = 0;
795
796 // Doing a read modify write
797 retval = raw_afe_read_register(
798 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, &read_val,
799 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
800
801 // NOTE: Remember that reading sys_ctrl also SETS the SPI_ABORT_DIS bit
802
803 if (retval != E_NO_ERROR) {
804 return retval;
805 }
806
807 // mask all bits but st_dis, or hart_en bits.
808 read_val &= (MXC_F_AFE_ADC_ZERO_SYS_CTRL_HART_EN | MXC_F_AFE_ADC_ZERO_SYS_CTRL_ST_DIS);
809
810 retval = raw_afe_write_register(
811 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, read_val,
812 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
813
814 if (retval != E_NO_ERROR) {
815 return retval;
816 }
817
818 // Read it back as an additional validation of proper SPI operation
819 retval = raw_afe_read_register(
820 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, &read_val,
821 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
822
823 // NOTE: Remember that reading sys_ctrl also SETS the SPI_ABORT_DIS bit
824
825 if (retval != E_NO_ERROR) {
826 return retval;
827 }
828
829 // mask all bits but st_dis, or hart_en bits.
830 read_val &= (MXC_F_AFE_ADC_ZERO_SYS_CTRL_HART_EN | MXC_F_AFE_ADC_ZERO_SYS_CTRL_ST_DIS);
831
832 if (device_version >= MXC_AFE_VERSION_POST_RESET) {
833 // ST_DIS MUST be set, and HART_EN MAY be set
834 if ((read_val !=
835 (MXC_F_AFE_ADC_ZERO_SYS_CTRL_HART_EN | MXC_F_AFE_ADC_ZERO_SYS_CTRL_ST_DIS)) &&
836 (read_val != (MXC_F_AFE_ADC_ZERO_SYS_CTRL_ST_DIS))) {
837 // Response does NOT matches written and expected value
838 return E_COMM_ERR;
839 }
840 } else {
841 // LEGACY silicon mode, the ST_DIS bit CANNOT be set as is doesn't exist, so look for 0
842 // However, HART_EN could be set, since we cannot reset the ME19
843 if ((read_val != 0) && (read_val != MXC_F_AFE_ADC_ZERO_SYS_CTRL_HART_EN)) {
844 // Response does NOT matches written and expected value
845 return E_COMM_ERR;
846 }
847 }
848
849 // Finally before continuing, we disable the HART clock, to avoid any unexpected behaviors.
850 // Should already be disabled by System Reset, or afe_reset, so this is just for safety.
851
852 hart_clock_disable();
853
854 return retval;
855 }
856
afe_setup(mxc_tmr_regs_t * tmr)857 int afe_setup(mxc_tmr_regs_t *tmr)
858 {
859 int retval = 0;
860 uint32_t true_por = 0;
861
862 // First setup the AFE
863 retval = afe_timer_config(tmr);
864 if (retval != E_NO_ERROR) {
865 return retval;
866 }
867
868 // Probe for Version to determine initialization procedure
869 retval = afe_micro_version_probe();
870 if (retval != E_NO_ERROR) {
871 return retval;
872 }
873
874 //
875 // NEW on ME16-0D, ensure reset is released for the AFE via GRC
876 // Reset could be active due to SW error recovery.
877 //
878 if (device_version >= MXC_AFE_VERSION_POST_RESET) {
879 MXC_GCR->rst1 &= ~MXC_F_GCR_RST1_AFE;
880 }
881
882 retval = afe_spi_setup();
883 if (retval != E_NO_ERROR) {
884 return retval;
885 }
886
887 retval = afe_spi_poll_for_ready(&true_por);
888 if (retval != E_NO_ERROR) {
889 return retval;
890 }
891
892 if (true_por) {
893 return afe_setup_true_por();
894 } else {
895 return afe_setup_non_por();
896 }
897 }
898
afe_reset(void)899 void afe_reset(void)
900 {
901 //
902 // Before resetting AFE, insure SPI pins are in known good state
903 //
904 afe_spi_idle_interface();
905
906 //
907 // Software controlled reset of the AFE is controlled via GCR
908 // Note, after calling this function afe_load_trims should be called to restore AFE functionality
909 //
910 MXC_GCR->rst1 |= MXC_F_GCR_RST1_AFE;
911
912 //
913 // Disable HART clock to avoid any unexpected behaviors by the HART block when reset is released
914 //
915 hart_clock_disable();
916 }
917
raw_afe_write_register(uint8_t reg_address,uint32_t value,uint8_t reg_length)918 static int raw_afe_write_register(uint8_t reg_address, uint32_t value, uint8_t reg_length)
919 {
920 int i = 0;
921 int retval = 0;
922
923 int txLen = AFE_SPI_ADDRESS_LEN + reg_length;
924
925 // First comes address
926 // AFE requires bit 7 of byte 0 CLEAR to indicate write command
927 afe_data[0] = reg_address & ~AFE_REG_ADDR_READ_BIT;
928
929 // Next data to write MSB first
930 for (i = reg_length; i > 0; i--) {
931 afe_data[i] = value & 0x0FF;
932 value >>= 8;
933 }
934
935 // Blocking SPI Transceive
936 retval = afe_spi_transceive(afe_data, txLen);
937
938 if (retval != E_NO_ERROR) {
939 return retval;
940 }
941
942 return retval;
943 }
944
raw_afe_read_register(uint8_t reg_address,uint32_t * value,uint8_t reg_length)945 static int raw_afe_read_register(uint8_t reg_address, uint32_t *value, uint8_t reg_length)
946 {
947 int i = 0;
948 int retval = 0;
949 int txLen = AFE_SPI_ADDRESS_LEN + reg_length;
950
951 // First comes address
952 // AFE requires bit 7 of byte 0 SET to indicate read command
953 afe_data[0] = reg_address | AFE_REG_ADDR_READ_BIT;
954
955 // Blocking SPI Transceive
956 retval = afe_spi_transceive(afe_data, txLen);
957
958 if (retval != E_NO_ERROR) {
959 return retval;
960 }
961
962 *value = 0;
963
964 // Extract value
965 for (i = 0; i < reg_length; i++) {
966 *value <<= 8;
967 *value |= afe_data[i + AFE_SPI_ADDRESS_LEN] & 0x0FF;
968 }
969
970 // TODO(ADI): If optional CRC5 is added in the future, verify CRC here
971
972 return retval;
973 }
974
afe_bank_select(uint8_t bank_num)975 static int afe_bank_select(uint8_t bank_num)
976 {
977 uint32_t read_val = 0;
978 int retval = 0;
979
980 // First, No need to check for current bank if we are already in it.
981 if (current_register_bank == bank_num) {
982 return E_NO_ERROR;
983 }
984
985 // Read current value, and or in our bits
986 // NOTE: SYC_CTRL exists in all register banks
987 //
988 // BIG NOTE: READING of this register arms the SPI_ABORT_DIS feature
989 //
990 retval = raw_afe_read_register(
991 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, &read_val,
992 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
993
994 if (retval != E_NO_ERROR) {
995 return retval;
996 }
997
998 //
999 // BIG NOTE: writing a register on the AFE during a ADC conversion will ABORT it.
1000 // If we are already in the correct bank, then do NOT write the SYS_CTRL register
1001 //
1002
1003 //
1004 // NOTE: As a workaround to allow for multiple ADC conversions, one in ADC0 and simultaneous one in ADC1
1005 // The SPI_ABORT_DIS feature in the sys_ctrl register can help. Note that there is only 1 sys_cntl register
1006 // but it is available from every register bank, ADC0, ADC1, DAC, and HART.
1007 //
1008 // Reading the sys_ctrl register arms the HW to set this bit automatically, it doesn't need to be set by SW.
1009 // WARNING: It blocks the abort signal. This means, if a conversion is active on the selected ADC, and
1010 // after reading sys_ctrl, a write occurs to ADC bank with conversion in progress, the ADC data will
1011 // be corrupted.
1012 //
1013
1014 if ((read_val & MXC_F_AFE_ADC_ZERO_SYS_CTRL_ANA_SRC_SEL) !=
1015 (bank_num & MXC_F_AFE_ADC_ZERO_SYS_CTRL_ANA_SRC_SEL)) {
1016 // Need to change the bank
1017 read_val = (read_val & ~MXC_F_AFE_ADC_ZERO_SYS_CTRL_ANA_SRC_SEL) |
1018 (bank_num & MXC_F_AFE_ADC_ZERO_SYS_CTRL_ANA_SRC_SEL);
1019
1020 retval = raw_afe_write_register(
1021 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR) >> AFE_REG_ADDR_POS, read_val,
1022 (MXC_R_AFE_ADC_ZERO_SYS_CTRL & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS);
1023
1024 if (retval != E_NO_ERROR) {
1025 return retval;
1026 }
1027
1028 // Update bank tracker
1029 current_register_bank = bank_num;
1030 }
1031 // Else already in the correct bank
1032
1033 return retval;
1034 }
1035
afe_write_register(uint32_t target_reg,uint32_t value)1036 int afe_write_register(uint32_t target_reg, uint32_t value)
1037 {
1038 uint8_t reg_bank = 0;
1039 uint8_t reg_address = 0;
1040 uint8_t reg_length = 0;
1041 int retval = 0;
1042
1043 //
1044 // Parse register parameters from register offset
1045 //
1046
1047 // Top 2 bytes of address encodes the register address
1048 // Address Bits 23&24 are MSB address bits, which must be written into
1049 // ana_src_sel[1:0] as bank select. Bottom byte of address encodes the
1050 // register width in bytes 1 - 4 (8bits to 32bits)
1051
1052 reg_length = (target_reg & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS;
1053 reg_bank = (target_reg & AFE_REG_ADDR_BANK) >> AFE_REG_ADDR_BANK_POS;
1054 reg_address = (target_reg & AFE_REG_ADDR) >> AFE_REG_ADDR_POS;
1055
1056 retval = afe_bank_select(reg_bank);
1057
1058 if (retval != E_NO_ERROR) {
1059 return retval;
1060 }
1061
1062 return raw_afe_write_register(reg_address, value, reg_length);
1063 }
1064
afe_bank_write_register(uint32_t target_reg,uint8_t reg_bank,uint32_t value)1065 int afe_bank_write_register(uint32_t target_reg, uint8_t reg_bank, uint32_t value)
1066 {
1067 uint8_t reg_address = 0;
1068 uint8_t reg_length = 0;
1069 int retval = 0;
1070
1071 //
1072 // Parse register parameters from register offset
1073 //
1074
1075 // Top 2 bytes of address encodes the register address
1076 // Address Bits 23&24 are MSB address bits, which must be written into
1077 // ana_src_sel[1:0] as bank select. Bottom byte of address encodes the
1078 // register width in bytes 1 - 4 (8bits to 32bits)
1079
1080 reg_length = (target_reg & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS;
1081 reg_address = (target_reg & AFE_REG_ADDR) >> AFE_REG_ADDR_POS;
1082
1083 retval = afe_bank_select(reg_bank);
1084
1085 if (retval != E_NO_ERROR) {
1086 return retval;
1087 }
1088
1089 return raw_afe_write_register(reg_address, value, reg_length);
1090 }
1091
afe_read_register(uint32_t target_reg,uint32_t * value)1092 int afe_read_register(uint32_t target_reg, uint32_t *value)
1093 {
1094 uint8_t reg_bank = 0;
1095 uint8_t reg_address = 0;
1096 uint8_t reg_length = 0;
1097 int retval = 0;
1098
1099 //
1100 // Parse register parameters from register offset
1101 //
1102
1103 // Top 2 bytes of address encodes the register address
1104 // Address Bits 23&24 are MSB address bits, which must be written into
1105 // ana_src_sel[1:0] as bank select. Bottom byte of address encodes the
1106 // register width in bytes 1 - 4 (8bits to 32bits)
1107
1108 reg_length = (target_reg & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS;
1109 reg_bank = (target_reg & AFE_REG_ADDR_BANK) >> AFE_REG_ADDR_BANK_POS;
1110 reg_address = (target_reg & AFE_REG_ADDR) >> AFE_REG_ADDR_POS;
1111
1112 retval = afe_bank_select(reg_bank);
1113
1114 if (retval != E_NO_ERROR) {
1115 return retval;
1116 }
1117
1118 return raw_afe_read_register(reg_address, value, reg_length);
1119 }
1120
afe_bank_read_register(uint32_t target_reg,uint8_t reg_bank,uint32_t * value)1121 int afe_bank_read_register(uint32_t target_reg, uint8_t reg_bank, uint32_t *value)
1122 {
1123 uint8_t reg_address = 0;
1124 uint8_t reg_length = 0;
1125 int retval = 0;
1126
1127 //
1128 // Parse register parameters from register offset
1129 //
1130
1131 // Top 2 bytes of address encodes the register address
1132 // Address Bits 23&24 are MSB address bits, which must be written into
1133 // ana_src_sel[1:0] as bank select. Bottom byte of address encodes the
1134 // register width in bytes 1 - 4 (8bits to 32bits)
1135
1136 reg_length = (target_reg & AFE_REG_ADDR_LEN) >> AFE_REG_ADDR_LEN_POS;
1137 reg_address = (target_reg & AFE_REG_ADDR) >> AFE_REG_ADDR_POS;
1138
1139 retval = afe_bank_select(reg_bank);
1140
1141 if (retval != E_NO_ERROR) {
1142 return retval;
1143 }
1144
1145 return raw_afe_read_register(reg_address, value, reg_length);
1146 }
1147
afe_load_trims(mxc_tmr_regs_t * tmr)1148 int afe_load_trims(mxc_tmr_regs_t *tmr)
1149 {
1150 int retval = 0;
1151 uint8_t info_buf[INFOBLOCK_LINE_SIZE];
1152 uint64_t afe_trim_low = 0;
1153 uint64_t afe_trim_high = 0;
1154 #ifdef DUMP_TRIM_DATA
1155 uint32_t read_val = 0;
1156 #endif
1157
1158 // setup the interface before we begin
1159 retval = afe_setup(tmr);
1160 if (retval != E_NO_ERROR) {
1161 return retval;
1162 }
1163
1164 //
1165 // Before Trimming, reset AFE to known state
1166 //
1167
1168 //
1169 // SYS_CTRL will be in a known state after a successful call to afe_setup()
1170 //
1171
1172 // Reset ADCs, as the MAX32675 Reset has no effect on them
1173 // After restoring POR defaults, ADCS enter Standby mode
1174 retval = afe_write_register(MXC_R_AFE_ADC_ZERO_PD, MXC_S_AFE_ADC_ZERO_PD_PD_RESET);
1175 if (retval != E_NO_ERROR) {
1176 return retval;
1177 }
1178 retval = afe_write_register(MXC_R_AFE_ADC_ONE_PD, MXC_S_AFE_ADC_ONE_PD_PD_RESET);
1179 if (retval != E_NO_ERROR) {
1180 return retval;
1181 }
1182
1183 //
1184 // Read in AFE Trims
1185 //
1186 retval = infoblock_read(AFE_TRIM_OTP_OFFSET_LOW, info_buf, INFOBLOCK_LINE_SIZE);
1187 if (retval != E_NO_ERROR) {
1188 return retval;
1189 }
1190
1191 for (int i = 7; i >= 0; i--) {
1192 afe_trim_low <<= 8;
1193 afe_trim_low |= info_buf[i];
1194 }
1195
1196 retval = infoblock_read(AFE_TRIM_OTP_OFFSET_HIGH, info_buf, INFOBLOCK_LINE_SIZE);
1197 if (retval != E_NO_ERROR) {
1198 return retval;
1199 }
1200
1201 for (int i = 7; i >= 0; i--) {
1202 afe_trim_high <<= 8;
1203 afe_trim_high |= info_buf[i];
1204 }
1205
1206 //
1207 // Parse out individual trims
1208 //
1209 // afe_trim_low
1210 trim_data.adc_trim0_adc0 = afe_trim_low & AFE_TRIM0_ADC0_MASK;
1211 afe_trim_low >>= AFE_TRIM0_ADC0_BIT_WIDTH;
1212
1213 trim_data.adc_trim1_adc0 = afe_trim_low & AFE_TRIM1_ADC0_MASK;
1214 afe_trim_low >>= AFE_TRIM1_ADC0_BIT_WIDTH;
1215
1216 trim_data.dac_trim = afe_trim_low & AFE_TRIM_DAC_MASK;
1217 afe_trim_low >>= AFE_TRIM_DAC_BIT_WIDTH;
1218
1219 trim_data.ana_trim_adc0 = afe_trim_low & AFE_TRIM_ANA_ADC0_MASK;
1220
1221 // afe_trim_high
1222 trim_data.adc_trim0_adc1 = afe_trim_high & AFE_TRIM0_ADC1_MASK;
1223 afe_trim_high >>= AFE_TRIM0_ADC1_BIT_WIDTH;
1224
1225 trim_data.adc_trim1_adc1 = afe_trim_high & AFE_TRIM1_ADC1_MASK;
1226 afe_trim_high >>= AFE_TRIM1_ADC1_BIT_WIDTH;
1227
1228 // Now got to take care of the ANA_TRIM_ADC1 which is embedded inside the HART trim
1229 trim_data.ana_trim_adc1 = afe_trim_high & AFE_TRIM_ANA_ADC1_MASK;
1230 trim_data.ana_trim_adc1 >>= AFE_TRIM_ANA_ADC1_OFFSET_1;
1231 trim_data.ana_trim_adc1 <<= AFE_TRIM_ANA_ADC1_OFFSET_2;
1232
1233 trim_data.hart_trim = afe_trim_high & AFE_TRIM_HART_MASK;
1234 // Force the embedded ANA trim to zeros.
1235 trim_data.hart_trim &= ~AFE_TRIM_ANA_ADC1_MASK;
1236 afe_trim_high >>= AFE_TRIM_HART_BIT_WIDTH;
1237
1238 trim_data.vref_trim = afe_trim_high & AFE_TRIM_VREF_MASK;
1239
1240 //
1241 // Dump Trims
1242 //
1243 #ifdef DUMP_TRIM_DATA
1244 printf("\n****************************************************\n");
1245 printf(" Trim Values Read from info block\n");
1246 printf("\n****************************************************\n");
1247
1248 printf("ADC0 adc trim 0: %08X\n", trim_data.adc_trim0_adc0);
1249 printf("ADC0 adc trim 1: %08X\n", trim_data.adc_trim1_adc0);
1250 printf("DAC trim: %08X\n", trim_data.dac_trim);
1251 printf("ANA ADC0 trim: %08X\n", trim_data.ana_trim_adc0);
1252
1253 printf("ADC1 adc trim 0: %08X\n", trim_data.adc_trim0_adc1);
1254 printf("ADC1 adc trim 1: %08X\n", trim_data.adc_trim1_adc1);
1255 printf("HART trim: %08X\n", trim_data.hart_trim);
1256 printf("ANA ADC1 trim: %08X\n", trim_data.ana_trim_adc1);
1257 printf("VREF trim: %08X\n", trim_data.vref_trim);
1258 #endif
1259
1260 //
1261 // Write Trims
1262 //
1263
1264 // Unlock trim for ADC0
1265 retval = afe_write_register(MXC_R_AFE_ADC_ZERO_FT_PWORD,
1266 MXC_V_AFE_ADC_ZERO_FT_PWORD_FT_PWORD_PWORD_1);
1267 if (retval != E_NO_ERROR) {
1268 return retval;
1269 }
1270 retval = afe_write_register(MXC_R_AFE_ADC_ZERO_FT_PWORD,
1271 MXC_V_AFE_ADC_ZERO_FT_PWORD_FT_PWORD_PWORD_2);
1272 if (retval != E_NO_ERROR) {
1273 return retval;
1274 }
1275
1276 // Unlock trim for ADC1
1277 retval =
1278 afe_write_register(MXC_R_AFE_ADC_ONE_FT_PWORD, MXC_V_AFE_ADC_ONE_FT_PWORD_FT_PWORD_PWORD_1);
1279 if (retval != E_NO_ERROR) {
1280 return retval;
1281 }
1282 retval =
1283 afe_write_register(MXC_R_AFE_ADC_ONE_FT_PWORD, MXC_V_AFE_ADC_ONE_FT_PWORD_FT_PWORD_PWORD_2);
1284 if (retval != E_NO_ERROR) {
1285 return retval;
1286 }
1287
1288 #ifdef DUMP_TRIM_DATA
1289 printf("\n****************************************************\n");
1290 printf(" AFE Trim Register before Writing (FT UNLOCKED)\n");
1291 printf("\n****************************************************\n");
1292
1293 afe_read_register(MXC_R_AFE_ADC_ZERO_ADC_TRIM0, &read_val);
1294 printf("ADC0 adc trim 0: %08X\n", read_val);
1295
1296 afe_read_register(MXC_R_AFE_ADC_ZERO_ADC_TRIM1, &read_val);
1297 printf("ADC0 adc trim 1: %08X\n", read_val);
1298
1299 afe_read_register(MXC_R_AFE_DAC_TRIM, &read_val);
1300 printf("DAC trim: %08X\n", read_val);
1301
1302 afe_read_register(MXC_R_AFE_ADC_ZERO_ANA_TRIM, &read_val);
1303 printf("ANA ADC0 trim: %08X\n", read_val);
1304
1305 afe_read_register(MXC_R_AFE_ADC_ONE_ADC_TRIM0, &read_val);
1306 printf("ADC1 adc trim 0: %08X\n", read_val);
1307
1308 afe_read_register(MXC_R_AFE_ADC_ONE_ADC_TRIM1, &read_val);
1309 printf("ADC1 adc trim 1: %08X\n", read_val);
1310
1311 afe_read_register(MXC_R_AFE_HART_TRIM, &read_val);
1312 printf("HART trim: %08X\n", read_val);
1313
1314 afe_read_register(MXC_R_AFE_ADC_ONE_ANA_TRIM, &read_val);
1315 printf("ANA ADC1 trim: %08X\n", read_val);
1316
1317 afe_read_register(MXC_R_AFE_DAC_VREF_TRIM, &read_val);
1318 printf("VREF trim: %08X\n", read_val);
1319
1320 printf("\n****************************************************\n");
1321 printf(" Writing Trim Values Into AFE\n");
1322 printf("\n****************************************************\n");
1323 #endif
1324
1325 retval = afe_write_register(MXC_R_AFE_ADC_ZERO_ADC_TRIM0, trim_data.adc_trim0_adc0);
1326 if (retval != E_NO_ERROR) {
1327 return retval;
1328 }
1329 retval = afe_write_register(MXC_R_AFE_ADC_ZERO_ADC_TRIM1, trim_data.adc_trim1_adc0);
1330 if (retval != E_NO_ERROR) {
1331 return retval;
1332 }
1333 retval = afe_write_register(MXC_R_AFE_DAC_TRIM, trim_data.dac_trim);
1334 if (retval != E_NO_ERROR) {
1335 return retval;
1336 }
1337 retval = afe_write_register(MXC_R_AFE_ADC_ZERO_ANA_TRIM, trim_data.ana_trim_adc0);
1338 if (retval != E_NO_ERROR) {
1339 return retval;
1340 }
1341 retval = afe_write_register(MXC_R_AFE_ADC_ONE_ADC_TRIM0, trim_data.adc_trim0_adc1);
1342 if (retval != E_NO_ERROR) {
1343 return retval;
1344 }
1345 retval = afe_write_register(MXC_R_AFE_ADC_ONE_ADC_TRIM1, trim_data.adc_trim1_adc1);
1346 if (retval != E_NO_ERROR) {
1347 return retval;
1348 }
1349 retval = afe_write_register(MXC_R_AFE_HART_TRIM, trim_data.hart_trim);
1350 if (retval != E_NO_ERROR) {
1351 return retval;
1352 }
1353 retval = afe_write_register(MXC_R_AFE_ADC_ONE_ANA_TRIM, trim_data.ana_trim_adc1);
1354 if (retval != E_NO_ERROR) {
1355 return retval;
1356 }
1357 retval = afe_write_register(MXC_R_AFE_DAC_VREF_TRIM, trim_data.vref_trim);
1358 if (retval != E_NO_ERROR) {
1359 return retval;
1360 }
1361
1362 #ifdef DUMP_TRIM_DATA
1363 printf("\n****************************************************\n");
1364 printf(" AFE Trim Register after Writing (FT UNLOCKED)\n");
1365 printf("\n****************************************************\n");
1366
1367 afe_read_register(MXC_R_AFE_ADC_ZERO_ADC_TRIM0, &read_val);
1368 printf("ADC0 adc trim 0: %08X\n", read_val);
1369
1370 afe_read_register(MXC_R_AFE_ADC_ZERO_ADC_TRIM1, &read_val);
1371 printf("ADC0 adc trim 1: %08X\n", read_val);
1372
1373 afe_read_register(MXC_R_AFE_DAC_TRIM, &read_val);
1374 printf("DAC trim: %08X\n", read_val);
1375
1376 afe_read_register(MXC_R_AFE_ADC_ZERO_ANA_TRIM, &read_val);
1377 printf("ANA ADC0 trim: %08X\n", read_val);
1378
1379 afe_read_register(MXC_R_AFE_ADC_ONE_ADC_TRIM0, &read_val);
1380 printf("ADC1 adc trim 0: %08X\n", read_val);
1381
1382 afe_read_register(MXC_R_AFE_ADC_ONE_ADC_TRIM1, &read_val);
1383 printf("ADC1 adc trim 1: %08X\n", read_val);
1384
1385 afe_read_register(MXC_R_AFE_HART_TRIM, &read_val);
1386 printf("HART trim: %08X\n", read_val);
1387
1388 afe_read_register(MXC_R_AFE_ADC_ONE_ANA_TRIM, &read_val);
1389 printf("ANA ADC1 trim: %08X\n", read_val);
1390
1391 afe_read_register(MXC_R_AFE_DAC_VREF_TRIM, &read_val);
1392 printf("VREF trim: %08X\n", read_val);
1393 #endif
1394
1395 // Lock Trims
1396 retval = afe_write_register(MXC_R_AFE_ADC_ONE_FT_PWORD, 0);
1397 if (retval != E_NO_ERROR) {
1398 return retval;
1399 }
1400 retval = afe_write_register(MXC_R_AFE_ADC_ZERO_FT_PWORD, 0);
1401
1402 return retval;
1403 }
1404
afe_dump_registers(uint32_t reg_bank)1405 void afe_dump_registers(uint32_t reg_bank)
1406 {
1407 uint32_t reg_add = 0;
1408 uint32_t reg_len = 0;
1409 uint32_t read_val = 0;
1410
1411 if (reg_bank == AFE_ADC0_BANK) {
1412 printf("Dumping registers of AFE ADC0 Bank\n");
1413 } else if (reg_bank == AFE_ADC1_BANK) {
1414 printf("Dumping registers of AFE ADC1 Bank\n");
1415 } else if (reg_bank == AFE_DAC_BANK) {
1416 printf("Dumping registers of AFE DAC Bank\n");
1417 } else if (reg_bank == AFE_HART_BANK) {
1418 printf("Dumping registers of AFE HART Bank\n");
1419 } else {
1420 printf("Unknown AFE bank number.\n");
1421 return;
1422 }
1423
1424 if ((reg_bank == AFE_ADC0_BANK) || (reg_bank == AFE_ADC1_BANK)) {
1425 reg_len = 1;
1426
1427 // 8 Bit Registers
1428 printf("\n** 8-bit Control Registers 0x00 - 0x10 **\n");
1429 for (reg_add = 0; reg_add < 0x11; reg_add++) {
1430 afe_read_register((reg_add << AFE_REG_ADDR_POS) | (reg_bank << AFE_REG_ADDR_BANK_POS) |
1431 (reg_len << AFE_REG_ADDR_LEN_POS),
1432 &read_val);
1433 printf("Reg 0x%02X is 0x%02X\n", reg_add, read_val);
1434 }
1435
1436 // 24 bit Registers
1437 printf("\n** 24-bit Control, Data, Status Registers 0x11 - 0x39 **\n");
1438 reg_len = 3;
1439 for (reg_add = 0x11; reg_add < 0x3A; reg_add++) {
1440 afe_read_register((reg_add << AFE_REG_ADDR_POS) | (reg_bank << AFE_REG_ADDR_BANK_POS) |
1441 (reg_len << AFE_REG_ADDR_LEN_POS),
1442 &read_val);
1443 printf("Reg 0x%02X is 0x%06X\n", reg_add, read_val);
1444 }
1445
1446 // 16 bit Registers
1447 printf("\n** 16-bit Sequencer Registers 0x3A - 0x6E **\n");
1448 reg_len = 2;
1449 for (reg_add = 0x3A; reg_add < 0x6F; reg_add++) {
1450 afe_read_register((reg_add << AFE_REG_ADDR_POS) | (reg_bank << AFE_REG_ADDR_BANK_POS) |
1451 (reg_len << AFE_REG_ADDR_LEN_POS),
1452 &read_val);
1453 printf("Reg 0x%02X is 0x%04X\n", reg_add, read_val);
1454 }
1455
1456 // UCADDR is only 8 bits
1457 printf("\n** 8-bit UCADDR Register **\n");
1458 reg_len = 1;
1459 reg_add = 0x6F;
1460 afe_read_register((reg_add << AFE_REG_ADDR_POS) | (reg_bank << AFE_REG_ADDR_BANK_POS) |
1461 (reg_len << AFE_REG_ADDR_LEN_POS),
1462 &read_val);
1463 printf("Reg 0x%02X is 0x%02X\n", 0x6F, read_val);
1464 } // End of ADC Register Dump
1465
1466 if (reg_bank == AFE_DAC_BANK) {
1467 reg_len = 4; // 32 Bit registers
1468 printf("\n** 32-bit DAC Registers 0x00 - 0x04 **\n");
1469 for (reg_add = 0x00; reg_add < 0x05; reg_add++) {
1470 afe_read_register((reg_add << AFE_REG_ADDR_POS) | (reg_bank << AFE_REG_ADDR_BANK_POS) |
1471 (reg_len << AFE_REG_ADDR_LEN_POS),
1472 &read_val);
1473 printf("Reg 0x%02X is 0x%08X\n", reg_add, read_val);
1474 }
1475
1476 reg_len = 3; // 24 Bit Registers
1477 printf("\n** 24-bit DAC Registers 0x05 - 0x07 **\n");
1478 for (reg_add = 0x05; reg_add < 0x08; reg_add++) {
1479 afe_read_register((reg_add << AFE_REG_ADDR_POS) | (reg_bank << AFE_REG_ADDR_BANK_POS) |
1480 (reg_len << AFE_REG_ADDR_LEN_POS),
1481 &read_val);
1482 printf("Reg 0x%02X is 0x%06X\n", reg_add, read_val);
1483 }
1484 } // End of ADC DAC Register Dump
1485
1486 if (reg_bank == AFE_HART_BANK) {
1487 reg_len = 3; // 24 Bit registers
1488 printf("\n** 24-bit HART Registers 0x00 - 0x0B **\n");
1489 for (reg_add = 0x00; reg_add < 0x0C; reg_add++) {
1490 afe_read_register((reg_add << AFE_REG_ADDR_POS) | (reg_bank << AFE_REG_ADDR_BANK_POS) |
1491 (reg_len << AFE_REG_ADDR_LEN_POS),
1492 &read_val);
1493 printf("Reg 0x%02X is 0x%06X\n", reg_add, read_val);
1494 }
1495 } // End of ADC HART Register Dump
1496
1497 printf("\n\n");
1498 }
1499