You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2020/09/03 14:08:47 UTC

[GitHub] [mynewt-core] kasjer commented on a change in pull request #2368: hw: Add MCU and BSP for Dialog CMAC

kasjer commented on a change in pull request #2368:
URL: https://github.com/apache/mynewt-core/pull/2368#discussion_r482947246



##########
File path: hw/mcu/dialog/cmac/include/mcu/cmac_timer.h
##########
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#ifndef __MCU_CMAC_TIMER_H_
+#define __MCU_CMAC_TIMER_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (cmac_timer_int_func_t)(void);
+
+extern volatile uint32_t cm_ll_int_stat_reg;
+
+void cmac_timer_init(void);
+void cmac_timer_slp_enable(uint32_t ticks);
+void cmac_timer_slp_disable(uint32_t exp_ticks);
+bool cmac_timer_slp_update(void);
+bool cmac_timer_slp_is_ready(void);
+#if MYNEWT_VAL(MCU_SLP_TIMER_32K_ONLY)
+static inline uint32_t
+cmac_timer_slp_tick_us(void)
+{
+    return 31;
+}
+#else
+uint32_t cmac_timer_slp_tick_us(void);
+#endif
+void cmac_timer_int_hal_timer_register(cmac_timer_int_func_t func);
+void cmac_timer_int_os_tick_register(cmac_timer_int_func_t func);
+void cmac_timer_int_os_tick_clear(void);
+
+uint32_t cmac_timer_next_at(void);
+uint32_t cmac_timer_usecs_to_lp_ticks(uint32_t usecs);
+
+uint32_t cmac_timer_get_hal_os_tick(void);
+
+static inline uint32_t
+cmac_timer_read_lo(void)
+{
+    return CMAC->CM_LL_TIMER1_9_0_REG;
+}
+
+static inline uint32_t
+cmac_timer_read_hi(void)
+{
+    return CMAC->CM_LL_TIMER1_36_10_REG;
+}
+
+/* Reads lsb 32-bit value of LL Timer */
+static inline uint32_t
+cmac_timer_read32(void)
+{
+    uint32_t hi;
+    uint32_t lo;
+
+    do {
+        hi = cmac_timer_read_hi();
+        lo = cmac_timer_read_lo();
+    } while (hi != cmac_timer_read_hi());
+
+    return (hi << 10) | lo;
+}
+
+/* Reads full 37-bit value of LL Timer */
+static inline uint64_t
+cmac_timer_read64(void)
+{
+    uint32_t hi;
+    uint32_t lo;
+
+    do {
+        hi = cmac_timer_read_hi();
+        lo = cmac_timer_read_lo();
+    } while (hi != cmac_timer_read_hi());
+
+    return ((uint64_t)hi << 10) | lo;
+}
+
+static inline void
+cmac_timer_trigger_hal(void)
+{
+    cm_ll_int_stat_reg = CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_EQ_X_SEL_Msk;
+    NVIC_SetPendingIRQ(LL_TIMER2LLC_IRQn);
+}
+
+/* Write comparator value for hal_timer callback */
+static inline void
+cmac_timer_write_eq_hal_timer(uint64_t val)
+{
+    CMAC->CM_LL_TIMER1_EQ_X_HI_REG = val >> 10;
+    CMAC->CM_LL_TIMER1_EQ_X_LO_REG = val;
+    CMAC->CM_LL_INT_MSK_SET_REG = CMAC_CM_LL_INT_MSK_SET_REG_LL_TIMER1_EQ_X_SEL_Msk;
+
+    /*
+     * Need to check if we set comparator in the past (e.g. when trying to set
+     * it at "now" and force interrupt. Note that we cannot mark particular
+     * comparator as triggered so we just use local variable as a "shadow"
+     * register.
+     */
+    if ((int64_t)(val - cmac_timer_read64()) <= 0) {
+        cm_ll_int_stat_reg = CMAC_CM_LL_INT_STAT_REG_LL_TIMER1_EQ_X_SEL_Msk;
+        NVIC_SetPendingIRQ(LL_TIMER2LLC_IRQn);
+    }
+}
+
+/* Disable comparator value for hal_timer callback */
+static inline void
+cmac_timer_disable_eq_hal_timer(void)
+{
+    CMAC->CM_LL_INT_MSK_CLR_REG = CMAC_CM_LL_INT_MSK_CLR_REG_LL_TIMER1_EQ_X_SEL_Msk;
+}
+
+/* Write comparator value for hal_os_tick callback */
+static inline void
+cmac_timer_write_eq_hal_os_tick(uint64_t val)
+{
+    CMAC->CM_LL_TIMER1_36_10_EQ_Y_REG = val >> 10;
+
+    if (((val >> 10) - cmac_timer_read_hi()) <= 0) {

Review comment:
       This is unsigned comparison < is never true, change to == or add cast to signed type if val>>10 can be lower then what function returns

##########
File path: hw/mcu/dialog/cmac/src/system_cmac.c
##########
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include "syscfg/syscfg.h"
+#include "mcu/cmac_hal.h"
+#include "mcu/cmac_pdc.h"
+#include "mcu/cmac_timer.h"
+#include "mcu/cmsis_nvic.h"
+#include "mcu/mcu.h"
+#include "hal/hal_system.h"
+#include "cmac_driver/cmac_diag.h"
+#include "CMAC.h"
+
+void SystemInit(void)
+{
+#if MYNEWT_VAL(CMAC_DEBUG_DIAG_ENABLE)
+    cmac_diag_setup_cmac();
+#endif
+
+#if MYNEWT_VAL(MCU_DEBUG_SWD_WAIT_FOR_ATTACH)
+    while (!hal_debugger_connected());
+    for (int i = 0; i < 1000000; i++);
+#endif
+
+    CMAC->CM_CTRL_REG &= ~CMAC_CM_CTRL_REG_CM_BS_RESET_N_Msk;
+    CMAC->CM_CTRL_REG |= CMAC_CM_CTRL_REG_CM_BS_RESET_N_Msk;
+
+    CMAC->CM_CTRL_REG = (CMAC->CM_CTRL_REG &
+                         ~CMAC_CM_CTRL_REG_CM_CLK_FREQ_MHZ_D2M1_Msk) |
+                        (15 << CMAC_CM_CTRL_REG_CM_CLK_FREQ_MHZ_D2M1_Pos);
+    CMAC->CM_CTRL2_REG = CMAC_CM_CTRL2_REG_LL_TIMER1_9_0_LIMITED_N_Msk;
+
+    CMAC->CM_CTRL_REG |= CMAC_CM_CTRL_REG_CM_BS_ENABLE_Msk;
+
+    cmac_timer_init();
+};

Review comment:
       ``;`` after function body

##########
File path: hw/mcu/dialog/cmac/include/mcu/mcu.h
##########
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#ifndef __MCU_MCU_H_
+#define __MCU_MCU_H_
+
+#include "CMAC.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SVC_IRQ_NUMBER                  SVCall_IRQn
+
+#define MCU_MEM_SYSRAM_START_ADDRESS    (0x20000000)
+#define MCU_MEM_SYSRAM_END_ADDRESS      (0x20080000)
+
+/* Map diagnostic signal to diagnostic port (output) */
+#define MCU_DIAG_MAP(_port, _word, _evt)                                \

Review comment:
       MCU_DIAG_MAP and MCU_DIAG_MAP_BIT are never used, but if they were ``;`` would be more expected on the lines that use those macros like in next macros in this file.

##########
File path: hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_arch_arm.c
##########
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "mcu/mcu.h"
+#include "hal/hal_os_tick.h"
+#include "os/os_arch_cmac.h"
+/* XXX fix this... */
+#include "../../../../../../apache-mynewt-core/kernel/os/src/os_priv.h"
+
+/* Initial program status register */
+#define INITIAL_xPSR    0x01000000
+
+/* Stack frame structure */
+struct stack_frame {
+    uint32_t    r4;
+    uint32_t    r5;
+    uint32_t    r6;
+    uint32_t    r7;
+    uint32_t    r8;
+    uint32_t    r9;
+    uint32_t    r10;
+    uint32_t    r11;
+    uint32_t    r0;
+    uint32_t    r1;
+    uint32_t    r2;
+    uint32_t    r3;
+    uint32_t    r12;
+    uint32_t    lr;
+    uint32_t    pc;
+    uint32_t    xpsr;
+};
+
+#define SVC_ArgN(n) \
+  register int __r##n __asm("r"#n);
+
+#define SVC_Arg0()  \
+  SVC_ArgN(0)       \
+  SVC_ArgN(1)       \
+  SVC_ArgN(2)       \
+  SVC_ArgN(3)
+
+#define SVC_Call(f)                                                     \
+  __asm volatile                                                        \
+  (                                                                     \
+    "ldr r7,="#f"\n\t"                                                  \
+    "mov r12,r7\n\t"                                                    \
+    "svc 0"                                                             \
+    :               "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)  \
+    :                "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)  \
+    : "r7", "r12", "lr", "cc"                                           \
+  );
+
+/* XXX: determine how we will deal with running un-privileged */
+uint32_t os_flags = OS_RUN_PRIV;
+
+void
+os_arch_ctx_sw(struct os_task *t)
+{
+    os_sched_ctx_sw_hook(t);
+
+    /* Set PendSV interrupt pending bit to force context switch */
+    os_arch_cmac_pendsvset();
+}
+
+os_stack_t *
+os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
+{
+    int i;
+    os_stack_t *s;
+    struct stack_frame *sf;
+
+    /* Get stack frame pointer */
+    s = (os_stack_t *) ((uint8_t *) stack_top - sizeof(*sf));
+
+    /* Zero out R1-R3, R12, LR */
+    for (i = 9; i < 14; ++i) {
+        s[i] = 0;
+    }
+
+    /* Set registers R4 - R11 on stack. */
+    os_arch_init_task_stack(s);
+
+    /* Set remaining portions of stack frame */
+    sf = (struct stack_frame *) s;
+    sf->xpsr = INITIAL_xPSR;
+    sf->pc = (uint32_t)t->t_func;
+    sf->r0 = (uint32_t)t->t_arg;
+
+    return (s);

Review comment:
       other places in this file do not use ``()`` for return values

##########
File path: hw/mcu/dialog/cmac/include/mcu/mcu.h
##########
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#ifndef __MCU_MCU_H_
+#define __MCU_MCU_H_
+
+#include "CMAC.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SVC_IRQ_NUMBER                  SVCall_IRQn
+
+#define MCU_MEM_SYSRAM_START_ADDRESS    (0x20000000)
+#define MCU_MEM_SYSRAM_END_ADDRESS      (0x20080000)
+
+/* Map diagnostic signal to diagnostic port (output) */
+#define MCU_DIAG_MAP(_port, _word, _evt)                                \
+    CMAC->CM_DIAG_PORT ## _port ## _REG =                               \
+        (_word << CMAC_CM_DIAG_PORT ## _port ## _REG_DIAG_WORD_Pos) |   \
+        (CMAC_CM_DIAG_WORD ## _word ## _REG_DIAG ## _word ## _ ## _evt ## _Pos << CMAC_CM_DIAG_PORT ## _port ## _REG_DIAG_BIT_Pos);
+#define MCU_DIAG_MAP_BIT(_port, _word, _evt, _bit)                      \
+    CMAC->CM_DIAG_PORT ## _port ## _REG =                               \
+        (_word << CMAC_CM_DIAG_PORT ## _port ## _REG_DIAG_WORD_Pos) |   \
+        ((CMAC_CM_DIAG_WORD ## _word ## _REG_DIAG ## _word ## _ ## _evt ## _Pos + (_bit)) << CMAC_CM_DIAG_PORT ## _port ## _REG_DIAG_BIT_Pos);
+
+/* Output diagnostic setial message */
+#ifndef MCU_DIAG_SER_DISABLE
+#define MCU_DIAG_SER(_ch)               \

Review comment:
       other macros with similar functionality here don't use ``do {} while (0)``.

##########
File path: hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_arch_arm.c
##########
@@ -0,0 +1,250 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "mcu/mcu.h"
+#include "hal/hal_os_tick.h"
+#include "os/os_arch_cmac.h"
+/* XXX fix this... */
+#include "../../../../../../apache-mynewt-core/kernel/os/src/os_priv.h"
+
+/* Initial program status register */
+#define INITIAL_xPSR    0x01000000
+
+/* Stack frame structure */
+struct stack_frame {
+    uint32_t    r4;
+    uint32_t    r5;
+    uint32_t    r6;
+    uint32_t    r7;
+    uint32_t    r8;
+    uint32_t    r9;
+    uint32_t    r10;
+    uint32_t    r11;
+    uint32_t    r0;
+    uint32_t    r1;
+    uint32_t    r2;
+    uint32_t    r3;
+    uint32_t    r12;
+    uint32_t    lr;
+    uint32_t    pc;
+    uint32_t    xpsr;
+};
+
+#define SVC_ArgN(n) \
+  register int __r##n __asm("r"#n);
+
+#define SVC_Arg0()  \
+  SVC_ArgN(0)       \
+  SVC_ArgN(1)       \
+  SVC_ArgN(2)       \
+  SVC_ArgN(3)
+
+#define SVC_Call(f)                                                     \
+  __asm volatile                                                        \
+  (                                                                     \
+    "ldr r7,="#f"\n\t"                                                  \
+    "mov r12,r7\n\t"                                                    \
+    "svc 0"                                                             \
+    :               "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)  \
+    :                "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)  \
+    : "r7", "r12", "lr", "cc"                                           \
+  );
+
+/* XXX: determine how we will deal with running un-privileged */
+uint32_t os_flags = OS_RUN_PRIV;
+
+void
+os_arch_ctx_sw(struct os_task *t)
+{
+    os_sched_ctx_sw_hook(t);
+
+    /* Set PendSV interrupt pending bit to force context switch */
+    os_arch_cmac_pendsvset();
+}
+
+os_stack_t *
+os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
+{
+    int i;
+    os_stack_t *s;
+    struct stack_frame *sf;
+
+    /* Get stack frame pointer */
+    s = (os_stack_t *) ((uint8_t *) stack_top - sizeof(*sf));

Review comment:
       space in case unlike other places few line down

##########
File path: hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_arch_cmac.c
##########
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "mcu/mcu.h"
+#include "hal/hal_os_tick.h"
+#include "CMAC.h"
+
+/*
+ * Interrupts handling on CMAC needs to be a bit different than in generic M0+
+ * arch. We need FIELD, FRAME and CALLBACK interrupts to be handled in real-time
+ * as otherwise PHY will fail due to interrupt latency. For this reason we need
+ * to have BASEPRI-like behavior but since M0+ does not support BASEPRI in hw,
+ * this is emulated in sw.
+ *
+ * CMAC.h includes os_arm_cmac.h which redefines NVIC_Enable/Disable to make
+ * sure ICER/ISER is not accessed directly outside this file.
+ *
+ * Configured state for ISER is kept in shadow register (g_cmac_iser_shadow)
+ * and is applied only when not in critical section or when exiting critical
+ * section.
+ *
+ * When entering critical section all standard (i.e. other than those we need
+ * to keep always enabled) interrupts are disabled via ICER and flag is set to
+ * mimic PRIMASK behavior.
+ *
+ * Additional handling is required for PendSV since it cannot be disabled from
+ * NVIC so there is another flag which indicates that PendSV should be set. This
+ * is done when exiting critical section - we assume that PendSV is being set to
+ * pending only when in critical section (which is true for Mynewt since it's
+ * done on context switch and we do not expect our controller on CMAC to work
+ * with any other OS ever).
+ *
+ * Finally, before execuing 'wfi' we need to globally disable all interrupts but
+ * so we can restore ISER for all interrupts and thus 'wfi' will wakeup on any
+ * configured interrupt. After 'wfi', ICER is used to restore pre-wfi state and
+ * interrupts and globally unlocked .
+ */
+
+/* XXX temporary, for dev only */
+#define CMAC_ARCH_SANITY_CHECK      (1)
+
+/*
+ * There are 3 groups of interrupts:
+ * - BS_CTRL -> bistream controller (FIELD/FRAME/CALLBACK) interrupts which
+ *              are not disabled while in critical section and can be only
+ *              disabled explicitly using NVIC_DisableIRQ or blocked using
+ *              os_arch_cmac_bs_ctrl_irq_block()
+ *              these interrupts cannot call functions that access OS or other
+ *              shared data
+ * - HI_PRIO -> SW_MAC interrupt which is disabled in critical section like
+ *              other interrupts, but will be enabled when executing idle
+ *              entry/exit code so it is not affected by increased latency
+ *              introduced by that code
+ *              this interrupt can safely access OS and other shared data,
+ *              except for functions that need accurate os_time since system
+ *              tick may be not up to date
+ * - OTHER   -> all other interrupts
+ */
+
+/*
+ * XXX for now add crypto to bs_ctrl although it probably should have separate
+ *     group since it's perfectly fine for it to be enabled during handover
+ */
+#define CMAC_ARCH_I_BS_CTRL         (0x0107)
+#define CMAC_ARCH_I_HI_PRIO         (0x0020)
+#define CMAC_ARCH_I_OTHER           (0x1ed8)
+#define CMAC_ARCH_I_NON_BS_CTRL     (CMAC_ARCH_I_HI_PRIO | \
+                                     CMAC_ARCH_I_OTHER)
+#define CMAC_ARCH_I_ALL             (CMAC_ARCH_I_BS_CTRL | \
+                                     CMAC_ARCH_I_HI_PRIO | \
+                                     CMAC_ARCH_I_OTHER)
+#define CMAC_ARCH_F_PRIMASK         (0x0001)
+#define CMAC_ARCH_F_PENDSV          (0x0002)
+#define CMAC_ARCH_F_IDLE_SECTION    (0x0004)
+#define CMAC_ARCH_F_BS_CTRL_BLOCKED (0x0008)
+
+static uint16_t g_cmac_arch_flags;
+static uint16_t g_cmac_arch_iser_shadow;
+
+extern int cmac_sleep_do_sleep(void) __attribute__((naked));
+
+os_sr_t
+os_arch_save_sr(void)
+{
+    uint32_t ctx;
+
+    __disable_irq();
+
+    ctx = g_cmac_arch_flags & CMAC_ARCH_F_PRIMASK;
+
+#if CMAC_ARCH_SANITY_CHECK
+    assert(!ctx ||
+           (!(g_cmac_arch_flags & CMAC_ARCH_F_IDLE_SECTION) && !(NVIC->ISER[0] & CMAC_ARCH_I_NON_BS_CTRL)) ||
+           ((g_cmac_arch_flags & CMAC_ARCH_F_IDLE_SECTION) && !(NVIC->ISER[0] & CMAC_ARCH_I_OTHER)));
+#endif
+
+    if (g_cmac_arch_flags & CMAC_ARCH_F_IDLE_SECTION) {
+        NVIC->ICER[0] = CMAC_ARCH_I_OTHER;
+    } else {
+        NVIC->ICER[0] = CMAC_ARCH_I_NON_BS_CTRL;
+    }
+    g_cmac_arch_flags |= CMAC_ARCH_F_PRIMASK;
+
+    __enable_irq();
+
+    return ctx;
+}
+
+void
+os_arch_restore_sr(os_sr_t ctx)
+{
+    if (ctx) {
+        return;
+    }
+
+#if CMAC_ARCH_SANITY_CHECK
+    assert(g_cmac_arch_flags & CMAC_ARCH_F_PRIMASK);
+    assert(!(NVIC->ISER[0] & CMAC_ARCH_I_NON_BS_CTRL));
+#endif
+
+    __disable_irq();
+
+    if (g_cmac_arch_flags & CMAC_ARCH_F_PENDSV) {
+        SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
+    }
+    g_cmac_arch_flags &= ~(CMAC_ARCH_F_PRIMASK | CMAC_ARCH_F_PENDSV);
+
+    NVIC->ISER[0] = g_cmac_arch_iser_shadow & CMAC_ARCH_I_NON_BS_CTRL;
+
+    __enable_irq();
+}
+
+int
+os_arch_in_critical(void)
+{
+    return g_cmac_arch_flags & CMAC_ARCH_F_PRIMASK;
+}
+
+void
+os_arch_cmac_enable_irq(IRQn_Type irqn)
+{
+    uint32_t irqm = 1 << irqn;
+
+    __disable_irq();
+
+    g_cmac_arch_iser_shadow |= irqm;
+
+    /*
+     * Enable interrupt in NVIC if either::

Review comment:
       double double colon

##########
File path: hw/mcu/dialog/cmac/src/hal_timer.c
##########
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <stdint.h>
+#include "syscfg/syscfg.h"
+#include "mcu/mcu.h"
+#include "mcu/cmac_hal.h"
+#include "mcu/cmac_timer.h"
+#include "hal/hal_timer.h"
+#include "sys/queue.h"
+#include "defs/error.h"
+#include "os/os_arch.h"
+#include "os/util.h"
+
+#define TICKS_GT(_t1, _t2)          ((int64_t)((_t1) - (_t2)) > 0)
+#define TICKS_GTE(_t1, _t2)         ((int64_t)((_t1) - (_t2)) >= 0)
+#define TICKS_LT(_t1, _t2)          ((int64_t)((_t1) - (_t2)) < 0)
+#define TICKS_LTE(_t1, _t2)         ((int64_t)((_t1) - (_t2)) <= 0)
+
+static TAILQ_HEAD(hal_timer_qhead, hal_timer) g_hal_timer_queue;
+
+/*
+ * To avoid converting back and forth between uint64_t values returned by
+ * cmac_timer and uint32_t representing hal_timer ticks, we compare cmac_timer
+ * ticks everywhere. For this we need to store expiry value as uint64_t, so we
+ * use bsp_timer (which is not used here since we only have one timer) pointer
+ * to store high word of value.
+ */
+
+static inline uint64_t
+hal_timer_expiry_get(struct hal_timer *timer)
+{
+    uint64_t ret;
+
+    ret = (uint64_t)POINTER_TO_UINT(timer->bsp_timer) << 10;
+    ret |= timer->expiry;
+
+    return ret;
+}
+
+static inline void
+hal_timer_expiry_set(struct hal_timer *timer, uint64_t val)
+{
+    timer->expiry = val & 0x3ff;
+    timer->bsp_timer = UINT_TO_POINTER(val >> 10);
+}
+
+static void
+hal_timer_check_queue(void)
+{
+    os_sr_t sr;
+    struct hal_timer *e;
+    uint64_t ll_timer_val;
+
+    OS_ENTER_CRITICAL(sr);
+
+    while ((e = TAILQ_FIRST(&g_hal_timer_queue)) != NULL) {
+        ll_timer_val = cmac_timer_read64();
+        if (TICKS_GT(hal_timer_expiry_get(e), ll_timer_val)) {
+            break;
+        }
+
+        TAILQ_REMOVE(&g_hal_timer_queue, e, link);
+        e->link.tqe_prev = NULL;
+        e->cb_func(e->cb_arg);
+    }
+
+    if (e != NULL) {
+        cmac_timer_write_eq_hal_timer(hal_timer_expiry_get(e));
+    } else {
+        cmac_timer_disable_eq_hal_timer();
+    }
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static void
+hal_timer_cmac_timer_cb(void)
+{
+#if MYNEWT_VAL(TIMER_0)
+    hal_timer_check_queue();
+#endif
+}
+
+int
+hal_timer_init(int timer_num, void *cfg)
+{
+    assert(timer_num == 0);
+
+    cmac_timer_int_hal_timer_register(hal_timer_cmac_timer_cb);
+
+    TAILQ_INIT(&g_hal_timer_queue);
+
+    return 0;
+}
+
+int
+hal_timer_config(int timer_num, uint32_t freq_hz)
+{
+    assert(timer_num == 0);
+    assert(freq_hz == 32768);
+
+    return 0;
+}
+
+int
+hal_timer_set_cb(int timer_num, struct hal_timer *timer, hal_timer_cb func,
+                 void *arg)
+{
+    assert(timer_num == 0);
+
+    timer->cb_func = func;
+    timer->cb_arg = arg;
+    timer->link.tqe_prev = NULL;
+
+    return 0;
+}
+
+int
+hal_timer_start_at(struct hal_timer *timer, uint32_t tick)
+{
+    struct hal_timer *e;

Review comment:
       ``e`` is strange choice of a name :)




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org