/* * @file config.h * @brief System configuration and constants * * Created: 21.09.2025 * Author: ThePetrovich * * Copyright YKSA - Sakha Aerospace Systems, LLC. * See the LICENSE file for details. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef CONFIG_H #define CONFIG_H // Firmware version #define FIRMWARE_VERSION_MAJOR 2 #define FIRMWARE_VERSION_MINOR 03 // Serial communication #define SERIAL_BAUD_RATE 38400 // Timing constants #define STATUS_LED_BLINK_PERIOD 500U #define MAIN_LOOP_DELAY 10 #define CPM_UPDATE_PERIOD 10000U #define RSENSE_CHANNEL_16_MASK 0x7FFU // 11-bit channel mask #define RSENSE_CHANNEL_32_MASK 0x3FFU // 10-bit channel mask #define RSENSE_CHANNEL_COUNT 2048 #define RSENSE_CHANNEL_32_COUNT 1024 // Temperature sensor constants (MCP9700) #define MCP9700_OFFSET_MV 500L // 500 mV at 0°C #define MCP9700_SCALE_MV 10L // 10 mV per degree #define ADC_OVERSAMPLING_BITS 2 // 16x oversampling -> 2 extra bits #define ADC_VREF_MV 3000L // 3.0V reference #define ADC_RESOLUTION 1024L // 10-bit ADC // Voltage divider constants #define VOLTAGE_DIVIDER_RATIO 20.0f // 200k and 10k resistors #define VOLTAGE_MV_PER_STEP 14.6484375f // (3.0 * 20) / 4096 // EEPROM addresses for potentiometer settings #define EEPROM_POT_HV_ADDR 0 #define EEPROM_POT_AMP_ADDR 1 #define EEPROM_POT_DET_ADDR 2 #define EEPROM_MAGIC_ADDR 3 #define EEPROM_MAGIC_VALUE 0xA5 // Magic value to check if EEPROM is initialized // Default potentiometer values #define DEFAULT_POT_VALUE 127 // Light sensor constants #define LSENSE_I2C_BASE_ADDR 0x38 #define LSENSE_EXPECTED_ID 0xE0 #define LSENSE_DATA_SIZE 12 typedef struct config_t { uint8_t magic1; // 0xA5 to indicate valid config uint8_t magic2; // 0x5A to indicate valid config uint8_t pot_hv; uint8_t pot_amp; uint8_t pot_det; struct { uint16_t adccal0; // ADC offset at GND uint16_t adccal3; // ADC reading at 3.0V reference uint16_t tempcal; uint16_t tempdrift_mvK; // SiPM temperature drift compensation in mV/K, normally around 20 mV/K float gainlow; // gain value for pot_amp = 0 float gainhigh; // gain value for pot_amp = 255 } calibration __attribute__((packed)); union { struct { uint8_t spectrum_oversample_bits : 2; // 0, 1, 2, or 3 for 1x, 4x, 16x, or 64x oversampling, only for spectrum measurement uint8_t spectrum_channel_bits : 1; // 0 for 16-bit channels, 1 for 32-bit channels uint8_t temperature_drift_compensation : 1; // 0 to disable, 1 to enable temperature compensation uint8_t adc_oversample_bits : 2; // 0, 1, 2, or 3 for 1x, 4x, 16x, or 64x ADC oversampling for // temperature and voltage measurements uint8_t reserved : 2; } fields __attribute__((packed)); uint8_t value; } flags __attribute__((packed)); struct { uint8_t tempdrift_pot_hv_low; uint8_t tempdrift_pot_hv_high; uint8_t tempdrift_pot_amp_low; uint8_t tempdrift_pot_amp_high; uint8_t tempdrift_pot_det_low; uint8_t tempdrift_pot_det_high; } temp_drift_compensation_ranges __attribute__((packed)); } __attribute__((packed)) config_t; extern config_t config; #endif // CONFIG_H