added sram saw

This commit is contained in:
Ayzen
2026-02-03 19:29:57 +03:00
parent fedc27bfa8
commit 7442f4dd3a
7 changed files with 24016 additions and 22093 deletions

View File

@ -44,7 +44,12 @@
#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_SRAM_DATA_BASE 0x6000u
#define AD9102_REG_CFG_ERROR 0x0060u
#define AD9102_PAT_STATUS_RUN (1u << 0)
@ -68,14 +73,28 @@
#define AD9102_EX4_PAT_PERIOD 0xFFFFu
#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_HOLD_DEFAULT 0x1u
#define AD9102_SRAM_SAMPLES_DEFAULT 16u
#define AD9102_SRAM_MAX_SAMPLES 4096u
#define AD9102_SRAM_RAMP_MIN (-8192)
#define AD9102_SRAM_RAMP_MAX (8191)
#define AD9102_SRAM_RAMP_SPAN (AD9102_SRAM_RAMP_MAX - AD9102_SRAM_RAMP_MIN)
#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_FLAG_ENABLE 0x0001u
#define AD9102_FLAG_TRIANGLE 0x0002u
#define AD9102_FLAG_ENABLE 0x0001u
#define AD9102_FLAG_TRIANGLE 0x0002u
#define AD9102_FLAG_SRAM 0x0004u
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
@ -124,17 +143,29 @@ static const uint16_t ad9102_reg_addr[AD9102_REG_COUNT] = {
0x001eu, 0x001du
};
static const uint16_t 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 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 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
};
@ -175,7 +206,10 @@ static void AD9102_WriteReg(uint16_t addr, uint16_t value);
static uint16_t AD9102_ReadReg(uint16_t addr);
static void AD9102_WriteRegTable(const uint16_t *values, uint16_t count);
static uint16_t AD9102_Apply(uint8_t saw_type, uint8_t enable, uint8_t saw_step, uint8_t pat_base, uint16_t pat_period);
static uint16_t AD9102_ApplySram(uint8_t enable, uint16_t samples, uint8_t hold, uint8_t triangle);
static void AD9102_LoadSramRamp(uint16_t samples, uint8_t triangle);
static uint8_t AD9102_CheckFlags(uint16_t pat_status, uint8_t expect_run, uint8_t saw_type, uint8_t saw_step, uint8_t pat_base, uint16_t pat_period);
static uint8_t AD9102_CheckFlagsSram(uint16_t pat_status, uint8_t expect_run, uint16_t samples, uint8_t hold);
uint8_t CheckChecksum(uint16_t *pbuff);
uint16_t CalculateChecksum(uint16_t *pbuff, uint16_t len);
//int SD_Init(void);
@ -435,45 +469,61 @@ int main(void)
}
break;
case AD9102_CMD://10 - Configure AD9102 sawtooth output
if (CalculateChecksum(COMMAND, AD9102_CMD_WORDS - 1) == COMMAND[AD9102_CMD_WORDS - 1])
if (CalculateChecksum(COMMAND, AD9102_CMD_WORDS - 1) == COMMAND[AD9102_CMD_WORDS - 1])
{
uint16_t flags = COMMAND[0];
uint16_t param0 = COMMAND[1];
uint16_t param1 = COMMAND[2];
uint8_t enable = (flags & AD9102_FLAG_ENABLE) ? 1u : 0u;
uint8_t triangle = (flags & AD9102_FLAG_TRIANGLE) ? 1u : 0u;
uint8_t saw_type = triangle ? AD9102_SAW_TYPE_TRI : AD9102_SAW_TYPE_UP;
uint8_t saw_step = (uint8_t)(param0 & 0x00FFu);
uint8_t pat_base = (uint8_t)((param0 >> 8) & 0x0Fu);
uint16_t pat_period = param1;
uint8_t sram_mode = (flags & AD9102_FLAG_SRAM) ? 1u : 0u;
if (param0 == 0u && param1 == 0u)
if (sram_mode)
{
saw_step = AD9102_SAW_STEP_DEFAULT;
pat_base = AD9102_PAT_PERIOD_BASE_DEFAULT;
pat_period = AD9102_PAT_PERIOD_DEFAULT;
uint16_t samples = param0;
uint8_t hold = (uint8_t)(param1 & 0x0Fu);
uint16_t pat_status = AD9102_ApplySram(enable, samples, hold, triangle);
State_Data[1] = (uint8_t)(pat_status & 0x00FFu);
if (AD9102_CheckFlagsSram(pat_status, enable, samples, hold))
{
State_Data[0] |= AD9102_ERR;
}
}
else
{
if (saw_step == 0u)
uint8_t saw_type = triangle ? AD9102_SAW_TYPE_TRI : AD9102_SAW_TYPE_UP;
uint8_t saw_step = (uint8_t)(param0 & 0x00FFu);
uint8_t pat_base = (uint8_t)((param0 >> 8) & 0x0Fu);
uint16_t pat_period = param1;
if (param0 == 0u && param1 == 0u)
{
saw_step = AD9102_SAW_STEP_DEFAULT;
}
else if (saw_step > 63u)
{
saw_step = 63u;
}
if (pat_period == 0u)
{
pat_base = AD9102_PAT_PERIOD_BASE_DEFAULT;
pat_period = AD9102_PAT_PERIOD_DEFAULT;
}
}
else
{
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;
}
}
uint16_t pat_status = AD9102_Apply(saw_type, enable, saw_step, pat_base, pat_period);
State_Data[1] = (uint8_t)(pat_status & 0x00FFu);
if (AD9102_CheckFlags(pat_status, enable, saw_type, saw_step, pat_base, pat_period))
{
State_Data[0] |= AD9102_ERR;
uint16_t pat_status = AD9102_Apply(saw_type, enable, saw_step, pat_base, pat_period);
State_Data[1] = (uint8_t)(pat_status & 0x00FFu);
if (AD9102_CheckFlags(pat_status, enable, saw_type, saw_step, pat_base, pat_period))
{
State_Data[0] |= AD9102_ERR;
}
}
}
else
@ -2521,6 +2571,137 @@ static uint16_t AD9102_Apply(uint8_t saw_type, uint8_t enable, uint8_t saw_step,
return AD9102_ReadReg(AD9102_REG_PAT_STATUS);
}
static void AD9102_LoadSramRamp(uint16_t samples, uint8_t triangle)
{
if (samples < 2u)
{
samples = 2u;
}
if (samples > AD9102_SRAM_MAX_SAMPLES)
{
samples = AD9102_SRAM_MAX_SAMPLES;
}
// Enable SRAM access.
AD9102_WriteReg(AD9102_REG_PAT_STATUS, 0x0004u);
for (uint16_t i = 0; i < samples; i++)
{
int32_t value;
if (triangle)
{
uint16_t half = samples / 2u;
if (half == 0u)
{
half = 1u;
}
if (i < half)
{
uint16_t denom = (half > 1u) ? (uint16_t)(half - 1u) : 1u;
value = AD9102_SRAM_RAMP_MIN +
((int32_t)AD9102_SRAM_RAMP_SPAN * (int32_t)i) / (int32_t)denom;
}
else
{
uint16_t tail = (uint16_t)(samples - half);
uint16_t denom = (tail > 1u) ? (uint16_t)(tail - 1u) : 1u;
value = AD9102_SRAM_RAMP_MAX -
((int32_t)AD9102_SRAM_RAMP_SPAN * (int32_t)(i - half)) / (int32_t)denom;
}
}
else
{
uint16_t denom = (samples > 1u) ? (uint16_t)(samples - 1u) : 1u;
value = AD9102_SRAM_RAMP_MIN +
((int32_t)AD9102_SRAM_RAMP_SPAN * (int32_t)i) / (int32_t)denom;
}
if (value < -8192)
{
value = -8192;
}
else if (value > 8191)
{
value = 8191;
}
uint16_t sample_u14 = (uint16_t)((int16_t)value) & 0x3FFFu;
uint16_t word = (uint16_t)(sample_u14 << 2);
AD9102_WriteReg((uint16_t)(AD9102_REG_SRAM_DATA_BASE + i), word);
}
// Disable SRAM access.
AD9102_WriteReg(AD9102_REG_PAT_STATUS, 0x0000u);
}
static uint16_t AD9102_ApplySram(uint8_t enable, uint16_t samples, uint8_t hold, uint8_t triangle)
{
if (samples == 0u)
{
samples = AD9102_SRAM_SAMPLES_DEFAULT;
}
if (samples < 2u)
{
samples = 2u;
}
if (samples > AD9102_SRAM_MAX_SAMPLES)
{
samples = AD9102_SRAM_MAX_SAMPLES;
}
if (hold == 0u)
{
hold = AD9102_SRAM_HOLD_DEFAULT;
}
if (hold > 0x0Fu)
{
hold = 0x0Fu;
}
uint16_t pat_timebase = (uint16_t)(((uint16_t)(hold & 0x0Fu) << 8) |
((AD9102_SRAM_PAT_PERIOD_BASE_DEFAULT & 0x0Fu) << 4) |
(AD9102_SRAM_START_DELAY_BASE_DEFAULT & 0x0Fu));
uint32_t pat_period = (uint32_t)samples * (uint32_t)(hold & 0x0Fu);
if (pat_period == 0u)
{
pat_period = samples;
}
if (pat_period > 0xFFFFu)
{
pat_period = 0xFFFFu;
}
AD9102_WriteRegTable(ad9102_example2_regval, AD9102_REG_COUNT);
AD9102_WriteReg(AD9102_REG_PAT_STATUS, 0x0000u);
AD9102_WriteReg(AD9102_REG_WAV_CONFIG, AD9102_EX2_WAV_CONFIG);
AD9102_WriteReg(AD9102_REG_SAW_CONFIG, AD9102_EX2_SAW_CONFIG);
AD9102_WriteReg(AD9102_REG_DAC_PAT, AD9102_EX2_DAC_PAT);
AD9102_WriteReg(AD9102_REG_PAT_TIMEBASE, pat_timebase);
AD9102_WriteReg(AD9102_REG_PAT_PERIOD, (uint16_t)pat_period);
AD9102_WriteReg(AD9102_REG_PAT_TYPE, 0x0000u); // continuous pattern repeat
AD9102_WriteReg(AD9102_REG_START_DLY, AD9102_SRAM_START_DLY_DEFAULT);
AD9102_WriteReg(AD9102_REG_START_ADDR, 0x0000u);
AD9102_WriteReg(AD9102_REG_STOP_ADDR, (uint16_t)((samples - 1u) << 4));
AD9102_WriteReg(AD9102_REG_RAMUPDATE, 0x0001u);
AD9102_LoadSramRamp(samples, triangle);
if (enable)
{
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_SET);
AD9102_WriteReg(AD9102_REG_PAT_STATUS, AD9102_PAT_STATUS_RUN);
AD9102_WriteReg(AD9102_REG_RAMUPDATE, 0x0001u);
for (volatile uint32_t d = 0; d < 1000; d++) {}
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_RESET);
}
else
{
AD9102_WriteReg(AD9102_REG_PAT_STATUS, 0x0000u);
HAL_GPIO_WritePin(AD9102_TRIG_GPIO_Port, AD9102_TRIG_Pin, GPIO_PIN_SET);
}
return AD9102_ReadReg(AD9102_REG_PAT_STATUS);
}
static uint8_t AD9102_CheckFlags(uint16_t pat_status, uint8_t expect_run, uint8_t saw_type, uint8_t saw_step, uint8_t pat_base, uint16_t pat_period)
{
uint16_t spiconfig = AD9102_ReadReg(AD9102_REG_SPICONFIG);
@ -2600,6 +2781,104 @@ static uint8_t AD9102_CheckFlags(uint16_t pat_status, uint8_t expect_run, uint8_
return (ok ? 0u : 1u);
}
static uint8_t AD9102_CheckFlagsSram(uint16_t pat_status, uint8_t expect_run, uint16_t samples, uint8_t hold)
{
uint16_t spiconfig = AD9102_ReadReg(AD9102_REG_SPICONFIG);
uint16_t powercfg = AD9102_ReadReg(AD9102_REG_POWERCONFIG);
uint16_t clockcfg = AD9102_ReadReg(AD9102_REG_CLOCKCONFIG);
uint16_t cfg_err = AD9102_ReadReg(AD9102_REG_CFG_ERROR);
if (samples == 0u)
{
samples = AD9102_SRAM_SAMPLES_DEFAULT;
}
if (samples < 2u)
{
samples = 2u;
}
if (samples > AD9102_SRAM_MAX_SAMPLES)
{
samples = AD9102_SRAM_MAX_SAMPLES;
}
if (hold == 0u)
{
hold = AD9102_SRAM_HOLD_DEFAULT;
}
if (hold > 0x0Fu)
{
hold = 0x0Fu;
}
uint16_t pat_timebase = (uint16_t)(((uint16_t)(hold & 0x0Fu) << 8) |
((AD9102_SRAM_PAT_PERIOD_BASE_DEFAULT & 0x0Fu) << 4) |
(AD9102_SRAM_START_DELAY_BASE_DEFAULT & 0x0Fu));
uint32_t pat_period = (uint32_t)samples * (uint32_t)(hold & 0x0Fu);
if (pat_period == 0u)
{
pat_period = samples;
}
if (pat_period > 0xFFFFu)
{
pat_period = 0xFFFFu;
}
uint16_t stop_addr = (uint16_t)((samples - 1u) << 4);
uint8_t ok = 1u;
if (spiconfig != 0x0000u)
{
ok = 0u;
}
if (powercfg & ((1u << 8) | (1u << 7) | (1u << 6) | (1u << 5) | (1u << 3)))
{
ok = 0u;
}
if (clockcfg & ((1u << 11) | (1u << 7) | (1u << 6) | (1u << 5)))
{
ok = 0u;
}
if (cfg_err & 0x003Fu)
{
ok = 0u;
}
if (expect_run && ((pat_status & AD9102_PAT_STATUS_RUN) == 0u))
{
ok = 0u;
}
if (AD9102_ReadReg(AD9102_REG_WAV_CONFIG) != AD9102_EX2_WAV_CONFIG)
{
ok = 0u;
}
if (AD9102_ReadReg(AD9102_REG_PAT_TIMEBASE) != pat_timebase)
{
ok = 0u;
}
if (AD9102_ReadReg(AD9102_REG_PAT_PERIOD) != (uint16_t)pat_period)
{
ok = 0u;
}
if (AD9102_ReadReg(AD9102_REG_PAT_TYPE) != 0x0000u)
{
ok = 0u;
}
if (AD9102_ReadReg(AD9102_REG_START_ADDR) != 0x0000u)
{
ok = 0u;
}
if (AD9102_ReadReg(AD9102_REG_STOP_ADDR) != stop_addr)
{
ok = 0u;
}
if (AD9102_ReadReg(AD9102_REG_DAC_PAT) != AD9102_EX2_DAC_PAT)
{
ok = 0u;
}
return (ok ? 0u : 1u);
}
void Set_LTEC(uint8_t num, uint16_t DATA)
{