-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathScanRSSI.hs
180 lines (161 loc) · 4.43 KB
/
ScanRSSI.hs
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
----------------------------------------------------------------------------
-- |
-- Module : ScanRSSI
-- Copyright : (c) Marc Fontaine 2016-2018
-- License : BSD3
--
-- Maintainer : [email protected]
-- Stability : experimental
-- Portability : GHC-only
--
-- Do some stuff and paint a TGA image
module ScanRSSI
where
import TRX
import IA4420
import IA4420_Register
import STM32.API as API
import STM32.GPIO as GPIO
import STM32.DMA as DMA
import STM32.SPI as SPI
import Data.Word
import Data.Bits
import Control.Monad
import Control.Monad.IO.Class
import System.IO
import qualified Data.ByteString as BS
approxRSSI :: TRX ()
approxRSSI = do
set DisableTransmisson
set FrequencyBand433
set AFCAutoOff
set AFCDeviation_3
set DisableFrequencyOffsetRegister
set DisableAFCOffsetCalculation
-- set $ frequencyMHz 438.817450
-- set LNA_0dB
set EnableReceiverChain
go RSSI_103dBm
where
go sens = do
liftIO $ putStr "\r"
liftIO $ putStr $ show sens
when ( sens == RSSI_85dBm || sens == RSSI_79dBm || sens == RSSI_73dBm) $ do
liftIO $ putStrLn $ show sens
liftIO $ putStrLn $ show sens
set sens
liftSTL $ delay 300000
status <- readStatus
if isRSSI status
then go $ sensitivityDown sens
else go $ sensitivityUp sens
-- [3975..4021]
-- [772 ..856]
defaultScanLevel :: [ConfigConst]
defaultScanLevel = [RSSI_79dBm,RSSI_85dBm,RSSI_91dBm,RSSI_97dBm,RSSI_103dBm]
scanRSSI :: [ConfigConst] -> IO ()
scanRSSI scanLevel = withBinaryFile "/mnt/tmp/t/t.tga" WriteMode $ \handle -> do
runReset $ do
liftIO $ BS.hPut handle tgaHeader
set DisableTransmisson
set FrequencyBand433
-- set $ frequencyMHz 438.817450
set RBW_67
set RSSI_85dBm
set LNA_0dB
set AFCAutoOff
set AFCDeviation_3
set DisableFrequencyOffsetRegister
set DisableAFCOffsetCalculation
set EnableReceiverChain
forM_ [0..100] $ \iter -> do
liftIO $ print (iter :: Int)
line <- forM [0..1023] $ \f -> do
set $ FrequencyValue f
approxLevel scanLevel
liftIO $ do
BS.hPut handle $ BS.concat $ map toColor line
hFlush handle
toColor :: Int -> BS.ByteString
toColor i = case i of
0 -> BS.pack [0,0,0]
1 -> BS.pack [0,20,0]
2 -> BS.pack [0,100,0]
3 -> BS.pack [0,200,0]
4 -> BS.pack [0,100,100]
5 -> BS.pack [0,0,200]
_ -> BS.pack [255,255,255]
approxLevel :: [ConfigConst] -> TRX Int
approxLevel scanLevel = worker 0 scanLevel
where
worker i [] = return i
worker i (l:rest) = do
set l
status <- readStatus
if isRSSI status
then return i
else worker (succ i) rest
isRSSI :: Word16 -> Bool
isRSSI w = testBit w 8
sensitivityUp :: ConfigConst -> ConfigConst
sensitivityUp r = case r of
RSSI_103dBm -> RSSI_103dBm
RSSI_97dBm -> RSSI_103dBm
RSSI_91dBm -> RSSI_97dBm
RSSI_85dBm -> RSSI_91dBm
RSSI_79dBm -> RSSI_85dBm
RSSI_73dBm -> RSSI_79dBm
x -> x
sensitivityDown :: ConfigConst -> ConfigConst
sensitivityDown r = case r of
RSSI_103dBm -> RSSI_97dBm
RSSI_97dBm -> RSSI_91dBm
RSSI_91dBm -> RSSI_85dBm
RSSI_85dBm -> RSSI_79dBm
RSSI_79dBm -> RSSI_73dBm
RSSI_73dBm -> RSSI_73dBm
x -> x
tgaHeader :: BS.ByteString
tgaHeader = BS.pack [
0,0,2
,0,0,0,0,0
,0,0,0,0 -- x0 y0
,0,4 --width
,0,4 -- hight
,24 --Bits-per-pixel
,16
]
sendCommandsDMA :: [Word16] -> MI ()
sendCommandsDMA cmds = do
let
dmaBuffer = 0x20001000
dmaConfig = DMA.Config {
_BufferSize = fromIntegral $ length cmds
,_Direction = PeripheralDST
,_MemoryBaseAddr = dmaBuffer
,_MemoryDataSize = HalfWord
,_MemoryInc = True
,DMA._Mode = Circular
,_PeripheralBaseAddr = regToAddr SPI2 DR
,_PeripheralDataSize = HalfWord
,_PeripheralInc = False
,_Priority = DMA.Low
}
peripheralClockOn DMA1
DMA.deInit DMA1_Channel5
writeMem8 dmaBuffer $ packCmds cmds
bitSet SPI2 CR2_TXDMAEN
DMA.disable DMA1_Channel5
DMA.init DMA1_Channel5 dmaConfig
pinLow spi_nss
DMA.enable DMA1_Channel5
packCmds :: [Word16] -> BS.ByteString
packCmds = BS.pack . concatMap lowHigh
where
lowHigh x = [fromIntegral (x .&. 0xff),fromIntegral $ x `shiftR` 8]
sweepCircular :: [Word16]
sweepCircular = map (\x -> 0xa000 .|. x) $ concat [
l
,reverse l
]
where l = [1000..2000]