diff options
Diffstat (limited to 'lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8DX4/scfw_api/main/ipc_imx8qx.c')
-rw-r--r-- | lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8DX4/scfw_api/main/ipc_imx8qx.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8DX4/scfw_api/main/ipc_imx8qx.c b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8DX4/scfw_api/main/ipc_imx8qx.c new file mode 100644 index 000000000..150459dd2 --- /dev/null +++ b/lib/chibios-contrib/ext/mcux-sdk/devices/MIMX8DX4/scfw_api/main/ipc_imx8qx.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, Freescale Semiconductor, Inc. | ||
3 | * Copyright 2017-2019 NXP | ||
4 | * | ||
5 | * SPDX-License-Identifier: BSD-3-Clause | ||
6 | */ | ||
7 | |||
8 | #include "MIMX8DX4_cm4.h" | ||
9 | #include "main/ipc.h" | ||
10 | #include "main/rpc.h" | ||
11 | #ifdef FSL_RTOS_FREE_RTOS | ||
12 | #include "FreeRTOS.h" | ||
13 | #include "task.h" | ||
14 | #endif | ||
15 | |||
16 | /******************************************************************************* | ||
17 | * Definitions | ||
18 | ******************************************************************************/ | ||
19 | |||
20 | /* Component ID definition, used by tools. */ | ||
21 | #ifndef FSL_COMPONENT_ID | ||
22 | #define FSL_COMPONENT_ID "platform.drivers.scfwapi" | ||
23 | #endif | ||
24 | |||
25 | /*----------------------------------------------------------------------*/ | ||
26 | /* RPC command/response */ | ||
27 | /*----------------------------------------------------------------------*/ | ||
28 | void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, sc_bool_t no_resp) | ||
29 | { | ||
30 | #ifdef FSL_RTOS_FREE_RTOS | ||
31 | if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) | ||
32 | { | ||
33 | /* Suspends the scheduler to make sure there's only one rpc call ongoing at a time. */ | ||
34 | vTaskSuspendAll(); | ||
35 | } | ||
36 | #endif | ||
37 | sc_ipc_write(ipc, msg); | ||
38 | if (!no_resp) | ||
39 | { | ||
40 | sc_ipc_read(ipc, msg); | ||
41 | } | ||
42 | #ifdef FSL_RTOS_FREE_RTOS | ||
43 | if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) | ||
44 | { | ||
45 | (void)xTaskResumeAll(); | ||
46 | } | ||
47 | #endif | ||
48 | } | ||
49 | |||
50 | /*--------------------------------------------------------------------------*/ | ||
51 | /* Open an IPC channel */ | ||
52 | /*--------------------------------------------------------------------------*/ | ||
53 | sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id) | ||
54 | { | ||
55 | MU_Type *base = (MU_Type *)id; | ||
56 | |||
57 | /* get mu base associated with ipc channel */ | ||
58 | if ((ipc == NULL) || (base == NULL)) | ||
59 | { | ||
60 | return SC_ERR_IPC; | ||
61 | } | ||
62 | |||
63 | /* Clear GIEn, RIEn, TIEn, GIRn and ABFn. */ | ||
64 | base->CR &= ~(MU_CR_GIEn_MASK | MU_CR_RIEn_MASK | MU_CR_TIEn_MASK | MU_CR_GIRn_MASK | MU_CR_Fn_MASK); | ||
65 | |||
66 | /* Return MU address as handle */ | ||
67 | *ipc = (sc_ipc_t)id; | ||
68 | |||
69 | return SC_ERR_NONE; | ||
70 | } | ||
71 | |||
72 | /*--------------------------------------------------------------------------*/ | ||
73 | /* Close an IPC channel */ | ||
74 | /*--------------------------------------------------------------------------*/ | ||
75 | void sc_ipc_close(sc_ipc_t ipc) | ||
76 | { | ||
77 | } | ||
78 | |||
79 | /*--------------------------------------------------------------------------*/ | ||
80 | /* Read message from an IPC channel */ | ||
81 | /*--------------------------------------------------------------------------*/ | ||
82 | void sc_ipc_read(sc_ipc_t ipc, void *data) | ||
83 | { | ||
84 | MU_Type *base = (MU_Type *)ipc; | ||
85 | sc_rpc_msg_t *msg = (sc_rpc_msg_t *)data; | ||
86 | uint8_t count = 0; | ||
87 | |||
88 | /* Check parms */ | ||
89 | if ((base == NULL) || (msg == NULL)) | ||
90 | { | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | /* Read first word */ | ||
95 | /* Wait RX register to be full. */ | ||
96 | while ((base->SR & (1UL << (MU_SR_RFn_SHIFT + 3U))) == 0U) | ||
97 | { | ||
98 | } | ||
99 | msg->header = base->RR[0]; | ||
100 | count++; | ||
101 | |||
102 | /* Check size */ | ||
103 | if (msg->size > SC_RPC_MAX_MSG) | ||
104 | { | ||
105 | msg->header = 0; | ||
106 | return; | ||
107 | } | ||
108 | |||
109 | /* Read remaining words */ | ||
110 | while (count < msg->size) | ||
111 | { | ||
112 | /* Wait RX register to be full. */ | ||
113 | while ((base->SR & (1UL << (MU_SR_RFn_SHIFT + 3U - count % MU_RR_COUNT))) == 0U) | ||
114 | { | ||
115 | } | ||
116 | msg->DATA.u32[count - 1U] = base->RR[count % MU_RR_COUNT]; | ||
117 | count++; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | /*--------------------------------------------------------------------------*/ | ||
122 | /* Write a message to an IPC channel */ | ||
123 | /*--------------------------------------------------------------------------*/ | ||
124 | void sc_ipc_write(sc_ipc_t ipc, const void *data) | ||
125 | { | ||
126 | MU_Type *base = (MU_Type *)ipc; | ||
127 | const sc_rpc_msg_t *msg = (const sc_rpc_msg_t *)data; | ||
128 | uint8_t count = 0; | ||
129 | |||
130 | /* Check parms */ | ||
131 | if ((base == NULL) || (msg == NULL)) | ||
132 | { | ||
133 | return; | ||
134 | } | ||
135 | |||
136 | /* Check size */ | ||
137 | if (msg->size > SC_RPC_MAX_MSG) | ||
138 | { | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | /* Write first word */ | ||
143 | while ((base->SR & (1UL << (MU_SR_TEn_SHIFT + 3U))) == 0U) | ||
144 | { | ||
145 | } | ||
146 | base->TR[0] = msg->header; | ||
147 | count++; | ||
148 | |||
149 | /* Write remaining words */ | ||
150 | while (count < msg->size) | ||
151 | { | ||
152 | /* Wait Tx register to be empty and send Tx Data. */ | ||
153 | while ((base->SR & (1UL << (MU_SR_TEn_SHIFT + 3U - count % MU_TR_COUNT))) == 0U) | ||
154 | { | ||
155 | } | ||
156 | base->TR[count % MU_TR_COUNT] = msg->DATA.u32[count - 1U]; | ||
157 | count++; | ||
158 | } | ||
159 | } | ||