---------------------------------------------------------------------------- -- | -- Module : App.TimerDMA -- Copyright : (c) Marc Fontaine 2017 -- License : BSD3 -- -- Maintainer : Marc.Fontaine@gmx.de -- Stability : experimental -- Portability : GHC-only -- -- This example show the combination of hardware timers with hardware DMA. -- Timer 4 triggers DMA1_Channel7 and the DMA writes data to the USART. -- Instead of the USART its also possible to write to any other periveral. -- Applications are wave form generation or any hard-real-time control. module App.TimerDMA where import Control.Monad import STM32.API import qualified STM32.USART as USART import STM32.DMA as DMA import STM32.Timer as Timer import Data.ByteString.Char8 as BS (pack) sendCommTimer :: IO () sendCommTimer = runMI $ sendCommTimer_Port USART.stm32F103_UartPort1 USART.defaultConfig -- only works for USART.stm32F103_UartPort1 at the moment sendCommTimer_Port :: USART.UartPort -> USART.Config -> MI () sendCommTimer_Port port config = do initMI resetHalt USART.configure port config let dmaBuffer = 0x20001000 dmaConfig = DMA.Config { _BufferSize = 16 ,_Direction = PeripheralDST ,_MemoryBaseAddr = dmaBuffer ,_MemoryDataSize = Byte ,_MemoryInc = True ,DMA._Mode = Circular ,_PeripheralBaseAddr = regToAddr USART1 DR ,_PeripheralDataSize = Byte ,_PeripheralInc = False ,_Priority = Low } peripheralClockOn DMA1 peripheralClockOn TIM4 DMA.deInit DMA1_Channel7 writeMem8 dmaBuffer $ BS.pack "abcdefghABCD123\n" DMA.disable DMA1_Channel7 DMA.init DMA1_Channel7 dmaConfig DMA.enable DMA1_Channel7 let timeBase = TimeBase { _Prescaler = 7200 -- 72 Mhz clock _Period counts in 0.1 ms ,_CounterMode = Down ,_Period = 10000 -- 1s ,_ClockDevision = CKD_DIV1 ,_RepetitionCounter =0 } Timer.deInit TIM4 Timer.timeBaseInit TIM4 timeBase bitReset TIM4 CR1_URS bitSet TIM4 DIER_UDE bitSet TIM4 CR1_CEN