1 //###########################################################################
2 //
3 // FILE: F2837xD_Ipc_Driver_Util.c
4 //
5 // TITLE: F2837xD Inter-Processor Communication (IPC) API Driver Utility
6 // Functions
7 //
8 // DESCRIPTION:
9 // API functions for inter-processor communications between the
10 // Local and Remote CPU system.
11 // The driver functions in this file are available only as
12 // sample functions for application development. Due to the generic
13 // nature of these functions and the cycle overhead inherent to a
14 // function call, the code is not intended to be used in cases where
15 // maximum efficiency is required in a system.
16 //
17 // NOTE: This source code is used by both CPUs. That is both CPU1 and CPU2
18 // cores use this code.
19 // The active debug CPU will be referred to as Local CPU and the other
20 // CPU will be referred to as Remote CPU.
21 // When using this source code in CPU1, the term "local"
22 // will mean CPU1 and the term "remote" CPU will be mean CPU2.
23 // When using this source code in CPU2, the term "local"
24 // will mean CPU2 and the term "remote" CPU will be mean CPU1.
25 //
26 // The abbreviations LtoR and RtoL within the function names mean
27 // Local to Remote and Remote to Local respectively.
28 //
29 //###########################################################################
30 // $TI Release: F2837xD Support Library v3.05.00.00 $
31 // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
32 // $Copyright:
33 // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
34 //
35 // Redistribution and use in source and binary forms, with or without
36 // modification, are permitted provided that the following conditions
37 // are met:
38 //
39 // Redistributions of source code must retain the above copyright
40 // notice, this list of conditions and the following disclaimer.
41 //
42 // Redistributions in binary form must reproduce the above copyright
43 // notice, this list of conditions and the following disclaimer in the
44 // documentation and/or other materials provided with the
45 // distribution.
46 //
47 // Neither the name of Texas Instruments Incorporated nor the names of
48 // its contributors may be used to endorse or promote products derived
49 // from this software without specific prior written permission.
50 //
51 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
52 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
53 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
54 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
55 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
56 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
57 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
61 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 // $
63 //###########################################################################
64
65 //*****************************************************************************
66 //
67 //! \addtogroup ipc_util_api
68 //! @{
69 //
70 //*****************************************************************************
71 #include "F2837xD_device.h"
72 #include "F2837xD_GlobalPrototypes.h"
73 #include "F2837xD_Gpio_defines.h"
74 #include "F2837xD_Ipc_drivers.h"
75
76 //*****************************************************************************
77 //
78 //! Local CPU Acknowledges Remote to Local IPC Flag.
79 //!
80 //! \param ulFlags specifies the IPC flag mask for flags being acknowledged.
81 //!
82 //! This function will allow the Local CPU system to acknowledge/clear the IPC
83 //! flag set by the Remote CPU system. The \e ulFlags parameter can be any of
84 //! the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
85 //!
86 //! \return None.
87 //
88 //*****************************************************************************
89 void
IPCRtoLFlagAcknowledge(uint32_t ulFlags)90 IPCRtoLFlagAcknowledge (uint32_t ulFlags)
91 {
92 IpcRegs.IPCACK.all |= ulFlags;
93 }
94
95 //*****************************************************************************
96 //
97 //! Determines whether the given Remote to Local IPC flags are busy or not.
98 //!
99 //! \param ulFlags specifies Remote to Local IPC Flag number masks to check the
100 //! status of.
101 //!
102 //! Allows the caller to determine whether the designated IPC flags are
103 //! pending. The \e ulFlags parameter can be any of the IPC flag
104 //! values: \b IPC_FLAG0 - \b IPC_FLAG31.
105 //!
106 //! \return Returns \b 1 if the IPC flags are busy or \b 0 if designated
107 //! IPC flags are free.
108 //
109 //*****************************************************************************
110 Uint16
IPCRtoLFlagBusy(uint32_t ulFlags)111 IPCRtoLFlagBusy (uint32_t ulFlags)
112 {
113 Uint16 returnStatus;
114
115 if ((IpcRegs.IPCSTS.all & ulFlags) == 0)
116 {
117 returnStatus = 0;
118 }
119 else
120 {
121 returnStatus = 1;
122 }
123
124 return returnStatus;
125 }
126
127 //*****************************************************************************
128 //
129 //! Determines whether the given IPC flags are busy or not.
130 //!
131 //! \param ulFlags specifies Local to Remote IPC Flag number masks to check the
132 //! status of.
133 //!
134 //! Allows the caller to determine whether the designated IPC flags are
135 //! available for further control to master system communication. If \b 0 is
136 //! returned, then all designated tasks have completed and are available.
137 //! The \e ulFlags parameter can be any of the IPC flag
138 //! values: \b IPC_FLAG0 - \b IPC_FLAG31.
139 //!
140 //! \return Returns \b 1 if the IPC flags are busy or \b 0 if designated
141 //! IPC flags are free.
142 //
143 //*****************************************************************************
144 Uint16
IPCLtoRFlagBusy(uint32_t ulFlags)145 IPCLtoRFlagBusy (uint32_t ulFlags)
146 {
147 Uint16 returnStatus;
148
149 if ((IpcRegs.IPCFLG.all & ulFlags) == 0)
150 {
151 returnStatus = 0;
152 }
153 else
154 {
155 returnStatus = 1;
156 }
157
158 return returnStatus;
159 }
160
161 //*****************************************************************************
162 //
163 //! Local CPU Sets Local to Remote IPC Flag
164 //!
165 //! \param ulFlags specifies the IPC flag mask for flags being set.
166 //!
167 //! This function will allow the Local CPU system to set the designated IPC
168 //! flags to send to the Remote CPU system. The \e ulFlags parameter can be any
169 //! of the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
170 //!
171 //! \return None.
172 //
173 //*****************************************************************************
174 void
IPCLtoRFlagSet(uint32_t ulFlags)175 IPCLtoRFlagSet (uint32_t ulFlags)
176 {
177 IpcRegs.IPCSET.all |= ulFlags;
178 }
179
180 //*****************************************************************************
181 //
182 //! Local CPU Clears Local to Remote IPC Flag
183 //!
184 //! \param ulFlags specifies the IPC flag mask for flags being set.
185 //!
186 //! This function will allow the Local CPU system to set the designated IPC
187 //! flags to send to the Remote CPU system. The \e ulFlags parameter can be any
188 //! of the IPC flag values: \b IPC_FLAG0 - \b IPC_FLAG31.
189 //!
190 //! \return None.
191 //
192 //*****************************************************************************
193 void
IPCLtoRFlagClear(uint32_t ulFlags)194 IPCLtoRFlagClear (uint32_t ulFlags)
195 {
196 IpcRegs.IPCCLR.all |= ulFlags;
197 }
198
199 //*****************************************************************************
200 //
201 //! Local Return CPU02 BOOT status
202 //!
203 //! This function returns the value at IPCBOOTSTS register.
204 //!
205 //! \return Boot status.
206 //
207 //*****************************************************************************
208 uint32_t
IPCGetBootStatus(void)209 IPCGetBootStatus (void)
210 {
211 return(IpcRegs.IPCBOOTSTS);
212 }
213
214 #if defined (CPU1)
215 //*****************************************************************************
216 //! Executes a CPU02 control system bootloader.
217 //!
218 //! \param ulBootMode specifies which CPU02 control system boot mode to execute.
219 //!
220 //! This function will allow the CPU01 master system to boot the CPU02 control
221 //! system via the following modes: Boot to RAM, Boot to Flash, Boot via SPI,
222 //! SCI, I2C, or parallel I/O. Unlike other IPCLite driver functions, this
223 //! function blocks and waits until the control system boot ROM is configured
224 //! and ready to receive CPU01 to CPU02 IPC INT0 interrupts. It then blocks and
225 //! waits until IPC INT0 and IPC FLAG31 are available in the CPU02 boot ROM
226 //! prior to sending the command to execute the selected bootloader. The \e
227 //! ulBootMode parameter accepts one of the following values: \b
228 //! C1C2_BROM_BOOTMODE_BOOT_FROM_PARALLEL, \b
229 //! C1C2_BROM_BOOTMODE_BOOT_FROM_SCI, \b
230 //! C1C2_BROM_BOOTMODE_BOOT_FROM_SPI, \b
231 //! C1C2_BROM_BOOTMODE_BOOT_FROM_I2C, \b C1C2_BROM_BOOTMODE_BOOT_FROM_CAN,
232 //! \b C1C2_BROM_BOOTMODE_BOOT_FROM_RAM, \b
233 //! C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH.
234 //!
235 //! \return 0 (success) if command is sent, or 1 (failure) if boot mode is
236 //! invalid and command was not sent.
237 //
238 //*****************************************************************************
239 uint16_t
IPCBootCPU2(uint32_t ulBootMode)240 IPCBootCPU2(uint32_t ulBootMode)
241 {
242 uint32_t bootStatus;
243 uint16_t pin;
244 uint16_t returnStatus = STATUS_PASS;
245
246 //
247 // If CPU2 has already booted, return a fail to let the application
248 // know that something is out of the ordinary.
249 //
250 bootStatus = IPCGetBootStatus() & 0x0000000F;
251
252 if(bootStatus == C2_BOOTROM_BOOTSTS_C2TOC1_BOOT_CMD_ACK)
253 {
254 //
255 // Check if MSB is set as well
256 //
257 bootStatus = ((uint32_t)(IPCGetBootStatus() & 0x80000000)) >> 31U;
258
259 if(bootStatus != 0)
260 {
261 returnStatus = STATUS_FAIL;
262
263 return returnStatus;
264 }
265 }
266
267 //
268 // Wait until CPU02 control system boot ROM is ready to receive
269 // CPU01 to CPU02 INT1 interrupts.
270 //
271 do
272 {
273 bootStatus = IPCGetBootStatus() & C2_BOOTROM_BOOTSTS_SYSTEM_READY;
274 } while ((bootStatus != C2_BOOTROM_BOOTSTS_SYSTEM_READY));
275
276 //
277 // Loop until CPU02 control system IPC flags 1 and 32 are available
278 //
279 while ((IPCLtoRFlagBusy(IPC_FLAG0) == 1) ||
280 (IPCLtoRFlagBusy(IPC_FLAG31) == 1))
281 {
282
283 }
284
285 if (ulBootMode >= C1C2_BROM_BOOTMODE_BOOT_COMMAND_MAX_SUPPORT_VALUE)
286 {
287 returnStatus = STATUS_FAIL;
288 }
289 else
290 {
291 //
292 // Based on boot mode, enable pull-ups on peripheral pins and
293 // give GPIO pin control to CPU02 control system.
294 //
295 switch (ulBootMode)
296 {
297 case C1C2_BROM_BOOTMODE_BOOT_FROM_SCI:
298
299 EALLOW;
300
301 //
302 //SCIA connected to CPU02
303 //
304 DevCfgRegs.CPUSEL5.bit.SCI_A = 1;
305
306 //
307 //Allows CPU02 bootrom to take control of clock
308 //configuration registers
309 //
310 ClkCfgRegs.CLKSEM.all = 0xA5A50000;
311
312 ClkCfgRegs.LOSPCP.all = 0x0002;
313 EDIS;
314
315 GPIO_SetupPinOptions(29, GPIO_OUTPUT, GPIO_ASYNC);
316 GPIO_SetupPinMux(29,GPIO_MUX_CPU2,1);
317
318 GPIO_SetupPinOptions(28, GPIO_INPUT, GPIO_ASYNC);
319 GPIO_SetupPinMux(28,GPIO_MUX_CPU2,1);
320
321 break;
322
323 case C1C2_BROM_BOOTMODE_BOOT_FROM_SPI:
324 EALLOW;
325
326 //
327 //SPI-A connected to CPU02
328 //
329 DevCfgRegs.CPUSEL6.bit.SPI_A = 1;
330
331 //
332 //Allows CPU02 bootrom to take control of clock configuration
333 // registers
334 //
335 ClkCfgRegs.CLKSEM.all = 0xA5A50000;
336 EDIS;
337
338 GPIO_SetupPinOptions(16, GPIO_INPUT, GPIO_ASYNC);
339 GPIO_SetupPinMux(16,GPIO_MUX_CPU2,1);
340
341 GPIO_SetupPinOptions(17, GPIO_INPUT, GPIO_ASYNC);
342 GPIO_SetupPinMux(17,GPIO_MUX_CPU2,1);
343
344 GPIO_SetupPinOptions(18, GPIO_INPUT, GPIO_ASYNC);
345 GPIO_SetupPinMux(18,GPIO_MUX_CPU2,1);
346
347 GPIO_SetupPinOptions(19, GPIO_OUTPUT, GPIO_ASYNC);
348 GPIO_SetupPinMux(19,GPIO_MUX_CPU2,0);
349
350 break;
351
352 case C1C2_BROM_BOOTMODE_BOOT_FROM_I2C:
353 EALLOW;
354
355 //
356 //I2CA connected to CPU02
357 //
358 DevCfgRegs.CPUSEL7.bit.I2C_A = 1;
359
360 //
361 //Allows CPU2 bootrom to take control of clock
362 //configuration registers
363 //
364 ClkCfgRegs.CLKSEM.all = 0xA5A50000;
365 ClkCfgRegs.LOSPCP.all = 0x0002;
366 EDIS;
367 GPIO_SetupPinOptions(32, GPIO_INPUT, GPIO_ASYNC);
368 GPIO_SetupPinMux(32,GPIO_MUX_CPU2,1);
369
370 GPIO_SetupPinOptions(33, GPIO_INPUT, GPIO_ASYNC);
371 GPIO_SetupPinMux(33,GPIO_MUX_CPU2,1);
372
373 break;
374 case C1C2_BROM_BOOTMODE_BOOT_FROM_PARALLEL:
375
376 for(pin=58;pin<=65;pin++)
377 {
378 GPIO_SetupPinOptions(pin, GPIO_INPUT, GPIO_ASYNC);
379 GPIO_SetupPinMux(pin,GPIO_MUX_CPU2,0);
380 }
381
382 GPIO_SetupPinOptions(69, GPIO_OUTPUT, GPIO_ASYNC);
383 GPIO_SetupPinMux(69,GPIO_MUX_CPU2,0);
384
385 GPIO_SetupPinOptions(70, GPIO_INPUT, GPIO_ASYNC);
386 GPIO_SetupPinMux(70,GPIO_MUX_CPU2,0);
387 break;
388
389
390 case C1C2_BROM_BOOTMODE_BOOT_FROM_CAN:
391 //
392 //Set up the GPIO mux to bring out CANATX on GPIO71
393 //and CANARX on GPIO70
394 //
395 EALLOW;
396 GpioCtrlRegs.GPCLOCK.all = 0x00000000; //Unlock GPIOs 64-95
397
398 //
399 //Give CPU2 control just in case
400 //
401 GpioCtrlRegs.GPCCSEL1.bit.GPIO71 = GPIO_MUX_CPU2;
402
403 //
404 //Set the extended mux to 0x5
405 //
406 GpioCtrlRegs.GPCGMUX1.bit.GPIO71 = 0x1;
407 GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 0x1;
408
409 //
410 //Set qualification to async just in case
411 //
412 GpioCtrlRegs.GPCQSEL1.bit.GPIO71 = 0x3;
413
414 GpioCtrlRegs.GPCLOCK.all = 0x00000000; //Unlock GPIOs 64-95
415
416 //
417 //Give CPU2 control just in case
418 //
419 GpioCtrlRegs.GPCCSEL1.bit.GPIO70 = GPIO_MUX_CPU2;
420
421 //
422 //Set the extended mux to bring out CANATX
423 //
424 GpioCtrlRegs.GPCGMUX1.bit.GPIO70 = 0x1;
425 GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 0x1;
426
427 //
428 //Set qualification to async just in case
429 //
430 GpioCtrlRegs.GPCQSEL1.bit.GPIO70 = 0x3;
431 GpioCtrlRegs.GPCLOCK.all = 0xFFFFFFFF; //Lock GPIOs 64-95
432 ClkCfgRegs.CLKSRCCTL2.bit.CANABCLKSEL = 0x0;
433 CpuSysRegs.PCLKCR10.bit.CAN_A = 1;
434 EDIS;
435
436 break;
437
438 }
439
440 //
441 //CPU01 to CPU02 IPC Boot Mode Register
442 //
443 IpcRegs.IPCBOOTMODE = ulBootMode;
444
445 //
446 // CPU01 To CPU02 IPC Command Register
447 //
448 IpcRegs.IPCSENDCOM = BROM_IPC_EXECUTE_BOOTMODE_CMD;
449
450 //
451 // CPU01 to CPU02 IPC flag register
452 //
453 IpcRegs.IPCSET.all = 0x80000001;
454
455 }
456
457
458
459 return returnStatus;
460 }
461
462
463 #endif
464 //*****************************************************************************
465 // Close the Doxygen group.
466 //! @}
467 //*****************************************************************************
468
469
470