|
| 1 | +------------------------------------------------------------------------------ |
| 2 | +-- -- |
| 3 | +-- Copyright (C) 2025, AdaCore -- |
| 4 | +-- -- |
| 5 | +-- Redistribution and use in source and binary forms, with or without -- |
| 6 | +-- modification, are permitted provided that the following conditions are -- |
| 7 | +-- met: -- |
| 8 | +-- 1. Redistributions of source code must retain the above copyright -- |
| 9 | +-- notice, this list of conditions and the following disclaimer. -- |
| 10 | +-- 2. Redistributions in binary form must reproduce the above copyright -- |
| 11 | +-- notice, this list of conditions and the following disclaimer in -- |
| 12 | +-- the documentation and/or other materials provided with the -- |
| 13 | +-- distribution. -- |
| 14 | +-- 3. Neither the name of the copyright holder nor the names of its -- |
| 15 | +-- contributors may be used to endorse or promote products derived -- |
| 16 | +-- from this software without specific prior written permission. -- |
| 17 | +-- -- |
| 18 | +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -- |
| 19 | +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -- |
| 20 | +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -- |
| 21 | +-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -- |
| 22 | +-- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -- |
| 23 | +-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -- |
| 24 | +-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -- |
| 25 | +-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -- |
| 26 | +-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -- |
| 27 | +-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -- |
| 28 | +-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- |
| 29 | +-- -- |
| 30 | +------------------------------------------------------------------------------ |
| 31 | + |
| 32 | +with STM32.Board; |
| 33 | +with STM32.Device; |
| 34 | +with STM32.PWM; |
| 35 | +with STM32.Timers; |
| 36 | +with STM32.DMA; |
| 37 | +with HAL; |
| 38 | + |
| 39 | +procedure Demo_PWM_DMA_Continuous is |
| 40 | + type Data is array (0 .. 200) of HAL.UInt32; |
| 41 | + for Data'Component_Size use 32; |
| 42 | + Bytes_To_Transfer : constant := Data'Length; |
| 43 | + Source_Block : Data; |
| 44 | + |
| 45 | + Controller : STM32.DMA.DMA_Controller renames STM32.Device.DMA_1; |
| 46 | + Configuration : STM32.DMA.DMA_Stream_Configuration; |
| 47 | + |
| 48 | + Tx_Channel : constant STM32.DMA.DMA_Channel_Selector := STM32.DMA.Channel_6; |
| 49 | + Tx_Stream : constant STM32.DMA.DMA_Stream_Selector := STM32.DMA.Stream_0; |
| 50 | + |
| 51 | + -- See RM0090, section 10.3.3, for the DMA channel request mapping tables |
| 52 | + -- that say which controllers, and which channels and streams on those |
| 53 | + -- controllers, can connect to which devices. For example, it is channel |
| 54 | + -- six and stream null that connect DMA1 to the timer of TIM5_UP, so |
| 55 | + -- we specify those values above. |
| 56 | + |
| 57 | + Selected_Timer : STM32.Timers.Timer renames STM32.Device.Timer_5; |
| 58 | + Timer_AF : constant STM32.GPIO_Alternate_Function := |
| 59 | + STM32.Device.GPIO_AF_TIM5_2; |
| 60 | + |
| 61 | + Output_Channel : constant STM32.Timers.Timer_Channel := |
| 62 | + STM32.Timers.Channel_2; |
| 63 | + |
| 64 | + Requested_Frequency : constant STM32.PWM.Hertz := 100; |
| 65 | + |
| 66 | + LED_Control : STM32.PWM.PWM_Modulator; |
| 67 | + |
| 68 | +begin |
| 69 | + |
| 70 | + STM32.PWM.Configure_PWM_Timer (Selected_Timer'Access, Requested_Frequency); |
| 71 | + |
| 72 | + LED_Control.Attach_PWM_Channel |
| 73 | + (Selected_Timer'Access, |
| 74 | + Output_Channel, |
| 75 | + STM32.Board.Green_LED, |
| 76 | + Timer_AF); |
| 77 | + LED_Control.Enable_Output; |
| 78 | + |
| 79 | + -- Initialize of values |
| 80 | + for Ind in 0 .. 100 loop |
| 81 | + Source_Block (Ind) := LED_Control.Calculate_Compare_Value (Ind); |
| 82 | + Source_Block (Data'Last - Ind) := Source_Block (Ind); |
| 83 | + end loop; |
| 84 | + |
| 85 | + STM32.Timers.Set_Output_Preload_Enable |
| 86 | + (Selected_Timer, Output_Channel, True); |
| 87 | + |
| 88 | + STM32.Timers.Configure_DMA (Selected_Timer, |
| 89 | + STM32.Timers.DMA_Base_CCR2, |
| 90 | + STM32.Timers.DMA_Burst_Length_1); |
| 91 | + |
| 92 | + STM32.Timers.Enable_DMA_Source |
| 93 | + (Selected_Timer, STM32.Timers.Timer_DMA_Update); |
| 94 | + |
| 95 | + STM32.Device.Enable_Clock (Controller); |
| 96 | + |
| 97 | + STM32.DMA.Reset (Controller, Tx_Stream); |
| 98 | + |
| 99 | + Configuration.Channel := Tx_Channel; |
| 100 | + Configuration.Direction := STM32.DMA.Memory_To_Peripheral; |
| 101 | + Configuration.Increment_Peripheral_Address := False; |
| 102 | + Configuration.Increment_Memory_Address := True; |
| 103 | + Configuration.Peripheral_Data_Format := STM32.DMA.Words; |
| 104 | + Configuration.Memory_Data_Format := STM32.DMA.Words; |
| 105 | + Configuration.Operation_Mode := STM32.DMA.Circular_Mode; |
| 106 | + Configuration.Priority := STM32.DMA.Priority_Very_High; |
| 107 | + Configuration.FIFO_Enabled := False; |
| 108 | + |
| 109 | + STM32.DMA.Configure (Controller, Tx_Stream, Configuration); |
| 110 | + |
| 111 | + STM32.DMA.Start_Transfer |
| 112 | + (Controller, |
| 113 | + Tx_Stream, |
| 114 | + Source => Source_Block'Address, |
| 115 | + Destination => STM32.PWM.Data_Register_Address (LED_Control), |
| 116 | + Data_Count => Bytes_To_Transfer); |
| 117 | + |
| 118 | + STM32.Timers.Enable_Capture_Compare_DMA (Selected_Timer); |
| 119 | + |
| 120 | + loop |
| 121 | + null; |
| 122 | + end loop; |
| 123 | +end Demo_PWM_DMA_Continuous; |
| 124 | + |
| 125 | + |
| 126 | + |
0 commit comments