You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2023/05/07 13:15:49 UTC
[mynewt-core] branch master updated: hw/drivers: Add ipc_cmac driver
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push:
new 24d9c3b3c hw/drivers: Add ipc_cmac driver
24d9c3b3c is described below
commit 24d9c3b3c1699fba734a2dc3e37935ff27ee04e3
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Tue Jan 3 16:21:47 2023 +0100
hw/drivers: Add ipc_cmac driver
This adds ipc_cmac driver which is basically cmac_driver moved from
nimble repo and with some extra changes to make configuration easier.
The structure of image header for CMAC image is modified to allow host
detect configuration of CMAC image. This means there's no need to sync
configuration on M33 and CMAC targets manually, it's enough to configure
CMAC image and M33 will detect configuration in runtime.
---
.../dialog/cmac => drivers/ipc_cmac/diag}/pkg.yml | 13 +-
hw/drivers/ipc_cmac/diag/src/cmac_diag.c | 66 +++
.../ipc_cmac/include/ipc_cmac/diag.h} | 42 +-
.../ipc_cmac/include/ipc_cmac/mbox.h} | 46 +-
.../ipc_cmac/include/ipc_cmac/rand.h} | 60 ++-
hw/drivers/ipc_cmac/include/ipc_cmac/shm.h | 146 +++++++
hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h | 47 ++
hw/drivers/ipc_cmac/include/ipc_cmac/shm_ll.h | 86 ++++
hw/{mcu/dialog/cmac => drivers/ipc_cmac}/pkg.yml | 27 +-
hw/drivers/ipc_cmac/scripts/build_libcmac.sh | 47 ++
.../ipc_cmac/scripts/create_cmac_bin.sh} | 28 +-
hw/drivers/ipc_cmac/src/mbox.c | 185 ++++++++
hw/drivers/ipc_cmac/src/rand.c | 147 +++++++
hw/drivers/ipc_cmac/src/shm_hs.c | 475 +++++++++++++++++++++
hw/drivers/ipc_cmac/src/shm_ll.c | 82 ++++
hw/drivers/ipc_cmac/syscfg.yml | 104 +++++
hw/mcu/dialog/cmac/cmac.ld | 33 +-
hw/mcu/dialog/cmac/pkg.yml | 1 +
.../cmac/src/arch/cortex_m0_cmac/os_arch_arm.c | 2 +-
.../dialog/cmac/src/arch/cortex_m0_cmac/os_fault.c | 29 +-
hw/mcu/dialog/cmac/src/cmac_isr.c | 21 +-
hw/mcu/dialog/cmac/src/cmac_sleep.c | 18 +-
hw/mcu/dialog/cmac/src/cmac_timer.c | 4 +-
hw/mcu/dialog/cmac/src/system_cmac.c | 2 +-
hw/mcu/dialog/da1469x/da1469x.ld | 2 +-
25 files changed, 1532 insertions(+), 181 deletions(-)
diff --git a/hw/mcu/dialog/cmac/pkg.yml b/hw/drivers/ipc_cmac/diag/pkg.yml
similarity index 74%
copy from hw/mcu/dialog/cmac/pkg.yml
copy to hw/drivers/ipc_cmac/diag/pkg.yml
index fc046095c..f6363d041 100644
--- a/hw/mcu/dialog/cmac/pkg.yml
+++ b/hw/drivers/ipc_cmac/diag/pkg.yml
@@ -17,19 +17,12 @@
# under the License.
#
-pkg.name: hw/mcu/dialog/cmac
-pkg.description: MCU definition for Dialog CMAC (Cortex-M0+ core)
+pkg.name: hw/drivers/ipc_cmac/diag
+pkg.description: Default diag configuration for CMAC
pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
- dialog
- da1469x
- cmac
-
-pkg.deps:
- - "@apache-mynewt-core/hw/cmsis-core"
- - "@apache-mynewt-core/hw/hal"
- - "@apache-mynewt-core/hw/mcu/dialog"
- - "@apache-mynewt-nimble/nimble/drivers/dialog_cmac"
-
-pkg.cflags: -I@apache-mynewt-core/kernel
+pkg.apis: dialog_cmac_diag
diff --git a/hw/drivers/ipc_cmac/diag/src/cmac_diag.c b/hw/drivers/ipc_cmac/diag/src/cmac_diag.c
new file mode 100644
index 000000000..83299038d
--- /dev/null
+++ b/hw/drivers/ipc_cmac/diag/src/cmac_diag.c
@@ -0,0 +1,66 @@
+/*
+ * 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 "syscfg/syscfg.h"
+#include "mcu/mcu.h"
+
+#if MYNEWT_VAL(BLE_CONTROLLER)
+void
+cmac_diag_setup_cmac(void)
+{
+ MCU_DIAG_MAP( 0, 4, DSER);
+ MCU_DIAG_MAP( 1, 6, CMAC_ON_ERROR);
+ MCU_DIAG_MAP( 2, 2, PHY_TX_EN);
+ MCU_DIAG_MAP( 3, 2, PHY_RX_EN);
+ MCU_DIAG_MAP( 4, 2, PHY_TXRX_DATA_COMB);
+ MCU_DIAG_MAP( 5, 2, PHY_TXRX_DATA_EN_COMB);
+ MCU_DIAG_MAP( 6, 5, EV1US_FRAME_START);
+ MCU_DIAG_MAP( 7, 5, EV_BS_START);
+ MCU_DIAG_MAP( 8, 5, EV1C_BS_STOP);
+ MCU_DIAG_MAP( 9, 5, EV1US_PHY_TO_IDLE);
+ MCU_DIAG_MAP(10, 9, CALLBACK_IRQ);
+ MCU_DIAG_MAP(11, 9, FIELD_IRQ);
+ MCU_DIAG_MAP(12, 9, FRAME_IRQ);
+ MCU_DIAG_MAP(13, 3, SLP_TIMER_ACTIVE);
+ MCU_DIAG_MAP(14, 4, SLEEPING);
+ MCU_DIAG_MAP(15, 8, LL_TIMER1_00);
+}
+#else
+void
+cmac_diag_setup_host(void)
+{
+ /* Setup pins for diagnostic signals */
+ mcu_gpio_set_pin_function(42, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG0); /* DIAG_0 @ P1.10 */
+ mcu_gpio_set_pin_function(43, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG1); /* DIAG_1 @ P1.11 */
+ mcu_gpio_set_pin_function(44, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAG2); /* DIAG_2 @ P1.12 */
+ mcu_gpio_set_pin_function(24, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_3 @ P0.24 */
+ mcu_gpio_set_pin_function(21, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_4 @ P0.21 */
+ mcu_gpio_set_pin_function(20, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_5 @ P0.20 */
+ mcu_gpio_set_pin_function(19, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_6 @ P0.19 */
+ mcu_gpio_set_pin_function(18, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_7 @ P0.18 */
+ mcu_gpio_set_pin_function(31, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_8 @ P0.31 */
+ mcu_gpio_set_pin_function(30, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_9 @ P0.30 */
+ mcu_gpio_set_pin_function(29, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_10 @ P0.29 */
+ mcu_gpio_set_pin_function(28, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_11 @ P0.28 */
+ mcu_gpio_set_pin_function(27, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_12 @ P0.27 */
+ mcu_gpio_set_pin_function(26, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_13 @ P0.26 */
+ mcu_gpio_set_pin_function(38, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_14 @ P1.06 */
+ mcu_gpio_set_pin_function(41, MCU_GPIO_MODE_OUTPUT, MCU_GPIO_FUNC_CMAC_DIAGX); /* DIAG_15 @ P1.09 */
+}
+#endif
diff --git a/hw/mcu/dialog/cmac/src/cmac_isr.c b/hw/drivers/ipc_cmac/include/ipc_cmac/diag.h
similarity index 50%
copy from hw/mcu/dialog/cmac/src/cmac_isr.c
copy to hw/drivers/ipc_cmac/include/ipc_cmac/diag.h
index 9d90ab9e2..dc6ee903d 100644
--- a/hw/mcu/dialog/cmac/src/cmac_isr.c
+++ b/hw/drivers/ipc_cmac/include/ipc_cmac/diag.h
@@ -17,38 +17,18 @@
* under the License.
*/
-#include "mcu/mcu.h"
-#include "mcu/cmac_pdc.h"
-#include "cmac_driver/cmac_shared.h"
-#include "cmac_priv.h"
-#include "CMAC.h"
+#ifndef __MCU_CMAC_DIAG_H_
+#define __MCU_CMAC_DIAG_H_
-extern void ble_rf_calibrate_req(void);
+#ifdef __cplusplus
+extern "C" {
+#endif
-void
-SYS2CMAC_IRQHandler(void)
-{
- uint16_t pending_ops;
+void cmac_diag_setup_host(void);
+void cmac_diag_setup_cmac(void);
- if (CMAC->CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_SYS2CMAC_Msk) {
- cmac_shared_lock();
- pending_ops = g_cmac_shared_data.pending_ops;
- g_cmac_shared_data.pending_ops = 0;
- cmac_shared_unlock();
-
- cmac_mbox_read();
- cmac_rand_read();
-
- if (pending_ops & CMAC_PENDING_OP_LP_CLK) {
- cmac_sleep_recalculate();
- }
-
- if (pending_ops & CMAC_PENDING_OP_RF_CAL) {
- ble_rf_calibrate_req();
- }
-
- CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_SYS2CMAC_Msk;
- }
-
- cmac_pdc_ack_all();
+#ifdef __cplusplus
}
+#endif
+
+#endif /* __MCU_CMAC_DIAG_H_ */
diff --git a/hw/mcu/dialog/cmac/src/cmac_isr.c b/hw/drivers/ipc_cmac/include/ipc_cmac/mbox.h
similarity index 50%
copy from hw/mcu/dialog/cmac/src/cmac_isr.c
copy to hw/drivers/ipc_cmac/include/ipc_cmac/mbox.h
index 9d90ab9e2..7e904a72c 100644
--- a/hw/mcu/dialog/cmac/src/cmac_isr.c
+++ b/hw/drivers/ipc_cmac/include/ipc_cmac/mbox.h
@@ -17,38 +17,26 @@
* under the License.
*/
-#include "mcu/mcu.h"
-#include "mcu/cmac_pdc.h"
-#include "cmac_driver/cmac_shared.h"
-#include "cmac_priv.h"
-#include "CMAC.h"
+#ifndef __IPC_CMAC_SHM_MBOX_H_
+#define __IPC_CMAC_SHM_MBOX_H_
-extern void ble_rf_calibrate_req(void);
+#include <stdint.h>
+#include "syscfg/syscfg.h"
-void
-SYS2CMAC_IRQHandler(void)
-{
- uint16_t pending_ops;
+#ifdef __cplusplus
+extern "C" {
+#endif
- if (CMAC->CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_SYS2CMAC_Msk) {
- cmac_shared_lock();
- pending_ops = g_cmac_shared_data.pending_ops;
- g_cmac_shared_data.pending_ops = 0;
- cmac_shared_unlock();
+typedef int (cmac_mbox_read_cb)(const void *data, uint16_t len);
+typedef void (cmac_mbox_write_notif_cb)(void);
- cmac_mbox_read();
- cmac_rand_read();
+int cmac_mbox_has_data(void);
+void cmac_mbox_cb_set(cmac_mbox_read_cb *read, cmac_mbox_write_notif_cb *write);
+int cmac_mbox_read(void);
+int cmac_mbox_write(const void *data, uint16_t len);
- if (pending_ops & CMAC_PENDING_OP_LP_CLK) {
- cmac_sleep_recalculate();
- }
-
- if (pending_ops & CMAC_PENDING_OP_RF_CAL) {
- ble_rf_calibrate_req();
- }
-
- CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_SYS2CMAC_Msk;
- }
-
- cmac_pdc_ack_all();
+#ifdef __cplusplus
}
+#endif
+
+#endif /* __IPC_CMAC_SHM_MBOX_H_ */
diff --git a/hw/mcu/dialog/cmac/src/cmac_isr.c b/hw/drivers/ipc_cmac/include/ipc_cmac/rand.h
similarity index 50%
copy from hw/mcu/dialog/cmac/src/cmac_isr.c
copy to hw/drivers/ipc_cmac/include/ipc_cmac/rand.h
index 9d90ab9e2..a018e684e 100644
--- a/hw/mcu/dialog/cmac/src/cmac_isr.c
+++ b/hw/drivers/ipc_cmac/include/ipc_cmac/rand.h
@@ -17,38 +17,30 @@
* under the License.
*/
-#include "mcu/mcu.h"
-#include "mcu/cmac_pdc.h"
-#include "cmac_driver/cmac_shared.h"
-#include "cmac_priv.h"
-#include "CMAC.h"
-
-extern void ble_rf_calibrate_req(void);
-
-void
-SYS2CMAC_IRQHandler(void)
-{
- uint16_t pending_ops;
-
- if (CMAC->CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_SYS2CMAC_Msk) {
- cmac_shared_lock();
- pending_ops = g_cmac_shared_data.pending_ops;
- g_cmac_shared_data.pending_ops = 0;
- cmac_shared_unlock();
-
- cmac_mbox_read();
- cmac_rand_read();
-
- if (pending_ops & CMAC_PENDING_OP_LP_CLK) {
- cmac_sleep_recalculate();
- }
-
- if (pending_ops & CMAC_PENDING_OP_RF_CAL) {
- ble_rf_calibrate_req();
- }
-
- CMAC->CM_EXC_STAT_REG = CMAC_CM_EXC_STAT_REG_EXC_SYS2CMAC_Msk;
- }
-
- cmac_pdc_ack_all();
+#ifndef __IPC_CMAC_SHM_RAND_H_
+#define __IPC_CMAC_SHM_RAND_H_
+
+#include <syscfg/syscfg.h>
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*cmac_rand_isr_cb_t)(uint8_t rnum);
+void cmac_rand_start(void);
+void cmac_rand_stop(void);
+void cmac_rand_read(void);
+void cmac_rand_write(void);
+void cmac_rand_chk_fill(void);
+int cmac_rand_get_next(void);
+int cmac_rand_is_active(void);
+int cmac_rand_is_full(void);
+void cmac_rand_fill(uint32_t *buf, int num_words);
+void cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb);
+
+#ifdef __cplusplus
}
+#endif
+
+#endif /* __IPC_CMAC_SHM_RAND_H_ */
diff --git a/hw/drivers/ipc_cmac/include/ipc_cmac/shm.h b/hw/drivers/ipc_cmac/include/ipc_cmac/shm.h
new file mode 100644
index 000000000..c28f32798
--- /dev/null
+++ b/hw/drivers/ipc_cmac/include/ipc_cmac/shm.h
@@ -0,0 +1,146 @@
+/*
+ * 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 __IPC_CMAC_SHM_H_
+#define __IPC_CMAC_SHM_H_
+
+#include <stdint.h>
+#include <syscfg/syscfg.h>
+#if MYNEWT_VAL(BLE_CONTROLLER)
+#include <ipc_cmac/shm_ll.h>
+#else
+#include <ipc_cmac/shm_hs.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MEMCTRL_BSR_SET_REG (*(volatile uint32_t *)0x50050074)
+#define MEMCTRL_BSR_STAT_REG (*(volatile uint32_t *)0x5005007c)
+#define MEMCTRL_BSR_RESET_REG (*(volatile uint32_t *)0x50050078)
+
+#define CMAC_SHM_CB_MAGIC 0xc3ac
+
+#define CMAC_SHM_CB_PENDING_OP_LP_CLK 0x0001
+#define CMAC_SHM_CB_PENDING_OP_RF_CAL 0x0002
+
+#define CMAC_SHM_VECT_MAGIC 0xc3ac0001
+#define CMAC_SHM_VECT_CRASHINFO 0x00000001
+#define CMAC_SHM_VECT_DEBUGDATA 0x00000002
+
+struct cmac_shm_config {
+ uint16_t mbox_s2c_size;
+ uint16_t mbox_c2s_size;
+ uint8_t trim_rfcu_size;
+ uint8_t trim_rfcu_mode1_size;
+ uint8_t trim_rfcu_mode2_size;
+ uint8_t trim_synth_size;
+ uint16_t rand_size;
+};
+
+struct cmac_shm_ctrl {
+ uint16_t magic;
+ uint16_t pending_ops;
+ uint16_t lp_clock_freq;
+ uint16_t xtal32m_settle_us;
+};
+
+struct cmac_shm_mbox {
+ uint16_t rd_off;
+ uint16_t wr_off;
+ uint8_t data[];
+};
+
+struct cmac_shm_trim {
+ uint8_t rfcu_len;
+ uint8_t rfcu_mode1_len;
+ uint8_t rfcu_mode2_len;
+ uint8_t synth_len;
+ uint32_t data[];
+};
+
+struct cmac_shm_rand {
+ uint16_t cmr_active;
+ uint16_t cmr_in;
+ uint16_t cmr_out;
+ uint32_t cmr_buf[];
+};
+
+struct cmac_shm_dcdc {
+ uint8_t enabled;
+ uint32_t v18;
+ uint32_t v18p;
+ uint32_t vdd;
+ uint32_t v14;
+ uint32_t ctrl1;
+};
+
+struct cmac_shm_crashinfo {
+ uint32_t lr;
+ uint32_t pc;
+ uint32_t assert;
+ const char *assert_file;
+ uint32_t assert_line;
+
+ uint32_t CM_STAT_REG;
+ uint32_t CM_LL_TIMER1_36_10_REG;
+ uint32_t CM_LL_TIMER1_9_0_REG;
+ uint32_t CM_ERROR_REG;
+ uint32_t CM_EXC_STAT_REG;
+};
+
+struct cmac_shm_debugdata {
+ int8_t tx_power_ovr_enable;
+ int8_t tx_power_ovr;
+ int8_t last_rx_rssi;
+
+ uint32_t cal_res_1;
+ uint32_t cal_res_2;
+ uint32_t trim_val1_tx_1;
+ uint32_t trim_val1_tx_2;
+ uint32_t trim_val2_tx;
+ uint32_t trim_val2_rx;
+};
+
+static inline void
+cmac_shm_lock(void)
+{
+ while ((MEMCTRL_BSR_STAT_REG & 0xc0000000) != CMAC_SHM_LOCK_VAL) {
+ MEMCTRL_BSR_SET_REG = CMAC_SHM_LOCK_VAL;
+ }
+}
+
+static inline void
+cmac_shm_unlock(void)
+{
+ MEMCTRL_BSR_RESET_REG = CMAC_SHM_LOCK_VAL;
+}
+
+#if MYNEWT_VAL(BLE_CONTROLLER)
+void cmac_shm_ll_ready(void);
+#else
+void cmac_shm_hs_ready(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IPC_CMAC_SHM_H_ */
diff --git a/hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h b/hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h
new file mode 100644
index 000000000..1de158a94
--- /dev/null
+++ b/hw/drivers/ipc_cmac/include/ipc_cmac/shm_hs.h
@@ -0,0 +1,47 @@
+/*
+ * 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 __IPC_CMAC_SHM_HS_H_
+#define __IPC_CMAC_SHM_HS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CMAC_SHM_LOCK_VAL 0x40000000
+
+extern volatile struct cmac_shm_config *g_cmac_shm_config;
+extern volatile struct cmac_shm_ctrl *g_cmac_shm_ctrl;
+extern volatile struct cmac_shm_mbox *g_cmac_shm_mbox_s2c;
+extern volatile struct cmac_shm_mbox *g_cmac_shm_mbox_c2s;
+extern volatile struct cmac_shm_dcdc *g_cmac_shm_dcdc;
+extern volatile struct cmac_shm_trim *g_cmac_shm_trim;
+extern volatile struct cmac_shm_rand *g_cmac_shm_rand;
+extern volatile struct cmac_shm_crashinfo *g_cmac_shm_crashinfo;
+extern volatile struct cmac_shm_debugdata *g_cmac_shm_debugdata;
+
+void cmac_host_init(void);
+void cmac_host_signal2cmac(void);
+void cmac_host_rf_calibrate(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IPC_CMAC_SHM_HS_H_ */
diff --git a/hw/drivers/ipc_cmac/include/ipc_cmac/shm_ll.h b/hw/drivers/ipc_cmac/include/ipc_cmac/shm_ll.h
new file mode 100644
index 000000000..465c7bb56
--- /dev/null
+++ b/hw/drivers/ipc_cmac/include/ipc_cmac/shm_ll.h
@@ -0,0 +1,86 @@
+/*
+ * 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 __IPC_CMAC_SHM_LL_H_
+#define __IPC_CMAC_SHM_LL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CMAC_SHM_LOCK_VAL 0xc0000000
+
+#define CMAC_SHM_MBOX_S2C_SIZE MYNEWT_VAL(CMAC_MBOX_SIZE_S2C)
+#define CMAC_SHM_MBOX_C2S_SIZE MYNEWT_VAL(CMAC_MBOX_SIZE_C2S)
+#define CMAC_SHM_TRIM_RFCU_SIZE MYNEWT_VAL(CMAC_TRIM_SIZE_RFCU)
+#define CMAC_SHM_TRIM_RFCU1_SIZE 2
+#define CMAC_SHM_TRIM_RFCU2_SIZE 2
+#define CMAC_SHM_TRIM_SYNTH_SIZE MYNEWT_VAL(CMAC_TRIM_SIZE_SYNTH)
+#define CMAC_SHM_RAND_SIZE 16
+
+struct cmac_shm_ll_mbox_s2c {
+ uint16_t rd_off;
+ uint16_t wr_off;
+ uint8_t data[CMAC_SHM_MBOX_S2C_SIZE];
+};
+
+struct cmac_shm_ll_mbox_c2s {
+ uint16_t rd_off;
+ uint16_t wr_off;
+ uint8_t data[CMAC_SHM_MBOX_C2S_SIZE];
+};
+
+struct cmac_shm_ll_trim {
+ uint8_t rfcu_len;
+ uint8_t rfcu_mode1_len;
+ uint8_t rfcu_mode2_len;
+ uint8_t synth_len;
+ uint32_t rfcu[CMAC_SHM_TRIM_RFCU_SIZE];
+ uint32_t rfcu_mode1[CMAC_SHM_TRIM_RFCU1_SIZE];
+ uint32_t rfcu_mode2[CMAC_SHM_TRIM_RFCU2_SIZE];
+ uint32_t synth[CMAC_SHM_TRIM_SYNTH_SIZE];
+};
+
+struct cmac_shm_ll_rand {
+ uint16_t cmr_active;
+ uint16_t cmr_in;
+ uint16_t cmr_out;
+ uint32_t cmr_buf[CMAC_SHM_RAND_SIZE];
+};
+
+extern volatile struct cmac_shm_ctrl g_cmac_shm_ctrl;
+extern volatile struct cmac_shm_ll_mbox_s2c g_cmac_shm_mbox_s2c;
+extern volatile struct cmac_shm_ll_mbox_c2s g_cmac_shm_mbox_c2s;
+extern volatile struct cmac_shm_dcdc g_cmac_shm_dcdc;
+extern volatile struct cmac_shm_ll_trim g_cmac_shm_trim;
+extern volatile struct cmac_shm_ll_rand g_cmac_shm_rand;
+#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE)
+extern volatile struct cmac_shm_crashinfo g_cmac_shm_crashinfo;
+#endif
+#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE)
+extern volatile struct cmac_shm_debugdata g_cmac_shm_debugdata;
+#endif
+
+void cmac_shm_ll_ready(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IPC_CMAC_SHM_LL_H_ */
diff --git a/hw/mcu/dialog/cmac/pkg.yml b/hw/drivers/ipc_cmac/pkg.yml
similarity index 67%
copy from hw/mcu/dialog/cmac/pkg.yml
copy to hw/drivers/ipc_cmac/pkg.yml
index fc046095c..7eb2443d5 100644
--- a/hw/mcu/dialog/cmac/pkg.yml
+++ b/hw/drivers/ipc_cmac/pkg.yml
@@ -6,7 +6,7 @@
# 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,
@@ -17,19 +17,20 @@
# under the License.
#
-pkg.name: hw/mcu/dialog/cmac
-pkg.description: MCU definition for Dialog CMAC (Cortex-M0+ core)
+pkg.name: hw/drivers/ipc_cmac
+pkg.description:
pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
+pkg.homepage: "https://mynewt.apache.org/"
pkg.keywords:
- - dialog
- - da1469x
- - cmac
-pkg.deps:
- - "@apache-mynewt-core/hw/cmsis-core"
- - "@apache-mynewt-core/hw/hal"
- - "@apache-mynewt-core/hw/mcu/dialog"
- - "@apache-mynewt-nimble/nimble/drivers/dialog_cmac"
+pkg.ign_files.BSP_dialog_cmac:
+ - shm_hs.c
+
+pkg.ign_files.'!BSP_dialog_cmac':
+ - shm_ll.c
+
+pkg.post_link_cmds.BLE_CONTROLLER:
+ scripts/create_cmac_bin.sh: 100
-pkg.cflags: -I@apache-mynewt-core/kernel
+pkg.pre_link_cmds.!BLE_CONTROLLER:
+ scripts/build_libcmac.sh: 100
diff --git a/hw/drivers/ipc_cmac/scripts/build_libcmac.sh b/hw/drivers/ipc_cmac/scripts/build_libcmac.sh
new file mode 100755
index 000000000..ca19aab17
--- /dev/null
+++ b/hw/drivers/ipc_cmac/scripts/build_libcmac.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# 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.
+
+NEWT=${MYNEWT_NEWT_PATH}
+OBJCOPY=${MYNEWT_OBJCOPY_PATH}
+AR=${MYNEWT_AR_PATH}
+LIBCMAC_A=${MYNEWT_USER_SRC_DIR}/libcmac.a
+
+export WORK_DIR=${MYNEWT_USER_WORK_DIR}
+export BASENAME_IMG=cmac.img
+export BASENAME_RAM=cmac.ram
+
+if [ ${MYNEWT_VAL_CMAC_IMAGE_SINGLE} -eq 0 ]; then
+ # Create empty image binary (1 byte required for objcopy)
+ truncate -s 1 ${WORK_DIR}/${BASENAME_IMG}.bin
+ # Create fixed size RAM image
+ truncate -s ${MYNEWT_VAL_CMAC_IMAGE_RAM_SIZE} ${WORK_DIR}/${BASENAME_RAM}.bin
+else
+ cd ${MYNEWT_PROJECT_ROOT}
+ ${NEWT} build ${MYNEWT_VAL_CMAC_IMAGE_TARGET_NAME}
+fi
+
+cd ${WORK_DIR}
+
+# Convert both binaries to objects and create archive to link
+${OBJCOPY} -I binary -O elf32-littlearm -B armv8-m.main \
+ --rename-section .data=.libcmac.img ${BASENAME_IMG}.bin ${BASENAME_IMG}.o
+${OBJCOPY} -I binary -O elf32-littlearm -B armv8-m.main \
+ --rename-section .data=.libcmac.ram ${BASENAME_RAM}.bin ${BASENAME_RAM}.o
+${AR} -rcs ${LIBCMAC_A} ${BASENAME_IMG}.o ${BASENAME_RAM}.o
+cp ${LIBCMAC_A} ${MYNEWT_APP_BIN_DIR}
diff --git a/hw/mcu/dialog/cmac/pkg.yml b/hw/drivers/ipc_cmac/scripts/create_cmac_bin.sh
old mode 100644
new mode 100755
similarity index 62%
copy from hw/mcu/dialog/cmac/pkg.yml
copy to hw/drivers/ipc_cmac/scripts/create_cmac_bin.sh
index fc046095c..45cc226db
--- a/hw/mcu/dialog/cmac/pkg.yml
+++ b/hw/drivers/ipc_cmac/scripts/create_cmac_bin.sh
@@ -1,4 +1,5 @@
-#
+#!/bin/bash
+
# 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
@@ -15,21 +16,16 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-#
-pkg.name: hw/mcu/dialog/cmac
-pkg.description: MCU definition for Dialog CMAC (Cortex-M0+ core)
-pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
- - dialog
- - da1469x
- - cmac
+OBJCOPY=${MYNEWT_OBJCOPY_PATH}
+ELF=${MYNEWT_APP_BIN_DIR}/blehci.elf
+
+cd ${WORK_DIR}
-pkg.deps:
- - "@apache-mynewt-core/hw/cmsis-core"
- - "@apache-mynewt-core/hw/hal"
- - "@apache-mynewt-core/hw/mcu/dialog"
- - "@apache-mynewt-nimble/nimble/drivers/dialog_cmac"
+# Create image by stripping .ram section
+${OBJCOPY} -R .ram -O binary ${ELF} ${BASENAME_IMG}.bin
+# RAM image is the same as binary created by newt
+cp ${ELF}.bin ${BASENAME_RAM}.bin
-pkg.cflags: -I@apache-mynewt-core/kernel
+# Create a copy of image to flash to partition, if required
+cp ${BASENAME_IMG}.bin ${ELF}.img.bin
diff --git a/hw/drivers/ipc_cmac/src/mbox.c b/hw/drivers/ipc_cmac/src/mbox.c
new file mode 100644
index 000000000..d38b68d32
--- /dev/null
+++ b/hw/drivers/ipc_cmac/src/mbox.c
@@ -0,0 +1,185 @@
+/*
+ * 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 <stdint.h>
+#include <string.h>
+#include <syscfg/syscfg.h>
+#include <ipc_cmac/shm.h>
+#include <ipc_cmac/mbox.h>
+#include <os/os.h>
+
+static cmac_mbox_read_cb *g_cmac_mbox_read_cb;
+static cmac_mbox_write_notif_cb *g_cmac_mbox_write_notif_cb;
+
+static struct cmac_shm_mbox *
+mbox_src_get(uint16_t *size)
+{
+#if MYNEWT_VAL(BLE_CONTROLLER)
+ struct cmac_shm_mbox *mbox = (struct cmac_shm_mbox *)&g_cmac_shm_mbox_s2c;
+ *size = MYNEWT_VAL(CMAC_MBOX_SIZE_S2C);
+#else
+ struct cmac_shm_mbox *mbox = (struct cmac_shm_mbox *)g_cmac_shm_mbox_c2s;
+ *size = g_cmac_shm_config->mbox_c2s_size;
+#endif
+
+ return mbox;
+}
+
+static struct cmac_shm_mbox *
+mbox_dst_get(uint16_t *size)
+{
+#if MYNEWT_VAL(BLE_CONTROLLER)
+ struct cmac_shm_mbox *mbox = (struct cmac_shm_mbox *)&g_cmac_shm_mbox_c2s;
+ *size = MYNEWT_VAL(CMAC_MBOX_SIZE_C2S);
+#else
+ struct cmac_shm_mbox *mbox = (struct cmac_shm_mbox *)g_cmac_shm_mbox_s2c;
+ *size = g_cmac_shm_config->mbox_s2c_size;
+#endif
+
+ return mbox;
+}
+
+int
+cmac_mbox_has_data(void)
+{
+ volatile struct cmac_shm_mbox *mbox;
+ uint16_t mbox_size;
+
+ mbox = mbox_src_get(&mbox_size);
+
+ return mbox->rd_off != mbox->wr_off;
+}
+
+void
+cmac_mbox_cb_set(cmac_mbox_read_cb *read, cmac_mbox_write_notif_cb *write_notif)
+{
+ g_cmac_mbox_read_cb = read;
+ g_cmac_mbox_write_notif_cb = write_notif;
+}
+
+int
+cmac_mbox_read(void)
+{
+ volatile struct cmac_shm_mbox *mbox;
+ uint16_t mbox_size;
+ uint8_t *mbox_buf;
+ uint16_t rd_off;
+ uint16_t wr_off;
+ uint16_t chunk;
+ int len = 0;
+
+ mbox = mbox_src_get(&mbox_size);
+ /* no need for volatile on data buffer */
+ mbox_buf = (void *)mbox->data;
+
+ if (!g_cmac_mbox_read_cb) {
+ return 0;
+ }
+
+ do {
+ rd_off = mbox->rd_off;
+ wr_off = mbox->wr_off;
+
+ if (rd_off <= wr_off) {
+ chunk = wr_off - rd_off;
+ } else {
+ chunk = mbox_size - rd_off;
+ }
+
+ while (chunk) {
+ len = g_cmac_mbox_read_cb(&mbox_buf[rd_off], chunk);
+ if (len < 0) {
+ break;
+ }
+
+ rd_off += len;
+ chunk -= len;
+ }
+
+ mbox->rd_off = rd_off == mbox_size ? 0 : rd_off;
+ } while ((mbox->rd_off != mbox->wr_off) && (len >= 0));
+
+ return 0;
+}
+
+int
+cmac_mbox_write(const void *data, uint16_t len)
+{
+ volatile struct cmac_shm_mbox *mbox;
+ uint16_t mbox_size;
+ uint8_t *mbox_buf;
+ uint16_t rd_off;
+ uint16_t wr_off;
+ uint16_t max_wr;
+ uint16_t chunk;
+
+ mbox = mbox_dst_get(&mbox_size);
+ /* no need for volatile on data buffer */
+ mbox_buf = (void *)mbox->data;
+
+ while (len) {
+ rd_off = mbox->rd_off;
+ wr_off = mbox->wr_off;
+
+ /*
+ * Calculate maximum length to write, i.e. up to end of buffer or stop
+ * before rd_off to be able to detect full queue.
+ */
+ if (rd_off > wr_off) {
+ /*
+ * |0|1|2|3|4|5|6|7|
+ * | | | |W| | |R| |
+ * `---^
+ */
+ max_wr = rd_off - wr_off - 1;
+ } else if (rd_off == 0) {
+ /*
+ * |0|1|2|3|4|5|6|7|
+ * |R| | |W| | | | |
+ * `-------^
+ */
+ max_wr = mbox_size - wr_off - 1;
+ } else {
+ /*
+ * |0|1|2|3|4|5|6|7|
+ * | |R| |W| | | | |
+ * `---------^
+ */
+ max_wr = mbox_size - wr_off;
+ }
+
+ chunk = min(len, max_wr);
+
+ if (chunk == 0) {
+ continue;
+ }
+
+ memcpy(&mbox_buf[wr_off], data, chunk);
+
+ wr_off += chunk;
+ mbox->wr_off = wr_off == mbox_size ? 0 : wr_off;
+
+ g_cmac_mbox_write_notif_cb();
+
+ len -= chunk;
+ data = (uint8_t *)data + chunk;
+ }
+
+ return 0;
+}
diff --git a/hw/drivers/ipc_cmac/src/rand.c b/hw/drivers/ipc_cmac/src/rand.c
new file mode 100644
index 000000000..b5fb6c0a6
--- /dev/null
+++ b/hw/drivers/ipc_cmac/src/rand.c
@@ -0,0 +1,147 @@
+/*
+ * 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 <string.h>
+#include <stdbool.h>
+#include "syscfg/syscfg.h"
+#include "mcu/mcu.h"
+#include <ipc_cmac/shm.h>
+#include <ipc_cmac/rand.h>
+#include "os/os_arch.h"
+#include "os/os.h"
+
+#if !MYNEWT_VAL(BLE_CONTROLLER)
+int
+cmac_rand_is_active(void)
+{
+ return g_cmac_shm_rand->cmr_active;
+}
+
+int
+cmac_rand_is_full(void)
+{
+ int next;
+ bool rc;
+
+ next = cmac_rand_get_next();
+ if (next == g_cmac_shm_rand->cmr_out) {
+ rc = 1;
+ } else {
+ rc = 0;
+ }
+ return rc;
+}
+
+int
+cmac_rand_get_next(void)
+{
+ int next;
+
+ /* If active and not full, put event on queue to get random numbers */
+ next = g_cmac_shm_rand->cmr_in + 1;
+ if (next == g_cmac_shm_config->rand_size) {
+ next = 0;
+ }
+ return next;
+}
+
+void
+cmac_rand_fill(uint32_t *buf, int num_words)
+{
+ int next;
+
+ /* XXX: if words is 0, is it possible we could get into a state
+ where we are waiting for random numbers but M33 does not know it
+ has to fill any? */
+
+ /* NOTE: we already know the buffer is not full first time through */
+ next = g_cmac_shm_rand->cmr_in;
+ while (num_words) {
+ g_cmac_shm_rand->cmr_buf[next] = buf[0];
+ next = cmac_rand_get_next();
+ g_cmac_shm_rand->cmr_in = next;
+ next = cmac_rand_get_next();
+ if (next == g_cmac_shm_rand->cmr_out) {
+ break;
+ }
+ --num_words;
+ ++buf;
+ }
+}
+#endif
+
+#if MYNEWT_VAL(BLE_CONTROLLER)
+
+static cmac_rand_isr_cb_t g_cmac_shm_rand_isr_cb;
+
+void
+cmac_rand_set_isr_cb(cmac_rand_isr_cb_t cb)
+{
+ g_cmac_shm_rand_isr_cb = cb;
+}
+
+void
+cmac_rand_start(void)
+{
+ g_cmac_shm_rand.cmr_active = 1;
+}
+
+void
+cmac_rand_stop(void)
+{
+ g_cmac_shm_rand.cmr_active = 0;
+}
+
+/**
+ * cmac rnum read
+ *
+ * Called during the system to cmac isr to take random numbers
+ * from shared memory into the BLE stack.
+ */
+void
+cmac_rand_read(void)
+{
+ uint8_t bytes_left;
+ uint32_t rnum;
+
+ /* Just leave if no callback. */
+ if (g_cmac_shm_rand_isr_cb == NULL) {
+ return;
+ }
+
+ bytes_left = 0;
+ while (g_cmac_shm_rand.cmr_active) {
+ if (bytes_left) {
+ --bytes_left;
+ rnum >>= 8;
+ } else if (g_cmac_shm_rand.cmr_out != g_cmac_shm_rand.cmr_in) {
+ bytes_left = 3;
+ rnum = g_cmac_shm_rand.cmr_buf[g_cmac_shm_rand.cmr_out];
+ ++g_cmac_shm_rand.cmr_out;
+ if (g_cmac_shm_rand.cmr_out == CMAC_SHM_RAND_SIZE) {
+ g_cmac_shm_rand.cmr_out = 0;
+ }
+ } else {
+ break;
+ }
+ (*g_cmac_shm_rand_isr_cb)((uint8_t)rnum);
+ }
+}
+#endif
diff --git a/hw/drivers/ipc_cmac/src/shm_hs.c b/hw/drivers/ipc_cmac/src/shm_hs.c
new file mode 100644
index 000000000..f93915bac
--- /dev/null
+++ b/hw/drivers/ipc_cmac/src/shm_hs.c
@@ -0,0 +1,475 @@
+/*
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "syscfg/syscfg.h"
+#include "sysflash/sysflash.h"
+#include "os/os.h"
+#include "mcu/mcu.h"
+#include "mcu/cmsis_nvic.h"
+#include "mcu/da1469x_hal.h"
+#include "mcu/da1469x_lpclk.h"
+#include "mcu/da1469x_clock.h"
+#include "mcu/da1469x_trimv.h"
+#include "mcu/da1469x_pdc.h"
+#include <ipc_cmac/shm.h>
+#include <ipc_cmac/mbox.h>
+#include <ipc_cmac/rand.h>
+#include "trng/trng.h"
+#include "console/console.h"
+
+extern char _binary_cmac_img_bin_start[];
+extern char _binary_cmac_img_bin_end;
+extern char _binary_cmac_ram_bin_start[];
+extern char _binary_cmac_ram_bin_end;
+
+struct cmac_img_info {
+ uint32_t magic;
+ uint32_t img_size;
+ uint32_t ram_size;
+ uint32_t data_offset;
+ uint32_t shared_offset;
+ uint32_t shared_addr;
+};
+
+struct cmac_img_hdr {
+ uint32_t isr[32];
+ struct cmac_img_info ii;
+ struct cmac_shm_config *shm_config;
+ struct cmac_shm_ctrl *shm_ctrl;
+ struct cmac_shm_mbox *shm_mbox_s2c;
+ struct cmac_shm_mbox *shm_mbox_c2s;
+ struct cmac_shm_trim *shm_trim;
+ struct cmac_shm_rand *shm_rand;
+ struct cmac_shm_dcdc *shm_dcdc;
+ struct cmac_shm_crashinfo *shm_crashinfo;
+ struct cmac_shm_debugdata *shm_debugdata;
+};
+
+/* Note: this can be only used after image was copied to RAM area */
+#define CMAC_RAM_HDR ((struct cmac_img_hdr *)_binary_cmac_ram_bin_start)
+
+#define CMAC_CODE_PTR(_ptr) ((void *)((uint32_t)(_ptr) + \
+ MCU_MEM_SYSRAM_START_ADDRESS + \
+ MEMCTRL->CMI_CODE_BASE_REG))
+#define CMAC_SHARED_PTR(_ptr) ((void *)((uint32_t)(_ptr) - \
+ CMAC_RAM_HDR->ii.shared_addr + \
+ MCU_MEM_SYSRAM_START_ADDRESS + \
+ MEMCTRL->CMI_SHARED_BASE_REG))
+
+volatile struct cmac_shm_config *g_cmac_shm_config;
+volatile struct cmac_shm_ctrl *g_cmac_shm_ctrl;
+volatile struct cmac_shm_mbox *g_cmac_shm_mbox_s2c;
+volatile struct cmac_shm_mbox *g_cmac_shm_mbox_c2s;
+volatile struct cmac_shm_trim *g_cmac_shm_trim;
+volatile struct cmac_shm_rand *g_cmac_shm_rand;
+volatile struct cmac_shm_dcdc *g_cmac_shm_dcdc;
+volatile struct cmac_shm_crashinfo *g_cmac_shm_crashinfo;
+volatile struct cmac_shm_debugdata *g_cmac_shm_debugdata;
+
+/* PDC entry for waking up CMAC */
+static int8_t g_cmac_host_pdc_sys2cmac;
+/* PDC entry for waking up M33 */
+static int8_t g_cmac_host_pdc_cmac2sys;
+
+static void cmac_host_rand_fill(struct os_event *ev);
+static struct os_event g_cmac_host_rand_ev = {
+ .ev_cb = cmac_host_rand_fill
+};
+
+static void cmac_host_rand_chk_fill(void);
+
+#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart)
+static void cmac_host_error_w4flush(struct os_event *ev);
+static struct os_event g_cmac_host_error_ev = {
+ .ev_cb = cmac_host_error_w4flush
+};
+#endif
+
+static void
+cmac2sys_isr(void)
+{
+ volatile struct cmac_shm_crashinfo *ci = g_cmac_shm_crashinfo;
+ const char *assert_file;
+
+ os_trace_isr_enter();
+
+ /* Clear CMAC2SYS interrupt */
+ *(volatile uint32_t *)0x40002000 = 2;
+
+ cmac_mbox_read();
+
+ if (*(volatile uint32_t *)0x40002000 & 0x1c00) {
+ if (ci) {
+ console_blocking_mode();
+ console_printf("CMAC error (0x%08lx)\n",
+ *(volatile uint32_t *)0x40002000);
+ console_printf(" lr:0x%08lx pc:0x%08lx\n", ci->lr, ci->pc);
+ if (ci->assert) {
+ console_printf(" assert:0x%08lx\n", ci->assert);
+ if (ci->assert_file) {
+ /* Need to translate pointer from M0 code segment to M33 data */
+ assert_file =
+ ci->assert_file + MCU_MEM_SYSRAM_START_ADDRESS +
+ MEMCTRL->CMI_CODE_BASE_REG;
+ console_printf(" %s:%d\n",
+ assert_file, (unsigned)ci->assert_line);
+ }
+ }
+ console_printf(" 0x%08lx CM_ERROR_REG\n", ci->CM_ERROR_REG);
+ console_printf(" 0x%08lx CM_EXC_STAT_REG\n", ci->CM_EXC_STAT_REG);
+ console_printf(" 0x%08lx CM_LL_TIMER1_36_10_REG\n",
+ ci->CM_LL_TIMER1_36_10_REG);
+ console_printf(" 0x%08lx CM_LL_TIMER1_9_0_REG\n",
+ ci->CM_LL_TIMER1_9_0_REG);
+
+ /* Spin if debugger is connected to CMAC to avoid resetting it */
+ if (ci->CM_STAT_REG & 0x20) {
+ while (1) {
+ }
+ }
+ }
+
+#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart)
+ NVIC_DisableIRQ(CMAC2SYS_IRQn);
+ /* Wait until UART is flushed and then assert */
+ cmac_host_error_w4flush(NULL);
+ return;
+#endif
+
+ /* XXX CMAC is in error state, need to recover */
+ assert(0);
+ return;
+ }
+
+ cmac_host_rand_chk_fill();
+
+ os_trace_isr_exit();
+}
+
+static void
+cmac_host_rand_fill(struct os_event *ev)
+{
+ size_t num_bytes;
+ struct trng_dev *trng;
+ uint32_t *rnum;
+ uint32_t rnums[g_cmac_shm_config->rand_size];
+
+ /* Check if full */
+ if (!cmac_rand_is_active() || cmac_rand_is_full()) {
+ return;
+ }
+
+ assert(ev->ev_arg != NULL);
+
+ /* Fill buffer with random numbers even though we may not use all of them */
+ trng = ev->ev_arg;
+ rnum = &rnums[0];
+ num_bytes = trng_read(trng, rnum, g_cmac_shm_config->rand_size * sizeof(uint32_t));
+
+ cmac_rand_fill(rnum, num_bytes / 4);
+ cmac_host_signal2cmac();
+}
+
+static void
+cmac_host_rand_chk_fill(void)
+{
+ if (cmac_rand_is_active() && !cmac_rand_is_full()) {
+ os_eventq_put(os_eventq_dflt_get(), &g_cmac_host_rand_ev);
+ }
+}
+
+static void
+cmac_host_lpclk_cb(uint32_t freq)
+{
+ /* No need to wakeup CMAC if LP clock frequency did not change */
+ if (g_cmac_shm_ctrl->lp_clock_freq == freq) {
+ return;
+ }
+
+ cmac_shm_lock();
+ g_cmac_shm_ctrl->lp_clock_freq = freq;
+ g_cmac_shm_ctrl->pending_ops |= CMAC_SHM_CB_PENDING_OP_LP_CLK;
+ cmac_shm_unlock();
+
+ cmac_host_signal2cmac();
+}
+
+static void
+shm_init(void)
+{
+ struct cmac_img_hdr *ih = CMAC_RAM_HDR;
+
+ g_cmac_shm_config = CMAC_CODE_PTR(ih->shm_config);
+ g_cmac_shm_ctrl = CMAC_SHARED_PTR(ih->shm_ctrl);
+ g_cmac_shm_mbox_s2c = CMAC_SHARED_PTR(ih->shm_mbox_s2c);
+ g_cmac_shm_mbox_c2s = CMAC_SHARED_PTR(ih->shm_mbox_c2s);
+ g_cmac_shm_trim = CMAC_SHARED_PTR(ih->shm_trim);
+ g_cmac_shm_rand = CMAC_SHARED_PTR(ih->shm_rand);
+ g_cmac_shm_dcdc = CMAC_SHARED_PTR(ih->shm_dcdc);
+ g_cmac_shm_crashinfo = CMAC_SHARED_PTR(ih->shm_crashinfo);
+ g_cmac_shm_debugdata = CMAC_SHARED_PTR(ih->shm_debugdata);
+}
+
+static void
+shm_configure(void)
+{
+ struct cmac_shm_trim *trim;
+ uint32_t *trim_data;
+
+ g_cmac_shm_ctrl->xtal32m_settle_us =
+ MYNEWT_VAL(MCU_CLOCK_XTAL32M_SETTLE_TIME_US);
+
+ trim = (struct cmac_shm_trim *)g_cmac_shm_trim;
+ trim_data = trim->data;
+
+ trim->rfcu_len =
+ da1469x_trimv_group_read(6, trim_data,
+ g_cmac_shm_config->trim_rfcu_size);
+ trim_data += g_cmac_shm_config->trim_rfcu_size;
+ trim->rfcu_mode1_len =
+ da1469x_trimv_group_read(8, trim_data,
+ g_cmac_shm_config->trim_rfcu_mode1_size);
+ trim_data += g_cmac_shm_config->trim_rfcu_mode1_size;
+ trim->rfcu_mode2_len =
+ da1469x_trimv_group_read(10, trim_data,
+ g_cmac_shm_config->trim_rfcu_mode2_size);
+ trim_data += g_cmac_shm_config->trim_rfcu_mode2_size;
+ trim->synth_len =
+ da1469x_trimv_group_read(7, trim_data,
+ g_cmac_shm_config->trim_synth_size);
+
+#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE)
+ cmac_host_print_trim("rfcu", trim->rfcu, trim->rfcu_len);
+ cmac_host_print_trim("rfcu_mode1", trim->rfcu_mode1, trim->rfcu_mode1_len);
+ cmac_host_print_trim("rfcu_mode2", trim->rfcu_mode2, trim->rfcu_mode2_len);
+ cmac_host_print_trim("synth", trim->synth, trim->synth_len);
+#endif
+
+ g_cmac_shm_dcdc->enabled = DCDC->DCDC_CTRL1_REG & DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk;
+ if (g_cmac_shm_dcdc->enabled) {
+ g_cmac_shm_dcdc->v18 = DCDC->DCDC_V18_REG;
+ g_cmac_shm_dcdc->v18p = DCDC->DCDC_V18P_REG;
+ g_cmac_shm_dcdc->vdd = DCDC->DCDC_VDD_REG;
+ g_cmac_shm_dcdc->v14 = DCDC->DCDC_V14_REG;
+ g_cmac_shm_dcdc->ctrl1 = DCDC->DCDC_CTRL1_REG;
+ }
+}
+
+#if MYNEWT_VAL_CHOICE(BLE_TRANSPORT_HS, uart)
+#if MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) < 0 || MYNEWT_VAL(BLE_TRANSPORT_UART_PORT) > 2
+#error Invalid BLE_HCI_UART_PORT
+#endif
+static void
+cmac_host_error_w4flush(struct os_event *ev)
+{
+ static UART_Type * const regs[] = {
+ (void *)UART,
+ (void *)UART2,
+ (void *)UART3
+ };
+
+ if (!ev) {
+ /* Move to task context, we do not want to spin in interrupt */
+ os_eventq_put(os_eventq_dflt_get(), &g_cmac_host_error_ev);
+ return;
+ }
+
+ do {
+ cmac_mbox_read();
+ while ((regs[MYNEWT_VAL(BLE_TRANSPORT_UART_PORT)]->UART_LSR_REG &
+ UART_UART_LSR_REG_UART_TEMT_Msk) == 0) {
+ /* Wait until both FIFO and shift registers are empty */
+ }
+ } while (cmac_mbox_has_data());
+
+ /* Reset CMAC */
+ CRG_TOP->CLK_RADIO_REG |= CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk;
+
+ assert(0);
+}
+#endif
+
+#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE)
+static void
+cmac_host_print_trim(const char *name, const uint32_t *tv, unsigned len)
+{
+ console_printf("[CMAC] Trim values for '%s'\n", name);
+
+ while (len) {
+ console_printf(" 0x%08x = 0x%08x\n", (unsigned)tv[0], (unsigned)tv[1]);
+ len -= 2;
+ tv += 2;
+ }
+}
+#endif
+
+static void
+cmac_load_image(void)
+{
+ struct cmac_img_hdr *ih = (struct cmac_img_hdr *)_binary_cmac_img_bin_start;
+ struct cmac_img_info ii;
+ uint32_t img_size;
+ uint32_t ram_size;
+#if !MYNEWT_VAL(CMAC_IMAGE_SINGLE)
+ const struct flash_area *fa;
+ int rc;
+#endif
+
+ /* Calculate size of image and RAM area */
+ img_size = &_binary_cmac_img_bin_end - &_binary_cmac_img_bin_start[0];
+ ram_size = &_binary_cmac_ram_bin_end - &_binary_cmac_ram_bin_start[0];
+
+ /* Load image header and check if image can be loaded */
+#if MYNEWT_VAL(CMAC_IMAGE_SINGLE)
+ memcpy(&ii, &ih->ii, sizeof(ii));
+#else
+ rc = flash_area_open(FLASH_AREA_IMAGE_1, &fa);
+ assert(rc == 0);
+ rc = flash_area_read(fa, 128, &ii, sizeof(ii));
+ assert(rc == 0);
+#endif
+
+ assert(ii.magic == 0xC3AC0001);
+ assert(ii.img_size == img_size);
+ assert(ii.ram_size <= ram_size);
+
+ /* Setup CMAC memory addresses */
+ MEMCTRL->CMI_CODE_BASE_REG = (uint32_t)&_binary_cmac_ram_bin_start;
+ MEMCTRL->CMI_DATA_BASE_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.data_offset;
+ MEMCTRL->CMI_SHARED_BASE_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.shared_offset;
+ MEMCTRL->CMI_END_REG = MEMCTRL->CMI_CODE_BASE_REG + ii.ram_size - 1;
+
+ /* Clear RAM area then copy image */
+ memset(&_binary_cmac_ram_bin_start, 0, ram_size);
+#if MYNEWT_VAL(CMAC_IMAGE_SINGLE)
+ memcpy(&_binary_cmac_ram_bin_start, &_binary_cmac_img_bin_start, img_size);
+#else
+ rc = flash_area_read(fa, 0, &_binary_cmac_ram_bin_start, img_size);
+ assert(rc == 0);
+#endif
+}
+
+static void
+cmac_configure(void)
+{
+ /* Add PDC entry to wake up CMAC from M33 */
+ g_cmac_host_pdc_sys2cmac = da1469x_pdc_add(MCU_PDC_TRIGGER_MAC_TIMER,
+ MCU_PDC_MASTER_CMAC,
+ MCU_PDC_EN_XTAL);
+ da1469x_pdc_set(g_cmac_host_pdc_sys2cmac);
+ da1469x_pdc_ack(g_cmac_host_pdc_sys2cmac);
+
+ /* Add PDC entry to wake up M33 from CMAC, if does not exist yet */
+ g_cmac_host_pdc_cmac2sys = da1469x_pdc_find(MCU_PDC_TRIGGER_COMBO,
+ MCU_PDC_MASTER_M33, 0);
+ if (g_cmac_host_pdc_cmac2sys < 0) {
+ g_cmac_host_pdc_cmac2sys = da1469x_pdc_add(MCU_PDC_TRIGGER_COMBO,
+ MCU_PDC_MASTER_M33,
+ MCU_PDC_EN_XTAL);
+ da1469x_pdc_set(g_cmac_host_pdc_cmac2sys);
+ da1469x_pdc_ack(g_cmac_host_pdc_cmac2sys);
+ }
+
+ /* Setup CMAC2SYS interrupt */
+ NVIC_SetVector(CMAC2SYS_IRQn, (uint32_t)cmac2sys_isr);
+ NVIC_SetPriority(CMAC2SYS_IRQn, MYNEWT_VAL(CMAC_CMAC2SYS_IRQ_PRIORITY));
+ NVIC_DisableIRQ(CMAC2SYS_IRQn);
+}
+
+static void
+cmac_start(void)
+{
+ /* Enable Radio LDO */
+ CRG_TOP->POWER_CTRL_REG |= CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Msk;
+
+ /* Enable CMAC, but keep it in reset */
+ CRG_TOP->CLK_RADIO_REG = (1 << CRG_TOP_CLK_RADIO_REG_RFCU_ENABLE_Pos) |
+ (1 << CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Pos) |
+ (0 << CRG_TOP_CLK_RADIO_REG_CMAC_CLK_SEL_Pos) |
+ (1 << CRG_TOP_CLK_RADIO_REG_CMAC_CLK_ENABLE_Pos) |
+ (0 << CRG_TOP_CLK_RADIO_REG_CMAC_DIV_Pos);
+
+#if MYNEWT_VAL(CMAC_DEBUG_SWD_ENABLE)
+ /* Enable CMAC debugger */
+ CRG_TOP->SYS_CTRL_REG |= 0x40; /* CRG_TOP_SYS_CTRL_REG_CMAC_DEBUGGER_ENABLE_Msk */
+#endif
+
+ /* Release CMAC from reset and sync */
+ CRG_TOP->CLK_RADIO_REG &= ~CRG_TOP_CLK_RADIO_REG_CMAC_SYNCH_RESET_Msk;
+
+ while (g_cmac_shm_ctrl->magic != CMAC_SHM_CB_MAGIC) {
+ /* Wait for CMAC to initialize */
+ }
+ NVIC_EnableIRQ(CMAC2SYS_IRQn);
+}
+
+void
+cmac_host_init(void)
+{
+ struct trng_dev *trng;
+
+ /* Get trng os device */
+ trng = (struct trng_dev *) os_dev_open("trng", OS_TIMEOUT_NEVER, NULL);
+ assert(trng);
+ g_cmac_host_rand_ev.ev_arg = trng;
+
+#if MYNEWT_VAL(CMAC_DEBUG_DIAG_ENABLE)
+ cmac_diag_setup_host();
+#endif
+
+ cmac_configure();
+ cmac_load_image();
+
+ shm_init();
+ shm_configure();
+
+ cmac_start();
+
+ da1469x_lpclk_register_cmac_cb(cmac_host_lpclk_cb);
+
+#if MYNEWT_VAL(CMAC_DEBUG_HOST_PRINT_ENABLE) && MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE)
+ /* Trim values are calculated on RF init, so are valid after synced with CMAC */
+ console_printf("[CMAC] Calculated trim_val1: 1=0x%08x 2=0x%08x\n",
+ (unsigned)g_cmac_shared_data->debug.trim_val1_tx_1,
+ (unsigned)g_cmac_shared_data->debug.trim_val1_tx_2);
+ console_printf("[CMAC] Calculated trim_val2: tx=0x%08x rx=0x%08x\n",
+ (unsigned)g_cmac_shared_data->debug.trim_val2_tx,
+ (unsigned)g_cmac_shared_data->debug.trim_val2_rx);
+#endif
+}
+
+void
+cmac_host_signal2cmac(void)
+{
+ da1469x_pdc_set(g_cmac_host_pdc_sys2cmac);
+}
+
+void
+cmac_host_rf_calibrate(void)
+{
+ cmac_shm_lock();
+ g_cmac_shm_ctrl->pending_ops |= CMAC_SHM_CB_PENDING_OP_RF_CAL;
+ cmac_shm_unlock();
+
+ cmac_host_signal2cmac();
+}
diff --git a/hw/drivers/ipc_cmac/src/shm_ll.c b/hw/drivers/ipc_cmac/src/shm_ll.c
new file mode 100644
index 000000000..2ff8a30de
--- /dev/null
+++ b/hw/drivers/ipc_cmac/src/shm_ll.c
@@ -0,0 +1,82 @@
+/*
+ * 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 <syscfg/syscfg.h>
+#include <mcu/mcu.h>
+#include <ipc_cmac/shm.h>
+
+#define CMAC_SHM_MAGIC __attribute__((section(".shm_magic")))
+#define CMAC_SHM_VECT __attribute__((section(".shm_vect")))
+#define CMAC_SHM_DATA __attribute__((section(".shm_data")))
+
+#define FIELD_ARRAY_SIZE(t, f) (sizeof(((t*)0)->f) / sizeof(((t*)0)->f[0]))
+
+const struct cmac_shm_config g_cmac_shm_config = {
+ .mbox_s2c_size = FIELD_ARRAY_SIZE(struct cmac_shm_ll_mbox_s2c, data),
+ .mbox_c2s_size = FIELD_ARRAY_SIZE(struct cmac_shm_ll_mbox_c2s, data),
+ .trim_rfcu_size = FIELD_ARRAY_SIZE(struct cmac_shm_ll_trim, rfcu),
+ .trim_rfcu_mode1_size = FIELD_ARRAY_SIZE(struct cmac_shm_ll_trim, rfcu_mode1),
+ .trim_rfcu_mode2_size = FIELD_ARRAY_SIZE(struct cmac_shm_ll_trim, rfcu_mode2),
+ .trim_synth_size = FIELD_ARRAY_SIZE(struct cmac_shm_ll_trim, synth),
+ .rand_size = FIELD_ARRAY_SIZE(struct cmac_shm_ll_rand, cmr_buf),
+};
+
+volatile struct cmac_shm_ctrl CMAC_SHM_DATA g_cmac_shm_ctrl;
+volatile struct cmac_shm_ll_mbox_s2c CMAC_SHM_DATA g_cmac_shm_mbox_s2c;
+volatile struct cmac_shm_ll_mbox_c2s CMAC_SHM_DATA g_cmac_shm_mbox_c2s;
+volatile struct cmac_shm_ll_trim CMAC_SHM_DATA g_cmac_shm_trim;
+volatile struct cmac_shm_ll_rand CMAC_SHM_DATA g_cmac_shm_rand;
+volatile struct cmac_shm_dcdc CMAC_SHM_DATA g_cmac_shm_dcdc;
+#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE)
+volatile struct cmac_shm_crashinfo CMAC_SHM_DATA g_cmac_shm_crashinfo;
+#endif
+#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE)
+volatile struct cmac_shm_debugdata CMAC_SHM_DATA g_cmac_shm_debugdata;
+#endif
+
+const uint32_t g_cmac_shm_magic CMAC_SHM_MAGIC = CMAC_SHM_VECT_MAGIC;
+
+const uint32_t g_cmac_shm_vect[] CMAC_SHM_VECT = {
+ (uint32_t)&g_cmac_shm_config,
+ (uint32_t)&g_cmac_shm_ctrl,
+ (uint32_t)&g_cmac_shm_mbox_s2c,
+ (uint32_t)&g_cmac_shm_mbox_c2s,
+ (uint32_t)&g_cmac_shm_trim,
+ (uint32_t)&g_cmac_shm_rand,
+ (uint32_t)&g_cmac_shm_dcdc,
+#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE)
+ (uint32_t)&g_cmac_shm_crashinfo,
+#else
+ 0,
+#endif
+#if MYNEWT_VAL(CMAC_DEBUG_DATA_ENABLE)
+ (uint32_t)&g_cmac_shm_debugdata,
+#else
+ 0,
+#endif
+};
+
+void
+cmac_shm_ll_ready(void)
+{
+ g_cmac_shm_ctrl.magic = CMAC_SHM_CB_MAGIC;
+
+ NVIC_SetPriority(SYS2CMAC_IRQn, 3);
+ NVIC_EnableIRQ(SYS2CMAC_IRQn);
+}
diff --git a/hw/drivers/ipc_cmac/syscfg.yml b/hw/drivers/ipc_cmac/syscfg.yml
new file mode 100644
index 000000000..bf265b937
--- /dev/null
+++ b/hw/drivers/ipc_cmac/syscfg.yml
@@ -0,0 +1,104 @@
+# 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.
+#
+
+syscfg.defs:
+ CMAC_DEBUG_SWD_ENABLE:
+ description: >
+ Enable CMAC SWD interface.
+ value: 0
+
+syscfg.defs.BLE_CONTROLLER:
+ CMAC_MBOX_SIZE_S2C:
+ description: >
+ Size of mailbox for SYS to CMAC data. The size
+ value should be power of 2 to allow for better
+ code optimization.
+ value: 128
+ CMAC_MBOX_SIZE_C2S:
+ description: >
+ Size of mailbox for CMAC to SYS data. The size
+ value should be power of 2 to allow for better
+ code optimization.
+ value: 128
+
+ CMAC_TRIM_SIZE_RFCU:
+ description: >
+ Maximum number of trim values for RFCU that can
+ be set from host.
+ value: 10
+ CMAC_TRIM_SIZE_SYNTH:
+ description: >
+ Maximum number of trim values for SYNTH that can
+ be set from host.
+ value: 10
+
+ CMAC_DEBUG_DIAG_ENABLE:
+ description: >
+ Enable CMAC diagnostic lines.
+ value: 0
+ CMAC_DEBUG_DATA_ENABLE:
+ description: >
+ Enable extra debugging data in shared segment.
+ value: 0
+ CMAC_DEBUG_COREDUMP_ENABLE:
+ description: >
+ Enable dumping CMAC registers to shared segment
+ on fault.
+ value: 1
+
+syscfg.defs.'!BLE_CONTROLLER':
+ CMAC_IMAGE_SINGLE:
+ description: >
+ When enable, CMAC binary is linked with application image
+ creating a single image build. See CMAC_IMAGE_TARGET_NAME.
+ When disabled, CMAC binary is built and flashed separately
+ to flash partition. See CMAC_IMAGE_PARTITION.
+ value: 1
+ CMAC_IMAGE_TARGET_NAME:
+ description: >
+ Target name to build for CMAC binary for single image build.
+ value: "@apache-mynewt-nimble/targets/dialog_cmac"
+ CMAC_IMAGE_PARTITION:
+ description: >
+ Flash partition to load CMAC binary from if single image build
+ is disabled.
+ value: FLASH_AREA_IMAGE_1
+ CMAC_IMAGE_RAM_SIZE:
+ description: >
+ Size of RAM area in bytes reserved for CMAC if single image
+ build is disabled. Unit suffix (K, M) is allowed.
+ Note: for single image build this setting is not applicable
+ since proper RAM area size is automatically calculated from
+ CMAC binary.
+ value: 128K
+
+ CMAC_CMAC2SYS_IRQ_PRIORITY:
+ description: >
+ The priority of the CMAC2SYS IRQ. Default is 0, or highest
+ priority.
+ value: 0
+
+ CMAC_DEBUG_HOST_PRINT_ENABLE:
+ description: >
+ Enable some debug printouts to console from host side.
+ This will dump some settings during startup, useful to
+ check what is loaded to CMAC via shared data.
+ value: 0
+
+syscfg.restrictions.!BLE_CONTROLLER:
+ - TRNG
diff --git a/hw/mcu/dialog/cmac/cmac.ld b/hw/mcu/dialog/cmac/cmac.ld
index 8fc8d1680..f7eb6cec0 100644
--- a/hw/mcu/dialog/cmac/cmac.ld
+++ b/hw/mcu/dialog/cmac/cmac.ld
@@ -20,6 +20,17 @@ ENTRY(Reset_Handler)
SECTIONS
{
+ /* Size of binary image, i.e. ROM + initialized data */
+ img_size = LOADADDR(.data) + SIZEOF(.data);
+ /* Size of RAM area required for CMAC */
+ ram_size = LOADADDR(.data) + end_of_ram - ADDR(.data);
+ /* Offset of data section in binary image */
+ data_offset = LOADADDR(.data);
+ /* Offset of shared section in binary image */
+ shared_offset = LOADADDR(.data) + ADDR(.shm) - ADDR(.data);
+ /* Base address of shared section on CMAC side (to translate pointers) */
+ shared_addr = ADDR(.shm);
+
.text :
{
__text = .;
@@ -29,11 +40,13 @@ SECTIONS
__isr_vector_end = .;
/* Put image info just after intvect so loader can locate it easily */
- LONG(0xC3ACC3AC)
- LONG(LOADADDR(.data) + SIZEOF(.data))
- LONG(LOADADDR(.data) + end_of_ram - ADDR(.data))
- LONG(LOADADDR(.data))
- LONG(LOADADDR(.data) + ADDR(.shdata) - ADDR(.data))
+ KEEP(*(.shm_magic))
+ LONG(img_size)
+ LONG(ram_size)
+ LONG(data_offset)
+ LONG(shared_offset)
+ LONG(shared_addr)
+ KEEP(*(.shm_vect))
*(.text*)
@@ -141,11 +154,11 @@ SECTIONS
*(.stack*)
} > RAM
- .shdata (NOLOAD) : ALIGN(1K)
+ .shm (NOLOAD) : ALIGN(1K)
{
- __shdata_start__ = .;
- *(.shdata)
- __shdata_end__ = .;
+ __shm_start__ = .;
+ *(.shm_data)
+ __shm_end__ = .;
} > RAM
. = ALIGN(1K);
@@ -160,7 +173,7 @@ SECTIONS
} AT > ROM
__HeapBase = ADDR(.heap_dummy);
- __StackTop = ADDR(.shdata);
+ __StackTop = ADDR(.shm);
/* Move stack limit down by size of stack_dummy section */
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
diff --git a/hw/mcu/dialog/cmac/pkg.yml b/hw/mcu/dialog/cmac/pkg.yml
index fc046095c..0591ba542 100644
--- a/hw/mcu/dialog/cmac/pkg.yml
+++ b/hw/mcu/dialog/cmac/pkg.yml
@@ -30,6 +30,7 @@ pkg.deps:
- "@apache-mynewt-core/hw/cmsis-core"
- "@apache-mynewt-core/hw/hal"
- "@apache-mynewt-core/hw/mcu/dialog"
+ - "@apache-mynewt-core/hw/drivers/ipc_cmac"
- "@apache-mynewt-nimble/nimble/drivers/dialog_cmac"
pkg.cflags: -I@apache-mynewt-core/kernel
diff --git a/hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_arch_arm.c b/hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_arch_arm.c
index c63bc659e..174571673 100644
--- a/hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_arch_arm.c
+++ b/hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_arch_arm.c
@@ -20,7 +20,7 @@
#include "mcu/mcu.h"
#include "hal/hal_os_tick.h"
#include "os/os_arch_cmac.h"
-#include "os/src/os_priv.h"
+#include "../../os/src/os_priv.h"
/* Initial program status register */
#define INITIAL_xPSR 0x01000000
diff --git a/hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_fault.c b/hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_fault.c
index 67adcd1fc..1c1be9212 100644
--- a/hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_fault.c
+++ b/hw/mcu/dialog/cmac/src/arch/cortex_m0_cmac/os_fault.c
@@ -23,7 +23,8 @@
#include "hal/hal_system.h"
#include "CMAC.h"
#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE)
-#include "cmac_driver/cmac_shared.h"
+#include <ipc_cmac/shm.h>
+#include <ipc_cmac/mbox.h>
#endif
#ifndef max
@@ -156,11 +157,11 @@ void
__assert_func(const char *file, int line, const char *func, const char *e)
{
#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE)
- volatile struct cmac_coredump *cd = &g_cmac_shared_data.coredump;
+ volatile struct cmac_shm_crashinfo *ci = &g_cmac_shm_crashinfo;
- cd->assert = (uint32_t)__builtin_return_address(0);
- cd->assert_file = file;
- cd->assert_line = line;
+ ci->assert = (uint32_t)__builtin_return_address(0);
+ ci->assert_file = file;
+ ci->assert_line = line;
#endif
#if MYNEWT_VAL(MCU_DEBUG_HCI_EVENT_ON_ASSERT)
@@ -174,7 +175,7 @@ void
os_default_irq(struct trap_frame *tf)
{
#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE)
- volatile struct cmac_coredump *cd = &g_cmac_shared_data.coredump;
+ volatile struct cmac_shm_crashinfo *ci = &g_cmac_shm_crashinfo;
#endif
if (((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) == (NMI_IRQn + 16)) &&
@@ -194,14 +195,14 @@ os_default_irq(struct trap_frame *tf)
}
#if MYNEWT_VAL(CMAC_DEBUG_COREDUMP_ENABLE)
- cd->lr = tf->ef->lr;
- cd->pc = tf->ef->pc;
-
- cd->CM_STAT_REG = CMAC->CM_STAT_REG;
- cd->CM_LL_TIMER1_36_10_REG = CMAC->CM_LL_TIMER1_36_10_REG;
- cd->CM_LL_TIMER1_9_0_REG = CMAC->CM_LL_TIMER1_9_0_REG;
- cd->CM_ERROR_REG = CMAC->CM_ERROR_REG;
- cd->CM_EXC_STAT_REG = CMAC->CM_EXC_STAT_REG;
+ ci->lr = tf->ef->lr;
+ ci->pc = tf->ef->pc;
+
+ ci->CM_STAT_REG = CMAC->CM_STAT_REG;
+ ci->CM_LL_TIMER1_36_10_REG = CMAC->CM_LL_TIMER1_36_10_REG;
+ ci->CM_LL_TIMER1_9_0_REG = CMAC->CM_LL_TIMER1_9_0_REG;
+ ci->CM_ERROR_REG = CMAC->CM_ERROR_REG;
+ ci->CM_EXC_STAT_REG = CMAC->CM_EXC_STAT_REG;
#endif
#if MYNEWT_VAL(MCU_DEBUG_HCI_EVENT_ON_FAULT)
diff --git a/hw/mcu/dialog/cmac/src/cmac_isr.c b/hw/mcu/dialog/cmac/src/cmac_isr.c
index 9d90ab9e2..a460687d3 100644
--- a/hw/mcu/dialog/cmac/src/cmac_isr.c
+++ b/hw/mcu/dialog/cmac/src/cmac_isr.c
@@ -17,11 +17,12 @@
* under the License.
*/
-#include "mcu/mcu.h"
-#include "mcu/cmac_pdc.h"
-#include "cmac_driver/cmac_shared.h"
+#include <CMAC.h>
+#include <mcu/cmac_pdc.h>
+#include <ipc_cmac/shm.h>
+#include <ipc_cmac/mbox.h>
+#include <ipc_cmac/rand.h>
#include "cmac_priv.h"
-#include "CMAC.h"
extern void ble_rf_calibrate_req(void);
@@ -31,19 +32,19 @@ SYS2CMAC_IRQHandler(void)
uint16_t pending_ops;
if (CMAC->CM_EXC_STAT_REG & CMAC_CM_EXC_STAT_REG_EXC_SYS2CMAC_Msk) {
- cmac_shared_lock();
- pending_ops = g_cmac_shared_data.pending_ops;
- g_cmac_shared_data.pending_ops = 0;
- cmac_shared_unlock();
+ cmac_shm_lock();
+ pending_ops = g_cmac_shm_ctrl.pending_ops;
+ g_cmac_shm_ctrl.pending_ops = 0;
+ cmac_shm_unlock();
cmac_mbox_read();
cmac_rand_read();
- if (pending_ops & CMAC_PENDING_OP_LP_CLK) {
+ if (pending_ops & CMAC_SHM_CB_PENDING_OP_LP_CLK) {
cmac_sleep_recalculate();
}
- if (pending_ops & CMAC_PENDING_OP_RF_CAL) {
+ if (pending_ops & CMAC_SHM_CB_PENDING_OP_RF_CAL) {
ble_rf_calibrate_req();
}
diff --git a/hw/mcu/dialog/cmac/src/cmac_sleep.c b/hw/mcu/dialog/cmac/src/cmac_sleep.c
index b3158daa2..bcf6c12d4 100644
--- a/hw/mcu/dialog/cmac/src/cmac_sleep.c
+++ b/hw/mcu/dialog/cmac/src/cmac_sleep.c
@@ -24,7 +24,7 @@
#include <assert.h>
#include "mcu/cmac_pdc.h"
-#include "cmac_driver/cmac_shared.h"
+#include "ipc_cmac/shm.h"
#include "mcu/cmac_timer.h"
#include "mcu/mcu.h"
#include "hal/hal_system.h"
@@ -145,15 +145,15 @@ cmac_sleep_regs_restore(void)
static void
cmac_sleep_enable_dcdc(void)
{
- if (!g_cmac_shared_data.dcdc.enabled) {
+ if (!g_cmac_shm_dcdc.enabled) {
return;
}
- *(volatile uint32_t *)0x50000314 = g_cmac_shared_data.dcdc.v18;
- *(volatile uint32_t *)0x50000318 = g_cmac_shared_data.dcdc.v18p;
- *(volatile uint32_t *)0x50000310 = g_cmac_shared_data.dcdc.vdd;
- *(volatile uint32_t *)0x5000030c = g_cmac_shared_data.dcdc.v14;
- *(volatile uint32_t *)0x50000304 = g_cmac_shared_data.dcdc.ctrl1;
+ *(volatile uint32_t *)0x50000314 = g_cmac_shm_dcdc.v18;
+ *(volatile uint32_t *)0x50000318 = g_cmac_shm_dcdc.v18p;
+ *(volatile uint32_t *)0x50000310 = g_cmac_shm_dcdc.vdd;
+ *(volatile uint32_t *)0x5000030c = g_cmac_shm_dcdc.v14;
+ *(volatile uint32_t *)0x50000304 = g_cmac_shm_dcdc.ctrl1;
}
static void
@@ -174,7 +174,7 @@ cmac_sleep_wait4xtal(void)
static void
cmac_sleep_calculate_wakeup_time(void)
{
- assert(g_cmac_shared_data.xtal32m_settle_us);
+ assert(g_cmac_shm_ctrl.xtal32m_settle_us);
g_mcu_wakeup_usecs_min =
/*
@@ -195,7 +195,7 @@ cmac_sleep_calculate_wakeup_time(void)
* worst case. Finally, LLP compensation takes around 50us.
*/
T_LPTICK_U(2) + T_LPTICK_U(2) +
- max(T_LPTICK_U(3), T_USEC(g_cmac_shared_data.xtal32m_settle_us)) +
+ max(T_LPTICK_U(3), T_USEC(g_cmac_shm_ctrl.xtal32m_settle_us)) +
T_LPTICK(2) + T_USEC(50);
}
diff --git a/hw/mcu/dialog/cmac/src/cmac_timer.c b/hw/mcu/dialog/cmac/src/cmac_timer.c
index 72ef956ae..569c3f6d4 100644
--- a/hw/mcu/dialog/cmac/src/cmac_timer.c
+++ b/hw/mcu/dialog/cmac/src/cmac_timer.c
@@ -23,7 +23,7 @@
#include "mcu/cmac_hal.h"
#include "mcu/cmac_timer.h"
#include "mcu/mcu.h"
-#include "cmac_driver/cmac_shared.h"
+#include <ipc_cmac/shm.h>
#include "os/os.h"
#include "CMAC.h"
@@ -349,7 +349,7 @@ cmac_timer_slp_update(void)
{
uint32_t lp_clock_freq;
- lp_clock_freq = g_cmac_shared_data.lp_clock_freq;
+ lp_clock_freq = g_cmac_shm_ctrl.lp_clock_freq;
if (lp_clock_freq == g_cmac_timer_slp.freq) {
return false;
diff --git a/hw/mcu/dialog/cmac/src/system_cmac.c b/hw/mcu/dialog/cmac/src/system_cmac.c
index e7413681a..c0af58446 100644
--- a/hw/mcu/dialog/cmac/src/system_cmac.c
+++ b/hw/mcu/dialog/cmac/src/system_cmac.c
@@ -25,7 +25,7 @@
#include "mcu/cmsis_nvic.h"
#include "mcu/mcu.h"
#include "hal/hal_system.h"
-#include "cmac_driver/cmac_diag.h"
+#include <ipc_cmac/diag.h>
#include "CMAC.h"
void
diff --git a/hw/mcu/dialog/da1469x/da1469x.ld b/hw/mcu/dialog/da1469x/da1469x.ld
index 1fb6489c3..e1ff35452 100644
--- a/hw/mcu/dialog/da1469x/da1469x.ld
+++ b/hw/mcu/dialog/da1469x/da1469x.ld
@@ -66,7 +66,7 @@ SECTIONS
*(.text)
*(.text.*)
- *(.libcmac.rom)
+ *(.libcmac.img)
KEEP(*(.init))
KEEP(*(.fini))