@@ -672,8 +672,6 @@ struct ADCDomain {
672672 return nullptr ;
673673 }
674674
675-
676-
677675 struct Instance {
678676 ADC_HandleTypeDef* handle = nullptr ;
679677 Channel channel = Channel::CH0 ;
@@ -739,11 +737,15 @@ struct ADCDomain {
739737 static inline std::array<Instance, N> instances{};
740738
741739 static constexpr auto buffer_sizes = calculate_buffer_sizes(cfgs);
740+ static constexpr std::size_t total_dma_slots =
741+ buffer_sizes.adc1_size + buffer_sizes.adc2_size + buffer_sizes.adc3_size;
742+ static_assert (
743+ total_dma_slots <= max_instances,
744+ " ADC DMA buffer size exceeds max_instances"
745+ );
742746
743- // Static DMA buffers in non-cached D1 RAM, sized to actual usage
744- D1_NC static inline std::array<uint16_t , buffer_sizes.adc1_size > 0 ? buffer_sizes.adc1_size : 1 > dma_buffer_adc1{};
745- D1_NC static inline std::array<uint16_t , buffer_sizes.adc2_size > 0 ? buffer_sizes.adc2_size : 1 > dma_buffer_adc2{};
746- D1_NC static inline std::array<uint16_t , buffer_sizes.adc3_size > 0 ? buffer_sizes.adc3_size : 1 > dma_buffer_adc3{};
747+ alignas (32 ) D1_NC
748+ static inline uint16_t dma_buffer_pool[total_dma_slots > 0 ? total_dma_slots : 1 ]{};
747749
748750 static constexpr bool is_resolved_config (const Config& cfg) {
749751 return cfg.peripheral != Peripheral::AUTO && cfg.channel != Channel::AUTO ;
@@ -763,57 +765,59 @@ struct ADCDomain {
763765 return &hadc1;
764766 }
765767
766- static uint16_t * get_dma_buffer (Peripheral peripheral) {
767- uint16_t * buffer = nullptr ;
768- size_t buffer_size = 0 ;
769-
768+ static constexpr std::size_t buffer_size_for (Peripheral peripheral) {
770769 switch (peripheral) {
771770 case Peripheral::ADC_1 :
772- buffer = dma_buffer_adc1.data ();
773- buffer_size = buffer_sizes.adc1_size ;
774- break ;
771+ return buffer_sizes.adc1_size ;
775772 case Peripheral::ADC_2 :
776- buffer = dma_buffer_adc2.data ();
777- buffer_size = buffer_sizes.adc2_size ;
778- break ;
773+ return buffer_sizes.adc2_size ;
779774 case Peripheral::ADC_3 :
780- buffer = dma_buffer_adc3. data () ;
781- buffer_size = buffer_sizes. adc3_size ;
775+ return buffer_sizes. adc3_size ;
776+ case Peripheral:: AUTO :
782777 break ;
778+ }
779+ return 0 ;
780+ }
781+
782+ static constexpr std::size_t buffer_offset_for (Peripheral peripheral) {
783+ switch (peripheral) {
784+ case Peripheral::ADC_1 :
785+ return 0 ;
786+ case Peripheral::ADC_2 :
787+ return buffer_sizes.adc1_size ;
788+ case Peripheral::ADC_3 :
789+ return buffer_sizes.adc1_size + buffer_sizes.adc2_size ;
783790 case Peripheral::AUTO :
784791 break ;
785792 }
786-
787- if (buffer == nullptr || buffer_size == 0 ) {
793+ return 0 ;
794+ }
795+ static uint16_t * get_dma_buffer (Peripheral peripheral) {
796+ const auto buffer_size = buffer_size_for (peripheral);
797+ const auto buffer_offset = buffer_offset_for (peripheral);
798+ if (buffer_size == 0U ) {
788799 ErrorHandler (" ADC DMA buffer not available" );
789800 return nullptr ;
790801 }
802+ if ((buffer_offset + buffer_size) > total_dma_slots) {
803+ ErrorHandler (" ADC DMA pool overflow" );
804+ return nullptr ;
805+ }
791806
807+ uint16_t * buffer = &dma_buffer_pool[buffer_offset];
792808 std::fill_n (buffer, buffer_size, uint16_t {0 });
793809 return buffer;
794810 }
795811
796812 static uint16_t * get_dma_slot (Peripheral peripheral, uint8_t index) {
797- switch (peripheral) {
798- case Peripheral::ADC_1 :
799- if (index < buffer_sizes.adc1_size ) {
800- return &dma_buffer_adc1[index];
801- }
802- break ;
803- case Peripheral::ADC_2 :
804- if (index < buffer_sizes.adc2_size ) {
805- return &dma_buffer_adc2[index];
806- }
807- break ;
808- case Peripheral::ADC_3 :
809- if (index < buffer_sizes.adc3_size ) {
810- return &dma_buffer_adc3[index];
811- }
812- break ;
813- case Peripheral::AUTO :
814- break ;
813+ if (index >= buffer_size_for (peripheral)) {
814+ return nullptr ;
815+ }
816+ const auto buffer_offset = buffer_offset_for (peripheral);
817+ if ((buffer_offset + index) >= total_dma_slots) {
818+ return nullptr ;
815819 }
816- return nullptr ;
820+ return &dma_buffer_pool[buffer_offset + index] ;
817821 }
818822
819823 static void configure_peripheral (const Config& cfg, uint8_t channel_count) {
@@ -851,7 +855,7 @@ struct ADCDomain {
851855 }
852856
853857 static void init (
854- std::span<const Config, N> cfgs ,
858+ std::span<const Config, N> runtime_cfgs ,
855859 std::span<GPIODomain::Instance> gpio_instances = std::span<GPIODomain::Instance>{},
856860 std::span<DMADomain::Instance> dma_peripherals = std::span<DMADomain::Instance>{}
857861 ) {
@@ -866,7 +870,7 @@ struct ADCDomain {
866870 }
867871
868872 for (std::size_t i = 0 ; i < N; ++i) {
869- const auto & cfg = cfgs [i];
873+ const auto & cfg = runtime_cfgs [i];
870874 if (!is_resolved_config (cfg)) {
871875 ErrorHandler (" ADC config unresolved (AUTO)" );
872876 continue ;
@@ -883,7 +887,7 @@ struct ADCDomain {
883887
884888 const Peripheral peripheral = peripheral_from_index (pidx);
885889 const Config* first_cfg = nullptr ;
886- for (const auto & cfg : cfgs ) {
890+ for (const auto & cfg : runtime_cfgs ) {
887891 if (cfg.peripheral == peripheral) {
888892 first_cfg = &cfg;
889893 break ;
@@ -921,7 +925,7 @@ struct ADCDomain {
921925
922926 uint8_t rank = 0 ;
923927 bool config_error = false ;
924- for (const auto & cfg : cfgs ) {
928+ for (const auto & cfg : runtime_cfgs ) {
925929 if (cfg.peripheral != peripheral) {
926930 continue ;
927931 }
@@ -959,7 +963,7 @@ struct ADCDomain {
959963 }
960964
961965 for (std::size_t i = 0 ; i < N; ++i) {
962- const auto & cfg = cfgs [i];
966+ const auto & cfg = runtime_cfgs [i];
963967 if (!instance_cfg_valid[i]) {
964968 continue ;
965969 }
@@ -969,7 +973,8 @@ struct ADCDomain {
969973 instances[i].sample_time = cfg.sample_time ;
970974 instances[i].resolution = cfg.resolution ;
971975 instances[i].output = cfg.output ;
972- instances[i].dma_slot = periph_ready[pidx] ? get_dma_slot (cfg.peripheral , instance_ranks[i]) : nullptr ;
976+ instances[i].dma_slot =
977+ periph_ready[pidx] ? get_dma_slot (cfg.peripheral , instance_ranks[i]) : nullptr ;
973978 }
974979 }
975980 };
0 commit comments