1010#include " ErrorHandler/ErrorHandler.hpp"
1111#include " HALAL/Models/DMA/DMA2.hpp"
1212#include " HALAL/Models/GPIO.hpp"
13- # include " HALAL/Models/MPUManager/MPUManager.hpp "
13+
1414#include " HALAL/Models/Pin.hpp"
15+ #include " HALAL/Models/MPU.hpp"
1516
1617using std::array;
1718using std::size_t ;
@@ -250,7 +251,32 @@ struct ADCDomain {
250251 return regular_ranks[zero_based_rank];
251252 }
252253
253- static inline std::array<uint16_t *, 3 > dma_buffers{nullptr , nullptr , nullptr };
254+ struct BufferSizes {
255+ std::size_t adc1_size = 0 ;
256+ std::size_t adc2_size = 0 ;
257+ std::size_t adc3_size = 0 ;
258+ };
259+
260+ static consteval BufferSizes calculate_buffer_sizes (span<const Config> cfgs) {
261+ BufferSizes sizes;
262+ for (const auto & cfg : cfgs) {
263+ switch (cfg.peripheral ) {
264+ case Peripheral::ADC_1:
265+ sizes.adc1_size ++;
266+ break ;
267+ case Peripheral::ADC_2:
268+ sizes.adc2_size ++;
269+ break ;
270+ case Peripheral::ADC_3:
271+ sizes.adc3_size ++;
272+ break ;
273+ case Peripheral::AUTO:
274+ compile_error (" ADC: peripheral not resolved" );
275+ break ;
276+ }
277+ }
278+ return sizes;
279+ }
254280
255281 static consteval bool is_valid_channel (Channel ch) {
256282 switch (ch) {
@@ -646,21 +672,7 @@ struct ADCDomain {
646672 return nullptr ;
647673 }
648674
649- static uint16_t * ensure_dma_buffer (Peripheral peripheral) {
650- const uint8_t pidx = peripheral_index (peripheral);
651- if (dma_buffers[pidx] == nullptr ) {
652- dma_buffers[pidx] = static_cast <uint16_t *>(MPUManager::allocate_non_cached_memory (
653- sizeof (uint16_t ) * max_channels_per_peripheral
654- ));
655- }
656- if (dma_buffers[pidx] == nullptr ) {
657- ErrorHandler (" ADC DMA buffer allocation failed" );
658- return nullptr ;
659- }
660675
661- std::fill_n (dma_buffers[pidx], max_channels_per_peripheral, uint16_t {0 });
662- return dma_buffers[pidx];
663- }
664676
665677 struct Instance {
666678 ADC_HandleTypeDef* handle = nullptr ;
@@ -723,9 +735,16 @@ struct ADCDomain {
723735 }
724736 };
725737
726- template <std::size_t N> struct Init {
738+ template <std::size_t N, std::array<Config, N> cfgs > struct Init {
727739 static inline std::array<Instance, N> instances{};
728740
741+ static constexpr auto buffer_sizes = calculate_buffer_sizes(cfgs);
742+
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+
729748 static constexpr bool is_resolved_config (const Config& cfg) {
730749 return cfg.peripheral != Peripheral::AUTO && cfg.channel != Channel::AUTO;
731750 }
@@ -744,6 +763,59 @@ struct ADCDomain {
744763 return &hadc1;
745764 }
746765
766+ static uint16_t * get_dma_buffer (Peripheral peripheral) {
767+ uint16_t * buffer = nullptr ;
768+ size_t buffer_size = 0 ;
769+
770+ switch (peripheral) {
771+ case Peripheral::ADC_1:
772+ buffer = dma_buffer_adc1.data ();
773+ buffer_size = buffer_sizes.adc1_size ;
774+ break ;
775+ case Peripheral::ADC_2:
776+ buffer = dma_buffer_adc2.data ();
777+ buffer_size = buffer_sizes.adc2_size ;
778+ break ;
779+ case Peripheral::ADC_3:
780+ buffer = dma_buffer_adc3.data ();
781+ buffer_size = buffer_sizes.adc3_size ;
782+ break ;
783+ case Peripheral::AUTO:
784+ break ;
785+ }
786+
787+ if (buffer == nullptr || buffer_size == 0 ) {
788+ ErrorHandler (" ADC DMA buffer not available" );
789+ return nullptr ;
790+ }
791+
792+ std::fill_n (buffer, buffer_size, uint16_t {0 });
793+ return buffer;
794+ }
795+
796+ 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 ;
815+ }
816+ return nullptr ;
817+ }
818+
747819 static void configure_peripheral (const Config& cfg, uint8_t channel_count) {
748820 ADC_HandleTypeDef* hadc = handle_for (cfg.peripheral );
749821
@@ -833,8 +905,7 @@ struct ADCDomain {
833905 ErrorHandler (" ADC DMA instance unavailable" );
834906 continue ;
835907 }
836-
837- uint16_t * buffer = ensure_dma_buffer (peripheral);
908+ uint16_t * buffer = get_dma_buffer (peripheral);
838909 if (buffer == nullptr ) {
839910 continue ;
840911 }
@@ -898,9 +969,7 @@ struct ADCDomain {
898969 instances[i].sample_time = cfg.sample_time ;
899970 instances[i].resolution = cfg.resolution ;
900971 instances[i].output = cfg.output ;
901- instances[i].dma_slot = (periph_ready[pidx] && dma_buffers[pidx] != nullptr )
902- ? &dma_buffers[pidx][instance_ranks[i]]
903- : nullptr ;
972+ instances[i].dma_slot = periph_ready[pidx] ? get_dma_slot (cfg.peripheral , instance_ranks[i]) : nullptr ;
904973 }
905974 }
906975 };
0 commit comments