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