/** * @file adc_mux.c * @brief External photodiode ADC and internal STM32 ADC helpers. */ #include "adc_mux.h" #include #include "board_handles.h" #include "main.h" uint16_t adc_mux_read_external_channel(uint8_t channel_index) { uint16_t result = 0u; uint32_t delay_counter; HAL_GPIO_WritePin(SPI4_CNV_GPIO_Port, SPI4_CNV_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(SPI5_CNV_GPIO_Port, SPI5_CNV_Pin, GPIO_PIN_RESET); for (delay_counter = 0u; delay_counter < 500u; ++delay_counter) { } HAL_GPIO_WritePin(SPI4_CNV_GPIO_Port, SPI4_CNV_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(SPI5_CNV_GPIO_Port, SPI5_CNV_Pin, GPIO_PIN_SET); for (delay_counter = 0u; delay_counter < 500u; ++delay_counter) { } if (channel_index == 1u) { HAL_GPIO_WritePin(ADC_ThrLD1_CS_GPIO_Port, ADC_ThrLD1_CS_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(ADC_MPD1_CS_GPIO_Port, ADC_MPD1_CS_Pin, GPIO_PIN_RESET); for (delay_counter = 0u; delay_counter < 500u; ++delay_counter) { } LL_SPI_Enable(SPI4); delay_counter = 0u; while ((!LL_SPI_IsActiveFlag_RXNE(SPI4)) && (delay_counter <= 1000u)) { ++delay_counter; } LL_SPI_Disable(SPI4); while (delay_counter < 500u) { ++delay_counter; } HAL_GPIO_WritePin(ADC_MPD1_CS_GPIO_Port, ADC_MPD1_CS_Pin, GPIO_PIN_SET); result = LL_SPI_ReceiveData16(SPI4); } else if (channel_index == 2u) { HAL_GPIO_WritePin(ADC_ThrLD2_CS_GPIO_Port, ADC_ThrLD2_CS_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(ADC_MPD2_CS_GPIO_Port, ADC_MPD2_CS_Pin, GPIO_PIN_RESET); for (delay_counter = 0u; delay_counter < 500u; ++delay_counter) { } LL_SPI_Enable(SPI5); delay_counter = 0u; while ((!LL_SPI_IsActiveFlag_RXNE(SPI5)) && (delay_counter <= 1000u)) { ++delay_counter; } LL_SPI_Disable(SPI5); while (delay_counter < 500u) { ++delay_counter; } HAL_GPIO_WritePin(ADC_MPD2_CS_GPIO_Port, ADC_MPD2_CS_Pin, GPIO_PIN_SET); result = LL_SPI_ReceiveData16(SPI5); } else if (channel_index == 3u) { HAL_GPIO_WritePin(ADC_MPD1_CS_GPIO_Port, ADC_MPD1_CS_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(ADC_ThrLD1_CS_GPIO_Port, ADC_ThrLD1_CS_Pin, GPIO_PIN_RESET); for (delay_counter = 0u; delay_counter < 500u; ++delay_counter) { } LL_SPI_Enable(SPI4); delay_counter = 0u; while ((!LL_SPI_IsActiveFlag_RXNE(SPI4)) && (delay_counter <= 1000u)) { ++delay_counter; } LL_SPI_Disable(SPI4); while (delay_counter < 500u) { ++delay_counter; } HAL_GPIO_WritePin(ADC_ThrLD1_CS_GPIO_Port, ADC_ThrLD1_CS_Pin, GPIO_PIN_SET); result = LL_SPI_ReceiveData16(SPI4); } else if (channel_index == 4u) { HAL_GPIO_WritePin(ADC_MPD2_CS_GPIO_Port, ADC_MPD2_CS_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(ADC_ThrLD2_CS_GPIO_Port, ADC_ThrLD2_CS_Pin, GPIO_PIN_RESET); for (delay_counter = 0u; delay_counter < 500u; ++delay_counter) { } LL_SPI_Enable(SPI5); delay_counter = 0u; while ((!LL_SPI_IsActiveFlag_RXNE(SPI5)) && (delay_counter <= 1000u)) { ++delay_counter; } LL_SPI_Disable(SPI5); while (delay_counter < 500u) { ++delay_counter; } HAL_GPIO_WritePin(ADC_ThrLD2_CS_GPIO_Port, ADC_ThrLD2_CS_Pin, GPIO_PIN_SET); result = LL_SPI_ReceiveData16(SPI5); } return result; } static bool adc_mux_read_sequence(ADC_HandleTypeDef *hadc, uint16_t *output_buffer, uint8_t sample_count) { uint8_t sample_index; if ((hadc == NULL) || (output_buffer == NULL) || (sample_count == 0u)) { return false; } 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; }