diff --git a/src/common/platforms/arm/arm_nsleep100.c b/src/common/platforms/arm/arm_nsleep100.c
new file mode 100644
index 0000000000000000000000000000000000000000..554d20441d2db32dfc6ecebd204c07d807d3e04d
--- /dev/null
+++ b/src/common/platforms/arm/arm_nsleep100.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014-2018 Cesanta Software Limited
+ * All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the ""License"");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an ""AS IS"" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <math.h>
+
+#include "mgos.h"
+#include "mgos_system.h"
+
+void (*mgos_nsleep100)(uint32_t n);
+uint32_t mgos_nsleep100_loop_count = 0;
+/* Provided by arm_nsleep100_{m4,m7}.S for M4 and M7 respectively. */
+extern void mgos_nsleep100_impl(uint32_t n);
+
+void mgos_nsleep100_cal(void) {
+  uint32_t cpu_freq = mgos_get_cpu_freq();
+  /* # of instruction cycles per 100 ns */
+  mgos_nsleep100_loop_count =
+      roundf((100.0f / 1000000000.0f) / (1.0f / cpu_freq));
+  mgos_nsleep100 = mgos_nsleep100_impl;
+}
diff --git a/src/common/platforms/arm/arm_nsleep100_m4.S b/src/common/platforms/arm/arm_nsleep100_m4.S
new file mode 100644
index 0000000000000000000000000000000000000000..d40820f698fa9a15d56eb723b79c0f3026bee489
--- /dev/null
+++ b/src/common/platforms/arm/arm_nsleep100_m4.S
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014-2018 Cesanta Software Limited
+ * All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the ""License"");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an ""AS IS"" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.arch armv7e-m
+.syntax unified
+.thumb
+
+/* These are required to satisfy TI linker. */
+.eabi_attribute Tag_ABI_align_needed, 1
+.eabi_attribute Tag_ABI_align_preserved, 1
+
+.global mgos_nsleep100_impl
+.global mgos_nsleep100_loop_count
+
+.section .iram.mgos_nsleep100_impl
+.type mgos_nsleep100_impl, %function
+.align 4
+
+mgos_nsleep100_impl:
+      ldr     r3, =mgos_nsleep100_loop_count
+      ldr     r3, [r3]
+      mul     r0, r3
+      mov     r1, #6
+      udiv    r0, r0, r1
+      cbz     r0, xxx
+lxx:
+      subs    r0, #1
+      bne     lxx
+xxx:
+      bx      lr
+.align 4
+.size mgos_nsleep100_impl, . - mgos_nsleep100_impl
diff --git a/src/common/platforms/arm/arm_nsleep100_m7.S b/src/common/platforms/arm/arm_nsleep100_m7.S
new file mode 100644
index 0000000000000000000000000000000000000000..c0e8f49015e5b62831c3abf76acbd8b4be06c991
--- /dev/null
+++ b/src/common/platforms/arm/arm_nsleep100_m7.S
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014-2018 Cesanta Software Limited
+ * All rights reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the ""License"");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an ""AS IS"" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.arch armv7e-m
+.syntax unified
+.thumb
+
+/* These are required to satisfy TI linker. */
+.eabi_attribute Tag_ABI_align_needed, 1
+.eabi_attribute Tag_ABI_align_preserved, 1
+
+.global mgos_nsleep100_impl
+.global mgos_nsleep100_loop_count
+
+.section .iram.mgos_nsleep100_impl
+.type mgos_nsleep100_impl, %function
+.align 4
+
+mgos_nsleep100_impl:
+      ldr     r3, =mgos_nsleep100_loop_count
+      ldr     r3, [r3]
+      /* Because of speculative fetch, the core loop only takes 1 cycle. */
+      muls    r0, r3
+      cbz     r0, xxx
+lxx:
+      subs    r0, #1
+      bne     lxx
+xxx:
+      bx      lr
+.align 4
+.size mgos_nsleep100_impl, . - mgos_nsleep100_impl