From 7f59c32bb94b6d3859fae9821139a3c640e5b014 Mon Sep 17 00:00:00 2001
From: selinahsu <selinaraindrop@gmail.com>
Date: Wed, 5 May 2021 18:21:29 +0000
Subject: [PATCH 1/8] delay_us implemented without soft timer

---
 libraries/ms-common/src/delay.c       | 14 +++++---------
 libraries/ms-common/test/test_delay.c | 19 +++++++++++++++++++
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/libraries/ms-common/src/delay.c b/libraries/ms-common/src/delay.c
index 47412bbb2..b3c41c68e 100644
--- a/libraries/ms-common/src/delay.c
+++ b/libraries/ms-common/src/delay.c
@@ -2,19 +2,15 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <time.h>
 
 #include "soft_timer.h"
 #include "wait.h"
 
-static void prv_delay_it(SoftTimerId timer_id, void *context) {
-  volatile bool *block = context;
-  *block = false;
-}
-
 void delay_us(uint32_t t) {
-  volatile bool block = true;
-  soft_timer_start(t, prv_delay_it, (void *)&block, NULL);
-  while (block) {
-    wait();
+  clock_t end = t * (CLOCKS_PER_SEC / 1000000);
+  clock_t start = clock();
+
+  while ((clock() - start) < end) {
   }
 }
diff --git a/libraries/ms-common/test/test_delay.c b/libraries/ms-common/test/test_delay.c
index 457a891fc..855b0ad79 100644
--- a/libraries/ms-common/test/test_delay.c
+++ b/libraries/ms-common/test/test_delay.c
@@ -4,6 +4,8 @@
 #include "soft_timer.h"
 #include "unity.h"
 
+bool soft_timer_done;
+
 // These tests serve a dual purpose as they also implicitly test the wait
 // module.
 
@@ -17,3 +19,20 @@ void teardown_test(void) {}
 void test_delay_us(void) {
   delay_us(10000);
 }
+
+// The following 2 functions test that delay_us can be used
+// inside a soft timer callback without deadlock (issue SOFT-298)
+static void callback(SoftTimerId timer, void *context) {
+  LOG_DEBUG("Callback started\n");
+  delay_us(10000);
+  soft_timer_done = true;
+  LOG_DEBUG("Callback ended\n");
+}
+void test_delay_in_soft_timer(void) {
+  soft_timer_done = false;
+  soft_timer_start(10000, callback, NULL, NULL);
+
+  // Soft timer should be done within 1 second
+  delay_us(1000000);
+  TEST_ASSERT_TRUE(soft_timer_done);
+}

From 0e88d5af66efcb2e552305b11d2fee188b8207db Mon Sep 17 00:00:00 2001
From: selinahsu <selinaraindrop@gmail.com>
Date: Wed, 5 May 2021 18:40:54 +0000
Subject: [PATCH 2/8] rmed print statements

---
 libraries/ms-common/test/test_delay.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/libraries/ms-common/test/test_delay.c b/libraries/ms-common/test/test_delay.c
index 855b0ad79..b44956ce1 100644
--- a/libraries/ms-common/test/test_delay.c
+++ b/libraries/ms-common/test/test_delay.c
@@ -23,10 +23,8 @@ void test_delay_us(void) {
 // The following 2 functions test that delay_us can be used
 // inside a soft timer callback without deadlock (issue SOFT-298)
 static void callback(SoftTimerId timer, void *context) {
-  LOG_DEBUG("Callback started\n");
   delay_us(10000);
   soft_timer_done = true;
-  LOG_DEBUG("Callback ended\n");
 }
 void test_delay_in_soft_timer(void) {
   soft_timer_done = false;

From df292ba911ec3e50c2abf5227c5e1cc1fe51ce69 Mon Sep 17 00:00:00 2001
From: selinahsu <selinaraindrop@gmail.com>
Date: Thu, 6 May 2021 16:39:56 +0000
Subject: [PATCH 3/8] occasionally failing tests

---
 libraries/ms-common/src/delay.c       | 16 +++++++++++++---
 libraries/ms-common/test/test_delay.c |  4 ++--
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/libraries/ms-common/src/delay.c b/libraries/ms-common/src/delay.c
index b3c41c68e..342cb6b15 100644
--- a/libraries/ms-common/src/delay.c
+++ b/libraries/ms-common/src/delay.c
@@ -2,15 +2,25 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
 #include <time.h>
 
 #include "soft_timer.h"
 #include "wait.h"
 
 void delay_us(uint32_t t) {
-  clock_t end = t * (CLOCKS_PER_SEC / 1000000);
-  clock_t start = clock();
+  volatile struct timespec start, timer;
 
-  while ((clock() - start) < end) {
+  // Start clocks
+  clock_gettime(CLOCK_MONOTONIC_RAW, &start);
+  clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
+
+  // Convert t to nanoseconds
+  uint32_t end = t * 1000;
+
+  while ((((timer.tv_sec - start.tv_sec) * 1000000000) + (double)(timer.tv_nsec - start.tv_nsec)) <
+         end) {
+    clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
   }
 }
diff --git a/libraries/ms-common/test/test_delay.c b/libraries/ms-common/test/test_delay.c
index b44956ce1..65346c015 100644
--- a/libraries/ms-common/test/test_delay.c
+++ b/libraries/ms-common/test/test_delay.c
@@ -30,7 +30,7 @@ void test_delay_in_soft_timer(void) {
   soft_timer_done = false;
   soft_timer_start(10000, callback, NULL, NULL);
 
-  // Soft timer should be done within 1 second
-  delay_us(1000000);
+  // Soft timer should be done after 20000 us
+  delay_us(20000);
   TEST_ASSERT_TRUE(soft_timer_done);
 }

From ec0479549975242d4782390c6b75767c248fb98d Mon Sep 17 00:00:00 2001
From: selinahsu <selinaraindrop@gmail.com>
Date: Fri, 7 May 2021 15:58:45 +0000
Subject: [PATCH 4/8] ok then we using nanoseconds

---
 libraries/ms-common/src/delay.c          | 16 ++++++++--------
 libraries/ms-common/test/test_watchdog.c |  8 ++++----
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/libraries/ms-common/src/delay.c b/libraries/ms-common/src/delay.c
index 342cb6b15..fb7bf0ab8 100644
--- a/libraries/ms-common/src/delay.c
+++ b/libraries/ms-common/src/delay.c
@@ -10,17 +10,17 @@
 #include "wait.h"
 
 void delay_us(uint32_t t) {
-  volatile struct timespec start, timer;
-
-  // Start clocks
-  clock_gettime(CLOCK_MONOTONIC_RAW, &start);
-  clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
+  volatile struct timespec timer;
 
   // Convert t to nanoseconds
-  uint32_t end = t * 1000;
+  time_t end = t * 1000;
+
+  // Start clock
+  clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
+  time_t start_sec = timer.tv_sec;
+  time_t start_nano = timer.tv_nsec;
 
-  while ((((timer.tv_sec - start.tv_sec) * 1000000000) + (double)(timer.tv_nsec - start.tv_nsec)) <
-         end) {
+  while ((((timer.tv_sec - start_sec) * 1000000000) + (double)(timer.tv_nsec - start_nano)) < end) {
     clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
   }
 }
diff --git a/libraries/ms-common/test/test_watchdog.c b/libraries/ms-common/test/test_watchdog.c
index 436d54390..849cdd66f 100644
--- a/libraries/ms-common/test/test_watchdog.c
+++ b/libraries/ms-common/test/test_watchdog.c
@@ -41,7 +41,7 @@ void test_watchdog_expiry(void) {
   watchdog_start(&s_watchdog, TIMEOUT_MS, prv_expiry_callback, &context_data);
   TEST_ASSERT_FALSE(s_expiry_called);
 
-  delay_ms(TIMEOUT_MS + 5);
+  delay_ms(TIMEOUT_MS + 50);
 
   TEST_ASSERT_TRUE(s_expiry_called);
   TEST_ASSERT_EQUAL(&context_data, s_passed_context);
@@ -55,7 +55,7 @@ void test_watchdog_kick(void) {
   TEST_ASSERT_FALSE(s_expiry_called);
 
   watchdog_kick(&s_watchdog);
-  delay_ms(10);
+  delay_ms(50);
   TEST_ASSERT_FALSE(s_expiry_called);
 
   delay_ms(TIMEOUT_MS);
@@ -67,7 +67,7 @@ void test_watchdog_expired_does_not_call_callback_multiple_times(void) {
   uint32_t context_data = 0xdeadbeef;
   watchdog_start(&s_watchdog, TIMEOUT_MS, prv_expiry_callback, &context_data);
 
-  delay_ms(TIMEOUT_MS + 5);
+  delay_ms(TIMEOUT_MS + 20);
 
   TEST_ASSERT_TRUE(s_expiry_called);
   TEST_ASSERT_EQUAL(&context_data, s_passed_context);
@@ -82,7 +82,7 @@ void test_watchdog_expired_can_start_again(void) {
   watchdog_start(&s_watchdog, TIMEOUT_MS, prv_expiry_callback, &context_data);
 
   // its expired
-  delay_ms(TIMEOUT_MS + 5);
+  delay_ms(TIMEOUT_MS + 20);
   TEST_ASSERT_TRUE(s_expiry_called);
   prv_reset_callback();
 

From 52bb540e5a832d3938f213b88f2002b7fa1fb118 Mon Sep 17 00:00:00 2001
From: Ryan Dancy <ryan@keal.ca>
Date: Fri, 7 May 2021 19:30:32 -0400
Subject: [PATCH 5/8] Switch to a non-floating point comparison

---
 libraries/ms-common/src/delay.c              |  8 ++++----
 libraries/ms-common/test/test_watchdog.c     |  2 +-
 libraries/ms-drivers/test/test_ads1259_adc.c | 17 +++++++++--------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/libraries/ms-common/src/delay.c b/libraries/ms-common/src/delay.c
index fb7bf0ab8..fb393c47a 100644
--- a/libraries/ms-common/src/delay.c
+++ b/libraries/ms-common/src/delay.c
@@ -12,15 +12,15 @@
 void delay_us(uint32_t t) {
   volatile struct timespec timer;
 
-  // Convert t to nanoseconds
-  time_t end = t * 1000;
-
   // Start clock
   clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
   time_t start_sec = timer.tv_sec;
   time_t start_nano = timer.tv_nsec;
 
-  while ((((timer.tv_sec - start_sec) * 1000000000) + (double)(timer.tv_nsec - start_nano)) < end) {
+  time_t end_sec = start_sec + t / 1000000;
+  time_t end_nano = start_nano + (t % 1000000) * 1000;
+
+  while (timer.tv_sec < end_sec || (timer.tv_sec == end_sec && timer.tv_nsec < end_nano)) {
     clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
   }
 }
diff --git a/libraries/ms-common/test/test_watchdog.c b/libraries/ms-common/test/test_watchdog.c
index 849cdd66f..7870d31dd 100644
--- a/libraries/ms-common/test/test_watchdog.c
+++ b/libraries/ms-common/test/test_watchdog.c
@@ -55,7 +55,7 @@ void test_watchdog_kick(void) {
   TEST_ASSERT_FALSE(s_expiry_called);
 
   watchdog_kick(&s_watchdog);
-  delay_ms(50);
+  delay_ms(10);
   TEST_ASSERT_FALSE(s_expiry_called);
 
   delay_ms(TIMEOUT_MS);
diff --git a/libraries/ms-drivers/test/test_ads1259_adc.c b/libraries/ms-drivers/test/test_ads1259_adc.c
index 7678af0ec..0ecaeeda4 100644
--- a/libraries/ms-drivers/test/test_ads1259_adc.c
+++ b/libraries/ms-drivers/test/test_ads1259_adc.c
@@ -12,6 +12,7 @@
 #define NUM_CONFIG_REGISTERS 3
 #define TEST_CHK_SUM_FLAG_BIT 0x80
 #define TEST_DATA_SETTLING_TIME_MS 17
+#define DATA_SETTLING_BUFFER_MS 3
 
 #define TEST_BAUDRATE 60000
 #define TEST_MOSI_PIN \
@@ -210,7 +211,7 @@ void test_ads1259_get_conversion_data() {
   s_test_mode = ADS1259_MODE_MAX_POS_DATA;
   uint32_t test_raw = 0x7FFFFF;
   ads1259_get_conversion_data(&s_storage);
-  delay_ms(TEST_DATA_SETTLING_TIME_MS);
+  delay_ms(TEST_DATA_SETTLING_TIME_MS + DATA_SETTLING_BUFFER_MS);
   TEST_ASSERT_EQUAL(0xFF, s_storage.conv_data.LSB | s_storage.conv_data.MID);
   TEST_ASSERT_EQUAL(0x7F, s_storage.conv_data.MSB);
   // Math changed as a result of hardware testing, so assertions on s_storage.reading are wrong.
@@ -222,32 +223,32 @@ void test_ads1259_get_conversion_data() {
   s_test_mode = ADS1259_MODE_MAX_NEG_DATA;
   test_raw = 0x800000;
   ads1259_get_conversion_data(&s_storage);
-  delay_ms(TEST_DATA_SETTLING_TIME_MS);
+  delay_ms(TEST_DATA_SETTLING_TIME_MS + DATA_SETTLING_BUFFER_MS);
   // TEST_ASSERT_EQUAL(-50, s_storage.reading);
 
   // test with min readable pos data
   s_test_mode = ADS1259_MODE_MIN_POS_DATA;
   ads1259_get_conversion_data(&s_storage);
-  delay_ms(TEST_DATA_SETTLING_TIME_MS);
+  delay_ms(TEST_DATA_SETTLING_TIME_MS + DATA_SETTLING_BUFFER_MS);
   // TEST_ASSERT_EQUAL(0.000095, s_storage.reading);
 
   // test with min readable neg data
   s_test_mode = ADS1259_MODE_MIN_NEG_DATA;
   ads1259_get_conversion_data(&s_storage);
-  delay_ms(TEST_DATA_SETTLING_TIME_MS);
+  delay_ms(TEST_DATA_SETTLING_TIME_MS + DATA_SETTLING_BUFFER_MS);
   // TEST_ASSERT_EQUAL(-0.000095, s_storage.reading);
 
   // test with zero data
   s_test_mode = ADS1259_MODE_ZERO_DATA;
   ads1259_get_conversion_data(&s_storage);
-  delay_ms(TEST_DATA_SETTLING_TIME_MS);
+  delay_ms(TEST_DATA_SETTLING_TIME_MS + DATA_SETTLING_BUFFER_MS);
   // TEST_ASSERT_EQUAL(0, s_storage.reading);
 
   // test with a random data set
   s_test_mode = ADS1259_MODE_MIXED_DATA;
   test_raw = 0x102030;
   ads1259_get_conversion_data(&s_storage);
-  delay_ms(TEST_DATA_SETTLING_TIME_MS);
+  delay_ms(TEST_DATA_SETTLING_TIME_MS + DATA_SETTLING_BUFFER_MS);
   TEST_ASSERT_EQUAL(0x10, s_storage.conv_data.MSB);
   TEST_ASSERT_EQUAL(0x20, s_storage.conv_data.MID);
   TEST_ASSERT_EQUAL(0x30, s_storage.conv_data.LSB);
@@ -258,13 +259,13 @@ void test_ads1259_get_conversion_data() {
   s_test_mode = ADS1259_MODE_CHECKSUM_FAULT;
   s_checksum = false;
   ads1259_get_conversion_data(&s_storage);
-  delay_ms(TEST_DATA_SETTLING_TIME_MS);
+  delay_ms(TEST_DATA_SETTLING_TIME_MS + DATA_SETTLING_BUFFER_MS);
   TEST_ASSERT_TRUE(s_checksum);
 
   // test out of range flag triggered
   s_test_mode = ADS1259_MODE_OUT_RANGE_FLAG_TRIGGERED;
   s_out_of_range = false;
   ads1259_get_conversion_data(&s_storage);
-  delay_ms(TEST_DATA_SETTLING_TIME_MS);
+  delay_ms(TEST_DATA_SETTLING_TIME_MS + DATA_SETTLING_BUFFER_MS);
   TEST_ASSERT_TRUE(s_out_of_range);
 }

From 14edc613b94ca9586c504a4626920047479e1f34 Mon Sep 17 00:00:00 2001
From: ShiCheng Lu <shichenglu0708@gmail.com>
Date: Thu, 17 Jun 2021 02:46:58 +0000
Subject: [PATCH 6/8] moved delay.c for x86 into src/x86/, added implementation
 for STM32

---
 libraries/ms-common/src/stm32f0xx/delay.c | 21 +++++++++++++++++++++
 libraries/ms-common/src/{ => x86}/delay.c |  1 -
 mu/ctl/args.py                            |  1 +
 mu/ctl/req.py                             |  1 +
 mu/ctl/sims.py                            |  9 +++++++--
 mu/harness/pm.py                          |  2 +-
 mu/srv/handler.py                         |  2 ++
 mu/srv/server.py                          |  1 +
 8 files changed, 34 insertions(+), 4 deletions(-)
 create mode 100644 libraries/ms-common/src/stm32f0xx/delay.c
 rename libraries/ms-common/src/{ => x86}/delay.c (96%)

diff --git a/libraries/ms-common/src/stm32f0xx/delay.c b/libraries/ms-common/src/stm32f0xx/delay.c
new file mode 100644
index 000000000..e67593a1d
--- /dev/null
+++ b/libraries/ms-common/src/stm32f0xx/delay.c
@@ -0,0 +1,21 @@
+#include "delay.h"
+#include <stdbool.h>
+#include "stm32f0xx.h"
+
+// needs soft_timer to be initalized
+
+void delay_us(uint32_t t) {
+  uint32_t current_time = TIM_GetCounter(TIM2);  // use TIM2
+  uint32_t end_time = current_time + t;
+  // since t is uint32, there is a max of 1 rollover
+  bool rollover = (end_time < current_time);
+
+  while (rollover || current_time < end_time) {
+    // update time
+    uint32_t time = TIM_GetCounter(TIM2);
+    if (time < current_time) {  // rollover detection
+      rollover = false;
+    }
+    current_time = time;
+  }
+}
diff --git a/libraries/ms-common/src/delay.c b/libraries/ms-common/src/x86/delay.c
similarity index 96%
rename from libraries/ms-common/src/delay.c
rename to libraries/ms-common/src/x86/delay.c
index fb393c47a..8e91a3ebc 100644
--- a/libraries/ms-common/src/delay.c
+++ b/libraries/ms-common/src/x86/delay.c
@@ -6,7 +6,6 @@
 #include <sys/time.h>
 #include <time.h>
 
-#include "soft_timer.h"
 #include "wait.h"
 
 void delay_us(uint32_t t) {
diff --git a/mu/ctl/args.py b/mu/ctl/args.py
index 4a676d2ee..6924658c7 100644
--- a/mu/ctl/args.py
+++ b/mu/ctl/args.py
@@ -2,6 +2,7 @@
 from mu.ctl.log import logs
 from mu.ctl import sims
 
+
 def get_args():
     parser = argparse.ArgumentParser(prog='muctl', description='interact with musrv')
     parser.set_defaults(func=lambda _: parser.print_usage())
diff --git a/mu/ctl/req.py b/mu/ctl/req.py
index d7d596a8b..0fc2a3581 100644
--- a/mu/ctl/req.py
+++ b/mu/ctl/req.py
@@ -1,6 +1,7 @@
 import requests
 from mu.srv.server import TCP_PORT
 
+
 def send(route, body=None):
     url = 'http://localhost:{}/{}'.format(TCP_PORT, route)
     r = requests.get(url, params=body)
diff --git a/mu/ctl/sims.py b/mu/ctl/sims.py
index fe6f4534e..affa43f59 100644
--- a/mu/ctl/sims.py
+++ b/mu/ctl/sims.py
@@ -2,20 +2,24 @@
 
 import mu.ctl.req as req
 
+
 def reset(args):
     r = req.send('reset')
     print(r)
 
+
 def start(args):
-    body = { 'sim': args.sim, 'proj': args.proj }
+    body = {'sim': args.sim, 'proj': args.proj}
     r = req.send('start', body)
     print(r)
 
+
 def stop(args):
-    body = { 'sim': args.sim }
+    body = {'sim': args.sim}
     r = req.send('stop', body)
     print(r)
 
+
 def sims(args):
     r = req.send('sims')
     sims = json.loads(r)
@@ -23,6 +27,7 @@ def sims(args):
     for sim in sims:
         print(sim)
 
+
 def sim_list(args):
     r = req.send('list')
     sims = json.loads(r)
diff --git a/mu/harness/pm.py b/mu/harness/pm.py
index a9000d799..1a397d486 100644
--- a/mu/harness/pm.py
+++ b/mu/harness/pm.py
@@ -162,7 +162,7 @@ def sim_cat(self):
         for sim_file in sim_files:
             if not sim_file.endswith('.py'):
                 continue
-            sim_name = sim_file[:len(sim_file)-3]
+            sim_name = sim_file[:len(sim_file) - 3]
             mod_name = 'mu.sims.{}'.format(sim_name)
             mod = importlib.import_module(mod_name)
             sim_classes = inspect.getmembers(mod, inspect.isclass)
diff --git a/mu/srv/handler.py b/mu/srv/handler.py
index 0382202af..65b3c4806 100644
--- a/mu/srv/handler.py
+++ b/mu/srv/handler.py
@@ -4,9 +4,11 @@
 
 from mu.harness import logger
 
+
 class InternalError(Exception):
     pass
 
+
 class ReqHandler(http.server.BaseHTTPRequestHandler):
     def __init__(self, pm, *args, **kwargs):
         self.pm = pm
diff --git a/mu/srv/server.py b/mu/srv/server.py
index 2a1e7881e..1665a2b2c 100644
--- a/mu/srv/server.py
+++ b/mu/srv/server.py
@@ -8,6 +8,7 @@
 
 TCP_PORT = 8989
 
+
 class ThreadedServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
     def __init__(self, pm, address, handler_class):
         super().__init__(address, handler_class)

From 4587930453e3bcede38faf03053431301f21004e Mon Sep 17 00:00:00 2001
From: ShiCheng Lu <shichenglu0708@gmail.com>
Date: Mon, 21 Jun 2021 19:52:06 +0000
Subject: [PATCH 7/8] use soft_timer when not in critical section, use clock
 timer when in critical section (interrupts disabled), jank fix, but delay
 really shouldn't be used in critical section anyway

---
 libraries/ms-common/src/stm32f0xx/delay.c | 31 +++++++++++++-
 libraries/ms-common/src/x86/delay.c       | 49 ++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/libraries/ms-common/src/stm32f0xx/delay.c b/libraries/ms-common/src/stm32f0xx/delay.c
index e67593a1d..cabdcfcb3 100644
--- a/libraries/ms-common/src/stm32f0xx/delay.c
+++ b/libraries/ms-common/src/stm32f0xx/delay.c
@@ -1,10 +1,16 @@
 #include "delay.h"
+
 #include <stdbool.h>
+#include <stddef.h>
+
+#include "soft_timer.h"
 #include "stm32f0xx.h"
+#include "stm32f0xx_misc.h"
+#include "wait.h"
 
 // needs soft_timer to be initalized
 
-void delay_us(uint32_t t) {
+static void prv_delay_us_sys_clock(uint32_t t) {
   uint32_t current_time = TIM_GetCounter(TIM2);  // use TIM2
   uint32_t end_time = current_time + t;
   // since t is uint32, there is a max of 1 rollover
@@ -19,3 +25,26 @@ void delay_us(uint32_t t) {
     current_time = time;
   }
 }
+
+static void prv_delay_it(SoftTimerId timer_id, void *context) {
+  volatile bool *block = context;
+  *block = false;
+}
+
+static void prv_delay_us_soft_timer(uint32_t t) {
+  volatile bool block = true;
+  soft_timer_start(t, prv_delay_it, (void *)&block, NULL);
+  while (block) {
+    wait();
+  }
+}
+
+void delay_us(uint32_t t) {
+  // use softtimer if interrupts are not disabled
+  // use clock delay if iterrupts are disabled
+  if (__get_PRIMASK()) {  // interrupts disabled
+    prv_delay_us_sys_clock(t);
+  } else {
+    prv_delay_us_soft_timer(t);
+  }
+}
diff --git a/libraries/ms-common/src/x86/delay.c b/libraries/ms-common/src/x86/delay.c
index 8e91a3ebc..53b34046a 100644
--- a/libraries/ms-common/src/x86/delay.c
+++ b/libraries/ms-common/src/x86/delay.c
@@ -6,9 +6,11 @@
 #include <sys/time.h>
 #include <time.h>
 
+#include "soft_timer.h"
 #include "wait.h"
+#include "x86_interrupt.h"
 
-void delay_us(uint32_t t) {
+static void prv_delay_us_sys_clock(uint32_t t) {
   volatile struct timespec timer;
 
   // Start clock
@@ -23,3 +25,48 @@ void delay_us(uint32_t t) {
     clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
   }
 }
+
+// static uint32_t prv_get_time_us() {
+//   struct timespec timer;
+//   clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
+//   return (timer.tv_sec * 1000000 + timer.tv_nsec / 1000);
+// }
+
+// void delay_us(uint32_t t) {
+//   uint32_t current_time = prv_get_time_us();
+//   uint32_t end_time = current_time + t;
+//   // since t is uint32, there is a max of 1 rollover
+//   bool rollover = (end_time < current_time);
+
+//   while (rollover || current_time < end_time) {
+//     // update time
+//     uint32_t time = prv_get_time_us();
+//     if (time < current_time) {  // rollover detection
+//       rollover = false;
+//     }
+//     current_time = time;
+//   }
+// }
+
+static void prv_delay_it(SoftTimerId timer_id, void *context) {
+  volatile bool *block = context;
+  *block = false;
+}
+
+static void prv_delay_us_soft_timer(uint32_t t) {
+  volatile bool block = true;
+  soft_timer_start(t, prv_delay_it, (void *)&block, NULL);
+  while (block) {
+    wait();
+  }
+}
+
+void delay_us(uint32_t t) {
+  // use softtimer if interrupts are not disabled
+  // use clock delay if iterrupts are disabled
+  if (x86_interrupt_in_handler()) {  // interrupts disabled
+    prv_delay_us_sys_clock(t);
+  } else {
+    prv_delay_us_soft_timer(t);
+  }
+}

From 8254f1757dd7b12a06de8d95c3d002beec49e183 Mon Sep 17 00:00:00 2001
From: ShiCheng Lu <shichenglu0708@gmail.com>
Date: Mon, 21 Jun 2021 20:04:25 +0000
Subject: [PATCH 8/8] format

---
 libraries/ms-common/src/x86/delay.c | 22 ----------------------
 mu/ctl/args.py                      |  1 -
 mu/ctl/req.py                       |  1 +
 mu/ctl/sims.py                      |  6 ++----
 mu/srv/handler.py                   |  1 -
 5 files changed, 3 insertions(+), 28 deletions(-)

diff --git a/libraries/ms-common/src/x86/delay.c b/libraries/ms-common/src/x86/delay.c
index 53b34046a..b011d27a8 100644
--- a/libraries/ms-common/src/x86/delay.c
+++ b/libraries/ms-common/src/x86/delay.c
@@ -26,28 +26,6 @@ static void prv_delay_us_sys_clock(uint32_t t) {
   }
 }
 
-// static uint32_t prv_get_time_us() {
-//   struct timespec timer;
-//   clock_gettime(CLOCK_MONOTONIC_RAW, &timer);
-//   return (timer.tv_sec * 1000000 + timer.tv_nsec / 1000);
-// }
-
-// void delay_us(uint32_t t) {
-//   uint32_t current_time = prv_get_time_us();
-//   uint32_t end_time = current_time + t;
-//   // since t is uint32, there is a max of 1 rollover
-//   bool rollover = (end_time < current_time);
-
-//   while (rollover || current_time < end_time) {
-//     // update time
-//     uint32_t time = prv_get_time_us();
-//     if (time < current_time) {  // rollover detection
-//       rollover = false;
-//     }
-//     current_time = time;
-//   }
-// }
-
 static void prv_delay_it(SoftTimerId timer_id, void *context) {
   volatile bool *block = context;
   *block = false;
diff --git a/mu/ctl/args.py b/mu/ctl/args.py
index 59a5ef9ed..0b2dd2fda 100644
--- a/mu/ctl/args.py
+++ b/mu/ctl/args.py
@@ -4,7 +4,6 @@
 from mu.ctl import stores
 
 
-
 def get_args():
     parser = argparse.ArgumentParser(prog='muctl', description='interact with musrv')
     parser.set_defaults(func=lambda _: parser.print_usage())
diff --git a/mu/ctl/req.py b/mu/ctl/req.py
index fbbaa1acd..83937f8a2 100644
--- a/mu/ctl/req.py
+++ b/mu/ctl/req.py
@@ -1,6 +1,7 @@
 import requests
 from mu.srv.server import TCP_PORT
 
+
 def send(route, params=None, body=None):
     url = 'http://localhost:{}/{}'.format(TCP_PORT, route)
     return requests.get(url, params=params, json=body)
diff --git a/mu/ctl/sims.py b/mu/ctl/sims.py
index 72a0ddd7a..f32cd5f83 100644
--- a/mu/ctl/sims.py
+++ b/mu/ctl/sims.py
@@ -8,20 +8,18 @@ def reset(args):
     print(r.text)
 
 
-
 def start(args):
-    params = { 'sim': args.sim, 'proj': args.proj }
+    params = {'sim': args.sim, 'proj': args.proj}
     r = req.send('start', params)
     print(r.text)
 
 
 def stop(args):
-    params = { 'sim': args.sim }
+    params = {'sim': args.sim}
     r = req.send('stop', params)
     print(r.text)
 
 
-
 def sims(args):
     r = req.send('sims')
     sims = json.loads(r.text)
diff --git a/mu/srv/handler.py b/mu/srv/handler.py
index b78d086ea..81491cf9f 100644
--- a/mu/srv/handler.py
+++ b/mu/srv/handler.py
@@ -9,7 +9,6 @@
 from mu.protogen.stores_pb2 import MuStoreType
 
 
-
 class InternalError(Exception):
     pass