|
| 1 | +/** |
| 2 | + ****************************************************************************** |
| 3 | + * @file mbox_ipcc.c |
| 4 | + * @author MCD Application Team |
| 5 | + * @brief This file provides code for the configuration |
| 6 | + * of the mailbox_ipcc_if.c MiddleWare. |
| 7 | + ****************************************************************************** |
| 8 | + * @attention |
| 9 | + * |
| 10 | + * <h2><center>© Copyright (c) 2019 STMicroelectronics. |
| 11 | + * All rights reserved.</center></h2> |
| 12 | + * |
| 13 | + * This software component is licensed by ST under BSD 3-Clause license, |
| 14 | + * the "License"; You may not use this file except in compliance with the |
| 15 | + * License. You may obtain a copy of the License at: |
| 16 | + * opensource.org/licenses/BSD-3-Clause |
| 17 | + * |
| 18 | + ****************************************************************************** |
| 19 | + */ |
| 20 | +#ifdef VIRTIOCON |
| 21 | + |
| 22 | +/* |
| 23 | + * Channel direction and usage: |
| 24 | + * virtio_rpmsg_bus.c rpmsg_virtio.c |
| 25 | + * ======== <-- new msg ---=============--------<------ ======= |
| 26 | + * || || rvq (rx) || CHANNEL 1 || svq (tx_vq) || || |
| 27 | + * || A7 || ------->-------=============--- buf free--> || M4 || |
| 28 | + * || || || || |
| 29 | + * ||master|| <-- buf free---=============--------<------ ||slave|| |
| 30 | + * || || svq (tx) || CHANNEL 2 || rvq (rx_vq) || || |
| 31 | + * ======== ------->-------=============----new msg --> ======= |
| 32 | + */ |
| 33 | + |
| 34 | +/* Includes ------------------------------------------------------------------*/ |
| 35 | +#include "openamp/open_amp.h" |
| 36 | +#include "stm32_def.h" |
| 37 | +#include "openamp_conf.h" |
| 38 | + |
| 39 | +/* Within 'USER CODE' section, code will be kept by default at each generation */ |
| 40 | +/* USER CODE BEGIN 0 */ |
| 41 | + |
| 42 | +/* USER CODE END 0 */ |
| 43 | + |
| 44 | +/* Private define ------------------------------------------------------------*/ |
| 45 | +#define MASTER_CPU_ID 0 |
| 46 | +#define REMOTE_CPU_ID 1 |
| 47 | +#define IPCC_CPU_A7 MASTER_CPU_ID |
| 48 | +#define IPCC_CPU_M4 REMOTE_CPU_ID |
| 49 | + |
| 50 | +#define RX_NO_MSG 0 |
| 51 | +#define RX_NEW_MSG 1 |
| 52 | +#define RX_BUF_FREE 2 |
| 53 | + |
| 54 | +/* Private variables ---------------------------------------------------------*/ |
| 55 | +extern IPCC_HandleTypeDef hipcc; |
| 56 | +int msg_received_ch1 = RX_NO_MSG; |
| 57 | +int msg_received_ch2 = RX_NO_MSG; |
| 58 | +uint32_t vring0_id = 0; /* used for channel 1 */ |
| 59 | +uint32_t vring1_id = 1; /* used for channel 2 */ |
| 60 | + |
| 61 | + |
| 62 | + |
| 63 | + |
| 64 | +IPCC_HandleTypeDef hipcc; |
| 65 | + |
| 66 | + |
| 67 | + |
| 68 | + |
| 69 | +/* Private function prototypes -----------------------------------------------*/ |
| 70 | +void IPCC_channel1_callback(IPCC_HandleTypeDef *hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir); |
| 71 | +void IPCC_channel2_callback(IPCC_HandleTypeDef *hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir); |
| 72 | + |
| 73 | + |
| 74 | +/** |
| 75 | + * @brief Initialize MAILBOX with IPCC peripheral |
| 76 | + * @param None |
| 77 | + * @retval : Operation result |
| 78 | + */ |
| 79 | +int MAILBOX_Init(void) |
| 80 | +{ |
| 81 | + __HAL_RCC_IPCC_CLK_ENABLE(); |
| 82 | + HAL_NVIC_SetPriority(IPCC_RX1_IRQn, IPCC_IRQ_PRIO, IPCC_IRQ_SUBPRIO); |
| 83 | + HAL_NVIC_EnableIRQ(IPCC_RX1_IRQn); |
| 84 | + hipcc.Instance = IPCC; |
| 85 | + if (HAL_IPCC_Init(&hipcc) != HAL_OK) { |
| 86 | + Error_Handler(); |
| 87 | + } |
| 88 | + |
| 89 | + if (HAL_IPCC_ActivateNotification(&hipcc, IPCC_CHANNEL_1, IPCC_CHANNEL_DIR_RX, |
| 90 | + IPCC_channel1_callback) != HAL_OK) { |
| 91 | + Error_Handler(); |
| 92 | + return -1; |
| 93 | + } |
| 94 | + |
| 95 | + if (HAL_IPCC_ActivateNotification(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_RX, |
| 96 | + IPCC_channel2_callback) != HAL_OK) { |
| 97 | + Error_Handler(); |
| 98 | + return -1; |
| 99 | + } |
| 100 | + |
| 101 | + return 0; |
| 102 | +} |
| 103 | + |
| 104 | +/** |
| 105 | + * @brief Initialize MAILBOX with IPCC peripheral |
| 106 | + * @param virtio device |
| 107 | + * @retval : Operation result |
| 108 | + */ |
| 109 | +int MAILBOX_Poll(struct virtio_device *vdev) |
| 110 | +{ |
| 111 | + /* If we got an interrupt, ask for the corresponding virtqueue processing */ |
| 112 | + |
| 113 | + if (msg_received_ch1 == RX_BUF_FREE) { |
| 114 | + OPENAMP_log_dbg("Running virt0 (ch_1 buf free)\r\n"); |
| 115 | + rproc_virtio_notified(vdev, VRING0_ID); |
| 116 | + msg_received_ch1 = RX_NO_MSG; |
| 117 | + return 0; |
| 118 | + } |
| 119 | + |
| 120 | + if (msg_received_ch2 == RX_NEW_MSG) { |
| 121 | + OPENAMP_log_dbg("Running virt1 (ch_2 new msg)\r\n"); |
| 122 | + rproc_virtio_notified(vdev, VRING1_ID); |
| 123 | + msg_received_ch2 = RX_NO_MSG; |
| 124 | + |
| 125 | + /* The OpenAMP framework does not notify for free buf: do it here */ |
| 126 | + rproc_virtio_notified(NULL, VRING1_ID); |
| 127 | + return 0; |
| 128 | + } |
| 129 | + |
| 130 | + return -1; |
| 131 | +} |
| 132 | + |
| 133 | + |
| 134 | +/** |
| 135 | + * @brief Callback function called by OpenAMP MW to notify message processing |
| 136 | + * @param VRING id |
| 137 | + * @retval Operation result |
| 138 | + */ |
| 139 | +int MAILBOX_Notify(void *priv, uint32_t id) |
| 140 | +{ |
| 141 | + uint32_t channel; |
| 142 | + (void)priv; |
| 143 | + |
| 144 | + /* Called after virtqueue processing: time to inform the remote */ |
| 145 | + if (id == VRING0_ID) { |
| 146 | + channel = IPCC_CHANNEL_1; |
| 147 | + } else if (id == VRING1_ID) { |
| 148 | + /* Note: the OpenAMP framework never notifies this */ |
| 149 | + channel = IPCC_CHANNEL_2; |
| 150 | + return -1; |
| 151 | + } else { |
| 152 | + return -1; |
| 153 | + } |
| 154 | + |
| 155 | + /* Check that the channel is free (otherwise wait until it is) */ |
| 156 | + if (HAL_IPCC_GetChannelStatus(&hipcc, channel, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED) { |
| 157 | + // Wait for channel to be freed |
| 158 | + while (HAL_IPCC_GetChannelStatus(&hipcc, channel, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED) |
| 159 | + ; |
| 160 | + } |
| 161 | + |
| 162 | + /* Inform A7 (either new message, or buf free) */ |
| 163 | + HAL_IPCC_NotifyCPU(&hipcc, channel, IPCC_CHANNEL_DIR_TX); |
| 164 | + return 0; |
| 165 | +} |
| 166 | + |
| 167 | +/* Private function ---------------------------------------------------------*/ |
| 168 | +/* Callback from IPCC Interrupt Handler: Master Processor informs that there are some free buffers */ |
| 169 | +void IPCC_channel1_callback(IPCC_HandleTypeDef *hipcc, |
| 170 | + uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir) |
| 171 | +{ |
| 172 | + if (msg_received_ch1 != RX_NO_MSG) { |
| 173 | + OPENAMP_log_dbg("IPCC_channel1_callback: previous IRQ not treated (status = %d)\r\n", msg_received_ch1); |
| 174 | + } |
| 175 | + |
| 176 | + msg_received_ch1 = RX_BUF_FREE; |
| 177 | + |
| 178 | + /* Inform A7 that we have received the 'buff free' msg */ |
| 179 | + HAL_IPCC_NotifyCPU(hipcc, ChannelIndex, IPCC_CHANNEL_DIR_RX); |
| 180 | +} |
| 181 | + |
| 182 | +/* Callback from IPCC Interrupt Handler: new message received from Master Processor */ |
| 183 | +void IPCC_channel2_callback(IPCC_HandleTypeDef *hipcc, |
| 184 | + uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir) |
| 185 | +{ |
| 186 | + if (msg_received_ch2 != RX_NO_MSG) { |
| 187 | + OPENAMP_log_dbg("IPCC_channel2_callback: previous IRQ not treated (status = %d)\r\n", msg_received_ch2); |
| 188 | + } |
| 189 | + |
| 190 | + msg_received_ch2 = RX_NEW_MSG; |
| 191 | + |
| 192 | + /* Inform A7 that we have received the new msg */ |
| 193 | + OPENAMP_log_dbg("Ack new message on ch2\r\n"); |
| 194 | + HAL_IPCC_NotifyCPU(hipcc, ChannelIndex, IPCC_CHANNEL_DIR_RX); |
| 195 | +} |
| 196 | + |
| 197 | +/** |
| 198 | + * @brief This function handles IPCC RX1 occupied interrupt. |
| 199 | + */ |
| 200 | +void IPCC_RX1_IRQHandler(void) |
| 201 | +{ |
| 202 | + /* USER CODE BEGIN IPCC_RX1_IRQn 0 */ |
| 203 | + /* USER CODE END IPCC_RX1_IRQn 0 */ |
| 204 | + HAL_IPCC_RX_IRQHandler(&hipcc); |
| 205 | + /* USER CODE BEGIN IPCC_RX1_IRQn 1 */ |
| 206 | + |
| 207 | + /* USER CODE END IPCC_RX1_IRQn 1 */ |
| 208 | +} |
| 209 | + |
| 210 | +#endif /* VIRTIOCON */ |
| 211 | +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |
0 commit comments