Article Using Warmboot Via API

Warmboot can be used in TES but can't be used to generate C99 code for warmboot due to the evaluation system limitations. In this document, a code sample of how you might use warmboot via APIs. Warmboot is detailed in greater detail in our User Guide.

There are two types of warmboot APIs: memory optimised and non-memory optimised. The ‘Max Array’ functions are the non-memory optimised version and the ‘Unique Array’ is the memory optimised version. In this document we will use the memory optimised functions.

The warmboot APIs are shown below and detailed more extensively in the doxygen file that comes with our SDK.

To use these, the general steps are:

  1. Use the adi_adrv9001_cals_InitCals_WarmBoot_UniqueEnabledCals_Get() function to calculate the memory requirements
  2. Assign the correct amount of memory as calculated
  3. Use the adi_adrv9001_cals_InitCals_WarmBoot_Coefficients_UniqueArray_Get/Set() functions to set and get wb coefficients to/from the assigned memory location

This should have much lower memory requirements than the non-memory optimised version.

A code snippet is shown below. This code snippet is an edited version of the auto-generated 'main.c' C99 code from TES. This file was used to replace the 'main.c' file and compiled and run in a similar fashion to as described here. An example method of reading and writing the coefficients to a binary file is also included. This may be useful if you intend to load calibrations that were stored previously.

/* This file contains code automatically generated by a machine. */
/* It has not been independently verified by any human. */
/* The generation process is deterministic and tested (not generative AI), */
/* but not every scenario or risk has been captured in unit tests. */
/* All code is provided as-is for example purposes only. */
/* The customer assumes all risks related to the use of this code. */

 

 

/* Transceiver Name: ADRV9002*/
/* Silicon Revision: C0*/
/* Evaluation Board Revision: 2A*/
/* Tx / Rx optimal carrier frequencies: 30 MHz to 3 GHz*/
/* External LO optimal frequencies: 60 MHz to 6 GHz*/
/* */
/* FPGA: v8.3.7*/
/* Device Driver API: v68.13.12*/
/* Device Driver Client: v68.13.12*/
/* Firmware: v0.22.33*/
/* Profile Generator: v0.53.7.0*/
/* Stream Generator Assembly: v0.7.12.0*/
/* Transceiver Evaluation Software: v0.26.1*/
/* ADRV9001 Plugin: v0.26.1*/

 

#include "initialize.h"
#include "calibrate.h"
#include "configure.h"
#include "prime.h"
#include "beginReceiving.h"
#include "dataCapture.h"
#include "stopReceiving.h"
#include "beginTransmitting.h"
#include "stopTransmitting.h"
#include <stdlib.h>
#include "linux_uio_init.h"
//extern adi_adrv9001_Init_t initialize_init_8;

 

 

int main()
{
  int32_t error_code = 0;

 

  adi_adrv9001_Device_t * adrv9001Device_0 = (adi_adrv9001_Device_t *) calloc(1, sizeof(adi_adrv9001_Device_t));

 

  adi_fpga9001_Device_t * fpga9001Device_0 = (adi_fpga9001_Device_t *) calloc(1, sizeof(adi_fpga9001_Device_t));

 

  error_code = linux_uio_initialize(adrv9001Device_0, fpga9001Device_0, NULL, NULL, NULL, NULL, NULL);
  ADI_HANDLE_ERROR(error_code);

 

 

  error_code = initialize(adrv9001Device_0, fpga9001Device_0);
  ADI_HANDLE_ERROR(error_code);

 

  error_code = calibrate(adrv9001Device_0);
  ADI_HANDLE_ERROR(error_code);

  printf("\033[0;32m");
  printf("%s", "\nCalibration is done and coefficients are stored for warm boot up. Press enter\n");
  getchar();
  ADI_HANDLE_ERROR(error_code);
  printf("\033[0;37m");

  //3. Get wb coefficients

 

  adi_adrv9001_InitCals_t initCals = {
    .sysInitCalMask = (adi_adrv9001_InitCalibrations_e) 0, 
    .chanInitCalMask = { ADI_ADRV9001_INIT_CAL_TX_QEC | ADI_ADRV9001_INIT_CAL_TX_LO_LEAKAGE | ADI_ADRV9001_INIT_CAL_TX_LB_PD | ADI_ADRV9001_INIT_CAL_TX_BBAF | ADI_ADRV9001_INIT_CAL_TX_BBAF_GD | ADI_ADRV9001_INIT_CAL_TX_ATTEN_DELAY | ADI_ADRV9001_INIT_CAL_TX_DAC | ADI_ADRV9001_INIT_CAL_TX_PATH_DELAY | ADI_ADRV9001_INIT_CAL_RX_HPADC_FLASH | ADI_ADRV9001_INIT_CAL_RX_LPADC | ADI_ADRV9001_INIT_CAL_RX_TIA_CUTOFF | ADI_ADRV9001_INIT_CAL_RX_GROUP_DELAY | ADI_ADRV9001_INIT_CAL_RX_QEC_TCAL | ADI_ADRV9001_INIT_CAL_RX_QEC_FIC | ADI_ADRV9001_INIT_CAL_RX_RF_DC_OFFSET | ADI_ADRV9001_INIT_CAL_RX_GAIN_PATH_DELAY, (adi_adrv9001_InitCalibrations_e) 0  }, 
    .calMode = ADI_ADRV9001_INIT_CAL_MODE_ALL, 
    .force = false};

 

  adi_adrv9001_Warmboot_CalNumbers_t  calNumbers = {}; 

  // 3.a Find wb memory requirements
  error_code = adi_adrv9001_cals_InitCals_WarmBoot_UniqueEnabledCals_Get(adrv9001Device_0, &calNumbers, initCals.chanInitCalMask[0], initCals.chanInitCalMask[1]);
ADI_HANDLE_ERROR(error_code);


  printf("Num Cals: %d, Num Bytes: %d \n", calNumbers.numberUniqueEnabledCals, calNumbers.warmbootMemoryNumBytes);

  // 3.b Allocate some memory for wb coeff
  char * wb_memStartAddress_get = (char *)calloc(1, calNumbers.warmbootMemoryNumBytes);

  // 3.c Get wb coeff
  error_code = adi_adrv9001_cals_InitCals_WarmBoot_Coefficients_UniqueArray_Get(adrv9001Device_0, wb_memStartAddress_get, initCals.chanInitCalMask[0], initCals.chanInitCalMask[1]);
ADI_HANDLE_ERROR(error_code);

//optionally save to file
  FILE* f_write = fopen("warmboot_coeff.bin", "wb");
  fwrite(wb_memStartAddress_get, calNumbers.warmbootMemoryNumBytes, 1, f_write);
  fclose(f_write);

 

  free(wb_memStartAddress_get);

//4. Reset
   printf("\033[0;32m");
   printf("%s", "\nHardware reset for initializing warm bootup. Press enter.\n");
   getchar();
   ADI_HANDLE_ERROR(error_code);
   printf("\033[0;37m");

 

  error_code = adi_adrv9001_HwReset(adrv9001Device_0);
  ADI_HANDLE_ERROR(error_code);


// 5. WB Init

  // 5.a set wb flag

  initialize_init_8.sysConfig.warmBootEnable = true;

  // 5.b init
  error_code = initialize(adrv9001Device_0, fpga9001Device_0);
ADI_HANDLE_ERROR(error_code);


//6. Set wb coefficients
  char * wb_memStartAddress_set = (char *)calloc(1, calNumbers.warmbootMemoryNumBytes);
  //optionally read from file
  FILE* f_read = fopen("warmboot_coeff.bin", "rb");
  fread(wb_memStartAddress_set, calNumbers.warmbootMemoryNumBytes, 1, f_read);
  fclose(f_read);

  error_code = adi_adrv9001_cals_InitCals_WarmBoot_Coefficients_UniqueArray_Set(adrv9001Device_0, wb_memStartAddress_set, initCals.chanInitCalMask[0], initCals.chanInitCalMask[1]);
ADI_HANDLE_ERROR(error_code);

free(wb_memStartAddress_set);

 

  //7. Wb cal
   printf("\033[0;32m");
   printf("%s", "\nUsing warm bootup coefficients. Press enter.\n");
   getchar();
   ADI_HANDLE_ERROR(error_code);
   printf("\033[0;37m");

 

  error_code = calibrate(adrv9001Device_0);
ADI_HANDLE_ERROR(error_code);

 

 

  
//8. Rest of Program
  error_code = configure(adrv9001Device_0);
  ADI_HANDLE_ERROR(error_code);

 

  error_code = prime(adrv9001Device_0);
  ADI_HANDLE_ERROR(error_code);

 

  error_code = beginReceiving(adrv9001Device_0, fpga9001Device_0);
  ADI_HANDLE_ERROR(error_code);

 

  error_code = dataCapture(fpga9001Device_0);
  ADI_HANDLE_ERROR(error_code);

 

  error_code = stopReceiving(fpga9001Device_0);
  ADI_HANDLE_ERROR(error_code);

 

  error_code = beginTransmitting(adrv9001Device_0, fpga9001Device_0);
  ADI_HANDLE_ERROR(error_code);

 

  error_code = stopTransmitting(fpga9001Device_0);
  ADI_HANDLE_ERROR(error_code);

 

 

  return error_code;
}

Before You Switch


Switching languages will make ADI Explorer unavailable. Resume your session by switching back to English and reopening ADI Explorer.