184 lines
5.1 KiB
C
184 lines
5.1 KiB
C
/**
|
|
* @file adc_mux.c
|
|
* @brief External photodiode ADC and internal STM32 ADC helpers.
|
|
*/
|
|
|
|
#include "adc_mux.h"
|
|
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|