Files
RadioPhotonic_PCB_software/App/Devices/ad9102_device.c
2026-04-24 16:51:15 +03:00

717 lines
21 KiB
C

/**
* @file ad9102_device.c
* @brief AD9102 waveform-generation device driver.
*/
#include "ad9102_device.h"
#include "board_io.h"
#include "main.h"
/* AD9102 register map used by the existing firmware. See ad9102.pdf. */
#define AD9102_REG_SPICONFIG 0x0000u
#define AD9102_REG_POWERCONFIG 0x0001u
#define AD9102_REG_CLOCKCONFIG 0x0002u
#define AD9102_REG_RAMUPDATE 0x001Du
#define AD9102_REG_PAT_STATUS 0x001Eu
#define AD9102_REG_PAT_TYPE 0x001Fu
#define AD9102_REG_WAV_CONFIG 0x0027u
#define AD9102_REG_PAT_TIMEBASE 0x0028u
#define AD9102_REG_PAT_PERIOD 0x0029u
#define AD9102_REG_DAC_PAT 0x002Bu
#define AD9102_REG_SAW_CONFIG 0x0037u
#define AD9102_REG_START_DLY 0x005Cu
#define AD9102_REG_START_ADDR 0x005Du
#define AD9102_REG_STOP_ADDR 0x005Eu
#define AD9102_REG_CFG_ERROR 0x0060u
#define AD9102_REG_SRAM_DATA_BASE 0x6000u
#define AD9102_PAT_STATUS_RUN (1u << 0)
#define AD9102_SAW_TYPE_UP 0u
#define AD9102_SAW_TYPE_TRIANGLE 2u
#define AD9102_SAW_STEP_DEFAULT 1u
#define AD9102_PAT_PERIOD_BASE_DEFAULT 0x2u
#define AD9102_START_DELAY_BASE_DEFAULT 0x1u
#define AD9102_PAT_TIMEBASE_HOLD_DEFAULT 0x1u
#define AD9102_PAT_PERIOD_DEFAULT 0xFFFFu
#define AD9102_EX4_WAV_CONFIG 0x3212u
#define AD9102_EX4_SAW_CONFIG 0x0606u
#define AD9102_EX2_WAV_CONFIG 0x3030u
#define AD9102_EX2_DAC_PAT 0x0101u
#define AD9102_EX2_SAW_CONFIG 0x0200u
#define AD9102_SRAM_PAT_PERIOD_BASE_DEFAULT 0x1u
#define AD9102_SRAM_START_DELAY_BASE_DEFAULT 0x1u
#define AD9102_SRAM_START_DLY_DEFAULT 0x0000u
#define AD9102_SRAM_RAMP_MIN (-8192)
#define AD9102_SRAM_RAMP_MAX (8191)
#define AD9102_REG_COUNT 66u
#define AD9102_WAVE_MAX_CHUNK_SAMPLES 12u
static const uint16_t g_ad9102_reg_addr[AD9102_REG_COUNT] = {
0x0000u, 0x0001u, 0x0002u, 0x0003u, 0x0004u, 0x0005u, 0x0006u, 0x0007u,
0x0008u, 0x0009u, 0x000Au, 0x000Bu, 0x000Cu, 0x000Du, 0x000Eu, 0x001Fu,
0x0020u, 0x0022u, 0x0023u, 0x0024u, 0x0025u, 0x0026u, 0x0027u, 0x0028u,
0x0029u, 0x002Au, 0x002Bu, 0x002Cu, 0x002Du, 0x002Eu, 0x002Fu, 0x0030u,
0x0031u, 0x0032u, 0x0033u, 0x0034u, 0x0035u, 0x0036u, 0x0037u, 0x003Eu,
0x003Fu, 0x0040u, 0x0041u, 0x0042u, 0x0043u, 0x0044u, 0x0045u, 0x0047u,
0x0050u, 0x0051u, 0x0052u, 0x0053u, 0x0054u, 0x0055u, 0x0056u, 0x0057u,
0x0058u, 0x0059u, 0x005Au, 0x005Bu, 0x005Cu, 0x005Du, 0x005Eu, 0x005Fu,
0x001Eu, 0x001Du
};
static const uint16_t g_ad9102_example4_regval[AD9102_REG_COUNT] = {
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x4000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x1F00u, 0x0000u, 0x0000u, 0x0000u,
0x000Eu, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x3212u, 0x0121u,
0xFFFFu, 0x0000u, 0x0101u, 0x0003u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x4000u, 0x0000u, 0x0606u, 0x1999u,
0x9A00u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0FA0u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x16FFu,
0x0001u, 0x0001u
};
static const uint16_t g_ad9102_example2_regval[AD9102_REG_COUNT] = {
0x0000u, 0x0E00u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x4000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x1F00u, 0x0000u, 0x0000u, 0x0000u,
0x000Eu, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x3030u, 0x0111u,
0xFFFFu, 0x0000u, 0x0101u, 0x0003u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x4000u, 0x0000u, 0x0200u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u, 0x0FA0u, 0x0000u, 0x3FF0u, 0x0100u,
0x0001u, 0x0001u
};
typedef struct ad9102_upload_state_t {
uint8_t active;
uint16_t expected_samples;
uint16_t written_samples;
} ad9102_upload_state_t;
static ad9102_upload_state_t g_upload_state;
static void ad9102_write_reg(uint16_t address, uint16_t value)
{
uint16_t command = (uint16_t)(address & 0x7FFFu);
uint32_t timeout = 0u;
board_io_configure_spi2_mode(LL_SPI_POLARITY_LOW, LL_SPI_PHASE_1EDGE);
HAL_GPIO_WritePin(DAC_LD1_CS_GPIO_Port, DAC_LD1_CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DAC_TEC1_CS_GPIO_Port, DAC_TEC1_CS_Pin, GPIO_PIN_SET);
if (!LL_SPI_IsEnabled(SPI2))
{
LL_SPI_Enable(SPI2);
}
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_RESET);
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
{
}
LL_SPI_TransmitData16(SPI2, command);
timeout = 0u;
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
{
}
(void)SPI2->DR;
timeout = 0u;
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
{
}
LL_SPI_TransmitData16(SPI2, value);
timeout = 0u;
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
{
}
(void)SPI2->DR;
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
}
static uint16_t ad9102_read_reg(uint16_t address)
{
uint16_t command = (uint16_t)(0x8000u | (address & 0x7FFFu));
uint16_t value;
uint32_t timeout = 0u;
board_io_configure_spi2_mode(LL_SPI_POLARITY_LOW, LL_SPI_PHASE_1EDGE);
HAL_GPIO_WritePin(DAC_LD1_CS_GPIO_Port, DAC_LD1_CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(DAC_TEC1_CS_GPIO_Port, DAC_TEC1_CS_Pin, GPIO_PIN_SET);
if (!LL_SPI_IsEnabled(SPI2))
{
LL_SPI_Enable(SPI2);
}
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_RESET);
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
{
}
LL_SPI_TransmitData16(SPI2, command);
timeout = 0u;
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
{
}
(void)SPI2->DR;
timeout = 0u;
while ((!LL_SPI_IsActiveFlag_TXE(SPI2)) && (timeout++ < 1000u))
{
}
LL_SPI_TransmitData16(SPI2, 0x0000u);
timeout = 0u;
while ((!LL_SPI_IsActiveFlag_RXNE(SPI2)) && (timeout++ < 1000u))
{
}
value = LL_SPI_ReceiveData16(SPI2);
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
return value;
}
static void ad9102_write_reg_table(const uint16_t *values, uint16_t count)
{
uint16_t index;
for (index = 0u; index < count; ++index)
{
ad9102_write_reg(g_ad9102_reg_addr[index], values[index]);
}
}
static void ad9102_reset_upload_state(void)
{
g_upload_state.active = 0u;
g_upload_state.expected_samples = 0u;
g_upload_state.written_samples = 0u;
}
static void ad9102_start_output(void)
{
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_SET);
ad9102_write_reg(AD9102_REG_PAT_STATUS, AD9102_PAT_STATUS_RUN);
ad9102_write_reg(AD9102_REG_RAMUPDATE, 0x0001u);
for (volatile uint32_t delay_counter = 0u; delay_counter < 1000u; ++delay_counter)
{
}
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_RESET);
}
static void ad9102_configure_sram_playback(uint16_t sample_count, uint8_t hold_cycles)
{
uint16_t pat_timebase;
uint32_t pat_period;
if (sample_count < 2u)
{
sample_count = 2u;
}
if (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT)
{
sample_count = AD9102_SRAM_MAX_SAMPLE_COUNT;
}
if (hold_cycles == 0u)
{
hold_cycles = AD9102_SRAM_DEFAULT_HOLD;
}
if (hold_cycles > 0x0Fu)
{
hold_cycles = 0x0Fu;
}
pat_timebase = (uint16_t)(((uint16_t)(hold_cycles & 0x0Fu) << 8) |
((AD9102_SRAM_PAT_PERIOD_BASE_DEFAULT & 0x0Fu) << 4) |
(AD9102_SRAM_START_DELAY_BASE_DEFAULT & 0x0Fu));
pat_period = (uint32_t)sample_count * (uint32_t)(hold_cycles & 0x0Fu);
if (pat_period == 0u)
{
pat_period = sample_count;
}
if (pat_period > 0xFFFFu)
{
pat_period = 0xFFFFu;
}
ad9102_write_reg_table(g_ad9102_example2_regval, AD9102_REG_COUNT);
ad9102_stop_output();
ad9102_write_reg(AD9102_REG_WAV_CONFIG, AD9102_EX2_WAV_CONFIG);
ad9102_write_reg(AD9102_REG_SAW_CONFIG, AD9102_EX2_SAW_CONFIG);
ad9102_write_reg(AD9102_REG_DAC_PAT, AD9102_EX2_DAC_PAT);
ad9102_write_reg(AD9102_REG_PAT_TIMEBASE, pat_timebase);
ad9102_write_reg(AD9102_REG_PAT_PERIOD, (uint16_t)pat_period);
ad9102_write_reg(AD9102_REG_PAT_TYPE, 0x0000u);
ad9102_write_reg(AD9102_REG_START_DLY, AD9102_SRAM_START_DLY_DEFAULT);
ad9102_write_reg(AD9102_REG_START_ADDR, 0x0000u);
ad9102_write_reg(AD9102_REG_STOP_ADDR, (uint16_t)((sample_count - 1u) << 4));
ad9102_write_reg(AD9102_REG_RAMUPDATE, 0x0001u);
}
static void ad9102_load_sram_ramp(uint16_t sample_count, uint8_t triangle_mode, uint16_t amplitude)
{
uint16_t sample_index;
if (sample_count < 2u)
{
sample_count = 2u;
}
if (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT)
{
sample_count = AD9102_SRAM_MAX_SAMPLE_COUNT;
}
if (amplitude > AD9102_SRAM_DEFAULT_AMPLITUDE)
{
amplitude = AD9102_SRAM_DEFAULT_AMPLITUDE;
}
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0004u);
for (sample_index = 0u; sample_index < sample_count; ++sample_index)
{
int32_t value;
int32_t min_value = -(int32_t)amplitude;
int32_t max_value = (int32_t)amplitude;
int32_t span = max_value - min_value;
if (triangle_mode != 0u)
{
uint16_t half = sample_count / 2u;
if (half == 0u)
{
half = 1u;
}
if (sample_index < half)
{
uint16_t denominator = (half > 1u) ? (uint16_t)(half - 1u) : 1u;
value = min_value + (span * (int32_t)sample_index) / (int32_t)denominator;
}
else
{
uint16_t tail = (uint16_t)(sample_count - half);
uint16_t denominator = (tail > 1u) ? (uint16_t)(tail - 1u) : 1u;
value = max_value - (span * (int32_t)(sample_index - half)) / (int32_t)denominator;
}
}
else
{
uint16_t denominator = (sample_count > 1u) ? (uint16_t)(sample_count - 1u) : 1u;
value = min_value + (span * (int32_t)sample_index) / (int32_t)denominator;
}
if (value < AD9102_SRAM_RAMP_MIN)
{
value = AD9102_SRAM_RAMP_MIN;
}
else if (value > AD9102_SRAM_RAMP_MAX)
{
value = AD9102_SRAM_RAMP_MAX;
}
ad9102_write_reg((uint16_t)(AD9102_REG_SRAM_DATA_BASE + sample_index),
(uint16_t)(((uint16_t)((int16_t)value) & 0x3FFFu) << 2));
}
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0000u);
}
void ad9102_init(void)
{
HAL_GPIO_WritePin(AD9102_CS_GPIO_Port, AD9102_CS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9102_RESET_GPIO_Port, AD9102_RESET_Pin, GPIO_PIN_RESET);
for (volatile uint32_t delay_counter = 0u; delay_counter < 1000u; ++delay_counter)
{
}
HAL_GPIO_WritePin(AD9102_RESET_GPIO_Port, AD9102_RESET_Pin, GPIO_PIN_SET);
ad9102_write_reg_table(g_ad9102_example4_regval, AD9102_REG_COUNT);
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0000u);
ad9102_write_reg(AD9102_REG_RAMUPDATE, 0x0001u);
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_SET);
ad9102_reset_upload_state();
}
void ad9102_stop_output(void)
{
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0000u);
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_SET);
}
uint16_t ad9102_apply_saw(uint8_t saw_type,
uint8_t enabled,
uint8_t saw_step,
uint8_t pat_period_base,
uint16_t pat_period)
{
uint16_t saw_config;
uint16_t pat_timebase;
ad9102_reset_upload_state();
if (enabled == 0u)
{
ad9102_stop_output();
return ad9102_read_reg(AD9102_REG_PAT_STATUS);
}
if (saw_step == 0u)
{
saw_step = AD9102_SAW_STEP_DEFAULT;
}
else if (saw_step > 63u)
{
saw_step = 63u;
}
if (pat_period == 0u)
{
pat_period = AD9102_PAT_PERIOD_DEFAULT;
}
saw_config = (uint16_t)(((uint16_t)(saw_step & 0x3Fu) << 2) | ((uint16_t)(saw_type & 0x3u)));
pat_timebase = (uint16_t)(((AD9102_PAT_TIMEBASE_HOLD_DEFAULT & 0x0Fu) << 8) |
((pat_period_base & 0x0Fu) << 4) |
(AD9102_START_DELAY_BASE_DEFAULT & 0x0Fu));
ad9102_write_reg(AD9102_REG_WAV_CONFIG, AD9102_EX4_WAV_CONFIG);
ad9102_write_reg(AD9102_REG_SAW_CONFIG, saw_config);
ad9102_write_reg(AD9102_REG_PAT_TIMEBASE, pat_timebase);
ad9102_write_reg(AD9102_REG_PAT_PERIOD, pat_period);
ad9102_write_reg(AD9102_REG_PAT_TYPE, 0x0000u);
ad9102_start_output();
return ad9102_read_reg(AD9102_REG_PAT_STATUS);
}
uint16_t ad9102_apply_generated_sram(uint8_t enabled,
uint16_t sample_count,
uint8_t hold_cycles,
uint8_t triangle_mode,
uint16_t amplitude)
{
ad9102_reset_upload_state();
if (sample_count == 0u)
{
sample_count = AD9102_SRAM_DEFAULT_SAMPLE_COUNT;
}
if (sample_count < 2u)
{
sample_count = 2u;
}
if (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT)
{
sample_count = AD9102_SRAM_MAX_SAMPLE_COUNT;
}
if (hold_cycles == 0u)
{
hold_cycles = AD9102_SRAM_DEFAULT_HOLD;
}
if (hold_cycles > 0x0Fu)
{
hold_cycles = 0x0Fu;
}
if (amplitude > AD9102_SRAM_DEFAULT_AMPLITUDE)
{
amplitude = AD9102_SRAM_DEFAULT_AMPLITUDE;
}
ad9102_configure_sram_playback(sample_count, hold_cycles);
ad9102_load_sram_ramp(sample_count, triangle_mode, amplitude);
if (enabled != 0u)
{
ad9102_start_output();
}
else
{
ad9102_stop_output();
}
return ad9102_read_reg(AD9102_REG_PAT_STATUS);
}
bool ad9102_begin_custom_upload(uint16_t sample_count)
{
if ((sample_count < 2u) || (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT))
{
return false;
}
ad9102_stop_output();
ad9102_reset_upload_state();
ad9102_configure_sram_playback(sample_count, AD9102_SRAM_DEFAULT_HOLD);
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0004u);
g_upload_state.expected_samples = sample_count;
g_upload_state.written_samples = 0u;
g_upload_state.active = 1u;
return true;
}
bool ad9102_write_custom_chunk(const uint16_t *samples, uint16_t chunk_count)
{
uint16_t index;
if ((samples == NULL) || (g_upload_state.active == 0u))
{
return false;
}
if ((chunk_count == 0u) || (chunk_count > AD9102_WAVE_MAX_CHUNK_SAMPLES))
{
return false;
}
if (((uint32_t)g_upload_state.written_samples + (uint32_t)chunk_count) >
(uint32_t)g_upload_state.expected_samples)
{
return false;
}
for (index = 0u; index < chunk_count; ++index)
{
int16_t sample = (int16_t)samples[index];
if ((sample < AD9102_SRAM_RAMP_MIN) || (sample > AD9102_SRAM_RAMP_MAX))
{
return false;
}
ad9102_write_reg((uint16_t)(AD9102_REG_SRAM_DATA_BASE + g_upload_state.written_samples + index),
(uint16_t)(((uint16_t)sample & 0x3FFFu) << 2));
}
g_upload_state.written_samples = (uint16_t)(g_upload_state.written_samples + chunk_count);
return true;
}
uint16_t ad9102_commit_custom_upload(bool *out_ok)
{
uint16_t pat_status;
if (out_ok != NULL)
{
*out_ok = false;
}
if ((g_upload_state.active == 0u) ||
(g_upload_state.expected_samples < 2u) ||
(g_upload_state.written_samples != g_upload_state.expected_samples))
{
ad9102_cancel_custom_upload();
return ad9102_read_reg(AD9102_REG_PAT_STATUS);
}
ad9102_write_reg(AD9102_REG_PAT_STATUS, 0x0000u);
ad9102_write_reg(AD9102_REG_START_ADDR, 0x0000u);
ad9102_write_reg(AD9102_REG_STOP_ADDR, (uint16_t)((g_upload_state.expected_samples - 1u) << 4));
ad9102_write_reg(AD9102_REG_RAMUPDATE, 0x0001u);
ad9102_start_output();
pat_status = ad9102_read_reg(AD9102_REG_PAT_STATUS);
ad9102_reset_upload_state();
if (out_ok != NULL)
{
*out_ok = true;
}
return pat_status;
}
void ad9102_cancel_custom_upload(void)
{
if (g_upload_state.active != 0u)
{
ad9102_stop_output();
}
ad9102_reset_upload_state();
}
uint8_t ad9102_check_saw_configuration(uint16_t pat_status,
uint8_t expect_run,
uint8_t saw_type,
uint8_t saw_step,
uint8_t pat_period_base,
uint16_t pat_period)
{
uint16_t spiconfig = ad9102_read_reg(AD9102_REG_SPICONFIG);
uint16_t power_config = ad9102_read_reg(AD9102_REG_POWERCONFIG);
uint16_t clock_config = ad9102_read_reg(AD9102_REG_CLOCKCONFIG);
uint16_t config_error = ad9102_read_reg(AD9102_REG_CFG_ERROR);
uint16_t pat_timebase = (uint16_t)(((AD9102_PAT_TIMEBASE_HOLD_DEFAULT & 0x0Fu) << 8) |
((pat_period_base & 0x0Fu) << 4) |
(AD9102_START_DELAY_BASE_DEFAULT & 0x0Fu));
uint16_t expected_saw;
uint8_t ok = 1u;
if (saw_step == 0u)
{
saw_step = AD9102_SAW_STEP_DEFAULT;
}
if (saw_step > 63u)
{
saw_step = 63u;
}
if (pat_period == 0u)
{
pat_period = AD9102_PAT_PERIOD_DEFAULT;
}
expected_saw = (uint16_t)(((uint16_t)(saw_step & 0x3Fu) << 2) | ((uint16_t)(saw_type & 0x3u)));
if (spiconfig != 0x0000u)
{
ok = 0u;
}
if (power_config & ((1u << 8) | (1u << 7) | (1u << 6) | (1u << 5) | (1u << 3)))
{
ok = 0u;
}
if (clock_config & ((1u << 11) | (1u << 7) | (1u << 6) | (1u << 5)))
{
ok = 0u;
}
if (config_error & 0x003Fu)
{
ok = 0u;
}
if ((expect_run != 0u) && ((pat_status & AD9102_PAT_STATUS_RUN) == 0u))
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_WAV_CONFIG) != AD9102_EX4_WAV_CONFIG)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_PAT_TIMEBASE) != pat_timebase)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_PAT_PERIOD) != pat_period)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_PAT_TYPE) != 0x0000u)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_SAW_CONFIG) != expected_saw)
{
ok = 0u;
}
return (ok != 0u) ? 0u : 1u;
}
uint8_t ad9102_check_sram_configuration(uint16_t pat_status,
uint8_t expect_run,
uint16_t sample_count,
uint8_t hold_cycles)
{
uint16_t spiconfig = ad9102_read_reg(AD9102_REG_SPICONFIG);
uint16_t power_config = ad9102_read_reg(AD9102_REG_POWERCONFIG);
uint16_t clock_config = ad9102_read_reg(AD9102_REG_CLOCKCONFIG);
uint16_t config_error = ad9102_read_reg(AD9102_REG_CFG_ERROR);
uint16_t pat_timebase;
uint32_t pat_period;
uint16_t stop_address;
uint8_t ok = 1u;
if (sample_count == 0u)
{
sample_count = AD9102_SRAM_DEFAULT_SAMPLE_COUNT;
}
if (sample_count < 2u)
{
sample_count = 2u;
}
if (sample_count > AD9102_SRAM_MAX_SAMPLE_COUNT)
{
sample_count = AD9102_SRAM_MAX_SAMPLE_COUNT;
}
if (hold_cycles == 0u)
{
hold_cycles = AD9102_SRAM_DEFAULT_HOLD;
}
if (hold_cycles > 0x0Fu)
{
hold_cycles = 0x0Fu;
}
pat_timebase = (uint16_t)(((uint16_t)(hold_cycles & 0x0Fu) << 8) |
((AD9102_SRAM_PAT_PERIOD_BASE_DEFAULT & 0x0Fu) << 4) |
(AD9102_SRAM_START_DELAY_BASE_DEFAULT & 0x0Fu));
pat_period = (uint32_t)sample_count * (uint32_t)(hold_cycles & 0x0Fu);
if (pat_period == 0u)
{
pat_period = sample_count;
}
if (pat_period > 0xFFFFu)
{
pat_period = 0xFFFFu;
}
stop_address = (uint16_t)((sample_count - 1u) << 4);
if (spiconfig != 0x0000u)
{
ok = 0u;
}
if (power_config & ((1u << 8) | (1u << 7) | (1u << 6) | (1u << 5) | (1u << 3)))
{
ok = 0u;
}
if (clock_config & ((1u << 11) | (1u << 7) | (1u << 6) | (1u << 5)))
{
ok = 0u;
}
if (config_error & 0x003Fu)
{
ok = 0u;
}
if ((expect_run != 0u) && ((pat_status & AD9102_PAT_STATUS_RUN) == 0u))
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_WAV_CONFIG) != AD9102_EX2_WAV_CONFIG)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_PAT_TIMEBASE) != pat_timebase)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_PAT_PERIOD) != (uint16_t)pat_period)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_PAT_TYPE) != 0x0000u)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_START_ADDR) != 0x0000u)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_STOP_ADDR) != stop_address)
{
ok = 0u;
}
if (ad9102_read_reg(AD9102_REG_DAC_PAT) != AD9102_EX2_DAC_PAT)
{
ok = 0u;
}
return (ok != 0u) ? 0u : 1u;
}