接上个博客,今天实验了一下BL808的IPC通讯,使用的是博流自己的SDK;参考手册上并没有说明各个寄存器,是通过网友的结论和自己的部分修改达成的。
1.目前仅测试了LP内核和M0内核之间的通讯,使用SIPEED的M1S_Dock开发板,修改了\bouffalo_sdk\bsp\board\bl808dk\board.c文件,先将debug的管脚14 15分配给M0内核使用,方便打印M0内核的日志;
- static void console_init()
- {
- struct bflb_device_s *gpio;
-
- gpio = bflb_device_get_by_name("gpio");
- #if defined(CPU_M0)
- bflb_gpio_uart_init(gpio, GPIO_PIN_14, GPIO_UART_FUNC_UART0_TX);
- bflb_gpio_uart_init(gpio, GPIO_PIN_15, GPIO_UART_FUNC_UART0_RX);
- #elif defined(CPU_D0)
- /* sipeed m1s dock */
- bflb_gpio_init(gpio, GPIO_PIN_16, 21 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
- bflb_gpio_init(gpio, GPIO_PIN_17, 21 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
- #elif defined(CPU_LP)
- /* map GPIO_PIN_18 and GPIO_PIN_19 as UART for LP core */
- bflb_gpio_uart_init(gpio, GPIO_PIN_18, GPIO_UART_FUNC_UART1_TX);
- bflb_gpio_uart_init(gpio, GPIO_PIN_19, GPIO_UART_FUNC_UART1_RX);
- #endif
- struct bflb_uart_config_s cfg;
- cfg.baudrate = 2000000;
- cfg.data_bits = UART_DATA_BITS_8;
- cfg.stop_bits = UART_STOP_BITS_1;
- cfg.parity = UART_PARITY_NONE;
- cfg.flow_ctrl = 0;
- cfg.tx_fifo_threshold = 7;
- cfg.rx_fifo_threshold = 7;
- #if defined(CPU_M0)
- uart0 = bflb_device_get_by_name("uart0");
- #elif defined(CPU_D0)
- uart0 = bflb_device_get_by_name("uart3");
- #elif defined(CPU_LP)
- uart0 = bflb_device_get_by_name("uart1");
- #endif
- bflb_uart_init(uart0, &cfg);
- bflb_uart_set_console(uart0);
- }
2.在bouffalo_sdk\examples\bl808_triplecore\helloworld_m0例程上进行修改,M0主函数中对中断寄存器进行了初始化,定义了中断回调函数;并在中断函数中输出IPC中断号;其中对LED灯进行了一个0.5Hz的闪烁,来提示系统进行了正常的IPC通讯。
- #include "bflb_mtimer.h"
- #include "board.h"
- #include "bflb_gpio.h"
- #include "bl808.h"
- #include "ipc_reg.h"
- #include "bl808_ipc.h"
- #include "bl808_common.h"
-
- #define DBG_TAG "M0"
- #include "log.h"
-
- struct bflb_device_s *gpio;
- uint32_t value = 0;
- void IPC_M0_IRQHandler(void)
- {
- gpio = bflb_device_get_by_name("gpio");
- // Read Interrupt Status
- uint32_t irqStatus = BL_RD_REG(IPC0_BASE, IPC_CPU0_IPC_IRSRR);
-
- //Interrupt handle
- bflb_gpio_set(gpio,GPIO_PIN_8);
- LOG_F("the irqStatus value is %d\r\n",irqStatus);
- value = 1;
- //Clear Interrypt
- BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, irqStatus);
- }
-
- void m0_ipc_init(void)
- {
- /* setup the IPC Interupt */
- bflb_irq_attach(IPC_M0_IRQn, IPC_M0_IRQHandler, NULL);
- BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, 1 << 1);
- bflb_irq_enable(IPC_M0_IRQn);
- }
-
-
- int main(void)
- {
- board_init();
- m0_ipc_init();
- while (1) {
- if(value == 1)
- {
- bflb_gpio_set(gpio,GPIO_PIN_8);
- bflb_mtimer_delay_ms(1000);
- bflb_gpio_reset(gpio,GPIO_PIN_8);
- LOG_F("hello world m0\r\n");
- LOG_E("hello world m0\r\n");
- LOG_W("hello world m0\r\n");
- LOG_I("hello world m0\r\n");
- LOG_D("hello world m0\r\n");
- LOG_T("hello world m0\r\n");
-
- }
- bflb_mtimer_delay_ms(1000);
-
- }
-
- }
将M0程序烧录到开发板中;
2.在bouffalo_sdk\examples\bl808_triplecore\helloworld_lp将LP板载外设初始化,然后打开开发板上的LED灯,使用IO8控制;默认上电拉低IO8,打开闪光灯;进入主循环之前,使能M0内核的IPC通道1;
- #include "bflb_mtimer.h"
- #include "board.h"
- #include "bflb_gpio.h"
- #include "bl808.h"
- #include "ipc_reg.h"
- #include "bl808_common.h"
-
- #define DBG_TAG "MAIN"
- #include "log.h"
- struct bflb_device_s *gpio;
-
-
-
- int main(void)
- {
-
- board_init();
- gpio = bflb_device_get_by_name("gpio");
- bflb_gpio_init(gpio, GPIO_PIN_8, GPIO_OUTPUT | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_0);
- bflb_gpio_reset(gpio,GPIO_PIN_8);
-
-
- LOG_F("hello world lp\r\n");
- LOG_E("hello world lp\r\n");
- LOG_W("hello world lp\r\n");
- LOG_I("hello world lp\r\n");
- LOG_D("hello world lp\r\n");
- LOG_T("hello world lp\r\n");
- LOG_I("LPcore will comunity to M0 core");
- BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, 1 << 1);
-
- while (1) {
-
- bflb_mtimer_delay_ms(1000);
- }
- }
将LP内核程序烧录到开发板中,会看到LED灯先是亮起,然后被M0主程序改为1秒闪烁1次;
3.若是想看debug日志,默认是查看M0内核的日志,可以把board.c文件中LP和M0的串口引脚对换。输出的LP内核的日志:
- ____ __ __ _ _ _
- | _ \ / _|/ _| | | | | | |
- | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
- | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
- | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
- |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
-
- Build:18:11:43,Oct 1 2023
- Copyright (c) 2022 Bouffalolab team
- lp does not use memheap due to little ram
- sig1:ffff76ff
- sig2:0000ffff
- cgen1:9f7ffffd
- [F][LP] hello world lp
- [E][LP] hello world lp
- [W][LP] hello world lp
- [I][LP] hello world lp
- [I][LP] LPcore will comunity to M0 core
4.输出的M0内核日志:
-
- ____ __ __ _ _ _
- | _ \ / _|/ _| | | | | | |
- | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
- | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
- | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
- |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
-
- Build:18:21:31,Oct 1 2023
- Copyright (c) 2022 Bouffalolab team
- ======== flash cfg ========
- flash size 0x01000000
- jedec id 0xEF4018
- mid 0xEF
- iomode 0x04
- clk delay 0x01
- clk invert 0x01
- read reg cmd0 0x05
- read reg cmd1 0x35
- write reg cmd0 0x01
- write reg cmd1 0x31
- qe write len 0x01
- cread support 0x00
- cread code 0xFF
- burst wrap cmd 0x77
- ===========================
- dynamic memory init success,heap size = 21 Kbyte
- sig1:ffff32ff
- sig2:0000ffff
- [F][M0] the irqStatus value is 2
- [F][M0] hello world m0
- [E][M0] hello world m0
可以看到,M0日志显示"the irqSstatus value is 2",也就是通道1触发;
4.随机试验了一下其他的通道,试验通道0能否正常触发,修改LP内核main.c文件的触发为
- int main(void)
- {
-
- board_init();
- gpio = bflb_device_get_by_name("gpio");
- bflb_gpio_init(gpio, GPIO_PIN_8, GPIO_OUTPUT | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_0);
- bflb_gpio_reset(gpio,GPIO_PIN_8);
-
- LOG_F("hello world lp\r\n");
- LOG_E("hello world lp\r\n");
- LOG_W("hello world lp\r\n");
- LOG_I("hello world lp\r\n");
- LOG_D("hello world lp\r\n");
- LOG_T("hello world lp\r\n");
- LOG_I("LPcore will comunity to M0 core");
- BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, 1 << 0);
-
- while (1) {
-
- bflb_mtimer_delay_ms(1000);
- }
- }
修改M0内核中main.c文件中的使能通道
- void m0_ipc_init(void)
- {
- /* setup the IPC Interupt */
- bflb_irq_attach(IPC_M0_IRQn, IPC_M0_IRQHandler, NULL);
- BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, 1 << 0);
- bflb_irq_enable(IPC_M0_IRQn);
- }
-
编译烧录到开发板,发现M0内核的输出日志发生变化为"the irqSstatus value is 1",也就是通道0触发;
-
- ____ __ __ _ _ _
- | _ \ / _|/ _| | | | | | |
- | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
- | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
- | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
- |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
-
- Build:18:21:31,Oct 1 2023
- Copyright (c) 2022 Bouffalolab team
- ======== flash cfg ========
- flash size 0x01000000
- jedec id 0xEF4018
- mid 0xEF
- iomode 0x04
- clk delay 0x01
- clk invert 0x01
- read reg cmd0 0x05
- read reg cmd1 0x35
- write reg cmd0 0x01
- write reg cmd1 0x31
- qe write len 0x01
- cread support 0x00
- cread code 0xFF
- burst wrap cmd 0x77
- ===========================
- dynamic memory init success,heap size = 21 Kbyte
- sig1:ffff32ff
- sig2:0000ffff
- [F][M0] the irqStatus value is 1
- [F][M0] hello world m0
- [E][M0] hello world m0
SIPEED的默认M1S_BL808_SDK中对IPC和XRAM进行了更深层次的封装,也实现了XRAM的数据交互,包括bl808_ipc.c文件,其中XRAM是作为一个组件使用,封装的相当好,这里也是很不明白为什么博流自己的SDK却删掉了这部分的内容。贴个代码,应该就知道怎么使用了。
- /*
- * Copyright (c) 2020 Bouffalolab.
- *
- * This file is part of
- * *** Bouffalolab Software Dev Kit ***
- * (see www.bouffalolab.com).
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Bouffalo Lab nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "bl808_ipc.h"
-
- /** @addtogroup BL606P_Peripheral_Driver
- * @{
- */
- /** @addtogroup IPC
- * @{
- */
- /** @defgroup IPC_Private_Macros
- * @{
- */
- #define IPC_LP_OFFSET_IN_M0 0
- #define IPC_D0_OFFSET_IN_M0 16
-
- #define IPC_M0_OFFSET_IN_LP 0
- #define IPC_D0_OFFSET_IN_LP 16
-
- #define IPC_M0_OFFSET_IN_D0 0
- #define IPC_LP_OFFSET_IN_D0 16
-
- /*@} end of group IPC_Private_Macros */
-
- /** @defgroup IPC_Private_Types
- * @{
- */
- /*@} end of group IPC_Private_Types */
-
- /** @defgroup IPC_Private_Variables
- * @{
- */
- ipcIntCallback *m0IpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };
- ipcIntCallback *lpIpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };
- ipcIntCallback *d0IpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };
-
- /*@} end of group IPC_Private_Variables */
-
- /** @defgroup IPC_Global_Variables
- * @{
- */
- /*@} end of group IPC_Global_Variables */
-
- /** @defgroup IPC_Private_Fun_Declaration
- * @{
- */
- /*@} end of group IPC_Private_Fun_Declaration */
-
- /** @defgroup IPC_Private_Functions
- * @{
- */
- /*@} end of group IPC_Private_Functions */
-
- /** @defgroup IPC_Public_Functions
- * @{
- */
- #if defined(CPU_M0) || defined(CPU_LP)
- /****************************************************************************/ /**
- * @brief M0 IPC interrupt init
- *
- * @param onLPTriggerCallBack: Callback when LP trigger
- *
- * @param onD0TriggerCallBack: Callback when D0 trigger
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_M0_Init(ipcIntCallback *onLPTriggerCallBack,
- ipcIntCallback *onD0TriggerCallBack)
- {
- m0IpcIntCbfArra[0] = onLPTriggerCallBack;
- m0IpcIntCbfArra[1] = onD0TriggerCallBack;
-
- IPC_M0_Int_Unmask_By_Word(0xffffffff);
-
- #ifndef BFLB_USE_HAL_DRIVER
- Interrupt_Handler_Register(IPC_M0_IRQn, IPC_M0_IRQHandler);
- #endif
- CPU_Interrupt_Enable(IPC_M0_IRQn);
- }
- #endif
-
- /****************************************************************************/ /**
- * @brief M0 unmask IPC interrupt
- *
- * @param src: M0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_M0_Int_Unmask(IPC_Int_Src_Type src)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
-
- tmpVal = (1 << src);
-
- BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief M0 unmask IPC interrupt by word
- *
- * @param src: IPC interrupt source in word,every bit is interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_M0_Int_Unmask_By_Word(uint32_t src)
- {
- BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, src);
- }
-
- /****************************************************************************/ /**
- * @brief M0 get IPC interrupt raw status
- *
- * @param None
- *
- * @return IPC interrupt raw status
- *
- *******************************************************************************/
- uint32_t IPC_M0_Get_Int_Raw_Status(void)
- {
- return BL_RD_REG(IPC0_BASE, IPC_CPU0_IPC_IRSRR);
- }
-
- /****************************************************************************/ /**
- * @brief M0 clear IPC interrupt
- *
- * @param src: M0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_M0_Clear_Int(IPC_Int_Src_Type src)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
-
- tmpVal = (1 << src);
-
- BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief M0 clear IPC interrupt by word
- *
- * @param src: IPC interrupt source in word,every bit is interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_M0_Clear_Int_By_Word(uint32_t src)
- {
- BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, src);
- }
-
- /****************************************************************************/ /**
- * @brief CPUx trigger IPC interrupt to M0
- *
- * @param src: IPC interrupt source
- *
- * @param cpuxOffset: CPU interrupt offset
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_CPUx_Trigger_M0(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- //CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));
-
- tmpVal = (1 << (src + cpuxOffset));
-
- BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief LP trigger IPC interrupt to M0
- *
- * @param src: LP IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_LP_Trigger_M0(IPC_Grp_Int_Src_Type src)
- {
- IPC_CPUx_Trigger_M0(src, IPC_LP_OFFSET_IN_M0);
- }
-
- /****************************************************************************/ /**
- * @brief D0 trigger IPC interrupt to M0
- *
- * @param src: D0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_D0_Trigger_M0(IPC_Grp_Int_Src_Type src)
- {
- IPC_CPUx_Trigger_M0(src, IPC_D0_OFFSET_IN_M0);
- }
-
- #if defined(CPU_M0) || defined(CPU_LP)
- /****************************************************************************/ /**
- * @brief LP IPC interrupt init
- *
- * @param onM0TriggerCallBack: Callback when M0 trigger
- *
- * @param onD0TriggerCallBack: Callback when D0 trigger
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_LP_Init(ipcIntCallback *onM0TriggerCallBack,
- ipcIntCallback *onD0TriggerCallBack)
- {
- lpIpcIntCbfArra[0] = onM0TriggerCallBack;
- lpIpcIntCbfArra[1] = onD0TriggerCallBack;
-
- IPC_LP_Int_Unmask_By_Word(0xffffffff);
-
- #ifndef BFLB_USE_HAL_DRIVER
- Interrupt_Handler_Register(IPC_LP_IRQn, IPC_LP_IRQHandler);
- #endif
- CPU_Interrupt_Enable(IPC_LP_IRQn);
- }
- #endif
-
- /****************************************************************************/ /**
- * @brief LP unmask IPC interrupt
- *
- * @param src: LP IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_LP_Int_Unmask(IPC_Int_Src_Type src)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
-
- tmpVal = (1 << src);
-
- BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief LP unmask IPC interrupt by word
- *
- * @param src: IPC interrupt source in word,every bit is interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_LP_Int_Unmask_By_Word(uint32_t src)
- {
- BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_IUSR, src);
- }
-
- /****************************************************************************/ /**
- * @brief LP get IPC interrupt raw status
- *
- * @param None
- *
- * @return IPC interrupt raw status
- *
- *******************************************************************************/
- uint32_t IPC_LP_Get_Int_Raw_Status(void)
- {
- return BL_RD_REG(IPC1_BASE, IPC_CPU0_IPC_IRSRR);
- }
-
- /****************************************************************************/ /**
- * @brief LP clear IPC interrupt
- *
- * @param src: LP IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_LP_Clear_Int(IPC_Int_Src_Type src)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
-
- tmpVal = (1 << src);
-
- BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_ICR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief LP clear IPC interrupt by word
- *
- * @param src: IPC interrupt source in word,every bit is interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_LP_Clear_Int_By_Word(uint32_t src)
- {
- BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_ICR, src);
- }
-
- /****************************************************************************/ /**
- * @brief CPUx trigger IPC interrupt to LP
- *
- * @param src: IPC interrupt source
- *
- * @param cpuxOffset: CPU interrupt offset
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_CPUx_Trigger_LP(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- //CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));
-
- tmpVal = (1 << (src + cpuxOffset));
-
- BL_WR_REG(IPC1_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief M0 trigger IPC interrupt to LP
- *
- * @param src: M0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_M0_Trigger_LP(IPC_Grp_nIt_Src_Type src)
- {
- IPC_CPUx_Trigger_LP(src, IPC_M0_OFFSET_IN_LP);
- }
-
- /****************************************************************************/ /**
- * @brief D0 trigger IPC interrupt to LP
- *
- * @param src: D0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_D0_Trigger_LP(IPC_Grp_Int_Src_Type src)
- {
- IPC_CPUx_Trigger_LP(src, IPC_D0_OFFSET_IN_LP);
- }
-
- #if defined(CPU_D0) || defined(CPU_D1)
- /****************************************************************************/ /**
- * @brief D0 IPC interrupt init
- *
- * @param onM0TriggerCallBack: Callback when M0 trigger
- *
- * @param onLPTriggerCallBack: Callback when LP trigger
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_D0_Init(ipcIntCallback *onM0TriggerCallBack,
- ipcIntCallback *onLPTriggerCallBack)
- {
- d0IpcIntCbfArra[0] = onM0TriggerCallBack;
- d0IpcIntCbfArra[1] = onLPTriggerCallBack;
-
- IPC_D0_Int_Unmask_By_Word(0xffffffff);
-
- #ifndef BFLB_USE_HAL_DRIVER
- Interrupt_Handler_Register(IPC_D0_IRQn, IPC_D0_IRQHandler);
- #endif
- CPU_Interrupt_Enable(IPC_D0_IRQn);
- }
- #endif
-
- /****************************************************************************/ /**
- * @brief D0 unmask IPC interrupt
- *
- * @param src: D0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_D0_Int_Unmask(IPC_Int_Src_Type src)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
-
- tmpVal = (1 << src);
-
- BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief D0 unmask IPC interrupt by word
- *
- * @param src: D0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_D0_Int_Unmask_By_Word(uint32_t src)
- {
- BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_IUSR, src);
- }
-
- /****************************************************************************/ /**
- * @brief D0 get IPC interrupt raw status
- *
- * @param None
- *
- * @return IPC interrupt raw status
- *
- *******************************************************************************/
- uint32_t IPC_D0_Get_Int_Raw_Status(void)
- {
- return BL_RD_REG(IPC2_BASE, IPC_CPU0_IPC_IRSRR);
- }
-
- /****************************************************************************/ /**
- * @brief D0 clear IPC interrupt
- *
- * @param src: D0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_D0_Clear_Int(IPC_Int_Src_Type src)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
-
- tmpVal = (1 << src);
-
- BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_ICR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief D0 clear IPC interrupt by word
- *
- * @param src: IPC interrupt source in word,every bit is interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_D0_Clear_Int_By_Word(uint32_t src)
- {
- BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_ICR, src);
- }
-
- /****************************************************************************/ /**
- * @brief CPUx trigger IPC interrupt to D0
- *
- * @param src: IPC interrupt source
- *
- * @param cpuxOffset: CPU interrupt offset
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_CPUx_Trigger_D0(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
- {
- uint32_t tmpVal = 0;
-
- /* Check the parameters */
- //CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));
-
- tmpVal = (1 << (src + cpuxOffset));
-
- BL_WR_REG(IPC2_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
- }
-
- /****************************************************************************/ /**
- * @brief M0 trigger IPC interrupt to D0
- *
- * @param src: M0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_M0_Trigger_D0(IPC_Grp_Int_Src_Type src)
- {
- IPC_CPUx_Trigger_D0(src, IPC_M0_OFFSET_IN_D0);
- }
-
- /****************************************************************************/ /**
- * @brief LP trigger IPC interrupt to D0
- *
- * @param src: LP IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_LP_Trigger_D0(IPC_Grp_Int_Src_Type src)
- {
- IPC_CPUx_Trigger_D0(src, IPC_LP_OFFSET_IN_D0);
- }
-
- /****************************************************************************/ /**
- * @brief M0 trigger IPC interrupt to CPUx
- *
- * @param tgtCPU: Target CPU
- *
- * @param src: IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_M0_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
- {
- switch (tgtCPU) {
- case GLB_CORE_ID_LP:
- IPC_M0_Trigger_LP(src);
- break;
- case GLB_CORE_ID_D0:
- IPC_M0_Trigger_D0(src);
- break;
- default:
- break;
- }
- }
-
- /****************************************************************************/ /**
- * @brief LP trigger IPC interrupt to CPUx
- *
- * @param tgtCPU: Target CPU
- *
- * @param src: IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_LP_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
- {
- switch (tgtCPU) {
- case GLB_CORE_ID_M0:
- IPC_LP_Trigger_M0(src);
- break;
- case GLB_CORE_ID_D0:
- IPC_LP_Trigger_D0(src);
- break;
- default:
- break;
- }
- }
-
- /****************************************************************************/ /**
- * @brief D0 trigger IPC interrupt to CPUx
- *
- * @param tgtCPU: Target CPU
- *
- * @param src: IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_D0_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
- {
- switch (tgtCPU) {
- case GLB_CORE_ID_M0:
- IPC_D0_Trigger_M0(src);
- break;
- case GLB_CORE_ID_LP:
- IPC_D0_Trigger_LP(src);
- break;
- default:
- break;
- }
- }
-
- /****************************************************************************/ /**
- * @brief D0 trigger IPC interrupt to D1
- *
- * @param src: D0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_Trigger_Target_CPU(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
- {
- GLB_CORE_ID_Type localCPU = GLB_Get_Core_Type();
-
- switch (localCPU) {
- case GLB_CORE_ID_M0:
- IPC_M0_Trigger_CPUx(tgtCPU, src);
- break;
- case GLB_CORE_ID_LP:
- IPC_LP_Trigger_CPUx(tgtCPU, src);
- break;
- case GLB_CORE_ID_D0:
- IPC_D0_Trigger_CPUx(tgtCPU, src);
- break;
- default:
- break;
- }
- }
-
- /****************************************************************************/ /**
- * @brief D0 trigger IPC interrupt to D1
- *
- * @param src: D0 IPC interrupt source
- *
- * @return None
- *
- *******************************************************************************/
- void IPC_Common_Interrupt_Handler(uint32_t irqStatus, ipcIntCallback *callBack[GLB_CORE_ID_MAX - 1])
- {
- uint32_t tmp;
- uint32_t grp = 0;
-
- for (grp = 0; grp < GLB_CORE_ID_MAX - 1; grp++) {
- tmp = (irqStatus >> (16 * grp)) & 0xffff;
- if (tmp != 0) {
- if (callBack[grp] != NULL) {
- callBack[grp](tmp);
- }
- }
- }
- }
-
- /****************************************************************************/ /**
- * @brief M0 IPC IRQ handler
- *
- * @param None
- *
- * @return None
- *
- *******************************************************************************/
- #ifndef BFLB_USE_HAL_DRIVER
- void IPC_M0_IRQHandler(void)
- {
- uint32_t irqStatus;
- irqStatus = IPC_M0_Get_Int_Raw_Status();
- IPC_Common_Interrupt_Handler(irqStatus, m0IpcIntCbfArra);
- IPC_M0_Clear_Int_By_Word(irqStatus);
- }
- #endif
-
- /****************************************************************************/ /**
- * @brief LP IPC IRQ handler
- *
- * @param None
- *
- * @return None
- *
- *******************************************************************************/
- #ifndef BFLB_USE_HAL_DRIVER
- void IPC_LP_IRQHandler(void)
- {
- uint32_t irqStatus;
- irqStatus = IPC_LP_Get_Int_Raw_Status();
- IPC_Common_Interrupt_Handler(irqStatus, lpIpcIntCbfArra);
- IPC_LP_Clear_Int_By_Word(irqStatus);
- }
- #endif
-
- /****************************************************************************/ /**
- * @brief D0 IPC IRQ handler
- *
- * @param None
- *
- * @return None
- *
- *******************************************************************************/
- #ifndef BFLB_USE_HAL_DRIVER
- void IPC_D0_IRQHandler(void)
- {
- uint32_t irqStatus;
- irqStatus = IPC_D0_Get_Int_Raw_Status();
- IPC_Common_Interrupt_Handler(irqStatus, d0IpcIntCbfArra);
- IPC_D0_Clear_Int_By_Word(irqStatus);
- }
- #endif
-
- /*@} end of group IPC_Public_Functions */
-
- /*@} end of group IPC */
-
- /*@} end of group BL606P_Peripheral_Driver */
基本试验了IPC通讯,寄存器和触发动作应该是没问题的;看来后续要使用M1S_BL808_SDK作为开发主力的SDK了,好多函数封装了,功能实现的也比较好;只是目前只能在Linux下的开发环境使用,对于笔记本性能有限,懒得开虚拟机的我,还是eciplse的Windows客户端使用起来更方便一点。