some fixes

This commit is contained in:
Ayzen
2026-06-24 13:15:48 +03:00
parent d3d48a5255
commit 42795eb899
147 changed files with 332 additions and 291740 deletions

View File

@ -553,11 +553,6 @@ static void app_apply_profile_auxiliary_outputs(const profile_t *profile)
ad9833_apply(profile->ad9833.enabled, profile->ad9833.triangle, profile->ad9833.frequency_word);
stm32_dac_output_set(profile->stm32_dac.code, profile->stm32_dac.enabled);
if (profile->ds1809.apply_position)
{
ds1809_apply_position_from_min(profile->ds1809.position_from_min);
}
}
static void app_prepare_status_response(void)
@ -633,17 +628,19 @@ static bool app_activate_profile(const profile_t *profile, uint16_t index, bool
g_app.resume_mode = APP_MODE_WORK;
}
if (profile->ds1809.apply_position)
{
app_suspend_tec_modulation_spi();
ds1809_apply_position_from_min(profile->ds1809.position_from_min);
app_resume_tec_modulation_spi();
}
return true;
}
static void app_capture_live_frame(bool update_temperature_loops, bool drive_laser_currents)
{
uint16_t adc_slot_7;
uint16_t adc_slot_8;
uint16_t adc_slot_9;
uint16_t adc_slot_10;
uint16_t adc_slot_11;
uint16_t adc_slot_12;
adc_internal_telemetry_t internal_telemetry;
uint16_t tec_drive_code;
g_app.laser_runtime[0].power_raw = adc_mux_read_external_channel(1u);
@ -679,31 +676,22 @@ static void app_capture_live_frame(bool update_temperature_loops, bool drive_las
app_write_laser_dac_channel(2u, g_app.laser_config[1].current_raw);
}
(void)adc_mux_process_internal_adc_step(0u);
adc_slot_7 = adc_mux_process_internal_adc_step(1u);
adc_slot_8 = adc_mux_process_internal_adc_step(1u);
adc_slot_9 = adc_mux_process_internal_adc_step(1u);
adc_slot_10 = adc_mux_process_internal_adc_step(1u);
adc_slot_11 = adc_mux_process_internal_adc_step(1u);
(void)adc_mux_process_internal_adc_step(2u);
(void)adc_mux_process_internal_adc_step(3u);
(void)adc_mux_process_internal_adc_step(4u);
adc_slot_12 = adc_mux_process_internal_adc_step(4u);
(void)adc_mux_process_internal_adc_step(5u);
(void)adc_mux_capture_internal_telemetry(&internal_telemetry);
telemetry_set_message_id(&g_app.telemetry, g_app.work_config.message_id);
telemetry_set_live_data(&g_app.telemetry,
g_app.laser_runtime[0].power_raw,
g_app.laser_runtime[1].power_raw,
g_app.tick_10ms,
internal_telemetry.input_pf3_raw,
internal_telemetry.input_pf4_raw,
g_app.laser_runtime[0].current_temperature_raw,
g_app.laser_runtime[1].current_temperature_raw,
adc_slot_7,
adc_slot_8,
adc_slot_9,
adc_slot_10,
adc_slot_11,
adc_slot_12);
internal_telemetry.external_temperature_1_raw,
internal_telemetry.external_temperature_2_raw,
internal_telemetry.rail_3v3_raw,
internal_telemetry.rail_5v1_raw,
internal_telemetry.rail_5v2_raw,
internal_telemetry.rail_7v0_raw);
}
static void app_decode_work_packet(const uint16_t *packet_words)

View File

@ -5,6 +5,8 @@
#include "adc_mux.h"
#include <string.h>
#include "board_handles.h"
#include "main.h"
@ -117,35 +119,65 @@ uint16_t adc_mux_read_external_channel(uint8_t channel_index)
return result;
}
uint16_t adc_mux_process_internal_adc_step(uint8_t step)
static bool adc_mux_read_sequence(ADC_HandleTypeDef *hadc, uint16_t *output_buffer, uint8_t sample_count)
{
uint16_t output = 0u;
uint8_t sample_index;
switch (step)
if ((hadc == NULL) || (output_buffer == NULL) || (sample_count == 0u))
{
case 0u:
HAL_ADC_Start(&hadc1);
break;
case 1u:
HAL_ADC_PollForConversion(&hadc1, 100u);
output = HAL_ADC_GetValue(&hadc1);
break;
case 2u:
HAL_ADC_Stop(&hadc1);
break;
case 3u:
HAL_ADC_Start(&hadc3);
break;
case 4u:
HAL_ADC_PollForConversion(&hadc3, 100u);
output = HAL_ADC_GetValue(&hadc3);
break;
case 5u:
HAL_ADC_Stop(&hadc3);
break;
default:
break;
return false;
}
return output;
if (HAL_ADC_Start(hadc) != HAL_OK)
{
return false;
}
for (sample_index = 0u; sample_index < sample_count; ++sample_index)
{
if (HAL_ADC_PollForConversion(hadc, 100u) != HAL_OK)
{
(void)HAL_ADC_Stop(hadc);
return false;
}
output_buffer[sample_index] = (uint16_t)HAL_ADC_GetValue(hadc);
}
(void)HAL_ADC_Stop(hadc);
return true;
}
bool adc_mux_capture_internal_telemetry(adc_internal_telemetry_t *telemetry)
{
uint16_t adc1_samples[5];
uint16_t adc3_samples[3];
if (telemetry == NULL)
{
return false;
}
memset(telemetry, 0, sizeof(*telemetry));
if (!adc_mux_read_sequence(&hadc1, adc1_samples, 5u))
{
return false;
}
if (!adc_mux_read_sequence(&hadc3, adc3_samples, 3u))
{
return false;
}
telemetry->external_temperature_1_raw = adc1_samples[0];
telemetry->external_temperature_2_raw = adc1_samples[1];
telemetry->rail_3v3_raw = adc1_samples[2];
telemetry->rail_5v1_raw = adc1_samples[3];
telemetry->rail_5v2_raw = adc1_samples[4];
telemetry->input_pf3_raw = adc3_samples[0];
telemetry->input_pf4_raw = adc3_samples[1];
telemetry->rail_7v0_raw = adc3_samples[2];
return true;
}

View File

@ -6,9 +6,37 @@
#ifndef ADC_MUX_H
#define ADC_MUX_H
#include <stdbool.h>
#include <stdint.h>
/**
* @brief Snapshot of all internal STM32 ADC channels exported through telemetry.
*
* The firmware keeps the UART telemetry frame fixed at 30 bytes, so the host
* and the board agree on a stable slot order. These fields are captured from
* the MCU ADC peripherals once per telemetry refresh and then packed into that
* frame by the application core.
*/
typedef struct adc_internal_telemetry_t {
/** @brief Raw 12-bit code for external temperature sensor channel 1. */
uint16_t external_temperature_1_raw;
/** @brief Raw 12-bit code for external temperature sensor channel 2. */
uint16_t external_temperature_2_raw;
/** @brief Raw 12-bit code for the monitored 3.3V rail. */
uint16_t rail_3v3_raw;
/** @brief Raw 12-bit code for the monitored 5V1 rail. */
uint16_t rail_5v1_raw;
/** @brief Raw 12-bit code for the monitored 5V2 rail. */
uint16_t rail_5v2_raw;
/** @brief Raw 12-bit code read from free analog input PF3 / ADC3_IN9. */
uint16_t input_pf3_raw;
/** @brief Raw 12-bit code read from free analog input PF4 / ADC3_IN14. */
uint16_t input_pf4_raw;
/** @brief Raw 12-bit code for the monitored 7V rail. */
uint16_t rail_7v0_raw;
} adc_internal_telemetry_t;
uint16_t adc_mux_read_external_channel(uint8_t channel_index);
uint16_t adc_mux_process_internal_adc_step(uint8_t step);
bool adc_mux_capture_internal_telemetry(adc_internal_telemetry_t *telemetry);
#endif /* ADC_MUX_H */

View File

@ -8,9 +8,10 @@
#include "main.h"
#define DS1809_POSITION_COUNT 64u
#define DS1809_CPU_PULSE_WIDTH_MS 2u
#define DS1809_CPU_INTER_PULSE_HIGH_MS 2u
#define DS1809_CONTROL_PORT_READY_DELAY_MS 10u
#define DS1809_RESET_DOWN_PULSE_COUNT 80u
#define DS1809_CPU_PULSE_WIDTH_MS 8u
#define DS1809_CPU_INTER_PULSE_HIGH_MS 8u
#define DS1809_CONTROL_PORT_READY_DELAY_MS 500u
static void ds1809_drive_idle_high(void)
{
@ -69,7 +70,7 @@ void ds1809_apply_position_from_min(uint8_t position_from_min)
* - repetitive pulses need at least 1 ms of high time between steps;
* - the control inputs are locked out for at least 10 ms after power-up.
*
* Use 2 ms low/high timing for margin, always drive to the RL end first,
* Use 8 ms low/high timing for margin, always drive to the RL end first,
* then walk back up to the requested absolute position.
*/
if (position_from_min >= DS1809_POSITION_COUNT)
@ -78,6 +79,6 @@ void ds1809_apply_position_from_min(uint8_t position_from_min)
}
HAL_Delay(DS1809_CONTROL_PORT_READY_DELAY_MS);
ds1809_pulse_direction(0u, 1u, DS1809_POSITION_COUNT, DS1809_CPU_PULSE_WIDTH_MS, DS1809_CPU_INTER_PULSE_HIGH_MS);
ds1809_pulse_direction(0u, 1u, DS1809_RESET_DOWN_PULSE_COUNT, DS1809_CPU_PULSE_WIDTH_MS, DS1809_CPU_INTER_PULSE_HIGH_MS);
ds1809_pulse_direction(1u, 0u, position_from_min, DS1809_CPU_PULSE_WIDTH_MS, DS1809_CPU_INTER_PULSE_HIGH_MS);
}

View File

@ -31,15 +31,16 @@ void telemetry_set_message_id(telemetry_frame_t *frame, uint16_t message_id)
void telemetry_set_live_data(telemetry_frame_t *frame,
uint16_t laser1_power,
uint16_t laser2_power,
uint32_t tick_10ms,
uint16_t input_pf3_raw,
uint16_t input_pf4_raw,
uint16_t laser1_temperature,
uint16_t laser2_temperature,
uint16_t adc_slot_7,
uint16_t adc_slot_8,
uint16_t adc_slot_9,
uint16_t adc_slot_10,
uint16_t adc_slot_11,
uint16_t adc_slot_12)
uint16_t external_temperature_1_raw,
uint16_t external_temperature_2_raw,
uint16_t rail_3v3_raw,
uint16_t rail_5v1_raw,
uint16_t rail_5v2_raw,
uint16_t rail_7v0_raw)
{
if (frame == NULL)
{
@ -48,16 +49,16 @@ void telemetry_set_live_data(telemetry_frame_t *frame,
frame->words[1] = laser1_power;
frame->words[2] = laser2_power;
frame->words[3] = (uint16_t)(tick_10ms & 0xFFFFu);
frame->words[4] = (uint16_t)((tick_10ms >> 16) & 0xFFFFu);
frame->words[3] = input_pf3_raw;
frame->words[4] = input_pf4_raw;
frame->words[5] = laser1_temperature;
frame->words[6] = laser2_temperature;
frame->words[7] = adc_slot_7;
frame->words[8] = adc_slot_8;
frame->words[9] = adc_slot_9;
frame->words[10] = adc_slot_10;
frame->words[11] = adc_slot_11;
frame->words[12] = adc_slot_12;
frame->words[7] = external_temperature_1_raw;
frame->words[8] = external_temperature_2_raw;
frame->words[9] = rail_3v3_raw;
frame->words[10] = rail_5v1_raw;
frame->words[11] = rail_5v2_raw;
frame->words[12] = rail_7v0_raw;
}
void telemetry_finalize(telemetry_frame_t *frame)

View File

@ -15,15 +15,16 @@ void telemetry_set_message_id(telemetry_frame_t *frame, uint16_t message_id);
void telemetry_set_live_data(telemetry_frame_t *frame,
uint16_t laser1_power,
uint16_t laser2_power,
uint32_t tick_10ms,
uint16_t input_pf3_raw,
uint16_t input_pf4_raw,
uint16_t laser1_temperature,
uint16_t laser2_temperature,
uint16_t adc_slot_7,
uint16_t adc_slot_8,
uint16_t adc_slot_9,
uint16_t adc_slot_10,
uint16_t adc_slot_11,
uint16_t adc_slot_12);
uint16_t external_temperature_1_raw,
uint16_t external_temperature_2_raw,
uint16_t rail_3v3_raw,
uint16_t rail_5v1_raw,
uint16_t rail_5v2_raw,
uint16_t rail_7v0_raw);
void telemetry_finalize(telemetry_frame_t *frame);
void telemetry_to_bytes(const telemetry_frame_t *frame, uint8_t *out_bytes);