---------------------------------------------------------------------------- -- | -- Module : STM32.APP -- Copyright : (c) Marc Fontaine 2017 -- License : BSD3 -- -- Maintainer : Marc.Fontaine@gmx.de -- Stability : experimental -- Portability : GHC-only -- -- Analog Digital Converter {-# LANGUAGE OverloadedStrings #-} module STM32.ADC where import Device import STM32.MachineInterface import STM32.Utils import Data.Word import qualified STM32.RCC as RCC import Data.Bits deInit :: Peripheral -> MI () deInit = RCC.peripheralResetToggle data Config = Config { _Mode :: Mode ,_ScanConvMode :: Bool ,_ContinuousConvMode :: Bool ,_ExternalTrigConv :: ExternalTrigConv ,_DataAlign :: DataAlign ,_NbrOfChannel :: Word32 } deriving Show data Mode = Independent | RegInjecSimult | RegSimult_AlterTrig | InjecSimult_FastInterl | InjecSimult_SlowInterl | InjecSimult | RegSimult | FastInterl | SlowInterl | AlterTrig deriving (Show) instance RegisterField Mode where toBits m = case m of Independent -> "0000" RegInjecSimult -> "0001" RegSimult_AlterTrig -> "0010" InjecSimult_FastInterl -> "0011" InjecSimult_SlowInterl -> "0100" InjecSimult -> "0101" RegSimult -> "0110" FastInterl -> "0111" SlowInterl -> "1000" AlterTrig -> "1001" toField = const CR1_DUALMOD data ExternalTrigConv = ExternalTrigConv_T1_CC1 | ExternalTrigConv_T1_CC2 | ExternalTrigConv_T1_CC3 | ExternalTrigConv_T2_CC2 | ExternalTrigConv_T3_TRGO | ExternalTrigConv_T4_CC4 | ExternalTrigConv_Ext_IT11_TIM8_TRGO | ExternalTrigConv_None | ExternalTrigConv_T3_CC1 | ExternalTrigConv_T2_CC3 | ExternalTrigConv_T8_CC1 | ExternalTrigConv_T8_TRGO | ExternalTrigConv_T5_CC1 | ExternalTrigConv_T5_CC3 deriving Show instance RegisterField ExternalTrigConv where toBits x = case x of ExternalTrigConv_T1_CC1 -> "000" ExternalTrigConv_T1_CC2 -> "001" ExternalTrigConv_T1_CC3 -> "010" ExternalTrigConv_T2_CC2 -> "011" ExternalTrigConv_T3_TRGO -> "100" ExternalTrigConv_T4_CC4 -> "101" ExternalTrigConv_Ext_IT11_TIM8_TRGO -> "110" ExternalTrigConv_None -> "111" ExternalTrigConv_T3_CC1 -> "000" ExternalTrigConv_T2_CC3 -> "001" ExternalTrigConv_T8_CC1 -> "011" ExternalTrigConv_T8_TRGO -> "100" ExternalTrigConv_T5_CC1 -> "101" ExternalTrigConv_T5_CC3 -> "110" toField = const CR2_EXTSEL data DataAlign = AlignRight | AlignLeft deriving Show instance ToBit DataAlign where toBit AlignRight = False toBit AlignLeft = True data Channel = Channel_0 | Channel_1 | Channel_2 | Channel_3 | Channel_4 | Channel_5 | Channel_6 | Channel_7 | Channel_8 | Channel_9 | Channel_10 | Channel_11 | Channel_12 | Channel_13 | Channel_14 | Channel_15 | Channel_16 | Channel_17 deriving Show data SampleTime = SampleTime_1Cycles5 | SampleTime_7Cycles5 | SampleTime_13Cycles5 | SampleTime_28Cycles5 | SampleTime_41Cycles5 | SampleTime_55Cycles5 | SampleTime_71Cycles5 | SampleTime_239Cycles5 deriving Show instance ToBitField SampleTime where toBitField s = case s of SampleTime_1Cycles5 -> "000" SampleTime_7Cycles5 -> "001" SampleTime_13Cycles5 -> "010" SampleTime_28Cycles5 -> "011" SampleTime_41Cycles5 -> "100" SampleTime_55Cycles5 -> "101" SampleTime_71Cycles5 -> "110" SampleTime_239Cycles5 -> "111" data ExternalTrigInjecConv = ExternalTrigInjecConv_T1_TRGO | ExternalTrigInjecConv_T1_CC4 | ExternalTrigInjecConv_T2_TRGO | ExternalTrigInjecConv_T2_CC1 | ExternalTrigInjecConv_T3_CC4 | ExternalTrigInjecConv_T4_TRGO | ExternalTrigInjecConv_Ext_IT15_TIM8_CC4 | ExternalTrigInjecConv_None | ExternalTrigInjecConv_T4_CC3 | ExternalTrigInjecConv_T8_CC2 | ExternalTrigInjecConv_T8_CC4 | ExternalTrigInjecConv_T5_TRGO | ExternalTrigInjecConv_T5_CC4 deriving Show instance ToBitField ExternalTrigInjecConv where toBitField e = case e of ExternalTrigInjecConv_T1_TRGO -> "000" ExternalTrigInjecConv_T1_CC4 -> "001" ExternalTrigInjecConv_T2_TRGO -> "010" ExternalTrigInjecConv_T2_CC1 -> "011" ExternalTrigInjecConv_T3_CC4 -> "100" ExternalTrigInjecConv_T4_TRGO -> "101" ExternalTrigInjecConv_Ext_IT15_TIM8_CC4 -> "110" ExternalTrigInjecConv_None -> "111" ExternalTrigInjecConv_T4_CC3 -> "010" ExternalTrigInjecConv_T8_CC2 -> "011" ExternalTrigInjecConv_T8_CC4 -> "100" ExternalTrigInjecConv_T5_TRGO -> "101" ExternalTrigInjecConv_T5_CC4 -> "110" data InjectedChannel = InjectedChannel_1 | InjectedChannel_2 | InjectedChannel_3 | InjectedChannel_4 deriving Show data AnalogWatchdog = AnalogWatchdog_SingleRegEnable | AnalogWatchdog_SingleInjecEnable | AnalogWatchdog_SingleRegOrInjecEnable | AnalogWatchdog_AllRegEnable | AnalogWatchdog_AllInjecEnable | AnalogWatchdog_AllRegAllInjecEnable | AnalogWatchdog_None deriving Show init :: Peripheral -> Config -> MI () init p conf = do fieldWrite p $ _Mode conf bitWrite p CR1_SCAN $ _ScanConvMode conf bitWrite p CR2_ALIGN $ _DataAlign conf fieldWrite p $ _ExternalTrigConv conf bitWrite p CR2_CONT $ _ContinuousConvMode conf pokeReg p SQR1 ((_NbrOfChannel conf -1) `shiftL` 20) channelToSMP :: Channel -> Field channelToSMP ch = case ch of Channel_0 -> SMPR2_SMP0 Channel_1 -> SMPR2_SMP1 Channel_2 -> SMPR2_SMP2 Channel_3 -> SMPR2_SMP3 Channel_4 -> SMPR2_SMP4 Channel_5 -> SMPR2_SMP5 Channel_6 -> SMPR2_SMP6 Channel_7 -> SMPR2_SMP7 Channel_8 -> SMPR2_SMP8 Channel_9 -> SMPR2_SMP9 Channel_10 -> SMPR1_SMP10 Channel_11 -> SMPR1_SMP11 Channel_12 -> SMPR1_SMP12 Channel_13 -> SMPR1_SMP13 Channel_14 -> SMPR1_SMP14 Channel_15 -> SMPR1_SMP15 Channel_16 -> SMPR1_SMP16 Channel_17 -> SMPR1_SMP17 channelToSQBits :: Channel -> BitField channelToSQBits ch = case ch of Channel_0 -> "00000" Channel_1 -> "00001" Channel_2 -> "00010" Channel_3 -> "00011" Channel_4 -> "00100" Channel_5 -> "00101" Channel_6 -> "00110" Channel_7 -> "00111" Channel_8 -> "01000" Channel_9 -> "01001" Channel_10 -> "01010" Channel_11 -> "01011" Channel_12 -> "01100" Channel_13 -> "01101" Channel_14 -> "01110" Channel_15 -> "01111" Channel_16 -> "10000" Channel_17 -> "10001" rankToSQ :: Word8 -> Field rankToSQ r = case r of 1 -> SQR3_SQ1 2 -> SQR3_SQ2 3 -> SQR3_SQ3 4 -> SQR3_SQ4 5 -> SQR3_SQ5 6 -> SQR3_SQ6 7 -> SQR2_SQ7 8 -> SQR2_SQ8 9 -> SQR2_SQ9 10 -> SQR2_SQ10 11 -> SQR2_SQ11 12 -> SQR2_SQ12 13 -> SQR1_SQ13 14 -> SQR1_SQ14 15 -> SQR1_SQ15 16 -> SQR1_SQ16 _ -> error "ADC.hs rankToSQ" regularChannelConfig :: Peripheral -> Channel -> Word8 -> SampleTime -> MI () regularChannelConfig p channel rank sampleTime = do regFieldWrite p (channelToSMP channel) sampleTime regFieldWrite p (rankToSQ rank) (channelToSQBits channel) dmaCmd :: Peripheral -> Bool -> MI () dmaCmd p rs = case p of ADC1 -> bitWrite ADC1 CR2_DMA rs ADC2 -> error "dmaCMD: ADC2 no DMA available" ADC3 -> bitWrite ADC3 CR2_DMA rs _ -> error "dmaCMD" cmd :: Peripheral -> Bool -> MI () cmd p rs = bitWrite p CR2_ADON rs softwareStartConvCmd :: Peripheral -> Bool -> MI () softwareStartConvCmd p rs = do bitWrite p CR2_EXTTRIG rs bitWrite p CR2_SWSTART rs