1*** Keywords ***
2Create Machine With Button And LED
3    [Arguments]              ${firmware}  ${usart}=2  ${button_port}=B  ${button_pin}=2  ${led_port}=A  ${led_pin}=5
4    IF  "${firmware}" == "button"
5        Execute Command          $bin = @https://dl.antmicro.com/projects/renode/b_l072z_lrwan1--zephyr-button.elf-s_402204-2343dc7268dedc253893a84300f3dbd02bc63a2a
6    ELSE IF  "${firmware}" == "blinky"
7        Execute Command          $bin = @https://dl.antmicro.com/projects/renode/b_l072z_lrwan1--zephyr-blinky.elf-s_395652-4d2c6106335435629d3611d2a732e37ca9f17eeb
8    ELSE IF  "${firmware}" == "led_shell"
9        Execute Command          $bin = @https://dl.antmicro.com/projects/renode/b_l072z_lrwan1--zephyr-led_shell.elf-s_1471160-5398b2ac0ab1c71ec144eba55f4840d86ddb921a
10    ELSE IF  "${firmware}" == "pwm_shell"
11        Execute Command          $bin = @https://dl.antmicro.com/projects/renode/b_l072z_lrwan1--zephyr-custom_shell_pwm.elf-s_884872-f36f63ef9435aaf89f37922d3c78428c52be1320
12    ELSE
13        Fail                     Unknown firmware '${firmware}'
14    END
15    Execute Command          include @scripts/single-node/stm32l072.resc
16    Execute Command          machine LoadPlatformDescriptionFromString "gpioPort${led_port}: { ${led_pin} -> led@0 }; led: Miscellaneous.LED @ gpioPort${led_port} ${led_pin}"
17    Execute Command          machine LoadPlatformDescriptionFromString "button: Miscellaneous.Button @ gpioPort${button_port} ${button_pin} { invert: true; -> gpioPort${button_port}@${button_pin} }"
18
19    Create Terminal Tester   sysbus.usart${usart}
20    Create LED Tester        sysbus.gpioPort${led_port}.led  defaultTimeout=2
21
22Create Machine With Trivial Uart
23    ${platform}=             Catenate  SEPARATOR=${\n}
24    ...  """
25    ...  cpu: CPU.ARMv7R @ sysbus
26    ...  ${SPACE*4}cpuType: "cortex-r8"
27    ...  mem: Memory.MappedMemory @ sysbus 0x0
28    ...  ${SPACE*4}size: 0x400
29    ...  uart: UART.TrivialUart @ sysbus <0x1000, +0x100>
30    ...  """
31    Execute Command          using sysbus
32    Execute Command          mach create
33    Execute Command          machine LoadPlatformDescriptionFromString ${platform}
34
35Emulation Should Be Paused
36    ${st}=                   Execute Command  emulation IsStarted
37    Should Contain           ${st}  False
38
39Emulation Should Be Paused At Time
40    [Arguments]              ${time}
41    Emulation Should Be Paused
42    ${ts}=                   Execute Command  machine GetTimeSourceInfo
43    Should Contain           ${ts}  Elapsed Virtual Time: ${time}
44
45Emulation Should Not Be Paused
46    ${st}=                   Execute Command  emulation IsStarted
47    Should Contain           ${st}  True
48
49*** Test Cases ***
50Terminal Tester Assert Should Start Emulation
51    Create Machine With Button And LED  button
52
53    Emulation Should Be Paused
54
55    Wait For Line On Uart    Press the button
56
57    Emulation Should Not Be Paused
58
59Terminal Tester Idle Assert Should Start Emulation
60    # We attach the tester to usart1 because nothing is printed to it
61    Create Machine With Button And LED  button  usart=1
62
63    Emulation Should Be Paused
64
65    Test If Uart Is Idle     2
66
67    Emulation Should Not Be Paused
68
69Terminal Tester Assert Should Not Start Emulation If Matching String Has Already Been Printed
70    Create Machine With Button And LED  button
71
72    # Give the sample plenty of virtual time to print the string
73    Execute Command          emulation RunFor "0.1"
74
75    Emulation Should Be Paused At Time  00:00:00.100000
76
77    Provides                 string-printed-without-assert
78
79    Wait For Line On Uart    Press the button
80
81    Emulation Should Be Paused At Time  00:00:00.100000
82
83Terminal Tester Assert Should Not Start Emulation With Timeout 0
84    Requires                 string-printed-without-assert
85
86    Run Keyword And Expect Error  *Terminal tester failed*  Wait For Line On Uart  String that was not printed  timeout=0
87
88    Emulation Should Be Paused At Time  00:00:00.100000
89
90Terminal Tester Assert Should Precisely Pause Emulation
91    [Tags]                   instructions_counting
92    Create Machine With Button And LED  button
93
94    Wait For Line On Uart    Press the button  pauseEmulation=true
95
96    Execute Command          gpioPortB.button Press
97
98    ${l}=                    Wait For Line On Uart  Button pressed at (\\d+)  pauseEmulation=true  treatAsRegex=true
99    Should Be Equal          ${l.groups[0]}  4897
100
101    Emulation Should Be Paused At Time  00:00:00.000226
102    PC Should Be Equal       0x8002c0a  # this is the next instruction after STR that writes to TDR in LL_USART_TransmitData8
103
104Emulation Should Pause Precisely Between Translation Blocks
105    [Tags]                   instructions_counting
106    Create Machine With Button And LED  button
107    # Forcing all blocks to contain a single instruction will force the precise pauses to be handled between blocks
108    Execute Command          cpu MaximumBlockSize 1
109
110    Wait For Line On Uart    Press the button  pauseEmulation=true
111
112    Execute Command          gpioPortB.button Press
113
114    ${l}=                    Wait For Line On Uart  Button pressed at (\\d+)  pauseEmulation=true  treatAsRegex=true
115    Should Be Equal          ${l.groups[0]}  4215
116
117    Emulation Should Be Paused At Time  00:00:00.000226
118    PC Should Be Equal       0x8002c0a  # this is the next instruction after STR that writes to TDR in LL_USART_TransmitData8
119
120Quantum Should Not Impact Tester Pause PC
121    Create Machine With Button And LED  button
122    Execute Command          emulation SetGlobalQuantum "0.010000"
123
124    Wait For Line On Uart    Press the button  pauseEmulation=true
125
126    Execute Command          gpioPortB.button Press
127
128    Wait For Line On Uart    Button pressed at (\\d+)  pauseEmulation=true  treatAsRegex=true
129
130    PC Should Be Equal       0x8002c0a
131
132RunFor Should Work After Precise Pause
133    Create Machine With Button And LED  button
134
135    Wait For Line On Uart    Press the button  pauseEmulation=true
136    Emulation Should Be Paused At Time  00:00:00.000179
137
138    Execute Command          emulation RunFor "0.1"
139    Emulation Should Be Paused At Time  00:00:00.100179
140
141LED Tester Assert Should Start Emulation Unless The State Already Matches
142    Create Machine With Button And LED  blinky
143
144    # The LED state is false by default on reset because it is not inverted, so this assert
145    # should pass immediately without starting the emulation
146    Assert LED State         false
147    Emulation Should Be Paused At Time  00:00:00.000000
148
149    # And this one should start the emulation
150    Assert LED State         true
151    Emulation Should Not Be Paused
152
153LED Tester Assert Should Not Start Emulation With Timeout 0
154    Create Machine With Button And LED  blinky
155
156    # The LED state is false by default, so this assert should fail immediately without
157    # starting the emulation because the timeout is 0
158    Run Keyword And Expect Error  *LED assertion not met*  Assert LED State  true  0
159
160    Emulation Should Be Paused At Time  00:00:00.000000
161
162LED Tester Assert Should Precisely Pause Emulation
163    [Tags]                   instructions_counting
164    Create Machine With Button And LED  blinky
165
166    Assert LED State         true  pauseEmulation=true
167    Emulation Should Be Paused At Time  00:00:00.000115
168    PC Should Be Equal       0x8002a48  # this is the next instruction after STR that writes to BSRR in gpio_stm32_port_set_bits_raw
169
170    Assert LED State         false  pauseEmulation=true
171    Emulation Should Be Paused At Time  00:00:01.000157
172    PC Should Be Equal       0x80028a4  # this is the next instruction after STR that writes to BRR in LL_GPIO_ResetOutputPin
173
174    Provides                 synced-blinky
175
176LED Tester Assert And Hold Should Precisely Pause Emulation
177    [Tags]                   instructions_counting
178    Requires                 synced-blinky
179
180    # The expected times have 3 decimal places because the default quantum is 0.000100
181    ${state}=                Set Variable  False
182    FOR  ${i}  IN RANGE  2  5
183        Assert And Hold LED State  ${state}  timeoutAssert=1  timeoutHold=1  pauseEmulation=true
184        Emulation Should Be Paused At Time  00:00:0${i}.000
185        ${state}=                Evaluate  not ${state}
186    END
187
188LED Tester Assert Is Blinking Should Precisely Pause Emulation
189    [Tags]                   instructions_counting
190    Requires                 synced-blinky
191
192    Assert LED Is Blinking   testDuration=5  onDuration=1  offDuration=1  pauseEmulation=true
193    Emulation Should Be Paused At Time  00:00:06.000200
194
195LED Tester Assert Duty Cycle Should Precisely Pause Emulation
196    [Tags]                   instructions_counting
197    Requires                 synced-blinky
198
199    Assert LED Duty Cycle    testDuration=5  expectedDutyCycle=0.5  pauseEmulation=true
200    Emulation Should Be Paused At Time  00:00:06.000200
201
202LED And Terminal Testers Should Cooperate
203    Create Machine With Button And LED  led_shell
204
205    Wait For Prompt On Uart  $  pauseEmulation=true
206    Write Line To Uart       led on leds 0  waitForEcho=false
207    Wait For Line On Uart    leds: turning on LED 0  pauseEmulation=true
208    Emulation Should Be Paused At Time  00:00:00.001239
209    PC Should Be Equal       0x800b26c
210    # The LED should not be turned on yet: the string is printed before actually changing the GPIO
211    Assert LED State         false  0
212
213    # Now wait for the LED to turn on
214    Assert LED State         true  pauseEmulation=true
215    Emulation Should Be Paused At Time  00:00:00.001243
216    PC Should Be Equal       0x800af0c
217
218LED Tester Assertion Triggered By PWM Should Not Log Errors
219    Create Log Tester        0
220    Create Machine With Button And LED  pwm_shell  led_port=B  led_pin=10
221
222    ${pwm}=  Wait For Line On Uart  pwm device: (\\w+)  treatAsRegex=true  pauseEmulation=true
223    ${pwm}=  Set Variable    ${pwm.groups[0]}
224
225    Write Line To Uart       pwm cycles ${pwm} 3 256 127  pauseEmulation=true
226    Wait For Prompt On Uart  $  pauseEmulation=true
227
228    # The LED state is true at this point, so this will wait for it to turn off
229    Assert LED State         false  pauseEmulation=true
230
231    # There should be a warning but no errors
232    Wait For Log Entry       Failed to restart translation block for precise pause  keep=true
233    Should Not Be In Log     ${EMPTY}  level=Error
234
235Log Tester Assert Should Precisely Pause Emulation
236    [Tags]                   instructions_counting
237    Create Log Tester        5
238    Create Machine With Button And LED  pwm_shell  led_port=B  led_pin=10
239
240    ${pwm}=  Wait For Line On Uart  pwm device: (\\w+)  treatAsRegex=true  pauseEmulation=true
241    ${pwm}=  Set Variable    ${pwm.groups[0]}
242
243    Write Line To Uart       pwm cycles ${pwm} 3 256 127  waitForEcho=false
244
245    Provides                 waiting-for-unhandled-write-log
246
247    Wait For Log Entry       Unhandled write to offset 0x1C.  pauseEmulation=true
248    Emulation Should Be Paused At Time  00:00:00.001297
249
250    Provides                 paused-at-log-assertion
251
252Log Tester Should Not Be In Log Assert Should Precisely Pause Emulation
253    Requires                 paused-at-log-assertion
254
255    Should Not Be In Log     No such random message in log  timeout=2  pauseEmulation=true
256    # The time gets rounded to the sync point
257    Emulation Should Be Paused At Time  00:00:02.001300
258
259Log Tester Should Not Be In Log Assert Should Not Pause Emulation Later If The Matching String Actually Gets Logged
260    Requires                 waiting-for-unhandled-write-log
261
262    Run Keyword And Expect Error  *Unexpected line detected in the log*  Should Not Be In Log  Unhandled write to offset 0x1C.  timeout=2  pauseEmulation=true
263    Emulation Should Be Paused At Time  00:00:00.001297
264
265    Execute Command  emulation RunFor "3"
266    Emulation Should Be Paused At Time  00:00:03.001297
267
268Should Finish Instructions Before Pausing
269    Create Machine With Trivial Uart
270    Create Terminal Tester   sysbus.uart  defaultPauseEmulation=true
271
272    Execute Command          cpu SetRegister 0 0x1000  # UART write address
273    Execute Command          cpu SetRegister 1 0x4F  # 'O'
274    Execute Command          cpu SetRegister 2 0x6E  # 'n'
275    Execute Command          cpu SetRegister 3 0x65  # 'e'
276    Execute Command          cpu SetRegister 4 0x0A  # '\n'
277    Execute Command          cpu SetRegister 5 0x54  # 'T'
278    Execute Command          cpu SetRegister 6 0x77  # 'w'
279    Execute Command          cpu SetRegister 7 0x6F  # 'o'
280    Execute Command          cpu SetRegister 8 0x0A  # '\n'
281
282    Execute Command          sysbus WriteDoubleWord 0x10 0xE8A001FE  # stm r0!, {r1-r8}
283    Execute Command          cpu PC 0x10
284
285    Wait For Line On Uart    One
286    # This string should already be present, as the instruction printing it should have finished successfully
287    Wait For Line On Uart    Two  timeout=0  matchNextLine=true
288    PC Should Be Equal       0x14
289