---------------------------------------------------------------------------- -- | -- Module : STM32.GPIO -- Copyright : (c) Marc Fontaine 2017 -- License : BSD3 -- -- Maintainer : Marc.Fontaine@gmx.de -- Stability : experimental -- Portability : GHC-only -- -- Untested work in progress {-# LANGUAGE OverloadedStrings #-} module STM32.I2C where import Device import STM32.MachineInterface import STM32.Utils import qualified STM32.RCC as RCC import Control.Monad import Data.Word import Data.Bits data Config = Config { _mode :: Mode , _dutyCycle :: DutyCycle , _ownAddress1 :: Word16 , _ack :: Bool , _acknowledgedAddress :: AcknowledgedAddress , _clocks :: Clocks } deriving Show defaultConfig :: Config defaultConfig = Config { _mode = I2C , _dutyCycle = DutyCycle_2 , _ownAddress1 = 0 , _ack = False , _acknowledgedAddress = SevenBit , _clocks = defaultClocks } data Mode = I2C | SMBusDevice | SMBusHost deriving Show data DutyCycle = DutyCycle_16_9 | DutyCycle_2 deriving Show data Direction = Transmitter | Receiver deriving Show data AcknowledgedAddress = SevenBit | TenBit deriving Show data Clocks = Clocks { _freq :: Word32 ,_ccr :: Word32 ,_trise :: Word32 } deriving Show defaultClocks :: Clocks defaultClocks = Clocks {_freq = 36,_ccr=0,_trise=0} deInit :: Peripheral -> MI () deInit = RCC.peripheralResetToggle init :: Peripheral -> Config -> MI () init p conf = do cr2 <- peekReg p CR2 pokeReg p CR2 $ ((cr2 .&. 0xffffffe00) .|. (fromIntegral $ _freq $ _clocks conf)) disable p pokeReg p TRISE $ _trise $ _clocks conf pokeReg p CCR $ _ccr $ _clocks conf enable p let write field rs = bitWrite p field rs write CR1_SMBUS $ case _mode conf of I2C -> False SMBusDevice -> True SMBusHost -> True write CR1_SMBTYPE $ case _mode conf of I2C -> False SMBusDevice -> False SMBusHost -> True write CR1_ACK $ _ack conf oar1 <- peekReg p OAR1 pokeReg p OAR1 ( (oar1 .&. 0x000003ff) .|. 0x00004000 .|. (fromIntegral $ _ownAddress1 conf) .|. (case _acknowledgedAddress conf of SevenBit -> 0 TenBit -> 0x00008000 ) ) enable :: Peripheral -> MI () enable p = bitSet p CR1_PE disable :: Peripheral -> MI () disable p = bitReset p CR1_PE