diff --git a/zephyr/boards/arm/owntech_board/dts/adc-channels.dtsi b/zephyr/boards/arm/owntech_board/dts/adc-channels.dtsi index afbd459c7a4178ebc369290ff244bf3af0d24289..ba790ad62aff370ce8e5a9e662a47768478c346c 100644 --- a/zephyr/boards/arm/owntech_board/dts/adc-channels.dtsi +++ b/zephyr/boards/arm/owntech_board/dts/adc-channels.dtsi @@ -85,5 +85,10 @@ label = "TEMP_SENSOR"; };*/ + current-share { + io-channels = <&adc4 5>; + label = "ANALOG_COMM"; + }; + }; }; diff --git a/zephyr/boards/arm/owntech_board/dts/adc.dtsi b/zephyr/boards/arm/owntech_board/dts/adc.dtsi index dc940d46f03ff1e60170c7b6167f28df40acd45b..6547dc75beb38645c50381b70b90b6aa2b1384f6 100644 --- a/zephyr/boards/arm/owntech_board/dts/adc.dtsi +++ b/zephyr/boards/arm/owntech_board/dts/adc.dtsi @@ -15,5 +15,15 @@ label = "ADC_3"; #io-channel-cells = < 0x1 >; }; + + adc4: adc@50005100 { + compatible = "st,stm32-adc"; + reg = < 0x50005100 0x100 >; + clocks = < &rcc STM32_CLOCK_BUS_AHB2 0x00004000 >; + interrupts = < 18 0x0 >; + status = "disabled"; + label = "ADC_4"; + #io-channel-cells = < 0x1 >; + }; }; }; \ No newline at end of file diff --git a/zephyr/boards/arm/owntech_board/dts/pinctrl.dtsi b/zephyr/boards/arm/owntech_board/dts/pinctrl.dtsi index 421ef4f8b905a5ff4657c20a2dd5d237bd211a03..bf538671ee0d8af2bfd131f94f8b24d25fcfd7eb 100644 --- a/zephyr/boards/arm/owntech_board/dts/pinctrl.dtsi +++ b/zephyr/boards/arm/owntech_board/dts/pinctrl.dtsi @@ -10,6 +10,9 @@ tim4_etr_pb3: tim4_etr_pb3 { pinmux = <STM32_PINMUX('B', 3, AF2)>; }; + adc4_in5_pb15: adc4_in5_pb15 { + pinmux = <STM32_PINMUX('B', 15, ANALOG)>; + }; }; }; }; \ No newline at end of file diff --git a/zephyr/boards/arm/owntech_board/owntech_board.dts b/zephyr/boards/arm/owntech_board/owntech_board.dts index 7dc5db0341e4783facce6739a10eefc0c142d683..8f66afb138efb065ae1df6dc949ed6aa9f1f8a96 100644 --- a/zephyr/boards/arm/owntech_board/owntech_board.dts +++ b/zephyr/boards/arm/owntech_board/owntech_board.dts @@ -178,6 +178,11 @@ status = "okay"; }; +&adc4 { + pinctrl-0 = <&adc4_in5_pb15 >; + status = "okay"; +}; + /*******/ /* DAC */ /*******/ diff --git a/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c b/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c index aacc4d1a6f0363b6c6e3ad55a5c7c040e0e51d7b..183398cc56cfa7b6814affabf26bf807dbac03a3 100644 --- a/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c +++ b/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.c @@ -38,7 +38,7 @@ ///// // Constants -#define NUMBER_OF_ADCS 3 +#define NUMBER_OF_ADCS 4 ///// @@ -184,3 +184,8 @@ uint8_t adc_get_enabled_channels_count(uint8_t adc_num) { return adc_channels_get_enabled_channels_count(adc_num); } + +void adc_software_trigger_conversion(uint8_t adc_number) +{ + adc_core_start(adc_number); +} \ No newline at end of file diff --git a/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.h b/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.h index 91b6112545a579f1320909fff2177b021e8d2433..8f77684e33ae4ece20ddb72fbdb2bd9dfaf93e4a 100644 --- a/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.h +++ b/zephyr/modules/owntech_adc_driver/zephyr/public_api/adc.h @@ -144,6 +144,18 @@ void adc_start(); */ const char* adc_get_channel_name(uint8_t adc_number, uint8_t channel_rank); + +/** + * This function triggers a single conversion in the case of a software triggered adc. + * + * This function must only be called after + * adc_configure_adc_channels has been called. + * + * @param adc_number Number of the ADC. + */ +void adc_software_trigger_conversion(uint8_t adc_number); + + #ifdef __cplusplus } #endif diff --git a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_channels.c b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_channels.c index 7091a92084acbdf6d02b348f7618c46ba1708eba..0d6692d15e75af81a58958e304676ccdba2403eb 100644 --- a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_channels.c +++ b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_channels.c @@ -87,6 +87,7 @@ static channel_prop_t available_channels_props[] = static uint8_t adc1_available_channels_count; static uint8_t adc2_available_channels_count; static uint8_t adc3_available_channels_count; +static uint8_t adc4_available_channels_count; // List of available channels as defined in device tree. // These are arrays (range 0 to adcX_available_channels_count-1) @@ -94,11 +95,13 @@ static uint8_t adc3_available_channels_count; static channel_prop_t** adc1_available_channels_list; static channel_prop_t** adc2_available_channels_list; static channel_prop_t** adc3_available_channels_list; +static channel_prop_t** adc4_available_channels_list; // Number of enabled channels defined by the user configuration static uint8_t adc1_enabled_channels_count; static uint8_t adc2_enabled_channels_count; static uint8_t adc3_enabled_channels_count; +static uint8_t adc4_enabled_channels_count; // List of channels enabled by user configuration. // These are arrays (range 0 to adcX_enabled_channels_count-1) @@ -106,6 +109,7 @@ static uint8_t adc3_enabled_channels_count; static channel_prop_t** adc1_enabled_channels_list; static channel_prop_t** adc2_enabled_channels_list; static channel_prop_t** adc3_enabled_channels_list; +static channel_prop_t** adc4_enabled_channels_list; ///// @@ -120,6 +124,7 @@ static void _adc_channels_build_available_channels_lists() adc1_available_channels_count = 0; adc2_available_channels_count = 0; adc3_available_channels_count = 0; + adc4_available_channels_count = 0; for (int i = 0 ; i < CHANNEL_COUNT ; i++) { @@ -136,16 +141,22 @@ static void _adc_channels_build_available_channels_lists() { adc3_available_channels_count++; } + else if (adc_number == 4) + { + adc4_available_channels_count++; + } } // Build a list of channels by ADC adc1_available_channels_list = k_malloc(sizeof(channel_prop_t*) * adc1_available_channels_count); adc2_available_channels_list = k_malloc(sizeof(channel_prop_t*) * adc2_available_channels_count); adc3_available_channels_list = k_malloc(sizeof(channel_prop_t*) * adc3_available_channels_count); + adc4_available_channels_list = k_malloc(sizeof(channel_prop_t*) * adc4_available_channels_count); int adc1_index = 0; int adc2_index = 0; int adc3_index = 0; + int adc4_index = 0; for (int i = 0 ; i < CHANNEL_COUNT ; i++) { uint8_t adc_number = _get_adc_number_by_name(available_channels_props[i].adc); @@ -164,6 +175,11 @@ static void _adc_channels_build_available_channels_lists() adc3_available_channels_list[adc3_index] = &available_channels_props[i]; adc3_index++; } + else if (adc_number == 4) + { + adc4_available_channels_list[adc4_index] = &available_channels_props[i]; + adc4_index++; + } } } @@ -215,6 +231,9 @@ static channel_prop_t** _adc_channels_get_enabled_channels_list(uint8_t adc_num) case 3: enabled_channels_list = adc3_enabled_channels_list; break; + case 4: + enabled_channels_list = adc4_enabled_channels_list; + break; } return enabled_channels_list; } @@ -233,6 +252,9 @@ static channel_prop_t** _adc_channels_get_available_channels_list(uint8_t adc_nu case 3: available_channels_list = adc3_available_channels_list; break; + case 4: + available_channels_list = adc4_available_channels_list; + break; } return available_channels_list; } @@ -251,6 +273,9 @@ static uint8_t _adc_channels_get_available_channels_count(uint8_t adc_num) case 3: available_channels_count = adc3_available_channels_count; break; + case 4: + available_channels_count = adc4_available_channels_count; + break; } return available_channels_count; } @@ -269,6 +294,9 @@ static uint8_t _adc_channels_get_enabled_channels_count(uint8_t adc_num) case 3: enabled_channels_count = adc3_enabled_channels_count; break; + case 4: + enabled_channels_count = adc4_enabled_channels_count; + break; } return enabled_channels_count; } @@ -289,6 +317,10 @@ static void _adc_channels_set_enabled_channels(uint8_t adc_num, channel_prop_t** adc3_enabled_channels_list = enabled_channels; adc3_enabled_channels_count = enabled_channels_count; break; + case 4: + adc4_enabled_channels_list = enabled_channels; + adc4_enabled_channels_count = enabled_channels_count; + break; } } @@ -451,6 +483,9 @@ uint8_t adc_channels_get_enabled_channels_count(uint8_t adc_num) case 3: enabled_channels = adc3_enabled_channels_count; break; + case 4: + enabled_channels = adc4_enabled_channels_count; + break; } return enabled_channels; diff --git a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.c b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.c index ee1d03e913dd1a9cfc080532de529466b726d1d5..bcc19949fd836379e52af240330799f4877b32fa 100644 --- a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.c +++ b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_core.c @@ -177,6 +177,7 @@ void adc_core_init() _adc_core_wakeup(1); _adc_core_wakeup(2); _adc_core_wakeup(3); + _adc_core_wakeup(4); // Set common clock between ADC 1 and ADC 2 // Refer to RM 21.4.3 and 21.7.2 @@ -187,4 +188,5 @@ void adc_core_init() _adc_core_calibrate(1); _adc_core_calibrate(2); _adc_core_calibrate(3); + _adc_core_calibrate(4); } diff --git a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_helper.c b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_helper.c index 1b06cb1c806f79ee311aca73643913d04f29f847..02d8a964b7c8ab7e9474ade029794c8656ea49b5 100644 --- a/zephyr/modules/owntech_adc_driver/zephyr/src/adc_helper.c +++ b/zephyr/modules/owntech_adc_driver/zephyr/src/adc_helper.c @@ -43,6 +43,8 @@ ADC_TypeDef* _get_adc_by_name(char* name) adc = ADC2; else if ( strcmp(name, "ADC_3") == 0) adc = ADC3; + else if ( strcmp(name, "ADC_4") == 0) + adc = ADC4; return adc; } @@ -57,6 +59,8 @@ ADC_TypeDef* _get_adc_by_number(uint8_t adc_number) adc = ADC2; else if (adc_number == 3) adc = ADC3; + else if (adc_number == 4) + adc = ADC4; return adc; } @@ -71,6 +75,8 @@ uint8_t _get_adc_number_by_name(char* name) adc_number = 2; else if ( strcmp(name, "ADC_3") == 0) adc_number = 3; + else if ( strcmp(name, "ADC_4") == 0) + adc_number = 4; return adc_number; } diff --git a/zephyr/modules/owntech_data_acquisition/zephyr/data_conversion/data_conversion.c b/zephyr/modules/owntech_data_acquisition/zephyr/data_conversion/data_conversion.c index 39cb03843d594bb02a70bbd5d5b30d0f6d74b0b9..1c4c8a754a80763cda1a7dffdae9e7c2fe54aa63 100644 --- a/zephyr/modules/owntech_data_acquisition/zephyr/data_conversion/data_conversion.c +++ b/zephyr/modules/owntech_data_acquisition/zephyr/data_conversion/data_conversion.c @@ -54,6 +54,10 @@ static float32_t offset_extra = 1.0; //offset for the extra static float32_t gain_temperature = 1.0; static float32_t offset_temperature = 0.0; +// Analog Communication Bus +static float32_t gain_analog_comm = 1.0; +static float32_t offset_analog_comm = 0.0; + ///// // Public Functions @@ -102,6 +106,11 @@ float32_t data_conversion_convert_extra(uint16_t raw_value) return (raw_value*gain_extra)+offset_extra; } +float32_t data_conversion_convert_analog_comm(uint16_t raw_value) +{ + return (raw_value*gain_analog_comm)+offset_analog_comm; +} + /** @@ -154,3 +163,9 @@ void data_conversion_set_extra_parameters(float32_t gain, float32_t offset) gain_extra = gain; offset_extra = offset; } + +void data_conversion_set_analog_comm_parameters(float32_t gain, float32_t offset) +{ + gain_analog_comm = gain; + offset_analog_comm = offset; +} diff --git a/zephyr/modules/owntech_data_acquisition/zephyr/data_conversion/data_conversion.h b/zephyr/modules/owntech_data_acquisition/zephyr/data_conversion/data_conversion.h index 8d42f8eb04f65292c7425706d082cc757215bffe..ec6c74f89eb516eb5e5b6955191c3cd4f493d8c2 100644 --- a/zephyr/modules/owntech_data_acquisition/zephyr/data_conversion/data_conversion.h +++ b/zephyr/modules/owntech_data_acquisition/zephyr/data_conversion/data_conversion.h @@ -107,6 +107,16 @@ float32_t data_conversion_convert_temp(uint16_t raw_value); float32_t data_conversion_convert_extra(uint16_t raw_value); +/** + * @brief Converts the values of the analog communication into a physical unit + * + * @param[in] raw_value + * + * @return a foat32_t value for the analog communication + */ +float32_t data_conversion_convert_analog_comm(uint16_t raw_value); + + /** * @brief Change the parameters for the data conversion of V1_low * @@ -172,6 +182,15 @@ void data_conversion_set_temp_parameters(float32_t gain, float32_t offset); void data_conversion_set_extra_parameters(float32_t gain, float32_t offset); +/** + * @brief Change the parameters for the analog communication measurement + * + * @param[in] gain gain of the analog communication bus + * @param[in] offset offset of the analog communication + */ +void data_conversion_set_analog_comm_parameters(float32_t gain, float32_t offset); + + #ifdef __cplusplus } #endif diff --git a/zephyr/modules/owntech_data_acquisition/zephyr/dma/dma.c b/zephyr/modules/owntech_data_acquisition/zephyr/dma/dma.c index 5faebacab147db17a22911997678523fa150b51e..8b24ea4027fbd4d652e417e3ad763ee429e2f228 100644 --- a/zephyr/modules/owntech_data_acquisition/zephyr/dma/dma.c +++ b/zephyr/modules/owntech_data_acquisition/zephyr/dma/dma.c @@ -57,18 +57,20 @@ static const struct device* dma1 = DEVICE_DT_GET(DT_NODELABEL(dma1)); ///// // LL definitions -static uint32_t source_registers[3] = +static uint32_t source_registers[4] = { (uint32_t)(&(ADC1->DR)), (uint32_t)(&(ADC2->DR)), - (uint32_t)(&(ADC3->DR)) + (uint32_t)(&(ADC3->DR)), + (uint32_t)(&(ADC4->DR)) }; -static uint32_t source_triggers[3] = +static uint32_t source_triggers[4] = { LL_DMAMUX_REQ_ADC1, LL_DMAMUX_REQ_ADC2, - LL_DMAMUX_REQ_ADC3 + LL_DMAMUX_REQ_ADC3, + LL_DMAMUX_REQ_ADC4 }; @@ -91,7 +93,7 @@ static uint16_t** half_buffer_2; */ static void _dma_callback(const struct device* dev, void* user_data, uint32_t channel, int status) { - static uint8_t current_half_buffer[3] = {0}; + static uint8_t current_half_buffer[4] = {0}; uint8_t adc_number = channel + 1; if (current_half_buffer[channel] == 0) @@ -177,3 +179,13 @@ uint16_t* dma_get_dma2_buffer() { return half_buffer_1[1]; } + +uint16_t* dma_get_dma3_buffer() +{ + return half_buffer_1[2]; +} + +uint16_t* dma_get_dma4_buffer() +{ + return half_buffer_1[3]; +} diff --git a/zephyr/modules/owntech_data_acquisition/zephyr/dma/dma.h b/zephyr/modules/owntech_data_acquisition/zephyr/dma/dma.h index aec2116e35f936008c8c37a619c84633f06d6af6..c5deae815f912b3854f3e56dfbb8829186026e07 100644 --- a/zephyr/modules/owntech_data_acquisition/zephyr/dma/dma.h +++ b/zephyr/modules/owntech_data_acquisition/zephyr/dma/dma.h @@ -48,6 +48,8 @@ void dma_configure_and_start(uint8_t adc_count); // For debug purpose uint16_t* dma_get_dma1_buffer(); uint16_t* dma_get_dma2_buffer(); +uint16_t* dma_get_dma3_buffer(); +uint16_t* dma_get_dma4_buffer(); #ifdef __cplusplus diff --git a/zephyr/modules/owntech_data_acquisition/zephyr/public_api/DataAcquisition.cpp b/zephyr/modules/owntech_data_acquisition/zephyr/public_api/DataAcquisition.cpp index cb3bb94c9e5bbb96335915f3e3e4da86ca0cf758..68b2c408efa4aaaad154613533647921c5b18f16 100644 --- a/zephyr/modules/owntech_data_acquisition/zephyr/public_api/DataAcquisition.cpp +++ b/zephyr/modules/owntech_data_acquisition/zephyr/public_api/DataAcquisition.cpp @@ -57,6 +57,7 @@ DataAcquisition::channel_assignment_t DataAcquisition::i2_low_assignement DataAcquisition::channel_assignment_t DataAcquisition::i_high_assignement = {0}; DataAcquisition::channel_assignment_t DataAcquisition::temp_sensor_assignement = {0}; DataAcquisition::channel_assignment_t DataAcquisition::extra_sensor_assignement = {0}; +DataAcquisition::channel_assignment_t DataAcquisition::analog_comm_assignement = {0}; bool DataAcquisition::is_started = false; @@ -105,11 +106,16 @@ void DataAcquisition::setChannnelAssignment(uint8_t adc_number, const char* chan extra_sensor_assignement.adc_number = adc_number; extra_sensor_assignement.channel_rank = channel_rank; } + else if (strcmp(channel_name, "ANALOG_COMM") == 0) + { + analog_comm_assignement.adc_number = adc_number; + analog_comm_assignement.channel_rank = channel_rank; + } } void DataAcquisition::start() { - uint8_t number_of_adcs = 2; + uint8_t number_of_adcs = 4; for (uint8_t adc_num = 1 ; adc_num <= number_of_adcs ; adc_num++) { @@ -193,6 +199,12 @@ uint16_t* DataAcquisition::getExtraRawValues(uint32_t& number_of_values_acquired return data_dispatch_get_acquired_values(extra_sensor_assignement.adc_number, extra_sensor_assignement.channel_rank, &number_of_values_acquired); } +uint16_t* DataAcquisition::getAnalogCommRawValues(uint32_t& number_of_values_acquired) +{ + return data_dispatch_get_acquired_values(analog_comm_assignement.adc_number, analog_comm_assignement.channel_rank, &number_of_values_acquired); +} + + float32_t DataAcquisition::peekV1Low() { uint16_t rawValue = data_dispatch_peek_acquired_value(v1_low_assignement.adc_number, v1_low_assignement.channel_rank); @@ -361,6 +373,20 @@ float32_t DataAcquisition::getExtra() return converted_data; } +float32_t DataAcquisition::getAnalogComm() +{ + uint32_t data_count; + static float32_t converted_data = -10000; // Return an impossible value if no data has been acquired yet + uint16_t* buffer = getAnalogCommRawValues(data_count); + + if (data_count > 0) // If data was received it gets converted + { + uint16_t raw_value = buffer[data_count - 1]; + converted_data = data_conversion_convert_analog_comm(raw_value); + } + + return converted_data; +} float32_t DataAcquisition::convertV1Low(uint16_t raw_value) { @@ -402,6 +428,11 @@ float32_t DataAcquisition::convertExtra(uint16_t raw_value) return data_conversion_convert_extra(raw_value); } +float32_t DataAcquisition::convertAnalogComm(uint16_t raw_value) +{ + return data_conversion_convert_analog_comm(raw_value); +} + void DataAcquisition::setV1LowParameters(float32_t gain, float32_t offset) { @@ -442,3 +473,8 @@ void DataAcquisition::setExtraParameters(float32_t gain, float32_t offset) { data_conversion_set_extra_parameters(gain, offset); } + +void DataAcquisition::setAnalogCommParameters(float32_t gain, float32_t offset) +{ + data_conversion_set_analog_comm_parameters(gain, offset); +} diff --git a/zephyr/modules/owntech_data_acquisition/zephyr/public_api/DataAcquisition.h b/zephyr/modules/owntech_data_acquisition/zephyr/public_api/DataAcquisition.h index a049857185d0a96edc7edfb4f2a11b41c8686bf9..a323846604c0850ec55af0fd2ebe15549bd030b7 100644 --- a/zephyr/modules/owntech_data_acquisition/zephyr/public_api/DataAcquisition.h +++ b/zephyr/modules/owntech_data_acquisition/zephyr/public_api/DataAcquisition.h @@ -109,6 +109,7 @@ public: static uint16_t* getIHighRawValues(uint32_t& number_of_values_acquired); static uint16_t* getTemperatureRawValues(uint32_t& number_of_values_acquired); static uint16_t* getExtraRawValues(uint32_t& number_of_values_acquired); + static uint16_t* getAnalogCommRawValues(uint32_t& number_of_values_acquired); /** * Functions to access the latest value available from a channel expressed @@ -145,6 +146,7 @@ public: static float32_t getIHigh(); static float32_t getTemperature(); static float32_t getExtra(); + static float32_t getAnalogComm(); /** * Use these functions to convert values obtained using @@ -159,6 +161,7 @@ public: static float32_t convertIHigh(uint16_t raw_value); static float32_t convertTemperature(uint16_t raw_value); static float32_t convertExtra(uint16_t raw_value); + static float32_t convertAnalogComm(uint16_t raw_value); /** * Use these functions to tweak the conversion values for @@ -172,6 +175,7 @@ public: static void setIHighParameters(float32_t gain, float32_t offset); static void setTemperatureParameters(float32_t gain, float32_t offset); static void setExtraParameters(float32_t gain, float32_t offset); + static void setAnalogCommParameters(float32_t gain, float32_t offset); private: @@ -192,6 +196,7 @@ private: static channel_assignment_t i_high_assignement; static channel_assignment_t temp_sensor_assignement; static channel_assignment_t extra_sensor_assignement; + static channel_assignment_t analog_comm_assignement; }; diff --git a/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.cpp b/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.cpp index 23e3df0eb7e3e1a716a1faaa8476556d70eb6803..83b574e44d1a78848224ffe9e2f95f8ac7d63257 100644 --- a/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.cpp +++ b/zephyr/modules/owntech_hardware_configuration/zephyr/src/adc_configuration.cpp @@ -49,6 +49,7 @@ void _initialize() configure_adc_trigger_source(1, hrtim_ev1); configure_adc_trigger_source(2, hrtim_ev3); configure_adc_trigger_source(3, software); + configure_adc_trigger_source(4, software); adc_configure_discontinuous_mode(1, 1); adc_configure_discontinuous_mode(2, 1);