1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
{-# LANGUAGE OverloadedRecordDot #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
import Control.Monad (forM_, forever)
import Data.Function ((&))
import Data.Text (Text)
import Effectful (Eff, (:>), runEff)
import Effectful.Concurrent (Concurrent, runConcurrent, threadDelay)
import Effectful.Log (Log, runLog)
import Effectful.Reader.Static (Reader, ask, runReader)
import Hsm.Core.App (launch)
import Hsm.Core.Env (deriveFromYaml)
import Hsm.PWM (PWMEffect, dutyCycle, runPWM, withPWM)
import System.IO.Echo (withoutInputEcho)
data Env = Env
{ name :: Text
, pwmPeriod :: Word
, stepDelay :: Word
}
$(deriveFromYaml ''Env)
pwmLoop ::
(Concurrent :> es, Log :> es, PWMEffect :> es, Reader Env :> es)
=> Eff es ()
pwmLoop = do
env <- ask @Env
withPWM
$ forever
$ forM_ [0,env.pwmPeriod `div` 10 .. env.pwmPeriod]
$ \dc -> do
threadDelay $ fromIntegral env.stepDelay
dutyCycle dc
-- Dummy gradient service:
-- Simple test for PWM control. Increases duty-cycle gradually on default PWM
-- channel.
main :: IO ()
main =
launch @Env "dummy-gradient" withoutInputEcho $ \env logger level ->
pwmLoop
& runPWM @Env
& runConcurrent
& runLog env.name logger level
& runReader env
& runEff
|