diff --git a/Core/Src/main.c b/Core/Src/main.c index d62d1fe..92c887b 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -44,6 +44,9 @@ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ +ADC_HandleTypeDef hadc1; +DMA_HandleTypeDef hdma_adc1; + I2C_HandleTypeDef hi2c1; I2S_HandleTypeDef hi2s3; @@ -68,14 +71,17 @@ const osThreadAttr_t defaultTask_attributes = { /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); +static void MX_DMA_Init(void); static void MX_I2C1_Init(void); static void MX_I2S3_Init(void); static void MX_SPI1_Init(void); static void MX_TIM1_Init(void); static void MX_TIM2_Init(void); static void MX_TIM3_Init(void); +static void MX_ADC1_Init(void); void StartDefaultTask(void *argument); + /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -114,12 +120,14 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); + MX_DMA_Init(); MX_I2C1_Init(); MX_I2S3_Init(); MX_SPI1_Init(); MX_TIM1_Init(); MX_TIM2_Init(); MX_TIM3_Init(); + MX_ADC1_Init(); /* USER CODE BEGIN 2 */ // Small delay to ensure all peripherals are stable before USB init @@ -158,6 +166,9 @@ int main(void) ul_ulog_init(); + // Initialize KPIRover + KPIRover_Init(); + /* USER CODE END RTOS_THREADS */ @@ -227,6 +238,67 @@ void SystemClock_Config(void) } } +/** + * @brief ADC1 Initialization Function + * @param None + * @retval None + */ +static void MX_ADC1_Init(void) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) + */ + hadc1.Instance = ADC1; + hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; + hadc1.Init.Resolution = ADC_RESOLUTION_12B; + hadc1.Init.ScanConvMode = ENABLE; + hadc1.Init.ContinuousConvMode = ENABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 2; + hadc1.Init.DMAContinuousRequests = ENABLE; + hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_2; + sConfig.Rank = 1; + sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. + */ + sConfig.Channel = ADC_CHANNEL_3; + sConfig.Rank = 2; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ + +} + /** * @brief I2C1 Initialization Function * @param None @@ -518,6 +590,22 @@ static void MX_TIM3_Init(void) } +/** + * Enable DMA controller clock + */ +static void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_DMA2_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA2_Stream0_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); + +} + /** * @brief GPIO Initialization Function * @param None @@ -624,9 +712,10 @@ static void MX_GPIO_Init(void) /* USER CODE END Header_StartDefaultTask */ void StartDefaultTask(void *argument) { - uint32_t count = 0; - + /* init code for USB_DEVICE */ + MX_USB_DEVICE_Init(); /* USER CODE BEGIN 5 */ + static int count = 0; /* Infinite loop */ for(;;) { diff --git a/KPI_Rover/ADC/adc_driver.c b/KPI_Rover/ADC/adc_driver.c new file mode 100644 index 0000000..f26f992 --- /dev/null +++ b/KPI_Rover/ADC/adc_driver.c @@ -0,0 +1,351 @@ +#include "adc_driver.h" +#include "stm32f4xx_hal.h" +#include "ulog.h" + +#define MAX_ADC_CHANNELS 16 +#define EMA_ALPHA 0.05f +#define CALIB_SAMPLES_TARGET 36 + +static uint8_t adc_channels[MAX_ADC_CHANNELS]; +static uint16_t adc_raw_values[MAX_ADC_CHANNELS]; +static uint16_t adc_filtered_values[MAX_ADC_CHANNELS]; +static size_t channel_count = 0; + +static adc_callback_t registered_callback = NULL; + +static adc_calibration_t adc_calibration_data[MAX_ADC_CHANNELS]; + +static float adc_filtered_ema[MAX_ADC_CHANNELS] = {0.0f}; + +extern ADC_HandleTypeDef hadc1; + +static volatile adc_driver_state_t adc_driver_state = ADC_STATE_IDLE; +static volatile uint32_t adc_state_change_tick = 0; +static volatile uint8_t adc_request_calib_low_channel = 0xFF; +static volatile uint8_t adc_request_calib_high_channel = 0xFF; + +static adc_calib_substate_t calib_substate_low = CAL_SUB_IDLE; +static adc_calib_substate_t calib_substate_high = CAL_SUB_IDLE; + +#define CALIB_STABLE_MS 10 + +static uint16_t calib_samples[MAX_ADC_CHANNELS][CALIB_SAMPLES_TARGET]; +static uint8_t calib_sample_counts[MAX_ADC_CHANNELS] = {0}; + +static int find_channel_index(uint8_t channel) { + for (size_t i = 0; i < channel_count; ++i) { + if (adc_channels[i] == channel) return (int)i; + } + return -1; +} + +void ADC_Driver_Init(const uint8_t* channels, size_t count) { + channel_count = count > MAX_ADC_CHANNELS ? MAX_ADC_CHANNELS : count; + for (size_t i = 0; i < channel_count; i++) { + adc_channels[i] = channels[i]; + ADC_ChannelConfTypeDef sConfig = {0}; + sConfig.Channel = adc_channels[i]; + sConfig.Rank = 1; + sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { + ULOG_ERROR("ADC: channel %u config failed", adc_channels[i]); + } else { + ULOG_INFO("ADC channel %u initialized", adc_channels[i]); + } + } +} + +void ADC_Driver_Start(void) { + if (channel_count == 0) { + ULOG_ERROR("ADC start failed: no channels configured"); + return; + } + if (HAL_ADC_Start(&hadc1) != HAL_OK) { + ULOG_ERROR("Failed to start ADC (polling mode)"); + } else { + ULOG_INFO("ADC started in polling mode with %d channels", channel_count); + } +} + +void ADC_Driver_StartCalibrationLow(uint8_t channel) { + adc_request_calib_low_channel = channel; + int idx = find_channel_index(channel); + if (idx >= 0) calib_sample_counts[idx] = 0; + + adc_driver_state = ADC_STATE_CALIB_LOW_PENDING; + calib_substate_low = CAL_SUB_WAIT_STABLE; + adc_state_change_tick = HAL_GetTick(); + ULOG_INFO("ADC: queued START CALIB LOW for channel %u", channel); +} + +void ADC_Driver_StartCalibrationHigh(uint8_t channel) { + adc_request_calib_high_channel = channel; + int idx = find_channel_index(channel); + if (idx >= 0) calib_sample_counts[idx] = 0; + + adc_driver_state = ADC_STATE_CALIB_HIGH_PENDING; + calib_substate_high = CAL_SUB_WAIT_STABLE; + adc_state_change_tick = HAL_GetTick(); + ULOG_INFO("ADC: queued START CALIB HIGH for channel %u", channel); +} + + + +void ADC_Driver_SetCalibration(uint8_t channel, adc_calibration_t calib) { + int idx = find_channel_index(channel); + if (idx >= 0) { + adc_calibration_data[idx] = calib; + ULOG_INFO("Calibration set for channel %u", channel); + } else { + ULOG_WARNING("Attempted to calibrate unknown channel %u", channel); + } +} + +float ADC_Driver_GetCalibratedValue(uint8_t channel) { + int idx = find_channel_index(channel); + if (idx < 0) { + ULOG_WARNING("Calibrated value requested for unknown channel %u", channel); + return 0.0f; + } + + adc_calibration_t calib = adc_calibration_data[idx]; + uint16_t raw = adc_filtered_values[idx]; + + if (calib.raw_high == calib.raw_low) return 0.0f; + + float phys = calib.phys_low + ((float)(raw - calib.raw_low)) * + (calib.phys_high - calib.phys_low) / + (float)(calib.raw_high - calib.raw_low); + return phys; +} + +void ADC_Driver_RegisterCallback(adc_callback_t cb) { + registered_callback = cb; + ULOG_DEBUG("ADC callback registered"); +} + +uint16_t ADC_Driver_GetLastValue(uint8_t channel) { + int idx = find_channel_index(channel); + if (idx >= 0) { + return adc_filtered_values[idx]; + } + ULOG_WARNING("ADC: Requested value for unregistered channel %u", channel); + return 0; +} + + +void ADC_Driver_ReadChannels(void) { + for (size_t i = 0; i < channel_count; i++) { + HAL_ADC_Start(&hadc1); + if (HAL_ADC_PollForConversion(&hadc1, 5) == HAL_OK) { + uint16_t raw = HAL_ADC_GetValue(&hadc1); + + adc_filtered_ema[i] = EMA_ALPHA * (float)raw + + (1.0f - EMA_ALPHA) * adc_filtered_ema[i]; + adc_filtered_values[i] = (uint16_t)adc_filtered_ema[i]; + + if (adc_driver_state == ADC_STATE_CALIB_LOW_PENDING && + calib_substate_low == CAL_SUB_COLLECT && + adc_channels[i] == adc_request_calib_low_channel) + { + int idx = find_channel_index(adc_channels[i]); + if (idx >= 0 && calib_sample_counts[idx] < CALIB_SAMPLES_TARGET) { + calib_samples[idx][calib_sample_counts[idx]++] = adc_filtered_values[idx]; + } + } + + if (adc_driver_state == ADC_STATE_CALIB_HIGH_PENDING && + calib_substate_high == CAL_SUB_COLLECT && + adc_channels[i] == adc_request_calib_high_channel) + { + int idx = find_channel_index(adc_channels[i]); + if (idx >= 0 && calib_sample_counts[idx] < CALIB_SAMPLES_TARGET) { + calib_samples[idx][calib_sample_counts[idx]++] = adc_filtered_values[idx]; + } + } + + if (registered_callback) { + registered_callback(adc_channels[i], adc_filtered_values[i]); + } + } + HAL_ADC_Stop(&hadc1); + } +} + + + +void ADC_Driver_TimerTask(void) { + uint32_t now = HAL_GetTick(); + static adc_measurements_t adc_meas = {0}; + + switch (adc_driver_state) { + + case ADC_STATE_IDLE: { + if (now >= adc_meas.next_voltage_tick) { + adc_driver_state = ADC_STATE_MEASURE_VOLTAGE; + } + } break; + + case ADC_STATE_MEASURE_VOLTAGE: { + int idx = find_channel_index(2); + if (idx >= 0) { + adc_meas.voltage_raw = ADC_Driver_GetLastValue(adc_channels[idx]); + adc_meas.voltage_cal = ADC_Driver_GetCalibratedValue(adc_channels[idx]); + ULOG_INFO("Voltage: raw=%u, filtered=%.3f V", + adc_meas.voltage_raw, + adc_meas.voltage_cal); + } + adc_meas.next_voltage_tick = now + 10; + adc_driver_state = ADC_STATE_IDLE; + } break; + + case ADC_STATE_REQUEST_CALIB_LOW: { + uint8_t ch = adc_request_calib_low_channel; + int idx = find_channel_index(ch); + if (idx >= 0) { + calib_sample_counts[idx] = 0; + adc_driver_state = ADC_STATE_CALIB_LOW_PENDING; + adc_state_change_tick = now; + ULOG_INFO("ADC: CALIB LOW pending (channel %u)", ch); + } else { + adc_driver_state = ADC_STATE_IDLE; + } + } break; + + case ADC_STATE_CALIB_LOW_PENDING: { + uint8_t ch = adc_request_calib_low_channel; + int idx = find_channel_index(ch); + if (idx < 0) { + adc_driver_state = ADC_STATE_IDLE; + break; + } + + switch (calib_substate_low) { + case CAL_SUB_WAIT_STABLE: + if ((now - adc_state_change_tick) > CALIB_STABLE_MS) { + calib_sample_counts[idx] = 0; + calib_substate_low = CAL_SUB_COLLECT; + ULOG_INFO("ADC: CALIB LOW COLLECT start (channel %u)", ch); + } + break; + + case CAL_SUB_COLLECT: + if (calib_sample_counts[idx] >= CALIB_SAMPLES_TARGET) { + calib_substate_low = CAL_SUB_COMPUTE; + } + break; + + case CAL_SUB_COMPUTE: { + uint16_t min1 = 0xFFFF, min2 = 0xFFFF, max1 = 0, max2 = 0; + uint32_t sum = 0; + for (size_t i = 0; i < CALIB_SAMPLES_TARGET; i++) { + uint16_t v = calib_samples[idx][i]; + sum += v; + if (v < min1) { min2 = min1; min1 = v; } + else if (v < min2) min2 = v; + if (v > max1) { max2 = max1; max1 = v; } + else if (v > max2) max2 = v; + } + uint16_t avg_min = (min1 + min2) / 2; + uint16_t avg_max = (max1 + max2) / 2; + uint16_t avg_all = sum / CALIB_SAMPLES_TARGET; + uint16_t final = (avg_min + avg_max + avg_all) / 3; + + adc_calibration_t calib = adc_calibration_data[idx]; + calib.raw_low = final; + calib.phys_low = 0.0f; + ADC_Driver_SetCalibration(ch, calib); + + ULOG_INFO("ADC: CALIB LOW done ch=%u raw=%u", ch, final); + adc_driver_state = ADC_STATE_IDLE; + adc_request_calib_low_channel = 0xFF; + calib_substate_low = CAL_SUB_IDLE; + } break; + + default: + calib_substate_low = CAL_SUB_IDLE; + adc_driver_state = ADC_STATE_IDLE; + break; + } + } break; + + case ADC_STATE_REQUEST_CALIB_HIGH: { + uint8_t ch = adc_request_calib_high_channel; + int idx = find_channel_index(ch); + if (idx >= 0) { + calib_sample_counts[idx] = 0; + adc_driver_state = ADC_STATE_CALIB_HIGH_PENDING; + adc_state_change_tick = now; + ULOG_INFO("ADC: CALIB HIGH pending (channel %u)", ch); + } else { + adc_driver_state = ADC_STATE_IDLE; + } + } break; + + case ADC_STATE_CALIB_HIGH_PENDING: { + uint8_t ch = adc_request_calib_high_channel; + int idx = find_channel_index(ch); + if (idx < 0) { + adc_driver_state = ADC_STATE_IDLE; + break; + } + + switch (calib_substate_high) { + case CAL_SUB_WAIT_STABLE: + if ((now - adc_state_change_tick) > CALIB_STABLE_MS) { + calib_sample_counts[idx] = 0; + calib_substate_high = CAL_SUB_COLLECT; + ULOG_INFO("ADC: CALIB HIGH COLLECT start (channel %u)", ch); + } + break; + + case CAL_SUB_COLLECT: + if (calib_sample_counts[idx] >= CALIB_SAMPLES_TARGET) { + calib_substate_high = CAL_SUB_COMPUTE; + } + break; + + case CAL_SUB_COMPUTE: { + uint16_t min1 = 0xFFFF, min2 = 0xFFFF, max1 = 0, max2 = 0; + uint32_t sum = 0; + for (size_t i = 0; i < CALIB_SAMPLES_TARGET; i++) { + uint16_t v = calib_samples[idx][i]; + sum += v; + if (v < min1) { min2 = min1; min1 = v; } + else if (v < min2) min2 = v; + if (v > max1) { max2 = max1; max1 = v; } + else if (v > max2) max2 = v; + } + uint16_t avg_min = (min1 + min2) / 2; + uint16_t avg_max = (max1 + max2) / 2; + uint16_t avg_all = sum / CALIB_SAMPLES_TARGET; + uint16_t final = (avg_min + avg_max + avg_all) / 3; + + adc_calibration_t calib = adc_calibration_data[idx]; + calib.raw_high = final; + calib.phys_high = 3.3f; + ADC_Driver_SetCalibration(ch, calib); + + ULOG_INFO("ADC: CALIB HIGH done ch=%u raw=%u", ch, final); + adc_driver_state = ADC_STATE_IDLE; + adc_request_calib_high_channel = 0xFF; + calib_substate_high = CAL_SUB_IDLE; + } break; + + default: + calib_substate_high = CAL_SUB_IDLE; + adc_driver_state = ADC_STATE_IDLE; + break; + } + } break; + + case ADC_STATE_ERROR: + ULOG_ERROR("ADC driver error state"); + break; + + default: + ULOG_INFO("ADC: unknown state=%u", adc_driver_state); + adc_driver_state = ADC_STATE_IDLE; + break; + } +} diff --git a/KPI_Rover/ADC/adc_driver.h b/KPI_Rover/ADC/adc_driver.h new file mode 100644 index 0000000..e7c7f13 --- /dev/null +++ b/KPI_Rover/ADC/adc_driver.h @@ -0,0 +1,54 @@ +#ifndef ADC_DRIVER_H +#define ADC_DRIVER_H + +#include +#include + +typedef enum { + ADC_STATE_IDLE = 0, + ADC_STATE_REQUEST_CALIB_LOW, + ADC_STATE_CALIB_LOW_PENDING, + ADC_STATE_REQUEST_CALIB_HIGH, + ADC_STATE_CALIB_HIGH_PENDING, + ADC_STATE_MEASURE_VOLTAGE, + ADC_STATE_ERROR +} adc_driver_state_t; + +typedef enum { + CAL_SUB_IDLE = 0, + CAL_SUB_WAIT_STABLE, + CAL_SUB_COLLECT, + CAL_SUB_COMPUTE +} adc_calib_substate_t; + +typedef struct { + uint16_t raw_low; + uint16_t raw_high; + float phys_low; + float phys_high; +} adc_calibration_t; + +typedef void (*adc_callback_t)(uint8_t channel, uint16_t value); + +typedef struct { + uint32_t next_voltage_tick; + uint16_t voltage_raw; + float voltage_cal; +} adc_measurements_t; + +extern adc_measurements_t adc_meas; + +extern uint32_t counter; + +void ADC_Driver_Init(const uint8_t* channels, size_t count); +void ADC_Driver_Start(void); +void ADC_Driver_StartCalibrationLow(uint8_t channel); +void ADC_Driver_StartCalibrationHigh(uint8_t channel); +void ADC_Driver_SetCalibration(uint8_t channel, adc_calibration_t calib); +float ADC_Driver_GetCalibratedValue(uint8_t channel); +uint16_t ADC_Driver_GetLastValue(uint8_t channel); +void ADC_Driver_RegisterCallback(adc_callback_t cb); +void ADC_Driver_TimerTask(void); +void ADC_Driver_ReadChannels(void); + +#endif diff --git a/KPI_Rover/ADC/adc_manager.c b/KPI_Rover/ADC/adc_manager.c new file mode 100644 index 0000000..3a472d2 --- /dev/null +++ b/KPI_Rover/ADC/adc_manager.c @@ -0,0 +1,97 @@ +#include "adc_manager.h" +#include "ulog.h" +#include "cmsis_os.h" +#include "stm32f4xx_hal.h" +#include "stdbool.h" + +static const adc_channel_config_t adc_config[] = { + { .channel = 2, .phys_high = 3.3f, .calibration_required = 1 } +}; + +#define ADC_CONFIG_COUNT (sizeof(adc_config) / sizeof(adc_config[0])) + +#define ADC_TIMER_PERIOD_MS 100 + +static osTimerId_t adc_timer_handle; + +static uint16_t adc_last_raw[ADC_CONFIG_COUNT]; +static float adc_last_cal[ADC_CONFIG_COUNT]; + +static void adc_data_cb(uint8_t channel, uint16_t value) { + for (size_t i = 0; i < ADC_CONFIG_COUNT; i++) { + if (adc_config[i].channel == channel) { + adc_last_raw[i] = value; + adc_last_cal[i] = ADC_Driver_GetCalibratedValue(channel); + break; + } + } +} + +static volatile bool adc_timer_flag = false; + +static void adc_timer_callback(void *arg) { + adc_timer_flag = true; +} + + +void ADC_Manager_Init(void) { + uint8_t channels[ADC_CONFIG_COUNT]; + + for (size_t i = 0; i < ADC_CONFIG_COUNT; i++) { + channels[i] = adc_config[i].channel; + } + + ADC_Driver_Init(channels, ADC_CONFIG_COUNT); + + ADC_Driver_RegisterCallback(adc_data_cb); + + ADC_Driver_Start(); + + const osTimerAttr_t timer_attrs = { + .name = "ADC_Timer" + }; + + adc_timer_handle = osTimerNew(adc_timer_callback, osTimerPeriodic, NULL, &timer_attrs); + if (!adc_timer_handle) { + ULOG_ERROR("Failed to create ADC timer"); + osThreadExit(); + } + + osDelay(10); + + if (osTimerStart(adc_timer_handle, ADC_TIMER_PERIOD_MS) != osOK) { + ULOG_ERROR("Failed to start ADC timer"); + osThreadExit(); + } +} + + +void ADC_Manager_Task(void *argument) { + ADC_Manager_Init(); + + for (;;) { + ADC_Driver_ReadChannels(); + if (adc_timer_flag) { + adc_timer_flag = false; + ADC_Driver_TimerTask(); + } + osDelay(10); + +// int state = DB_ReadCalibState(); +// +// switch (0) { // (state) +// case 1: // start 0В +// ADC_Driver_StartCalibrationLow(adc_config[0].channel); +// DB_WriteCalibState(2); +// break; +// +// case 3: // start 3.3В +// ADC_Driver_StartCalibrationHigh(adc_config[0].channel); +// DB_WriteCalibState(4); +// break; +// +// default: +// break; +// } + } +} diff --git a/KPI_Rover/ADC/adc_manager.h b/KPI_Rover/ADC/adc_manager.h new file mode 100644 index 0000000..ddda3f9 --- /dev/null +++ b/KPI_Rover/ADC/adc_manager.h @@ -0,0 +1,20 @@ +#ifndef ADC_MANAGER_H +#define ADC_MANAGER_H + +#include +#include +#include "adc_driver.h" +#include "FreeRTOS.h" +#include "queue.h" + + +typedef struct { + uint8_t channel; + float phys_high; + uint8_t calibration_required; +} adc_channel_config_t; + +void ADC_Manager_Init(void); +void ADC_Manager_Task(void *argument); + +#endif // ADC_MANAGER_H diff --git a/KPI_Rover/KPIRover.c b/KPI_Rover/KPIRover.c new file mode 100644 index 0000000..73f9c1e --- /dev/null +++ b/KPI_Rover/KPIRover.c @@ -0,0 +1,16 @@ +#include "KPIRover.h" +#include "cmsis_os.h" +#include "ADC/adc_manager.h" + +void KPIRover_Init(void) { + + + // ADC + const osThreadAttr_t adcTask_attributes = { + .name = "adcTask", + .priority = (osPriority_t) osPriorityNormal, + .stack_size = 1024 * 4 + }; + (void) osThreadNew(ADC_Manager_Task, NULL, &adcTask_attributes); + +} diff --git a/KPI_Rover/KPIRover.h b/KPI_Rover/KPIRover.h new file mode 100644 index 0000000..fe1b72a --- /dev/null +++ b/KPI_Rover/KPIRover.h @@ -0,0 +1,6 @@ +#ifndef KPIROVER_H +#define KPIROVER_H + +void KPIRover_Init(void); + +#endif // KPIROVER_H diff --git a/ecu_sw.ioc b/ecu_sw.ioc index 4446ac9..f3e6297 100644 --- a/ecu_sw.ioc +++ b/ecu_sw.ioc @@ -1,7 +1,32 @@ #MicroXplorer Configuration settings - do not modify +ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_2 +ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_3 +ADC1.ContinuousConvMode=ENABLE +ADC1.DMAContinuousRequests=ENABLE +ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,master,DMAContinuousRequests,ScanConvMode,ContinuousConvMode,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,NbrOfConversion +ADC1.NbrOfConversion=2 +ADC1.NbrOfConversionFlag=1 +ADC1.Rank-0\#ChannelRegularConversion=1 +ADC1.Rank-1\#ChannelRegularConversion=2 +ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES +ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_144CYCLES +ADC1.ScanConvMode=ENABLE +ADC1.master=1 CAD.formats=[] CAD.pinconfig=Dual CAD.provider= +Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY +Dma.ADC1.0.FIFOMode=DMA_FIFOMODE_DISABLE +Dma.ADC1.0.Instance=DMA2_Stream0 +Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD +Dma.ADC1.0.MemInc=DMA_MINC_ENABLE +Dma.ADC1.0.Mode=DMA_CIRCULAR +Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD +Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE +Dma.ADC1.0.Priority=DMA_PRIORITY_LOW +Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode +Dma.Request0=ADC1 +Dma.RequestsNb=1 FREERTOS.IPParameters=Tasks01 FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL File.Version=6 @@ -17,69 +42,74 @@ I2S3.VirtualMode=I2S_MODE_MASTER KeepUserPlacement=false Mcu.CPN=STM32F407VGT6 Mcu.Family=STM32F4 -Mcu.IP0=FREERTOS -Mcu.IP1=I2C1 -Mcu.IP10=USB_DEVICE -Mcu.IP11=USB_OTG_FS -Mcu.IP2=I2S3 -Mcu.IP3=NVIC -Mcu.IP4=RCC -Mcu.IP5=SPI1 -Mcu.IP6=SYS -Mcu.IP7=TIM1 -Mcu.IP8=TIM2 -Mcu.IP9=TIM3 -Mcu.IPNb=12 +Mcu.IP0=ADC1 +Mcu.IP1=DMA +Mcu.IP10=TIM2 +Mcu.IP11=TIM3 +Mcu.IP12=USB_DEVICE +Mcu.IP13=USB_OTG_FS +Mcu.IP2=FREERTOS +Mcu.IP3=I2C1 +Mcu.IP4=I2S3 +Mcu.IP5=NVIC +Mcu.IP6=RCC +Mcu.IP7=SPI1 +Mcu.IP8=SYS +Mcu.IP9=TIM1 +Mcu.IPNb=14 Mcu.Name=STM32F407V(E-G)Tx Mcu.Package=LQFP100 Mcu.Pin0=PE3 Mcu.Pin1=PC14-OSC32_IN -Mcu.Pin10=PA5 -Mcu.Pin11=PA6 -Mcu.Pin12=PA7 -Mcu.Pin13=PB2 -Mcu.Pin14=PE9 -Mcu.Pin15=PE11 -Mcu.Pin16=PE13 -Mcu.Pin17=PE14 -Mcu.Pin18=PB10 -Mcu.Pin19=PC6 +Mcu.Pin10=PA3 +Mcu.Pin11=PA4 +Mcu.Pin12=PA5 +Mcu.Pin13=PA6 +Mcu.Pin14=PA7 +Mcu.Pin15=PB2 +Mcu.Pin16=PE9 +Mcu.Pin17=PE11 +Mcu.Pin18=PE13 +Mcu.Pin19=PE14 Mcu.Pin2=PC15-OSC32_OUT -Mcu.Pin20=PC7 -Mcu.Pin21=PA9 -Mcu.Pin22=PA10 -Mcu.Pin23=PA11 -Mcu.Pin24=PA12 -Mcu.Pin25=PA13 -Mcu.Pin26=PA14 -Mcu.Pin27=PA15 -Mcu.Pin28=PC10 -Mcu.Pin29=PC12 +Mcu.Pin20=PB10 +Mcu.Pin21=PC6 +Mcu.Pin22=PC7 +Mcu.Pin23=PA9 +Mcu.Pin24=PA10 +Mcu.Pin25=PA11 +Mcu.Pin26=PA12 +Mcu.Pin27=PA13 +Mcu.Pin28=PA14 +Mcu.Pin29=PA15 Mcu.Pin3=PH0-OSC_IN -Mcu.Pin30=PD4 -Mcu.Pin31=PD5 -Mcu.Pin32=PB3 -Mcu.Pin33=PB5 -Mcu.Pin34=PB6 -Mcu.Pin35=PB9 -Mcu.Pin36=PE1 -Mcu.Pin37=VP_FREERTOS_VS_CMSIS_V2 -Mcu.Pin38=VP_SYS_VS_Systick -Mcu.Pin39=VP_TIM1_VS_ClockSourceINT +Mcu.Pin30=PC10 +Mcu.Pin31=PC12 +Mcu.Pin32=PD4 +Mcu.Pin33=PD5 +Mcu.Pin34=PB3 +Mcu.Pin35=PB5 +Mcu.Pin36=PB6 +Mcu.Pin37=PB9 +Mcu.Pin38=PE1 +Mcu.Pin39=VP_FREERTOS_VS_CMSIS_V2 Mcu.Pin4=PH1-OSC_OUT -Mcu.Pin40=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS +Mcu.Pin40=VP_SYS_VS_Systick +Mcu.Pin41=VP_TIM1_VS_ClockSourceINT +Mcu.Pin42=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS Mcu.Pin5=PC0 Mcu.Pin6=PC3 Mcu.Pin7=PA0-WKUP Mcu.Pin8=PA1 -Mcu.Pin9=PA4 -Mcu.PinsNb=41 +Mcu.Pin9=PA2 +Mcu.PinsNb=43 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F407VGTx MxCube.Version=6.15.0 MxDb.Version=DB.6.0.150 NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false +NVIC.DMA2_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false\:false @@ -139,6 +169,10 @@ PA14.Signal=SYS_JTCK-SWCLK PA15.GPIOParameters=GPIO_PuPd PA15.GPIO_PuPd=GPIO_PULLUP PA15.Signal=S_TIM2_CH1_ETR +PA2.Locked=true +PA2.Signal=ADCx_IN2 +PA3.Locked=true +PA3.Signal=ADCx_IN3 PA4.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label,GPIO_Mode PA4.GPIO_Label=I2S3_WS [CS43L22_LRCK] PA4.GPIO_Mode=GPIO_MODE_AF_PP @@ -342,7 +376,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=true -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_I2C1_Init-I2C1-false-HAL-true,4-MX_I2S3_Init-I2S3-false-HAL-true,5-MX_SPI1_Init-SPI1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_TIM2_Init-TIM2-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_I2C1_Init-I2C1-false-HAL-true,5-MX_I2S3_Init-I2S3-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_TIM1_Init-TIM1-false-HAL-true,8-MX_TIM2_Init-TIM2-false-HAL-true,9-MX_TIM3_Init-TIM3-false-HAL-true,10-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,11-MX_ADC1_Init-ADC1-false-HAL-true RCC.48MHZClocksFreq_Value=48000000 RCC.AHBFreq_Value=168000000 RCC.APB1CLKDivider=RCC_HCLK_DIV4 @@ -375,6 +409,10 @@ RCC.VCOI2SOutputFreq_Value=192000000 RCC.VCOInputFreq_Value=1000000 RCC.VCOOutputFreq_Value=336000000 RCC.VcooutputI2S=96000000 +SH.ADCx_IN2.0=ADC1_IN2,IN2 +SH.ADCx_IN2.ConfNb=1 +SH.ADCx_IN3.0=ADC1_IN3,IN3 +SH.ADCx_IN3.ConfNb=1 SH.GPXTI0.0=GPIO_EXTI0 SH.GPXTI0.ConfNb=1 SH.GPXTI1.0=GPIO_EXTI1 @@ -423,4 +461,5 @@ VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS board=STM32F407G-DISC1 boardIOC=true +rtos.0.ip=FREERTOS isbadioc=false