• BL808学习日志-1-三核通讯


    接上个博客,今天实验了一下BL808的IPC通讯,使用的是博流自己的SDK;参考手册上并没有说明各个寄存器,是通过网友的结论和自己的部分修改达成的。

    一、实验代码

    1.目前仅测试了LP内核和M0内核之间的通讯,使用SIPEED的M1S_Dock开发板,修改了\bouffalo_sdk\bsp\board\bl808dk\board.c文件,先将debug的管脚14 15分配给M0内核使用,方便打印M0内核的日志;

    1. static void console_init()
    2. {
    3. struct bflb_device_s *gpio;
    4. gpio = bflb_device_get_by_name("gpio");
    5. #if defined(CPU_M0)
    6. bflb_gpio_uart_init(gpio, GPIO_PIN_14, GPIO_UART_FUNC_UART0_TX);
    7. bflb_gpio_uart_init(gpio, GPIO_PIN_15, GPIO_UART_FUNC_UART0_RX);
    8. #elif defined(CPU_D0)
    9. /* sipeed m1s dock */
    10. bflb_gpio_init(gpio, GPIO_PIN_16, 21 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
    11. bflb_gpio_init(gpio, GPIO_PIN_17, 21 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
    12. #elif defined(CPU_LP)
    13. /* map GPIO_PIN_18 and GPIO_PIN_19 as UART for LP core */
    14. bflb_gpio_uart_init(gpio, GPIO_PIN_18, GPIO_UART_FUNC_UART1_TX);
    15. bflb_gpio_uart_init(gpio, GPIO_PIN_19, GPIO_UART_FUNC_UART1_RX);
    16. #endif
    17. struct bflb_uart_config_s cfg;
    18. cfg.baudrate = 2000000;
    19. cfg.data_bits = UART_DATA_BITS_8;
    20. cfg.stop_bits = UART_STOP_BITS_1;
    21. cfg.parity = UART_PARITY_NONE;
    22. cfg.flow_ctrl = 0;
    23. cfg.tx_fifo_threshold = 7;
    24. cfg.rx_fifo_threshold = 7;
    25. #if defined(CPU_M0)
    26. uart0 = bflb_device_get_by_name("uart0");
    27. #elif defined(CPU_D0)
    28. uart0 = bflb_device_get_by_name("uart3");
    29. #elif defined(CPU_LP)
    30. uart0 = bflb_device_get_by_name("uart1");
    31. #endif
    32. bflb_uart_init(uart0, &cfg);
    33. bflb_uart_set_console(uart0);
    34. }

    2.在bouffalo_sdk\examples\bl808_triplecore\helloworld_m0例程上进行修改,M0主函数中对中断寄存器进行了初始化,定义了中断回调函数;并在中断函数中输出IPC中断号;其中对LED灯进行了一个0.5Hz的闪烁,来提示系统进行了正常的IPC通讯。

    1. #include "bflb_mtimer.h"
    2. #include "board.h"
    3. #include "bflb_gpio.h"
    4. #include "bl808.h"
    5. #include "ipc_reg.h"
    6. #include "bl808_ipc.h"
    7. #include "bl808_common.h"
    8. #define DBG_TAG "M0"
    9. #include "log.h"
    10. struct bflb_device_s *gpio;
    11. uint32_t value = 0;
    12. void IPC_M0_IRQHandler(void)
    13. {
    14. gpio = bflb_device_get_by_name("gpio");
    15. // Read Interrupt Status
    16. uint32_t irqStatus = BL_RD_REG(IPC0_BASE, IPC_CPU0_IPC_IRSRR);
    17. //Interrupt handle
    18. bflb_gpio_set(gpio,GPIO_PIN_8);
    19. LOG_F("the irqStatus value is %d\r\n",irqStatus);
    20. value = 1;
    21. //Clear Interrypt
    22. BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, irqStatus);
    23. }
    24. void m0_ipc_init(void)
    25. {
    26. /* setup the IPC Interupt */
    27. bflb_irq_attach(IPC_M0_IRQn, IPC_M0_IRQHandler, NULL);
    28. BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, 1 << 1);
    29. bflb_irq_enable(IPC_M0_IRQn);
    30. }
    31. int main(void)
    32. {
    33. board_init();
    34. m0_ipc_init();
    35. while (1) {
    36. if(value == 1)
    37. {
    38. bflb_gpio_set(gpio,GPIO_PIN_8);
    39. bflb_mtimer_delay_ms(1000);
    40. bflb_gpio_reset(gpio,GPIO_PIN_8);
    41. LOG_F("hello world m0\r\n");
    42. LOG_E("hello world m0\r\n");
    43. LOG_W("hello world m0\r\n");
    44. LOG_I("hello world m0\r\n");
    45. LOG_D("hello world m0\r\n");
    46. LOG_T("hello world m0\r\n");
    47. }
    48. bflb_mtimer_delay_ms(1000);
    49. }
    50. }

    将M0程序烧录到开发板中;

    2.在bouffalo_sdk\examples\bl808_triplecore\helloworld_lp将LP板载外设初始化,然后打开开发板上的LED灯,使用IO8控制;默认上电拉低IO8,打开闪光灯;进入主循环之前,使能M0内核的IPC通道1;

    1. #include "bflb_mtimer.h"
    2. #include "board.h"
    3. #include "bflb_gpio.h"
    4. #include "bl808.h"
    5. #include "ipc_reg.h"
    6. #include "bl808_common.h"
    7. #define DBG_TAG "MAIN"
    8. #include "log.h"
    9. struct bflb_device_s *gpio;
    10. int main(void)
    11. {
    12. board_init();
    13. gpio = bflb_device_get_by_name("gpio");
    14. bflb_gpio_init(gpio, GPIO_PIN_8, GPIO_OUTPUT | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_0);
    15. bflb_gpio_reset(gpio,GPIO_PIN_8);
    16. LOG_F("hello world lp\r\n");
    17. LOG_E("hello world lp\r\n");
    18. LOG_W("hello world lp\r\n");
    19. LOG_I("hello world lp\r\n");
    20. LOG_D("hello world lp\r\n");
    21. LOG_T("hello world lp\r\n");
    22. LOG_I("LPcore will comunity to M0 core");
    23. BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, 1 << 1);
    24. while (1) {
    25. bflb_mtimer_delay_ms(1000);
    26. }
    27. }

     将LP内核程序烧录到开发板中,会看到LED灯先是亮起,然后被M0主程序改为1秒闪烁1次;

    3.若是想看debug日志,默认是查看M0内核的日志,可以把board.c文件中LP和M0的串口引脚对换。输出的LP内核的日志:

    1. ____ __ __ _ _ _
    2. | _ \ / _|/ _| | | | | | |
    3. | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
    4. | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
    5. | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
    6. |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
    7. Build:18:11:43,Oct 1 2023
    8. Copyright (c) 2022 Bouffalolab team
    9. lp does not use memheap due to little ram
    10. sig1:ffff76ff
    11. sig2:0000ffff
    12. cgen1:9f7ffffd
    13. [F][LP] hello world lp
    14. [E][LP] hello world lp
    15. [W][LP] hello world lp
    16. [I][LP] hello world lp
    17. [I][LP] LPcore will comunity to M0 core

    4.输出的M0内核日志:

    1. ____ __ __ _ _ _
    2. | _ \ / _|/ _| | | | | | |
    3. | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
    4. | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
    5. | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
    6. |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
    7. Build:18:21:31,Oct 1 2023
    8. Copyright (c) 2022 Bouffalolab team
    9. ======== flash cfg ========
    10. flash size 0x01000000
    11. jedec id 0xEF4018
    12. mid 0xEF
    13. iomode 0x04
    14. clk delay 0x01
    15. clk invert 0x01
    16. read reg cmd0 0x05
    17. read reg cmd1 0x35
    18. write reg cmd0 0x01
    19. write reg cmd1 0x31
    20. qe write len 0x01
    21. cread support 0x00
    22. cread code 0xFF
    23. burst wrap cmd 0x77
    24. ===========================
    25. dynamic memory init success,heap size = 21 Kbyte
    26. sig1:ffff32ff
    27. sig2:0000ffff
    28. [F][M0] the irqStatus value is 2
    29. [F][M0] hello world m0
    30. [E][M0] hello world m0

    可以看到,M0日志显示"the irqSstatus value is 2",也就是通道1触发; 

    4.随机试验了一下其他的通道,试验通道0能否正常触发,修改LP内核main.c文件的触发为

    1. int main(void)
    2. {
    3. board_init();
    4. gpio = bflb_device_get_by_name("gpio");
    5. bflb_gpio_init(gpio, GPIO_PIN_8, GPIO_OUTPUT | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_0);
    6. bflb_gpio_reset(gpio,GPIO_PIN_8);
    7. LOG_F("hello world lp\r\n");
    8. LOG_E("hello world lp\r\n");
    9. LOG_W("hello world lp\r\n");
    10. LOG_I("hello world lp\r\n");
    11. LOG_D("hello world lp\r\n");
    12. LOG_T("hello world lp\r\n");
    13. LOG_I("LPcore will comunity to M0 core");
    14. BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, 1 << 0);
    15. while (1) {
    16. bflb_mtimer_delay_ms(1000);
    17. }
    18. }

    修改M0内核中main.c文件中的使能通道

    1. void m0_ipc_init(void)
    2. {
    3. /* setup the IPC Interupt */
    4. bflb_irq_attach(IPC_M0_IRQn, IPC_M0_IRQHandler, NULL);
    5. BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, 1 << 0);
    6. bflb_irq_enable(IPC_M0_IRQn);
    7. }

     编译烧录到开发板,发现M0内核的输出日志发生变化为"the irqSstatus value is 1",也就是通道0触发; 

    1. ____ __ __ _ _ _
    2. | _ \ / _|/ _| | | | | | |
    3. | |_) | ___ _ _| |_| |_ __ _| | ___ | | __ _| |__
    4. | _ < / _ \| | | | _| _/ _` | |/ _ \| |/ _` | '_ \
    5. | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
    6. |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/
    7. Build:18:21:31,Oct 1 2023
    8. Copyright (c) 2022 Bouffalolab team
    9. ======== flash cfg ========
    10. flash size 0x01000000
    11. jedec id 0xEF4018
    12. mid 0xEF
    13. iomode 0x04
    14. clk delay 0x01
    15. clk invert 0x01
    16. read reg cmd0 0x05
    17. read reg cmd1 0x35
    18. write reg cmd0 0x01
    19. write reg cmd1 0x31
    20. qe write len 0x01
    21. cread support 0x00
    22. cread code 0xFF
    23. burst wrap cmd 0x77
    24. ===========================
    25. dynamic memory init success,heap size = 21 Kbyte
    26. sig1:ffff32ff
    27. sig2:0000ffff
    28. [F][M0] the irqStatus value is 1
    29. [F][M0] hello world m0
    30. [E][M0] hello world m0

    二、SIPEED默认库IPC描述

    SIPEED的默认M1S_BL808_SDK中对IPC和XRAM进行了更深层次的封装,也实现了XRAM的数据交互,包括bl808_ipc.c文件,其中XRAM是作为一个组件使用,封装的相当好,这里也是很不明白为什么博流自己的SDK却删掉了这部分的内容。贴个代码,应该就知道怎么使用了。

    1. /*
    2. * Copyright (c) 2020 Bouffalolab.
    3. *
    4. * This file is part of
    5. * *** Bouffalolab Software Dev Kit ***
    6. * (see www.bouffalolab.com).
    7. *
    8. * Redistribution and use in source and binary forms, with or without modification,
    9. * are permitted provided that the following conditions are met:
    10. * 1. Redistributions of source code must retain the above copyright notice,
    11. * this list of conditions and the following disclaimer.
    12. * 2. Redistributions in binary form must reproduce the above copyright notice,
    13. * this list of conditions and the following disclaimer in the documentation
    14. * and/or other materials provided with the distribution.
    15. * 3. Neither the name of Bouffalo Lab nor the names of its contributors
    16. * may be used to endorse or promote products derived from this software
    17. * without specific prior written permission.
    18. *
    19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    20. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    25. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    26. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    27. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29. */
    30. #include "bl808_ipc.h"
    31. /** @addtogroup BL606P_Peripheral_Driver
    32. * @{
    33. */
    34. /** @addtogroup IPC
    35. * @{
    36. */
    37. /** @defgroup IPC_Private_Macros
    38. * @{
    39. */
    40. #define IPC_LP_OFFSET_IN_M0 0
    41. #define IPC_D0_OFFSET_IN_M0 16
    42. #define IPC_M0_OFFSET_IN_LP 0
    43. #define IPC_D0_OFFSET_IN_LP 16
    44. #define IPC_M0_OFFSET_IN_D0 0
    45. #define IPC_LP_OFFSET_IN_D0 16
    46. /*@} end of group IPC_Private_Macros */
    47. /** @defgroup IPC_Private_Types
    48. * @{
    49. */
    50. /*@} end of group IPC_Private_Types */
    51. /** @defgroup IPC_Private_Variables
    52. * @{
    53. */
    54. ipcIntCallback *m0IpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };
    55. ipcIntCallback *lpIpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };
    56. ipcIntCallback *d0IpcIntCbfArra[GLB_CORE_ID_MAX - 1] = { NULL };
    57. /*@} end of group IPC_Private_Variables */
    58. /** @defgroup IPC_Global_Variables
    59. * @{
    60. */
    61. /*@} end of group IPC_Global_Variables */
    62. /** @defgroup IPC_Private_Fun_Declaration
    63. * @{
    64. */
    65. /*@} end of group IPC_Private_Fun_Declaration */
    66. /** @defgroup IPC_Private_Functions
    67. * @{
    68. */
    69. /*@} end of group IPC_Private_Functions */
    70. /** @defgroup IPC_Public_Functions
    71. * @{
    72. */
    73. #if defined(CPU_M0) || defined(CPU_LP)
    74. /****************************************************************************/ /**
    75. * @brief M0 IPC interrupt init
    76. *
    77. * @param onLPTriggerCallBack: Callback when LP trigger
    78. *
    79. * @param onD0TriggerCallBack: Callback when D0 trigger
    80. *
    81. * @return None
    82. *
    83. *******************************************************************************/
    84. void IPC_M0_Init(ipcIntCallback *onLPTriggerCallBack,
    85. ipcIntCallback *onD0TriggerCallBack)
    86. {
    87. m0IpcIntCbfArra[0] = onLPTriggerCallBack;
    88. m0IpcIntCbfArra[1] = onD0TriggerCallBack;
    89. IPC_M0_Int_Unmask_By_Word(0xffffffff);
    90. #ifndef BFLB_USE_HAL_DRIVER
    91. Interrupt_Handler_Register(IPC_M0_IRQn, IPC_M0_IRQHandler);
    92. #endif
    93. CPU_Interrupt_Enable(IPC_M0_IRQn);
    94. }
    95. #endif
    96. /****************************************************************************/ /**
    97. * @brief M0 unmask IPC interrupt
    98. *
    99. * @param src: M0 IPC interrupt source
    100. *
    101. * @return None
    102. *
    103. *******************************************************************************/
    104. void IPC_M0_Int_Unmask(IPC_Int_Src_Type src)
    105. {
    106. uint32_t tmpVal = 0;
    107. /* Check the parameters */
    108. CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
    109. tmpVal = (1 << src);
    110. BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
    111. }
    112. /****************************************************************************/ /**
    113. * @brief M0 unmask IPC interrupt by word
    114. *
    115. * @param src: IPC interrupt source in word,every bit is interrupt source
    116. *
    117. * @return None
    118. *
    119. *******************************************************************************/
    120. void IPC_M0_Int_Unmask_By_Word(uint32_t src)
    121. {
    122. BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_IUSR, src);
    123. }
    124. /****************************************************************************/ /**
    125. * @brief M0 get IPC interrupt raw status
    126. *
    127. * @param None
    128. *
    129. * @return IPC interrupt raw status
    130. *
    131. *******************************************************************************/
    132. uint32_t IPC_M0_Get_Int_Raw_Status(void)
    133. {
    134. return BL_RD_REG(IPC0_BASE, IPC_CPU0_IPC_IRSRR);
    135. }
    136. /****************************************************************************/ /**
    137. * @brief M0 clear IPC interrupt
    138. *
    139. * @param src: M0 IPC interrupt source
    140. *
    141. * @return None
    142. *
    143. *******************************************************************************/
    144. void IPC_M0_Clear_Int(IPC_Int_Src_Type src)
    145. {
    146. uint32_t tmpVal = 0;
    147. /* Check the parameters */
    148. CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
    149. tmpVal = (1 << src);
    150. BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, tmpVal);
    151. }
    152. /****************************************************************************/ /**
    153. * @brief M0 clear IPC interrupt by word
    154. *
    155. * @param src: IPC interrupt source in word,every bit is interrupt source
    156. *
    157. * @return None
    158. *
    159. *******************************************************************************/
    160. void IPC_M0_Clear_Int_By_Word(uint32_t src)
    161. {
    162. BL_WR_REG(IPC0_BASE, IPC_CPU0_IPC_ICR, src);
    163. }
    164. /****************************************************************************/ /**
    165. * @brief CPUx trigger IPC interrupt to M0
    166. *
    167. * @param src: IPC interrupt source
    168. *
    169. * @param cpuxOffset: CPU interrupt offset
    170. *
    171. * @return None
    172. *
    173. *******************************************************************************/
    174. void IPC_CPUx_Trigger_M0(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
    175. {
    176. uint32_t tmpVal = 0;
    177. /* Check the parameters */
    178. //CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));
    179. tmpVal = (1 << (src + cpuxOffset));
    180. BL_WR_REG(IPC0_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
    181. }
    182. /****************************************************************************/ /**
    183. * @brief LP trigger IPC interrupt to M0
    184. *
    185. * @param src: LP IPC interrupt source
    186. *
    187. * @return None
    188. *
    189. *******************************************************************************/
    190. void IPC_LP_Trigger_M0(IPC_Grp_Int_Src_Type src)
    191. {
    192. IPC_CPUx_Trigger_M0(src, IPC_LP_OFFSET_IN_M0);
    193. }
    194. /****************************************************************************/ /**
    195. * @brief D0 trigger IPC interrupt to M0
    196. *
    197. * @param src: D0 IPC interrupt source
    198. *
    199. * @return None
    200. *
    201. *******************************************************************************/
    202. void IPC_D0_Trigger_M0(IPC_Grp_Int_Src_Type src)
    203. {
    204. IPC_CPUx_Trigger_M0(src, IPC_D0_OFFSET_IN_M0);
    205. }
    206. #if defined(CPU_M0) || defined(CPU_LP)
    207. /****************************************************************************/ /**
    208. * @brief LP IPC interrupt init
    209. *
    210. * @param onM0TriggerCallBack: Callback when M0 trigger
    211. *
    212. * @param onD0TriggerCallBack: Callback when D0 trigger
    213. *
    214. * @return None
    215. *
    216. *******************************************************************************/
    217. void IPC_LP_Init(ipcIntCallback *onM0TriggerCallBack,
    218. ipcIntCallback *onD0TriggerCallBack)
    219. {
    220. lpIpcIntCbfArra[0] = onM0TriggerCallBack;
    221. lpIpcIntCbfArra[1] = onD0TriggerCallBack;
    222. IPC_LP_Int_Unmask_By_Word(0xffffffff);
    223. #ifndef BFLB_USE_HAL_DRIVER
    224. Interrupt_Handler_Register(IPC_LP_IRQn, IPC_LP_IRQHandler);
    225. #endif
    226. CPU_Interrupt_Enable(IPC_LP_IRQn);
    227. }
    228. #endif
    229. /****************************************************************************/ /**
    230. * @brief LP unmask IPC interrupt
    231. *
    232. * @param src: LP IPC interrupt source
    233. *
    234. * @return None
    235. *
    236. *******************************************************************************/
    237. void IPC_LP_Int_Unmask(IPC_Int_Src_Type src)
    238. {
    239. uint32_t tmpVal = 0;
    240. /* Check the parameters */
    241. CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
    242. tmpVal = (1 << src);
    243. BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
    244. }
    245. /****************************************************************************/ /**
    246. * @brief LP unmask IPC interrupt by word
    247. *
    248. * @param src: IPC interrupt source in word,every bit is interrupt source
    249. *
    250. * @return None
    251. *
    252. *******************************************************************************/
    253. void IPC_LP_Int_Unmask_By_Word(uint32_t src)
    254. {
    255. BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_IUSR, src);
    256. }
    257. /****************************************************************************/ /**
    258. * @brief LP get IPC interrupt raw status
    259. *
    260. * @param None
    261. *
    262. * @return IPC interrupt raw status
    263. *
    264. *******************************************************************************/
    265. uint32_t IPC_LP_Get_Int_Raw_Status(void)
    266. {
    267. return BL_RD_REG(IPC1_BASE, IPC_CPU0_IPC_IRSRR);
    268. }
    269. /****************************************************************************/ /**
    270. * @brief LP clear IPC interrupt
    271. *
    272. * @param src: LP IPC interrupt source
    273. *
    274. * @return None
    275. *
    276. *******************************************************************************/
    277. void IPC_LP_Clear_Int(IPC_Int_Src_Type src)
    278. {
    279. uint32_t tmpVal = 0;
    280. /* Check the parameters */
    281. CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
    282. tmpVal = (1 << src);
    283. BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_ICR, tmpVal);
    284. }
    285. /****************************************************************************/ /**
    286. * @brief LP clear IPC interrupt by word
    287. *
    288. * @param src: IPC interrupt source in word,every bit is interrupt source
    289. *
    290. * @return None
    291. *
    292. *******************************************************************************/
    293. void IPC_LP_Clear_Int_By_Word(uint32_t src)
    294. {
    295. BL_WR_REG(IPC1_BASE, IPC_CPU0_IPC_ICR, src);
    296. }
    297. /****************************************************************************/ /**
    298. * @brief CPUx trigger IPC interrupt to LP
    299. *
    300. * @param src: IPC interrupt source
    301. *
    302. * @param cpuxOffset: CPU interrupt offset
    303. *
    304. * @return None
    305. *
    306. *******************************************************************************/
    307. void IPC_CPUx_Trigger_LP(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
    308. {
    309. uint32_t tmpVal = 0;
    310. /* Check the parameters */
    311. //CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));
    312. tmpVal = (1 << (src + cpuxOffset));
    313. BL_WR_REG(IPC1_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
    314. }
    315. /****************************************************************************/ /**
    316. * @brief M0 trigger IPC interrupt to LP
    317. *
    318. * @param src: M0 IPC interrupt source
    319. *
    320. * @return None
    321. *
    322. *******************************************************************************/
    323. void IPC_M0_Trigger_LP(IPC_Grp_nIt_Src_Type src)
    324. {
    325. IPC_CPUx_Trigger_LP(src, IPC_M0_OFFSET_IN_LP);
    326. }
    327. /****************************************************************************/ /**
    328. * @brief D0 trigger IPC interrupt to LP
    329. *
    330. * @param src: D0 IPC interrupt source
    331. *
    332. * @return None
    333. *
    334. *******************************************************************************/
    335. void IPC_D0_Trigger_LP(IPC_Grp_Int_Src_Type src)
    336. {
    337. IPC_CPUx_Trigger_LP(src, IPC_D0_OFFSET_IN_LP);
    338. }
    339. #if defined(CPU_D0) || defined(CPU_D1)
    340. /****************************************************************************/ /**
    341. * @brief D0 IPC interrupt init
    342. *
    343. * @param onM0TriggerCallBack: Callback when M0 trigger
    344. *
    345. * @param onLPTriggerCallBack: Callback when LP trigger
    346. *
    347. * @return None
    348. *
    349. *******************************************************************************/
    350. void IPC_D0_Init(ipcIntCallback *onM0TriggerCallBack,
    351. ipcIntCallback *onLPTriggerCallBack)
    352. {
    353. d0IpcIntCbfArra[0] = onM0TriggerCallBack;
    354. d0IpcIntCbfArra[1] = onLPTriggerCallBack;
    355. IPC_D0_Int_Unmask_By_Word(0xffffffff);
    356. #ifndef BFLB_USE_HAL_DRIVER
    357. Interrupt_Handler_Register(IPC_D0_IRQn, IPC_D0_IRQHandler);
    358. #endif
    359. CPU_Interrupt_Enable(IPC_D0_IRQn);
    360. }
    361. #endif
    362. /****************************************************************************/ /**
    363. * @brief D0 unmask IPC interrupt
    364. *
    365. * @param src: D0 IPC interrupt source
    366. *
    367. * @return None
    368. *
    369. *******************************************************************************/
    370. void IPC_D0_Int_Unmask(IPC_Int_Src_Type src)
    371. {
    372. uint32_t tmpVal = 0;
    373. /* Check the parameters */
    374. CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
    375. tmpVal = (1 << src);
    376. BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_IUSR, tmpVal);
    377. }
    378. /****************************************************************************/ /**
    379. * @brief D0 unmask IPC interrupt by word
    380. *
    381. * @param src: D0 IPC interrupt source
    382. *
    383. * @return None
    384. *
    385. *******************************************************************************/
    386. void IPC_D0_Int_Unmask_By_Word(uint32_t src)
    387. {
    388. BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_IUSR, src);
    389. }
    390. /****************************************************************************/ /**
    391. * @brief D0 get IPC interrupt raw status
    392. *
    393. * @param None
    394. *
    395. * @return IPC interrupt raw status
    396. *
    397. *******************************************************************************/
    398. uint32_t IPC_D0_Get_Int_Raw_Status(void)
    399. {
    400. return BL_RD_REG(IPC2_BASE, IPC_CPU0_IPC_IRSRR);
    401. }
    402. /****************************************************************************/ /**
    403. * @brief D0 clear IPC interrupt
    404. *
    405. * @param src: D0 IPC interrupt source
    406. *
    407. * @return None
    408. *
    409. *******************************************************************************/
    410. void IPC_D0_Clear_Int(IPC_Int_Src_Type src)
    411. {
    412. uint32_t tmpVal = 0;
    413. /* Check the parameters */
    414. CHECK_PARAM(IS_IPC_INT_SRC_TYPE(src));
    415. tmpVal = (1 << src);
    416. BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_ICR, tmpVal);
    417. }
    418. /****************************************************************************/ /**
    419. * @brief D0 clear IPC interrupt by word
    420. *
    421. * @param src: IPC interrupt source in word,every bit is interrupt source
    422. *
    423. * @return None
    424. *
    425. *******************************************************************************/
    426. void IPC_D0_Clear_Int_By_Word(uint32_t src)
    427. {
    428. BL_WR_REG(IPC2_BASE, IPC_CPU0_IPC_ICR, src);
    429. }
    430. /****************************************************************************/ /**
    431. * @brief CPUx trigger IPC interrupt to D0
    432. *
    433. * @param src: IPC interrupt source
    434. *
    435. * @param cpuxOffset: CPU interrupt offset
    436. *
    437. * @return None
    438. *
    439. *******************************************************************************/
    440. void IPC_CPUx_Trigger_D0(IPC_Grp_Int_Src_Type src, uint8_t cpuxOffset)
    441. {
    442. uint32_t tmpVal = 0;
    443. /* Check the parameters */
    444. //CHECK_PARAM(IS_IPC_Grp_Int_Src_Type(src));
    445. tmpVal = (1 << (src + cpuxOffset));
    446. BL_WR_REG(IPC2_BASE, IPC_CPU1_IPC_ISWR, tmpVal);
    447. }
    448. /****************************************************************************/ /**
    449. * @brief M0 trigger IPC interrupt to D0
    450. *
    451. * @param src: M0 IPC interrupt source
    452. *
    453. * @return None
    454. *
    455. *******************************************************************************/
    456. void IPC_M0_Trigger_D0(IPC_Grp_Int_Src_Type src)
    457. {
    458. IPC_CPUx_Trigger_D0(src, IPC_M0_OFFSET_IN_D0);
    459. }
    460. /****************************************************************************/ /**
    461. * @brief LP trigger IPC interrupt to D0
    462. *
    463. * @param src: LP IPC interrupt source
    464. *
    465. * @return None
    466. *
    467. *******************************************************************************/
    468. void IPC_LP_Trigger_D0(IPC_Grp_Int_Src_Type src)
    469. {
    470. IPC_CPUx_Trigger_D0(src, IPC_LP_OFFSET_IN_D0);
    471. }
    472. /****************************************************************************/ /**
    473. * @brief M0 trigger IPC interrupt to CPUx
    474. *
    475. * @param tgtCPU: Target CPU
    476. *
    477. * @param src: IPC interrupt source
    478. *
    479. * @return None
    480. *
    481. *******************************************************************************/
    482. void IPC_M0_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
    483. {
    484. switch (tgtCPU) {
    485. case GLB_CORE_ID_LP:
    486. IPC_M0_Trigger_LP(src);
    487. break;
    488. case GLB_CORE_ID_D0:
    489. IPC_M0_Trigger_D0(src);
    490. break;
    491. default:
    492. break;
    493. }
    494. }
    495. /****************************************************************************/ /**
    496. * @brief LP trigger IPC interrupt to CPUx
    497. *
    498. * @param tgtCPU: Target CPU
    499. *
    500. * @param src: IPC interrupt source
    501. *
    502. * @return None
    503. *
    504. *******************************************************************************/
    505. void IPC_LP_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
    506. {
    507. switch (tgtCPU) {
    508. case GLB_CORE_ID_M0:
    509. IPC_LP_Trigger_M0(src);
    510. break;
    511. case GLB_CORE_ID_D0:
    512. IPC_LP_Trigger_D0(src);
    513. break;
    514. default:
    515. break;
    516. }
    517. }
    518. /****************************************************************************/ /**
    519. * @brief D0 trigger IPC interrupt to CPUx
    520. *
    521. * @param tgtCPU: Target CPU
    522. *
    523. * @param src: IPC interrupt source
    524. *
    525. * @return None
    526. *
    527. *******************************************************************************/
    528. void IPC_D0_Trigger_CPUx(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
    529. {
    530. switch (tgtCPU) {
    531. case GLB_CORE_ID_M0:
    532. IPC_D0_Trigger_M0(src);
    533. break;
    534. case GLB_CORE_ID_LP:
    535. IPC_D0_Trigger_LP(src);
    536. break;
    537. default:
    538. break;
    539. }
    540. }
    541. /****************************************************************************/ /**
    542. * @brief D0 trigger IPC interrupt to D1
    543. *
    544. * @param src: D0 IPC interrupt source
    545. *
    546. * @return None
    547. *
    548. *******************************************************************************/
    549. void IPC_Trigger_Target_CPU(GLB_CORE_ID_Type tgtCPU, IPC_Grp_Int_Src_Type src)
    550. {
    551. GLB_CORE_ID_Type localCPU = GLB_Get_Core_Type();
    552. switch (localCPU) {
    553. case GLB_CORE_ID_M0:
    554. IPC_M0_Trigger_CPUx(tgtCPU, src);
    555. break;
    556. case GLB_CORE_ID_LP:
    557. IPC_LP_Trigger_CPUx(tgtCPU, src);
    558. break;
    559. case GLB_CORE_ID_D0:
    560. IPC_D0_Trigger_CPUx(tgtCPU, src);
    561. break;
    562. default:
    563. break;
    564. }
    565. }
    566. /****************************************************************************/ /**
    567. * @brief D0 trigger IPC interrupt to D1
    568. *
    569. * @param src: D0 IPC interrupt source
    570. *
    571. * @return None
    572. *
    573. *******************************************************************************/
    574. void IPC_Common_Interrupt_Handler(uint32_t irqStatus, ipcIntCallback *callBack[GLB_CORE_ID_MAX - 1])
    575. {
    576. uint32_t tmp;
    577. uint32_t grp = 0;
    578. for (grp = 0; grp < GLB_CORE_ID_MAX - 1; grp++) {
    579. tmp = (irqStatus >> (16 * grp)) & 0xffff;
    580. if (tmp != 0) {
    581. if (callBack[grp] != NULL) {
    582. callBack[grp](tmp);
    583. }
    584. }
    585. }
    586. }
    587. /****************************************************************************/ /**
    588. * @brief M0 IPC IRQ handler
    589. *
    590. * @param None
    591. *
    592. * @return None
    593. *
    594. *******************************************************************************/
    595. #ifndef BFLB_USE_HAL_DRIVER
    596. void IPC_M0_IRQHandler(void)
    597. {
    598. uint32_t irqStatus;
    599. irqStatus = IPC_M0_Get_Int_Raw_Status();
    600. IPC_Common_Interrupt_Handler(irqStatus, m0IpcIntCbfArra);
    601. IPC_M0_Clear_Int_By_Word(irqStatus);
    602. }
    603. #endif
    604. /****************************************************************************/ /**
    605. * @brief LP IPC IRQ handler
    606. *
    607. * @param None
    608. *
    609. * @return None
    610. *
    611. *******************************************************************************/
    612. #ifndef BFLB_USE_HAL_DRIVER
    613. void IPC_LP_IRQHandler(void)
    614. {
    615. uint32_t irqStatus;
    616. irqStatus = IPC_LP_Get_Int_Raw_Status();
    617. IPC_Common_Interrupt_Handler(irqStatus, lpIpcIntCbfArra);
    618. IPC_LP_Clear_Int_By_Word(irqStatus);
    619. }
    620. #endif
    621. /****************************************************************************/ /**
    622. * @brief D0 IPC IRQ handler
    623. *
    624. * @param None
    625. *
    626. * @return None
    627. *
    628. *******************************************************************************/
    629. #ifndef BFLB_USE_HAL_DRIVER
    630. void IPC_D0_IRQHandler(void)
    631. {
    632. uint32_t irqStatus;
    633. irqStatus = IPC_D0_Get_Int_Raw_Status();
    634. IPC_Common_Interrupt_Handler(irqStatus, d0IpcIntCbfArra);
    635. IPC_D0_Clear_Int_By_Word(irqStatus);
    636. }
    637. #endif
    638. /*@} end of group IPC_Public_Functions */
    639. /*@} end of group IPC */
    640. /*@} end of group BL606P_Peripheral_Driver */

    三、总结 

    基本试验了IPC通讯,寄存器和触发动作应该是没问题的;看来后续要使用M1S_BL808_SDK作为开发主力的SDK了,好多函数封装了,功能实现的也比较好;只是目前只能在Linux下的开发环境使用,对于笔记本性能有限,懒得开虚拟机的我,还是eciplse的Windows客户端使用起来更方便一点。

  • 相关阅读:
    主动发现系统稳定性缺陷:混沌工程 | 京东云技术团队
    软件测试中如何测试日志内容
    比较两个文本文件是否相等(C语言)
    VisualStudio删除干净电脑所有的有关文件
    动态规划 贪心算法
    【Redis】Redis的持久化
    还担心接口乱糟糟?快来试试“斯瓦格”在线文档管理平台!
    使用tesseract-ocr实现图片中的中英文字符提取
    java集合类史上最细讲解 - TreeSet,TreeMap篇
    (四)Shell编程之算数运算
  • 原文地址:https://blog.csdn.net/DINGDING_GO/article/details/133466986