1*** Variables ***
2${ACCEL}                 sysbus.i2c1.accel
3${UART}                  sysbus.usart2
4${ACCEL_POLLING_SAMPLE}  @https://dl.antmicro.com/projects/renode/b_l072z_lrwan1--zephyr-accel_polling.elf-s_731368-a41b79116936bdadbee51e497847273f971ed409
5${ACCEL_POLLING_SAMPLE_14BIT}  @https://dl.antmicro.com/projects/renode/b_l072z_lrwan1--zephyr-accel_polling-high_performance.elf-s_731368-049f6743622eb0b8068dbc2a24742561c8fa046a
6${CSV2RESD}              ${RENODETOOLS}/csv2resd/csv2resd.py
7
8*** Keywords ***
9Execute Python Script
10    [Arguments]  ${path}  ${args}
11
12    Evaluate  subprocess.run([sys.executable, "${path}", ${args}])  sys,subprocess
13
14Create Machine
15    Execute Command         using sysbus
16    Execute Command         mach create
17    Execute Command         machine LoadPlatformDescription @platforms/cpus/stm32l072.repl
18    Execute Command         machine LoadPlatformDescriptionFromString 'accel: Sensors.LIS2DW12 @ i2c1 0x2d'
19    Create Terminal Tester  ${UART}
20    Create Log Tester       0
21    Execute Command         logLevel -1 ${ACCEL}
22
23Format Fixed Point Integer As Decimal
24    [Arguments]  ${value}  ${places}
25
26    ${minus}=  Set Variable  ${EMPTY}
27    IF  ${value} < 0
28        ${minus}=  Set Variable  -
29        ${value}=  Evaluate  abs(${value})
30    END
31
32    ${divisor}=  Evaluate  10**${places}
33    ${units}=  Evaluate  ${value} / ${divisor}
34    ${fraction}=  Evaluate  ${value} % ${divisor}
35    ${string}=  Evaluate  "${minus}%d.%0${places}d" % (${units}, ${fraction})
36
37    RETURN  ${string}
38
39Wait For Peripheral Reading
40    [Arguments]  ${microg}  ${resolution}
41
42    IF  ${resolution} == 12
43        ${sensitivity}=  Set Variable  976
44        ${shift}=  Set Variable  4
45    ELSE IF  ${resolution} == 14
46        ${sensitivity}=  Set Variable  244
47        ${shift}=  Set Variable  2
48    ELSE
49        Fail               Invalid resolution ${resolution} bits
50    END
51
52    ${steps}=  Evaluate  int(${microg} / ${sensitivity})
53    ${outValue}=  Evaluate  ${steps} * ${sensitivity}
54    ${outStr}=  Format Fixed Point Integer As Decimal  ${outValue}  6
55
56    ${lsbs}=  Evaluate  abs(${steps}) << ${shift}
57    # Use twos-complement representation if negative
58    IF  ${steps} < 0
59        ${lsbs}=  Evaluate  (abs(${lsbs}) ^ 0xffff) + 1
60    END
61    ${lsbsStr}=  Convert To Hex  ${lsbs}  prefix=0x  length=4
62
63    Wait For Line On Uart  lis2dw12@2d *\\[g]: *\\( *${outStr}, *${outStr}, *${outStr}\\)  treatAsRegex=true  pauseEmulation=true
64    Wait For Log Entry     Conversion done with sensitivity: 0.${sensitivity}, result: ${lsbsStr}
65
66Wait For Peripheral Reading For Set Value And Known LSBs
67    [Arguments]  ${microg}  ${resolution}  ${lsbs}
68
69    ${g}=  Format Fixed Point Integer As Decimal  ${microg}  6
70    # For LIS2DW12 operating in FIFO mode, setting `DefaultAcceleration` would be enough
71    # as it would start returning default samples after RESD stream is finished.
72    # For Bypass mode it needs to be set explicitly (through `Acceleration` properties),
73    # because the actual sample is kept until it is overwritten by a new sample.
74    Execute Command        ${ACCEL} DefaultAccelerationX ${g}
75    Execute Command        ${ACCEL} DefaultAccelerationY ${g}
76    Execute Command        ${ACCEL} DefaultAccelerationZ ${g}
77    Execute Command        ${ACCEL} AccelerationX ${g}
78    Execute Command        ${ACCEL} AccelerationY ${g}
79    Execute Command        ${ACCEL} AccelerationZ ${g}
80    # Wait for the expected LSBs value keeping the entry for use by the following keyword
81    Wait For Log Entry     result: ${lsbs}  timeout=2  pauseEmulation=true  keep=true
82    Wait For Peripheral Reading  ${microg}  ${resolution}
83
84Create RESD File
85    [Arguments]  ${resdArgs}
86    ${resdPath}=  Evaluate  tempfile.mktemp()  tempfile
87    ${resdArgs}=  Catenate  SEPARATOR=,  ${resdArgs}  r"${resdPath}"
88
89    Execute Python Script  ${CSV2RESD}  ${resdArgs}
90
91    RETURN  ${resdPath}
92
93Test Teardown And Cleanup RESD File
94    [Arguments]  ${resdPath}
95
96    Test Teardown
97    Remove File  ${resdPath}
98
99LIS2DW12 Should Return Data From RESD
100    [Arguments]  ${firmware}  ${resolution}
101    ${resdArgs}=  Catenate  SEPARATOR=,
102                  ...       "--input", r"${CURDIR}/LIS2DW12-samples.csv"
103                  ...       "--frequency", "1"
104                  ...       "--start-time", "0"
105                  ...       "--map", "acceleration:x,y,z:x,y,z"
106
107    ${resdPath}=  Create RESD File  ${resdArgs}
108
109    Create Machine
110
111    Execute Command        sysbus LoadELF ${firmware}
112    Wait For Line On Uart  Booting Zephyr OS  pauseEmulation=true
113
114    Execute Command        ${ACCEL} FeedAccelerationSamplesFromRESD @${resdPath}
115
116    Wait For Peripheral Reading  100000  ${resolution}
117    Wait For Peripheral Reading  200000  ${resolution}
118    Wait For Peripheral Reading  300000  ${resolution}
119    Wait For Peripheral Reading  400000  ${resolution}
120    Wait For Peripheral Reading  500000  ${resolution}
121    Wait For Peripheral Reading  600000  ${resolution}
122    Wait For Peripheral Reading  700000  ${resolution}
123    Wait For Peripheral Reading  -100000  ${resolution}
124    Wait For Peripheral Reading  -200000  ${resolution}
125
126    # Run for an additional second to allow RESD stream to finish before setting an actual sample to an arbitrary value.
127    # Otherwise set sample will be overridden by the one fed from RESD.
128    Execute Command        emulation RunFor "1"
129
130    RETURN  ${resdPath}
131
132Prepare Multi-Frequency Data Test
133    # 3 blocks starting one after the other: low-frequency, high-frequency, low-frequency
134    ${resdArgs}=  Catenate  SEPARATOR=,
135                  ...       "--input", r"${CURDIR}/LIS2DW12-samples_lowfreq1.csv"
136                  ...       "--frequency", "100"
137                  ...       "--start-time", "0"
138                  ...       "--map", "acceleration:x,y,z:x,y,z"
139                  ...       "--input", r"${CURDIR}/LIS2DW12-samples_highfreq.csv"
140                  ...       "--frequency", "1600"
141                  ...       "--start-time", "320000000"
142                  ...       "--map", "acceleration:x,y,z:x,y,z"
143                  ...       "--input", r"${CURDIR}/LIS2DW12-samples_lowfreq2.csv"
144                  ...       "--frequency", "100"
145                  ...       "--start-time", "340000000"
146                  ...       "--map", "acceleration:x,y,z:x,y,z"
147
148    ${resdPath}=  Create RESD File  ${resdArgs}
149
150    Execute Command        allowPrivates true
151    Execute Command        using sysbus
152    Execute Command        mach create
153    Execute Command        machine LoadPlatformDescriptionFromString "i2c1: I2C.STM32F7_I2C @ sysbus 0x10000000"
154    Execute Command        machine LoadPlatformDescriptionFromString "accel: Sensors.LIS2DW12 @ i2c1 0"
155    Execute Command        logLevel -1 ${ACCEL}
156
157    # The accelerometer starts at 100 Hz, which we'll call the "low frequency"
158    Execute Command        ${ACCEL} SampleRate 100
159    Execute Command        ${ACCEL} FeedAccelerationSamplesFromRESD @${resdPath} type=MultiFrequency
160
161    RETURN  ${resdPath}
162
163Acceleration Should Be
164    [Arguments]  ${major}  ${minor}
165
166    ${actual}=  Execute Command  ${ACCEL} AccelerationX
167    ${minor}=  Evaluate  "{:03}".format(${minor})
168    # Why 2 separate rstrips? To turn 0.010 into 0.01, but 0.000 into 0 and not ""
169    ${expected}=  Evaluate  "${major}.${minor}".rstrip("0").rstrip(".")
170    Should Be Equal  ${actual.strip()}  ${expected}
171
172*** Test Cases ***
173LIS2DW12 Should Return Data From RESD In 12-Bit Mode
174    ${resdPath}=  LIS2DW12 Should Return Data From RESD  ${ACCEL_POLLING_SAMPLE}  12
175
176    # Test Teardown must be called from a test teardown as it uses Run Keyword If Test Failed, so
177    # we have to repeat this here instead of in LIS2DW12 Should Return Data From RESD
178    [Teardown]             Test Teardown And Cleanup RESD File  ${resdPath}
179
180LIS2DW12 Should Return Data From RESD In 14-Bit Mode
181    ${resdPath}=  LIS2DW12 Should Return Data From RESD  ${ACCEL_POLLING_SAMPLE_14BIT}  14
182
183    # Additionally verify the examples from ST AN5038. In the app note the calculated
184    # mg values are rounded to integers, these are exact values.
185    Wait For Peripheral Reading For Set Value And Known LSBs  -40992  14  0xFD60
186    Wait For Peripheral Reading For Set Value And Known LSBs  7320  14  0x0078
187    Wait For Peripheral Reading For Set Value And Known LSBs  1046028  14  0x42FC
188
189    [Teardown]             Test Teardown And Cleanup RESD File  ${resdPath}
190
191LIS2DW12 Should Return Multi-Frequency Data - Switch Late
192    ${resdPath}=  Prepare Multi-Frequency Data Test
193
194    # the full low-frequency block #1
195    FOR  ${i}  IN RANGE  32
196        Acceleration Should Be  0  ${i}  # the first low-frequency block has values 0, 0.001, ...
197        Execute Command        emulation RunFor "0.01"  # play one low-frequency point
198    END
199    # 3 more HF sample periods, staying at the low frequency
200    FOR  ${i}  IN RANGE  3
201        Acceleration Should Be  0  31  # the last low-frequency sample repeating
202        Execute Command        emulation RunFor "0.000625"  # play one high-frequency point
203    END
204    Execute Command        ${ACCEL} SampleRate 1600
205    FOR  ${i}  IN RANGE  32
206        Acceleration Should Be  1  ${i}  # the high-frequency block has values 1, 1.001, ...
207        Execute Command        emulation RunFor "0.000625"  # play one high-frequency point
208    END
209    # 3 more HF sample periods, staying at the high frequency
210    FOR  ${i}  IN RANGE  3
211        Acceleration Should Be  1  31  # the last high-frequency sample repeating
212        Execute Command        emulation RunFor "0.000625"  # play one high-frequency point
213    END
214    Execute Command        ${ACCEL} SampleRate 100
215    FOR  ${i}  IN RANGE  32
216        Acceleration Should Be  2  ${i}  # the second low-frequency block has values 2, 2.001, ...
217        Execute Command        emulation RunFor "0.01"  # play one low-frequency point
218    END
219
220    [Teardown]             Test Teardown And Cleanup RESD File  ${resdPath}
221
222LIS2DW12 Should Return Multi-Frequency Data - Switch Early
223    ${resdPath}=  Prepare Multi-Frequency Data Test
224
225    # the first 16 samples of low-frequency block #1
226    FOR  ${i}  IN RANGE  16
227        Acceleration Should Be  0  ${i}  # the first low-frequency block has values 0, 0.001, ...
228        Execute Command        emulation RunFor "0.01"  # play one low-frequency point
229    END
230    Execute Command        ${ACCEL} SampleRate 1600
231    # the first 20 samples of the high-frequency block
232    FOR  ${i}  IN RANGE  20
233        Acceleration Should Be  1  ${i}  # the high-frequency block has values 1, 1.001, ...
234        Execute Command        emulation RunFor "0.000625"  # play one high-frequency point
235    END
236    Execute Command        ${ACCEL} SampleRate 100
237    FOR  ${i}  IN RANGE  32
238        Acceleration Should Be  2  ${i}  # the second low-frequency block has values 2, 2.001, ...
239        Execute Command        emulation RunFor "0.01"  # play one low-frequency point
240    END
241
242    [Teardown]             Test Teardown And Cleanup RESD File  ${resdPath}
243