1 //###########################################################################
2 //
3 // FILE: F2837xD_Ipc_Driver.c
4 //
5 // TITLE: F2837xD Inter-Processor Communication (IPC) API Driver Functions.
6 //
7 // DESCRIPTION:
8 // 28x API functions for inter-processor communications between the
9 // two CPUs. The IPC functions require the usage of the CPU1 to CPU2
10 // and CPU2 to CPU1 MSG RAM's to store the circular ring
11 // buffer and indexes. Commands can be queued up in order on a single
12 // IPC interrupt channel. For those IPC commands which are not
13 // interdependent, multiple IPC interrupt channels may be used.
14 // The driver functions in this file are available only as
15 // sample functions for application development. Due to the generic
16 // nature of these functions and the cycle overhead inherent to a
17 // function call, the code is not intended to be used in cases where
18 // maximum efficiency is required in a system.
19 // NOTE: This source code is used by both CPUs. That is both CPU1 and CPU2
20 // Cores use this code.
21 // The active debug CPU will be referred to as Local CPU.
22 // When using this source code in CPU1, the term "local"
23 // will mean CPU1 and the term "remote" CPU will be mean CPU2.
24 // When using this source code in CPU2, the term "local"
25 // will mean CPU2 and the term "remote" CPU will be mean CPU1.
26 //
27 // The abbreviations LtoR and RtoL within the function names mean
28 // Local to Remote and Remote to Local respectively.
29 //
30 //###########################################################################
31 // $TI Release: F2837xD Support Library v3.05.00.00 $
32 // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
33 // $Copyright:
34 // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
35 //
36 // Redistribution and use in source and binary forms, with or without
37 // modification, are permitted provided that the following conditions
38 // are met:
39 //
40 // Redistributions of source code must retain the above copyright
41 // notice, this list of conditions and the following disclaimer.
42 //
43 // Redistributions in binary form must reproduce the above copyright
44 // notice, this list of conditions and the following disclaimer in the
45 // documentation and/or other materials provided with the
46 // distribution.
47 //
48 // Neither the name of Texas Instruments Incorporated nor the names of
49 // its contributors may be used to endorse or promote products derived
50 // from this software without specific prior written permission.
51 //
52 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
53 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
54 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
55 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
56 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
57 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
58 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
59 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
60 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
62 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 // $
64 //###########################################################################
65
66 //*****************************************************************************
67 //! \addtogroup ipc_driver_api
68 //! @{
69 //*****************************************************************************
70 #include "F2837xD_device.h"
71 #include "F2837xD_Ipc_drivers.h"
72
73 #if defined(CPU1)
74 #pragma DATA_SECTION(g_asIPCCPU1toCPU2Buffers, "PUTBUFFER");
75 #pragma DATA_SECTION(g_usPutWriteIndexes, "PUTWRITEIDX");
76 #pragma DATA_SECTION(g_usGetReadIndexes, "GETREADIDX");
77
78 #pragma DATA_SECTION(g_asIPCCPU2toCPU1Buffers, "GETBUFFER");
79 #pragma DATA_SECTION(g_usGetWriteIndexes, "GETWRITEIDX");
80 #pragma DATA_SECTION(g_usPutReadIndexes, "PUTREADIDX");
81
82 #elif defined(CPU2)
83
84 #pragma DATA_SECTION(g_asIPCCPU2toCPU1Buffers, "PUTBUFFER");
85 #pragma DATA_SECTION(g_usPutWriteIndexes, "PUTWRITEIDX");
86 #pragma DATA_SECTION(g_usGetReadIndexes, "GETREADIDX");
87
88 #pragma DATA_SECTION(g_asIPCCPU1toCPU2Buffers, "GETBUFFER");
89 #pragma DATA_SECTION(g_usGetWriteIndexes, "GETWRITEIDX");
90 #pragma DATA_SECTION(g_usPutReadIndexes, "PUTREADIDX");
91
92 #endif
93
94 //
95 // Global Circular Buffer Definitions
96 //
97 tIpcMessage g_asIPCCPU1toCPU2Buffers[NUM_IPC_INTERRUPTS][IPC_BUFFER_SIZE];
98 tIpcMessage g_asIPCCPU2toCPU1Buffers[NUM_IPC_INTERRUPTS][IPC_BUFFER_SIZE];
99
100 //
101 // Global Circular Buffer Index Definitions
102 //
103 uint16_t g_usPutWriteIndexes[NUM_IPC_INTERRUPTS];
104 uint16_t g_usPutReadIndexes[NUM_IPC_INTERRUPTS];
105 uint16_t g_usGetWriteIndexes[NUM_IPC_INTERRUPTS];
106 uint16_t g_usGetReadIndexes[NUM_IPC_INTERRUPTS];
107
108 //*****************************************************************************
109 //
110 //! Initializes System IPC driver controller
111 //!
112 //! \param psController specifies the address of a \e tIpcController instance
113 //! used to store information about the "Put" and "Get" circular buffers and
114 //! their respective indexes.
115 //! \param usCPU2IpcInterrupt specifies the CPU2 IPC interrupt number used by
116 //! psController.
117 //! \param usCPU1IpcInterrupt specifies the CPU1 IPC interrupt number used by
118 //! psController.
119 //!
120 //! This function initializes the IPC driver controller with circular buffer
121 //! and index addresses for an IPC interrupt pair. The
122 //! \e usCPU2IpcInterrupt and \e usCPU1IpcInterrupt parameters can be one of
123 //! the following values:
124 //! \b IPC_INT0, \b IPC_INT1, \b IPC_INT2, \b IPC_INT3.
125 //!
126 //! \note If an interrupt is currently in use by an \e tIpcController instance,
127 //! that particular interrupt should not be tied to a second \e tIpcController
128 //! instance.
129 //!
130 //! \note For a particular usCPU2IpcInterrupt - usCPU1IpcInterrupt pair, there
131 //! must be an instance of tIpcController defined and initialized on both the
132 //! CPU1 and CPU2 systems.
133 //!
134 //! \return None.
135 //
136 //*****************************************************************************
137 void
IPCInitialize(volatile tIpcController * psController,uint16_t usCPU2IpcInterrupt,uint16_t usCPU1IpcInterrupt)138 IPCInitialize (volatile tIpcController *psController,
139 uint16_t usCPU2IpcInterrupt, uint16_t usCPU1IpcInterrupt)
140 {
141 #if defined(CPU1)
142 // CPU1toCPU2PutBuffer and Index Initialization
143 psController->psPutBuffer = &g_asIPCCPU1toCPU2Buffers[usCPU2IpcInterrupt-1][0];
144 psController->pusPutWriteIndex = &g_usPutWriteIndexes[usCPU2IpcInterrupt-1];
145 psController->pusGetReadIndex = &g_usGetReadIndexes[usCPU1IpcInterrupt-1];
146 psController->ulPutFlag = (uint32_t)(1 << (usCPU2IpcInterrupt - 1));
147
148 // CPU1toCPU2GetBuffer and Index Initialization
149 psController->psGetBuffer = &g_asIPCCPU2toCPU1Buffers[usCPU1IpcInterrupt-1][0];
150 psController->pusGetWriteIndex = &g_usGetWriteIndexes[usCPU1IpcInterrupt-1];
151 psController->pusPutReadIndex = &g_usPutReadIndexes[usCPU2IpcInterrupt-1];
152 #elif defined(CPU2)
153 // CPU2toCPU1PutBuffer and Index Initialization
154 psController->psPutBuffer = &g_asIPCCPU2toCPU1Buffers[usCPU1IpcInterrupt-1][0];
155 psController->pusPutWriteIndex = &g_usPutWriteIndexes[usCPU1IpcInterrupt-1];
156 psController->pusGetReadIndex = &g_usGetReadIndexes[usCPU2IpcInterrupt-1];
157 psController->ulPutFlag = (uint32_t)(1 << (usCPU1IpcInterrupt - 1));
158
159 // CPU1toCPU2GetBuffer and Index Initialization
160 psController->psGetBuffer = &g_asIPCCPU1toCPU2Buffers[usCPU2IpcInterrupt-1][0];
161 psController->pusGetWriteIndex = &g_usGetWriteIndexes[usCPU2IpcInterrupt-1];
162 psController->pusPutReadIndex = &g_usPutReadIndexes[usCPU1IpcInterrupt-1];
163 #endif
164 // Initialize PutBuffer WriteIndex = 0 and GetBuffer ReadIndex = 0
165 *(psController->pusPutWriteIndex) = 0;
166 *(psController->pusGetReadIndex) = 0;
167 }
168
169 //*****************************************************************************
170 //
171 //! Writes a message into the PutBuffer.
172 //!
173 //! \param psController specifies the address of a \e tIpcController instance
174 //! used to store information about the "Put" and "Get" circular buffers and
175 //! their respective indexes.
176 //! \param psMessage specifies the address of the \e tIpcMessage instance to be
177 //! written to PutBuffer.
178 //! \param bBlock specifies whether to allow function to block until PutBuffer
179 //! has a free slot (1= wait until free spot available, 0 = exit with
180 //! STATUS_FAIL if no free slot).
181 //!
182 //! This function checks if there is a free slot in the PutBuffer. If so, it
183 //! puts the message pointed to by \e psMessage into the free slot and
184 //! increments the WriteIndex. Then it sets the appropriate IPC interrupt flag
185 //! specified by \e psController->usPutFlag. The \e bBlock parameter can be
186 //! one of the following values: \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
187 //!
188 //! \return \b STATUS_FAIL if PutBuffer is full. \b STATUS_PASS if Put occurs
189 //! successfully.
190 //
191 //*****************************************************************************
192 uint16_t
IpcPut(volatile tIpcController * psController,tIpcMessage * psMessage,uint16_t bBlock)193 IpcPut (volatile tIpcController *psController, tIpcMessage *psMessage,
194 uint16_t bBlock)
195 {
196 uint16_t writeIndex;
197 uint16_t readIndex;
198 uint16_t returnStatus = STATUS_PASS;
199
200 writeIndex = *(psController->pusPutWriteIndex);
201 readIndex = *(psController->pusPutReadIndex);
202
203 //
204 // Wait until Put Buffer slot is free
205 //
206 while (((writeIndex + 1) & MAX_BUFFER_INDEX) == readIndex)
207 {
208 //
209 // If designated as a "Blocking" function, and Put buffer is full,
210 // return immediately with fail status.
211 //
212 if (!bBlock)
213 {
214 returnStatus = STATUS_FAIL;
215 break;
216 }
217
218 readIndex = *(psController->pusPutReadIndex);
219 }
220
221 if (returnStatus != STATUS_FAIL)
222 {
223 //
224 // When slot is free, Write Message to PutBuffer, update PutWriteIndex,
225 // and set the CPU IPC INT Flag
226 //
227 psController->psPutBuffer[writeIndex] = *psMessage;
228
229 writeIndex = (writeIndex + 1) & MAX_BUFFER_INDEX;
230 *(psController->pusPutWriteIndex) = writeIndex;
231
232 IpcRegs.IPCSET.all |= psController->ulPutFlag;
233 }
234
235 return returnStatus;
236 }
237
238 //*****************************************************************************
239 //
240 //! Reads a message from the GetBuffer.
241 //!
242 //! \param psController specifies the address of a \e tIpcController instance
243 //! used to store information about the "Put" and "Get" circular buffers and
244 //! their respective indexes.
245 //! \param psMessage specifies the address of the \e tIpcMessage instance where
246 //! the message from GetBuffer should be written to.
247 //! \param bBlock specifies whether to allow function to block until GetBuffer
248 //! has a message (1= wait until message available, 0 = exit with STATUS_FAIL
249 //! if no message).
250 //!
251 //! This function checks if there is a message in the GetBuffer. If so, it gets
252 //! the message in the GetBuffer pointed to by the ReadIndex and writes it to
253 //! the address pointed to by \e psMessage. The \e bBlock parameter can be one
254 //! of the following
255 //! values: \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
256 //!
257 //! \return \b STATUS_PASS if GetBuffer is empty. \b STATUS_FAIL if Get occurs
258 //! successfully.
259 //
260 //*****************************************************************************
261 uint16_t
IpcGet(volatile tIpcController * psController,tIpcMessage * psMessage,uint16_t bBlock)262 IpcGet (volatile tIpcController *psController, tIpcMessage *psMessage,
263 uint16_t bBlock)
264 {
265 uint16_t writeIndex;
266 uint16_t readIndex;
267 uint16_t returnStatus = STATUS_PASS;
268
269 writeIndex = *(psController->pusGetWriteIndex);
270 readIndex = *(psController->pusGetReadIndex);
271
272 //
273 // Loop while GetBuffer is empty
274 //
275 while (writeIndex == readIndex)
276 {
277 //
278 // If designated as a "Blocking" function, and Get buffer is empty,
279 // return immediately with fail status.
280 //
281 if (!bBlock)
282 {
283 returnStatus = STATUS_FAIL;
284 break;
285 }
286
287 writeIndex = *(psController->pusGetWriteIndex);
288 }
289
290 if (returnStatus != STATUS_FAIL)
291 {
292 //
293 // If there is a message in GetBuffer, Read Message and update
294 // the ReadIndex
295 //
296 *psMessage = psController->psGetBuffer[readIndex];
297
298 readIndex = (readIndex + 1) & MAX_BUFFER_INDEX;
299 *(psController->pusGetReadIndex) = readIndex;
300 }
301
302 return returnStatus;
303 }
304
305 //*****************************************************************************
306 //
307 //! Sends a command to read either a 16- or 32-bit data word from the remote
308 //! CPU
309 //!
310 //! \param psController specifies the address of a \e tIpcController instance
311 //! used to store information about the "Put" and "Get" circular buffers and
312 //! their respective indexes.
313 //! \param ulAddress specifies the remote CPU address to read from
314 //! \param pvData is a pointer to the 16/32-bit variable where read data will
315 //! be stored.
316 //! \param usLength designates 16- or 32-bit read (1 = 16-bit, 2 = 32-bit)
317 //! \param bBlock specifies whether to allow function to block until PutBuffer
318 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
319 //! \param ulResponseFlag indicates the remote CPU to the local CPU Flag
320 //! number mask used to report when the read data is available at pvData.
321 //! (\e ulResponseFlag MUST use IPC flags 17-32, and not 1-16)
322 //!
323 //! This function will allow the local CPU system to send a 16/32-bit data
324 //! read command to the remote CPU system and set a ResponseFlag to track the
325 //! status of the read.
326 //! The remote CPU will respond with a DataWrite command which will place
327 //! the data in the local CPU address pointed to by \e pvData. When the local
328 //! CPU receives the DataWrite command and writes the read data into \e *pvData location,
329 //! it will clear the ResponseFlag, indicating to the rest of the system that
330 //! the data is ready. The \e usLength parameter can be one of the
331 //! following values: \b IPC_LENGTH_16_BITS or \b IPC_LENGTH_32_BITS. The \e
332 //! bBlock parameter can be one of the following values: \b ENABLE_BLOCKING or
333 //! \b DISABLE_BLOCKING.
334 //! The \e ulResponseFlag parameter can be any single one of the flags \b
335 //! IPC_FLAG16 - \b IPC_FLAG31 or \b NO_FLAG.
336 //!
337 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
338 //! because PutBuffer was full, command was not sent)
339 //
340 //*****************************************************************************
341 uint16_t
IPCLtoRDataRead(volatile tIpcController * psController,uint32_t ulAddress,void * pvData,uint16_t usLength,uint16_t bBlock,uint32_t ulResponseFlag)342 IPCLtoRDataRead (volatile tIpcController *psController, uint32_t ulAddress,
343 void *pvData, uint16_t usLength, uint16_t bBlock,
344 uint32_t ulResponseFlag)
345 {
346
347 uint16_t status;
348 tIpcMessage sMessage;
349
350 //
351 // Set up read command, address, dataw1 = ResponseFlag | word length,
352 // dataw2 = address where word
353 // should be written to when returned.
354 //
355 sMessage.ulcommand = IPC_DATA_READ;
356 sMessage.uladdress = ulAddress;
357 sMessage.uldataw1 = (ulResponseFlag & 0xFFFF0000)|(uint32_t)usLength;
358 sMessage.uldataw2 = (uint32_t)pvData;
359
360 //
361 // Set ResponseFlag (cleared once data is read into address at pvData)
362 // Put Message into PutBuffer and set IPC INT flag
363 //
364 IpcRegs.IPCSET.all |= (ulResponseFlag & 0xFFFF0000);
365 status = IpcPut (psController, &sMessage, bBlock);
366
367 return status;
368
369 //
370 //Note: Read Response will have sMessage.ulcommand = IPC_DATA_WRITE
371 // sMessage.uladdress = (uint32_t) pvData
372 // sMessage.uldataw1 = ulStatusFlag |
373 // (uint32_t) usLength;
374 // sMessage.uldataw2 = word to be read into
375 // pvData address.
376 //
377 }
378
379 //*****************************************************************************
380 //
381 //! Sends the command to read either a 16- or 32-bit data word from remote
382 //! CPU system address to a write-protected local CPU address.
383 //!
384 //! \param psController specifies the address of a \e tIpcController instance
385 //! used to store information about the "Put" and "Get" circular buffers and
386 //! their respective indexes.
387 //! \param ulAddress specifies the remote CPU address to read from
388 //! \param pvData is a pointer to the 16/32-bit variable where read data will
389 //! be stored.
390 //! \param usLength designates 16- or 32-bit read (1 = 16-bit, 2 = 32-bit)
391 //! \param bBlock specifies whether to allow function to block until PutBuffer
392 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
393 //! \param ulResponseFlag indicates the local CPU to remote CPU Flag number
394 //! mask used to report when the read data is available at pvData.
395 //! (\e ulResponseFlag MUST use IPC flags 17-32, and not 1-16)
396 //!
397 //! This function will allow the local CPU system to send a 16/32-bit data
398 //! read command to the remote CPU system and set a ResponseFlag to track the
399 //! status of the read.
400 //! The remote CPU system will respond with a DataWrite command which will
401 //! place the data in the local CPU address pointed to by \e pvData.
402 //! When the local CPU receives the DataWrite command and writes the read data
403 //! into \e *pvData location, it will clear the ResponseFlag, indicating to
404 //! the rest of the system that the data is ready. The \e usLength parameter
405 //! can be one of the following values: \b IPC_LENGTH_16_BITS or
406 //! \b IPC_LENGTH_32_BITS. The \e bBlock parameter can be one of the following
407 //! values: \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
408 //! The \e ulResponseFlag parameter can be any single one of the flags \b
409 //! IPC_FLAG16 - \b IPC_FLAG31 or \b NO_FLAG.
410 //!
411 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
412 //! because PutBuffer was full, command was not sent)
413 //
414 //*****************************************************************************
415 uint16_t
IPCLtoRDataRead_Protected(volatile tIpcController * psController,uint32_t ulAddress,void * pvData,uint16_t usLength,uint16_t bBlock,uint32_t ulResponseFlag)416 IPCLtoRDataRead_Protected (volatile tIpcController *psController,
417 uint32_t ulAddress, void *pvData, uint16_t usLength,
418 uint16_t bBlock,
419 uint32_t ulResponseFlag)
420 {
421 uint16_t status;
422 tIpcMessage sMessage;
423
424 //
425 // Set up read command, address, dataw1 = ResponseFlag | word length, dataw2
426 // = address where word should be written to when returned.
427 //
428 sMessage.ulcommand = IPC_DATA_READ_PROTECTED;
429 sMessage.uladdress = ulAddress;
430 sMessage.uldataw1 = (ulResponseFlag & 0xFFFF0000)|(uint32_t)usLength;
431 sMessage.uldataw2 = (uint32_t)pvData;
432
433 //
434 // Set ResponseFlag (cleared once data is read into address at pvData)
435 // Put Message into PutBuffer and set IPC INT flag
436 //
437 IpcRegs.IPCSET.all |= (ulResponseFlag & 0xFFFF0000);
438 status = IpcPut (psController, &sMessage, bBlock);
439
440 return status;
441 //
442 // Note: Read Response will have sMessage.ulcommand = IPC_DATA_WRITE
443 // sMessage.uladdress = (uint32_t) pvData
444 // sMessage.uldataw1 = ulStatusFlag |
445 // (uint32_t) usLength;
446 // sMessage.uldataw2 = word to be read into
447 // pvData address.
448 //
449 }
450
451 //*****************************************************************************
452 //
453 //! Sets the designated bits in a 16-bit data word at the remote CPU system
454 //! address
455 //!
456 //! \param psController specifies the address of a \e tIpcController instance
457 //! used to store information about the "Put" and "Get" circular buffers and
458 //! their respective indexes.
459 //! \param ulAddress specifies the remote CPU address to write to
460 //! \param ulMask specifies the 16/32-bit mask for bits which should be set at
461 //! \e ulAddress.
462 //! 16-bit masks should fill the lower 16-bits (upper 16-bits will be all
463 //! 0x0000).
464 //! \param usLength specifies the length of the bit mask (1=16-bits, 2=32-bits)
465 //! \param bBlock specifies whether to allow function to block until PutBuffer
466 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
467 //!
468 //! This function will allow the local CPU system to set bits specified by the
469 //! \e ulMask variable in a 16/32-bit word on the remote CPU system. The \e
470 //! usLength parameter can be one of the following values: \b IPC_LENGTH_16_BITS
471 //! or \b IPC_LENGTH_32_BITS. The \e bBlock parameter can be one of the
472 //! following values: \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
473 //!
474 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
475 //! because PutBuffer was full, command was not sent)
476 //
477 //*****************************************************************************
478 uint16_t
IPCLtoRSetBits(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulMask,uint16_t usLength,uint16_t bBlock)479 IPCLtoRSetBits(volatile tIpcController *psController, uint32_t ulAddress,
480 uint32_t ulMask, uint16_t usLength,
481 uint16_t bBlock)
482 {
483 uint16_t status;
484 tIpcMessage sMessage;
485
486 //
487 // Set up set bits command, address, dataw1 = word length, dataw2 =
488 // 16/32-bit mask
489 //
490 sMessage.ulcommand = IPC_SET_BITS;
491 sMessage.uladdress = ulAddress;
492 sMessage.uldataw1 = (uint32_t)usLength;
493 sMessage.uldataw2 = ulMask;
494
495 //
496 // Put Message into PutBuffer and set IPC INT flag
497 //
498 status = IpcPut (psController, &sMessage, bBlock);
499 return status;
500 }
501 //*****************************************************************************
502 //
503 //! Sets the designated bits in a 16-bit write-protected data word at the
504 //! remote CPU system address
505 //!
506 //! \param psController specifies the address of a \e tIpcController instance
507 //! used to store information about the "Put" and "Get" circular buffers and
508 //! their respective indexes.
509 //! \param ulAddress specifies the remote CPU address to write to
510 //! \param ulMask specifies the 16/32-bit mask for bits which should be set at
511 //! \e ulAddress. 16-bit masks should fill the lower 16-bits (upper 16-bits
512 //! will be all 0x0000).
513 //! \param usLength specifies the length of the bit mask (1=16-bits, 2=32-bits)
514 //! \param bBlock specifies whether to allow function to block until PutBuffer
515 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
516 //!
517 //! This function will allow the local CPU system to set bits specified by the
518 //! \e ulMask variable in a write-protected 16/32-bit word on the remote CPU
519 //! system. The \e usLength parameter can be one of the following values: \b
520 //! IPC_LENGTH_16_BITS or \b IPC_LENGTH_32_BITS. The \e bBlock parameter can be
521 //! one of the following values:
522 //! \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
523 //!
524 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
525 //! because PutBuffer was full, command was not sent)
526 //
527 //*****************************************************************************
528 uint16_t
IPCLtoRSetBits_Protected(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulMask,uint16_t usLength,uint16_t bBlock)529 IPCLtoRSetBits_Protected(volatile tIpcController *psController,
530 uint32_t ulAddress, uint32_t ulMask, uint16_t usLength,
531 uint16_t bBlock)
532 {
533 uint16_t status;
534 tIpcMessage sMessage;
535
536 //
537 // Set up set bits command, address, dataw1 = word length, dataw2 =
538 // 16/32-bit mask
539 //
540 sMessage.ulcommand = IPC_SET_BITS_PROTECTED;
541 sMessage.uladdress = ulAddress;
542 sMessage.uldataw1 = (uint32_t)usLength;
543 sMessage.uldataw2 = ulMask;
544
545 //
546 // Put Message into PutBuffer and set IPC INT flag
547 //
548 status = IpcPut (psController, &sMessage, bBlock);
549 return status;
550 }
551
552 //*****************************************************************************
553 //
554 //! Clears the designated bits in a 16-bit data word at the remote CPU system
555 //! address
556 //!
557 //! \param psController specifies the address of a \e tIpcController instance
558 //! used to store information about the "Put" and "Get" circular buffers and
559 //! their respective indexes.
560 //! \param ulAddress specifies the remote CPU address to write to
561 //! \param ulMask specifies the 16/32-bit mask for bits which should be cleared
562 //! at \e ulAddress. 16-bit masks should fill the lower 16-bits (upper 16-bits
563 //! will be all 0x0000).
564 //! \param usLength specifies the length of the bit mask (1=16-bits, 2=32-bits)
565 //! \param bBlock specifies whether to allow function to block until PutBuffer
566 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
567 //!
568 //! This function will allow the local CPU system to clear bits specified by
569 //! the \e ulMask variable in a 16/32-bit word on the remote CPU system. The \e
570 //! usLength parameter can be one of the following values: \b
571 //! IPC_LENGTH_16_BITS or \b IPC_LENGTH_32_BITS. The \e bBlock parameter can be
572 //! one of the following values: \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
573 //!
574 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
575 //! because PutBuffer was full, command was not sent)
576 //
577 //*****************************************************************************
578 uint16_t
IPCLtoRClearBits(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulMask,uint16_t usLength,uint16_t bBlock)579 IPCLtoRClearBits(volatile tIpcController *psController, uint32_t ulAddress,
580 uint32_t ulMask, uint16_t usLength,
581 uint16_t bBlock)
582 {
583 uint16_t status;
584 tIpcMessage sMessage;
585
586 //
587 // Set up clear bits command, address, dataw1 = word length, dataw2 =
588 // 16/32-bit mask
589 //
590 sMessage.ulcommand = IPC_CLEAR_BITS;
591 sMessage.uladdress = ulAddress;
592 sMessage.uldataw1 = (uint32_t)usLength;
593 sMessage.uldataw2 = ulMask;
594
595 //
596 // Put Message into PutBuffer and set IPC INT flag
597 //
598 status = IpcPut (psController, &sMessage, bBlock);
599 return status;
600 }
601
602 //*****************************************************************************
603 //
604 //! Clears the designated bits in a 16-bit write-protected data word at
605 //! remote CPU system address
606 //!
607 //! \param psController specifies the address of a \e tIpcController instance
608 //! used to store information about the "Put" and "Get" circular buffers and
609 //! their respective indexes.
610 //! \param ulAddress specifies the secondary CPU address to write to
611 //! \param ulMask specifies the 16/32-bit mask for bits which should be cleared
612 //! at \e ulAddress. 16-bit masks should fill the lower 16-bits (upper 16-bits
613 //! will be all 0x0000).
614 //! \param usLength specifies the length of the bit mask (1=16-bits, 2=32-bits)
615 //! \param bBlock specifies whether to allow function to block until PutBuffer
616 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
617 //!
618 //! This function will allow the local CPU system to set bits specified by the
619 //! \e ulMask variable in a write-protected 16/32-bit word on the remote CPU
620 //! system. The \e usLength parameter can be one of the following values: \b
621 //! IPC_LENGTH_16_BITS or \b IPC_LENGTH_32_BITS. The \e bBlock parameter can be
622 //! one of the following values: \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
623 //!
624 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
625 //! because PutBuffer was full, command was not sent)
626 //
627 //*****************************************************************************
628 uint16_t
IPCLtoRClearBits_Protected(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulMask,uint16_t usLength,uint16_t bBlock)629 IPCLtoRClearBits_Protected(volatile tIpcController *psController,
630 uint32_t ulAddress, uint32_t ulMask,
631 uint16_t usLength, uint16_t bBlock)
632 {
633 uint16_t status;
634 tIpcMessage sMessage;
635
636 //
637 // Set up clear bits command, address, dataw1 = word length, dataw2 =
638 // 16/32-bit mask
639 //
640 sMessage.ulcommand = IPC_CLEAR_BITS_PROTECTED;
641 sMessage.uladdress = ulAddress;
642 sMessage.uldataw1 = (uint32_t)usLength;
643 sMessage.uldataw2 = ulMask;
644
645 //
646 // Put Message into PutBuffer and set IPC INT flag
647 //
648 status = IpcPut (psController, &sMessage, bBlock);
649 return status;
650 }
651
652 //*****************************************************************************
653 //
654 //! Writes a 16/32-bit data word to the remote CPU system address
655 //!
656 //! \param psController specifies the address of a \e tIpcController instance
657 //! used to store information about the "Put" and "Get" circular buffers and
658 //! their respective indexes.
659 //! \param ulAddress specifies the remote cpu address to write to
660 //! \param ulData specifies the 16/32-bit word which will be written.
661 //! For 16-bit words, only the lower 16-bits of ulData will be considered by
662 //! the master system.
663 //! \param usLength is the length of the word to write (1 = 16-bits, 2 =
664 //! 32-bits)
665 //! \param bBlock specifies whether to allow function to block until PutBuffer
666 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
667 //! \param ulResponseFlag is used to pass the \e ulResponseFlag back to the
668 //! remote cpu only when this function is called in response to \e
669 //! IPCMtoCDataRead(). Otherwise, set to 0.
670 //!
671 //! This function will allow the local CPU system to write a 16/32-bit word
672 //! via the \e ulData variable to an address on the remote CPU system.
673 //! The \e usLength parameter can be one of the following values:
674 //! \b IPC_LENGTH_16_BITS or \b IPC_LENGTH_32_BITS. The \e bBlock parameter
675 //! can be one of the following values: \b ENABLE_BLOCKING or \b
676 //! DISABLE_BLOCKING.
677 //! The \e ulResponseFlag parameter can be any single one of the flags \b
678 //! IPC_FLAG16 - \b IPC_FLAG31 or \b NO_FLAG.
679 //!
680 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
681 //! because PutBuffer was full, command was not sent)
682 //
683 //*****************************************************************************
684 uint16_t
IPCLtoRDataWrite(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulData,uint16_t usLength,uint16_t bBlock,uint32_t ulResponseFlag)685 IPCLtoRDataWrite(volatile tIpcController *psController, uint32_t ulAddress,
686 uint32_t ulData, uint16_t usLength, uint16_t bBlock,
687 uint32_t ulResponseFlag)
688 {
689 uint16_t status;
690 tIpcMessage sMessage;
691
692 //
693 // Set up write command, address, dataw1 = ResponseFlag | word length,
694 // dataw2 = data to write
695 //
696 sMessage.ulcommand = IPC_DATA_WRITE;
697 sMessage.uladdress = ulAddress;
698 sMessage.uldataw1 = ulResponseFlag |(uint32_t)usLength;
699 sMessage.uldataw2 = ulData;
700
701 //
702 // Put Message into PutBuffer and set IPC INT flag
703 //
704 status = IpcPut (psController, &sMessage, bBlock);
705 return status;
706 }
707
708 //*****************************************************************************
709 //
710 //! Writes a 16/32-bit data word to a write-protected remote CPU system address
711 //!
712 //! \param psController specifies the address of a \e tIpcController instance
713 //! used to store information about the "Put" and "Get" circular buffers and
714 //! their respective indexes.
715 //! \param ulAddress specifies the write-protected remote CPU address to
716 //! write to
717 //! \param ulData specifies the 16/32-bit word which will be written. For
718 //! 16-bit words, only the lower 16-bits of ulData will be considered by the
719 //! master system.
720 //! \param usLength is the length of the word to write (1 = 16-bits, 2 =
721 //! 32-bits)
722 //! \param bBlock specifies whether to allow function to block until PutBuffer
723 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
724 //! \param ulResponseFlag is used to pass the \e ulResponseFlag back to the
725 //! remote CPU only when this function is called in response to \e
726 //! IPCMtoCDataRead(). Otherwise, set to 0.
727 //!
728 //! This function will allow the local CPU system to write a 16/32-bit word
729 //! via the \e ulData variable to a write-protected address on the remote CPU
730 //! system. The \e usLength parameter can be one of the following values:
731 //! \b IPC_LENGTH_16_BITS or \b IPC_LENGTH_32_BITS. The \e bBlock parameter
732 //! can be one of the following values: \b ENABLE_BLOCKING or \b
733 //! DISABLE_BLOCKING.
734 //! The \e ulResponseFlag parameter can be any single one of the flags \b
735 //! IPC_FLAG16 -
736 //! \b IPC_FLAG31 or \b NO_FLAG.
737 //!
738 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
739 //! because PutBuffer was full, command was not sent)
740 //
741 //*****************************************************************************
742 uint16_t
IPCLtoRDataWrite_Protected(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulData,uint16_t usLength,uint16_t bBlock,uint32_t ulResponseFlag)743 IPCLtoRDataWrite_Protected(volatile tIpcController *psController,
744 uint32_t ulAddress, uint32_t ulData,
745 uint16_t usLength, uint16_t bBlock,
746 uint32_t ulResponseFlag)
747 {
748 uint16_t status;
749 tIpcMessage sMessage;
750
751 //
752 // Set up write command, address, dataw1 = ResponseFlag | word length,
753 // dataw2 = data to write
754 //
755 sMessage.ulcommand = IPC_DATA_WRITE_PROTECTED;
756 sMessage.uladdress = ulAddress;
757 sMessage.uldataw1 = ulResponseFlag |(uint32_t)usLength;
758 sMessage.uldataw2 = ulData;
759
760 //
761 // Put Message into PutBuffer and set IPC INT flag
762 //
763 status = IpcPut (psController, &sMessage, bBlock);
764 return status;
765 }
766
767 //*****************************************************************************
768 //
769 //! Sends the command to read a block of data from remote CPU system address
770 //!
771 //! \param psController specifies the address of a \e tIpcController instance
772 //! used to store information about the "Put" and "Get" circular buffers and
773 //! their respective indexes.
774 //! \param ulAddress specifies the remote CPU memory block starting address
775 //! to read from.
776 //! \param ulShareAddress specifies the local CPU shared memory address the
777 //! read block will read to.
778 //! \param usLength designates the block size in 16-bit words.
779 //! \param bBlock specifies whether to allow function to block until PutBuffer
780 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
781 //! \param ulResponseFlag indicates the local CPU to remote CPU Flag number
782 //! mask used to report when the read block data is available starting at
783 //! /e ulShareAddress. (\e ulResponseFlag MUST use IPC flags 17-32, and not
784 //! 1-16)
785 //!
786 //! This function will allow the local CPU system to send a read block
787 //! command to the remote CPU system and set a ResponseFlag to track the status
788 //! of the read. The remote CPU system will process the read and place the data
789 //! in shared memory at the location specified in the \e ulShareAddress
790 //! parameter and then clear the ResponseFlag, indicating that the block is
791 //! ready. The \e bBlock parameter can be one of the following values: \b
792 //! ENABLE_BLOCKING or \b DISABLE_BLOCKING. The \e ulResponseFlag parameter can
793 //! be any single one of the flags \b IPC_FLAG16 - \b IPC_FLAG31 or \b NO_FLAG.
794 //!
795 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
796 //! because PutBuffer was full, command was not sent)
797 //
798 //*****************************************************************************
799 uint16_t
IPCLtoRBlockRead(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulShareAddress,uint16_t usLength,uint16_t bBlock,uint32_t ulResponseFlag)800 IPCLtoRBlockRead(volatile tIpcController *psController, uint32_t ulAddress,
801 uint32_t ulShareAddress, uint16_t usLength, uint16_t bBlock,
802 uint32_t ulResponseFlag)
803 {
804 uint16_t status;
805 tIpcMessage sMessage;
806
807 //
808 // Set up block read command, address, dataw1 = ResponseFlag | block length,
809 // dataw2 = remote CPU address in shared memory
810 // where block data should be read to
811 // (corresponding to local CPU ulShareAddress).
812 //
813 sMessage.ulcommand = IPC_BLOCK_READ;
814 sMessage.uladdress = ulAddress;
815 sMessage.uldataw1 = (ulResponseFlag & 0xFFFF0000) |(uint32_t)usLength;
816 sMessage.uldataw2 = ulShareAddress;
817
818 //
819 // Set ResponseFlag (cleared once data is read into Share Address location)
820 // Put Message into PutBuffer and set IPC INT flag
821 //
822 IpcRegs.IPCSET.all |= (ulResponseFlag & 0xFFFF0000);
823 status = IpcPut (psController, &sMessage, bBlock);
824
825 return status;
826 //
827 // Note: Read Block Response will occur in processing of ReadBlock (since
828 // remote CPU has access to shared memory)
829 //
830 }
831
832 //*****************************************************************************
833 //
834 //! Writes a block of data to remote CPU system address
835 //!
836 //! \param psController specifies the address of a \e tIpcController instance
837 //! used to store information about the "Put" and "Get" circular buffers and
838 //! their respective indexes.
839 //! \param ulAddress specifies the remote CPU memory block starting address
840 //! to write to.
841 //! \param ulShareAddress specifies the local CPU shared memory address where
842 //! data to write from resides.
843 //! \param usLength designates the block size in 16- or 32-bit words (depends
844 //! on \e usWordLength).
845 //! \param usWordLength designates the word size (16-bits = 1 or 32-bits = 2).
846 //! \param bBlock specifies whether to allow function to block until PutBuffer
847 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
848 //!
849 //! This function will allow the local CPU system to write a block of data to
850 //! the remote CPU system starting from the location specified by the
851 //! \e ulAdress parameter. Prior to calling this function, the local CPU
852 //! system code should place the data to write in shared memory starting at /e
853 //! ulShareAddress.
854 //! The \e usWordLength parameter can be one of the following values:
855 //! \b IPC_LENGTH_16_BITS or \b IPC_LENGTH_32_BITS. The \e bBlock parameter
856 //! can be one of the following values: \b ENABLE_BLOCKING or \b
857 //! DISABLE_BLOCKING.
858 //! The \e ulResponseFlag parameter can be any single one of the flags \b
859 //! IPC_FLAG16 - \b IPC_FLAG31 or \b NO_FLAG.
860 //!
861 //! \note If the shared SARAM blocks are used to pass the RAM block between the
862 //! processors, the IPCReqMemAccess() function must be called first in order to
863 //! give the slave CPU write access to the shared memory block(s).
864 //!
865 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
866 //! because PutBuffer was full, command was not sent)
867 //
868 //*****************************************************************************
869 uint16_t
IPCLtoRBlockWrite(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulShareAddress,uint16_t usLength,uint16_t usWordLength,uint16_t bBlock)870 IPCLtoRBlockWrite(volatile tIpcController *psController, uint32_t ulAddress,
871 uint32_t ulShareAddress, uint16_t usLength,
872 uint16_t usWordLength, uint16_t bBlock)
873 {
874 uint16_t status;
875 tIpcMessage sMessage;
876
877 //
878 // Set up block write command, address, dataw1 = block length,
879 // dataw2 = remote CPU shared mem address
880 // where write data resides
881 //
882 sMessage.ulcommand = IPC_BLOCK_WRITE;
883 sMessage.uladdress = ulAddress;
884 sMessage.uldataw1 = ((uint32_t)(usWordLength)<<16) + (uint32_t)usLength;
885 sMessage.uldataw2 = ulShareAddress;
886
887 //
888 // Put Message into PutBuffer and set IPC INT flag
889 //
890 status = IpcPut (psController, &sMessage, bBlock);
891 return status;
892 }
893
894 //*****************************************************************************
895 //
896 //! Writes a block of data to a write-protected remote CPU system address
897 //!
898 //! \param psController specifies the address of a \e tIpcController instance
899 //! used to store information about the "Put" and "Get" circular buffers and
900 //! their respective indexes.
901 //! \param ulAddress specifies the write-protected remote CPU block starting
902 //! address to write to.
903 //! \param ulShareAddress specifies the local CPU shared memory address where
904 //! data to write from resides.
905 //! \param usLength designates the block size in 16- or 32-bit words (depends
906 //! on \e usWordLength).
907 //! \param usWordLength designates the word size (16-bits = 1 or 32-bits = 2).
908 //! \param bBlock specifies whether to allow function to block until PutBuffer
909 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
910 //!
911 //! This function will allow the local CPU system to write a block of data to
912 //! a write-protected region on the remote CPU system starting from the
913 //! location specified by the \e ulAdress parameter. Prior to calling this
914 //! function, the local CPU system code should place the data to write in
915 //! shared memory starting at /e ulShareAddress.
916 //! The \e usWordLength parameter can be one of the following values:
917 //! \b IPC_LENGTH_16_BITS or \b IPC_LENGTH_32_BITS. The \e bBlock parameter
918 //! can be one of the following values: \b ENABLE_BLOCKING or \b
919 //! DISABLE_BLOCKING.
920 //! The \e ulResponseFlag parameter can be any single one of the flags \b
921 //! IPC_FLAG16 - \b IPC_FLAG31 or \b NO_FLAG.
922 //!
923 //! \note If the shared SARAM blocks are used to pass the RAM block between the
924 //! processors, the IPCReqMemAccess() function must be called first in order to
925 //! give the the slave CPU write access to the shared memory block(s).
926 //!
927 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
928 //! because PutBuffer was full, command was not sent)
929 //
930 //*****************************************************************************
931 uint16_t
IPCLtoRBlockWrite_Protected(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulShareAddress,uint16_t usLength,uint16_t usWordLength,uint16_t bBlock)932 IPCLtoRBlockWrite_Protected(volatile tIpcController *psController,
933 uint32_t ulAddress, uint32_t ulShareAddress,
934 uint16_t usLength, uint16_t usWordLength,
935 uint16_t bBlock)
936 {
937 uint16_t status;
938 tIpcMessage sMessage;
939
940 //
941 // Set up block write command, address, dataw1 = block length,
942 // dataw2 = remote CPU shared mem address
943 // where write data resides
944 //
945 sMessage.ulcommand = IPC_BLOCK_WRITE_PROTECTED;
946 sMessage.uladdress = ulAddress;
947 sMessage.uldataw1 = ((uint32_t)(usWordLength)<<16) + (uint32_t)usLength;
948 sMessage.uldataw2 = ulShareAddress;
949
950 //
951 // Put Message into PutBuffer and set IPC INT flag
952 //
953 status = IpcPut (psController, &sMessage, bBlock);
954 return status;
955 }
956
957 //*****************************************************************************
958 //
959 //! Calls remote CPU function with 1 optional parameter .
960 //!
961 //! \param psController specifies the address of a \e tIpcController instance
962 //! used to store information about the "Put" and "Get" circular buffers and
963 //! their respective indexes.
964 //! \param ulAddress specifies the remote CPU function address
965 //! \param ulParam specifies the 32-bit optional parameter value. If not used,
966 //! this can be a dummy value.
967 //! \param bBlock specifies whether to allow function to block until PutBuffer
968 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
969 //!
970 //! This function will allow the local CPU system to call a function on the
971 //! remote CPU. The \e ulParam variable is a single optional 32-bit parameter
972 //! to pass to the function. The \e bBlock parameter can be one of the
973 //! following values: \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
974 //!
975 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
976 //! because PutBuffer was full, command was not sent)
977 //
978 //*****************************************************************************
979 uint16_t
IPCLtoRFunctionCall(volatile tIpcController * psController,uint32_t ulAddress,uint32_t ulParam,uint16_t bBlock)980 IPCLtoRFunctionCall(volatile tIpcController *psController, uint32_t ulAddress,
981 uint32_t ulParam,
982 uint16_t bBlock)
983 {
984 uint16_t status;
985 tIpcMessage sMessage;
986
987 //
988 // Set up function call command, address, dataw1 = 32-bit parameter
989 //
990 sMessage.ulcommand = IPC_FUNC_CALL;
991 sMessage.uladdress = ulAddress;
992 sMessage.uldataw1 = ulParam;
993
994 //
995 // Put Message into PutBuffer and set IPC INT flag
996 //
997 status = IpcPut (psController, &sMessage, bBlock);
998 return status;
999 }
1000
1001 //*****************************************************************************
1002 //
1003 //! Sends generic message to remote CPU system
1004 //!
1005 //! \param psController specifies the address of a \e tIpcController instance
1006 //! used to store information about the "Put" and "Get" circular buffers and
1007 //! their respective indexes.
1008 //! \param ulCommand specifies 32-bit command word to insert into message.
1009 //! \param ulAddress specifies 32-bit address word to insert into message.
1010 //! \param ulDataW1 specifies 1st 32-bit data word to insert into message.
1011 //! \param ulDataW2 specifies 2nd 32-bit data word to insert into message.
1012 //! \param bBlock specifies whether to allow function to block until PutBuffer
1013 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
1014 //!
1015 //! This function will allow the local CPU system to send a generic message to
1016 //! the remote CPU system. Note that the user should create a corresponding
1017 //! function on the remote CPU side to interpret/use the message or fill
1018 //! parameters in such a way that the existing IPC drivers can recognize the
1019 //! command and properly process the message.
1020 //! The \e bBlock parameter can be one of the following values: \b
1021 //! ENABLE_BLOCKING or \b DISABLE_BLOCKING.
1022 //!
1023 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
1024 //! because PutBuffer was full, command was not sent)
1025 //
1026 //*****************************************************************************
1027 uint16_t
IPCLtoRSendMessage(volatile tIpcController * psController,uint32_t ulCommand,uint32_t ulAddress,uint32_t ulDataW1,uint32_t ulDataW2,uint16_t bBlock)1028 IPCLtoRSendMessage(volatile tIpcController *psController, uint32_t ulCommand,
1029 uint32_t ulAddress, uint32_t ulDataW1, uint32_t ulDataW2,
1030 uint16_t bBlock)
1031 {
1032 uint16_t status;
1033 tIpcMessage sMessage;
1034
1035 //
1036 // Package message to send
1037 //
1038 sMessage.ulcommand = ulCommand;
1039 sMessage.uladdress = ulAddress;
1040 sMessage.uldataw1 = ulDataW1;
1041 sMessage.uldataw2 = ulDataW2;
1042
1043 //
1044 // Put Message into PutBuffer and set IPC INT flag
1045 //
1046 status = IpcPut (psController, &sMessage, bBlock);
1047 return status;
1048 }
1049
1050 #if defined (CPU2)
1051 //*****************************************************************************
1052 //
1053 //! Slave CPU Configures master R/W/Exe Access to Shared SARAM.
1054 //!
1055 //! \param psController specifies the address of a \e tIpcController instance
1056 //! used to store information about the "Put" and "Get" circular buffers and
1057 //! their respective indexes.
1058 //! \param ulMask specifies the 32-bit mask for the GSxMSEL RAM control
1059 //! register to indicate which GSx SARAM blocks the slave CPU is requesting
1060 //! master access to.
1061 //! \param usMaster specifies whether the CPU1 or CPU2 are given
1062 //! master access to the GSx blocks.
1063 //! \param bBlock specifies whether to allow function to block until PutBuffer
1064 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
1065 //!
1066 //! This function will allow the slave CPU system to configure master R/W/Exe
1067 //! access to the GSx SARAM blocks specified by the /e ulMask parameter. The
1068 //! function calls the \e IPCSetBits_Protected() or \e
1069 //! IPCClearBits_Protected() functions, and therefore in the master CPU
1070 //! application code, the corresponding functions should be called.
1071 //! The \e bBlock parameter can be one of the following values: \b
1072 //! ENABLE_BLOCKING or \b DISABLE_BLOCKING. The \e usMaster parameter can be
1073 //! either: \b IPC_GSX_CPU2_MASTER or \b IPC_GSX_CPU1_MASTER. The \e ulMask
1074 //! parameter can be any of the options: \b S0_ACCESS - \b S7_ACCESS.
1075 //!
1076 //! \return status of command (\b STATUS_PASS =success, \b STATUS_FAIL = error
1077 //! because PutBuffer was full, command was not sent)
1078 //
1079 //*****************************************************************************
1080 uint16_t
IPCReqMemAccess(volatile tIpcController * psController,uint32_t ulMask,uint16_t usMaster,uint16_t bBlock)1081 IPCReqMemAccess (volatile tIpcController *psController, uint32_t ulMask,
1082 uint16_t usMaster, uint16_t bBlock)
1083 {
1084 uint16_t status = STATUS_PASS;
1085 uint32_t GSxMSEL_REGaddress = (uint32_t)(&MemCfgRegs.GSxMSEL.all);
1086
1087 if (usMaster == IPC_GSX_CPU2_MASTER)
1088 {
1089 if ((MemCfgRegs.GSxMSEL.all & ulMask) != ulMask)
1090 {
1091 status =
1092 IPCLtoRSetBits_Protected (psController, GSxMSEL_REGaddress,
1093 ulMask, IPC_LENGTH_32_BITS,
1094 bBlock);
1095 }
1096 }
1097 else if (usMaster == IPC_GSX_CPU1_MASTER)
1098 {
1099 if ((MemCfgRegs.GSxMSEL.all & ulMask) != 0)
1100 {
1101 status =
1102 IPCLtoRClearBits_Protected (psController, GSxMSEL_REGaddress,
1103 ulMask, IPC_LENGTH_32_BITS,
1104 bBlock);
1105 }
1106 }
1107
1108 return status;
1109 }
1110 #endif
1111
1112 //*****************************************************************************
1113 //
1114 //! Responds to 16/32-bit data word write command the remote CPU system
1115 //!
1116 //! \param psMessage specifies the pointer to the message received from remote
1117 //! CPU system which includes the 16/32-bit data word to write to the local CPU
1118 //! address.
1119 //!
1120 //! This function will allow the local CPU system to write a 16/32-bit word
1121 //! received from the remote CPU system to the address indicated in \e
1122 //! *psMessage. In the event that the IPC_DATA_WRITE command was received as a
1123 //! result of an IPC_DATA_READ command, this function will also clear the IPC
1124 //! response flag tracking the read so other threads in the local CPU system
1125 //! will be aware that the data is ready.
1126 //!
1127 //! \return None.
1128 //
1129 //*****************************************************************************
1130 void
IPCRtoLDataWrite(tIpcMessage * psMessage)1131 IPCRtoLDataWrite(tIpcMessage *psMessage)
1132 {
1133 //
1134 // Data word length = dataw1 (15:0), responseFlag = valid only for IPC
1135 // flags 17-32
1136 //
1137 uint16_t length = (uint16_t) psMessage->uldataw1;
1138 uint32_t responseFlag = (psMessage->uldataw1) & 0xFFFF0000;
1139
1140 //
1141 // Write 16/32-bit word to address
1142 //
1143 if (length == IPC_LENGTH_16_BITS)
1144 {
1145 *(uint16_t *)(psMessage->uladdress) = (uint16_t)psMessage->uldataw2;
1146 }
1147 else if (length == IPC_LENGTH_32_BITS)
1148 {
1149 *(uint32_t *)(psMessage->uladdress) = psMessage->uldataw2;
1150 }
1151
1152 //
1153 // If data write command is in response to a data read command from remote
1154 // CPU to local CPU clear ResponseFlag, indicating read data from remote
1155 // CPU is ready.
1156 //
1157 IpcRegs.IPCCLR.all |= responseFlag;
1158 }
1159
1160 //*****************************************************************************
1161 //
1162 //! Responds to 16/32-bit write-protected data word write command from
1163 //! secondary CPU system
1164 //!
1165 //! \param psMessage specifies the pointer to the message received from the
1166 //! secondary CPU system which includes the 16/32-bit data word to write to the
1167 //! local CPU address.
1168 //!
1169 //! This function will allow the local CPU system to write a 16/32-bit word
1170 //! received from the secondary CPU system to the write-protected address
1171 //! indicated in \e *psMessage.
1172 //! In the event that the IPC_DATA_WRITE_PROTECTED command was received as a
1173 //! result of an IPC_DATA_READ_PROTECTED command, this function will also clear
1174 //! the IPC response flag tracking the read so other threads in the local CPU
1175 //! will be aware that the data is ready.
1176 //!
1177 //! \return None.
1178 //
1179 //*****************************************************************************
1180 void
IPCRtoLDataWrite_Protected(tIpcMessage * psMessage)1181 IPCRtoLDataWrite_Protected(tIpcMessage *psMessage)
1182 {
1183 //
1184 // Data word length = dataw1 (15:0), responseFlag = valid only for IPC
1185 // flags 17-32
1186 //
1187 uint16_t length = (uint16_t) psMessage->uldataw1;
1188 uint32_t responseFlag = (psMessage->uldataw1) & 0xFFFF0000;
1189
1190 //
1191 // Allow access to EALLOW-protected registers.
1192 //
1193 EALLOW;
1194
1195 //
1196 // Write 16/32-bit word to EALLOW-protected address
1197 //
1198 if (length == IPC_LENGTH_16_BITS)
1199 {
1200 *(uint16_t *)(psMessage->uladdress) = (uint16_t)psMessage->uldataw2;
1201 }
1202 else if (length == IPC_LENGTH_32_BITS)
1203 {
1204 *(uint32_t *)(psMessage->uladdress) = psMessage->uldataw2;
1205 }
1206
1207 //
1208 // Disable access to EALLOW-protected registers.
1209 //
1210 EDIS;
1211
1212 //
1213 // If data write command is in response to a data read command from local
1214 // CPU to remote CPU, clear ResponseFlag, indicating read data from
1215 // secondary CPU is ready
1216 //
1217 IpcRegs.IPCCLR.all |= responseFlag;
1218 }
1219
1220 //*****************************************************************************
1221 //
1222 //! Responds to 16/32-bit data word read command from remote CPU system.
1223 //!
1224 //! \param psController specifies the address of a \e tIpcController instance
1225 //! used to store information about the "Put" and "Get" circular buffers and
1226 //! their respective indexes.
1227 //! \param psMessage specifies the pointer to the message received from the
1228 //! remote CPU system.
1229 //! \param bBlock specifies whether to allow function to block until PutBuffer
1230 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
1231 //!
1232 //! This function will allow the remote CPU system to read a 16/32-bit data
1233 //! word at the local CPU address specified in /e psMessage, and send a Write
1234 //! command with the read data back to the local CPU system. It will also send
1235 //! the Response Flag used to track the read back to the remote CPU.
1236 //! The \e bBlock parameter can be one of the following values: \b
1237 //! ENABLE_BLOCKING or \b DISABLE_BLOCKING.
1238 //!
1239 //! \return None.
1240 //
1241 //*****************************************************************************
1242 void
IPCRtoLDataRead(volatile tIpcController * psController,tIpcMessage * psMessage,uint16_t bBlock)1243 IPCRtoLDataRead(volatile tIpcController *psController, tIpcMessage *psMessage,
1244 uint16_t bBlock)
1245 {
1246 unsigned long ulReaddata;
1247 uint16_t usLength;
1248
1249 //
1250 // If data word length = 16-bits, read the 16-bit value at the given
1251 // address and cast as 32-bit word to send back to remote CPU.
1252 // If data word length = 32-bits, read the 32-bit value at the given
1253 // address.
1254 //
1255 usLength = (uint16_t)psMessage->uldataw1;
1256
1257 if (usLength == IPC_LENGTH_16_BITS)
1258 {
1259 ulReaddata = (unsigned long)(*(volatile uint16_t *)psMessage->uladdress);
1260 }
1261 else if (usLength == IPC_LENGTH_32_BITS)
1262 {
1263 ulReaddata = *(unsigned long *)psMessage->uladdress;
1264 }
1265
1266 //
1267 // Send a Write command to write the requested data to the remote CPU read
1268 // into address.
1269 // psMessage->uldataw2 contains remote CPU address where readdata will be
1270 // written.
1271 // psMessage->uldataw1 contains the read response flag in IPC flag 17-32.
1272 //
1273 IPCLtoRDataWrite(psController, psMessage->uldataw2, ulReaddata, usLength,
1274 bBlock,(psMessage->uldataw1 & 0xFFFF0000));
1275 }
1276
1277 //*****************************************************************************
1278 //
1279 //! Responds to 16/32-bit data word read command from remote CPU system.
1280 //! to read into a write-protected word on the remote CPU system.
1281 //!
1282 //! \param psController specifies the address of a \e tIpcController instance
1283 //! used to store information about the "Put" and "Get" circular buffers and
1284 //! their respective indexes.
1285 //! \param psMessage specifies the pointer to the message received from the
1286 //! remote CPU system.
1287 //! \param bBlock specifies whether to allow function to block until PutBuffer
1288 //! has a slot (1= wait until slot free, 0 = exit with STATUS_FAIL if no slot).
1289 //!
1290 //! This function will allow the remote CPU system to read a 16/32-bit data
1291 //! word at the local CPU address specified in /e psMessage, and send a Write
1292 //! Protected command with the read data back to the remote CPU system at a
1293 //! write protected address. It will also send the Response Flag used to track
1294 //! the read back to the remote CPU. The \e bBlock parameter can be one of the
1295 //! following values: \b ENABLE_BLOCKING or \b DISABLE_BLOCKING.
1296 //!
1297 //! \return None.
1298 //
1299 //*****************************************************************************
1300 void
IPCRtoLDataRead_Protected(volatile tIpcController * psController,tIpcMessage * psMessage,uint16_t bBlock)1301 IPCRtoLDataRead_Protected(volatile tIpcController *psController,
1302 tIpcMessage *psMessage, uint16_t bBlock)
1303 {
1304 unsigned long ulReaddata;
1305 uint16_t usLength;
1306
1307 //
1308 // If data word length = 16-bits, read the 16-bit value at the given
1309 // address and cast as 32-bit word to send back to remote CPU.
1310 // If data word length = 32-bits, read the 32-bit value at the given
1311 // address.
1312 //
1313 usLength = (uint16_t)psMessage->uldataw1;
1314
1315 if (usLength == IPC_LENGTH_16_BITS)
1316 {
1317 ulReaddata = (unsigned long)(*(volatile uint16_t *)psMessage->uladdress);
1318 }
1319 else if (usLength == IPC_LENGTH_32_BITS)
1320 {
1321 ulReaddata = *(unsigned long *)psMessage->uladdress;
1322 }
1323
1324 //
1325 // Send a Write command to write the requested data to the remote CPU read
1326 // into address.
1327 // psMessage->uldataw2 contains remote CPU address where readdata will be
1328 // written.
1329 // psMessage->uldataw1 contains the read response flag in IPC flag 17-32.
1330 //
1331 IPCLtoRDataWrite_Protected(psController, psMessage->uldataw2, ulReaddata,
1332 usLength, bBlock,
1333 (psMessage->uldataw1 & 0xFFFF0000));
1334 }
1335
1336 //*****************************************************************************
1337 //
1338 //! Sets the designated bits in a 16/32-bit data word at a local CPU system
1339 //! address
1340 //!
1341 //! \param psMessage specifies the pointer to the message received from the
1342 //! remote CPU system.
1343 //!
1344 //! This function will allow the remote CPU system to set the bits in a
1345 //! 16/32-bit word on the local CPU system via a local CPU address and mask
1346 //! passed in via the \e psMessage.
1347 //!
1348 //! \return None.
1349 //
1350 //*****************************************************************************
1351 void
IPCRtoLSetBits(tIpcMessage * psMessage)1352 IPCRtoLSetBits(tIpcMessage *psMessage)
1353 {
1354 uint16_t usLength;
1355
1356 //
1357 // Determine length of word at psMessage->uladdress and then set bits based
1358 // on either the 16-bit or 32-bit bit-mask in psMessage->uldataw2.
1359 // (16-bit length ignores upper 16-bits of psMessage->uldataw2)
1360 //
1361 usLength = (uint16_t)psMessage->uldataw1;
1362
1363 if (usLength == IPC_LENGTH_16_BITS)
1364 {
1365 *(volatile uint16_t*)psMessage->uladdress |=
1366 (uint16_t) psMessage->uldataw2;
1367 }
1368 else if (usLength == IPC_LENGTH_32_BITS)
1369 {
1370 *(volatile unsigned long *)psMessage->uladdress |= psMessage->uldataw2;
1371 }
1372 }
1373
1374 //*****************************************************************************
1375 //
1376 //! Sets the designated bits in a 16/32-bit write-protected data word at a
1377 //! local CPU system address
1378 //!
1379 //! \param psMessage specifies the pointer to the message received from the
1380 //! remote CPU system.
1381 //!
1382 //! This function will allow the remote CPU system to set the bits in a write-
1383 //! protected 16/32-bit word on the local CPU system via a local CPU address
1384 //! and mask passed in via the \e psMessage.
1385 //!
1386 //! \return None
1387 //
1388 //*****************************************************************************
1389 void
IPCRtoLSetBits_Protected(tIpcMessage * psMessage)1390 IPCRtoLSetBits_Protected(tIpcMessage *psMessage)
1391 {
1392 uint16_t usLength;
1393
1394 //
1395 // Allow access to EALLOW-protected registers.
1396 //
1397 EALLOW;
1398
1399 //
1400 // Determine length of word at psMessage->uladdress and then set bits based
1401 // on either the 16-bit or 32-bit bit-mask in psMessage->uldataw2.
1402 // (16-bit length ignores upper 16-bits of psMessage->uldataw2)
1403 //
1404 usLength = (uint16_t)psMessage->uldataw1;
1405
1406 if (usLength == IPC_LENGTH_16_BITS)
1407 {
1408 *(volatile uint16_t*)psMessage->uladdress |=
1409 (uint16_t) psMessage->uldataw2;
1410 }
1411 else if (usLength == IPC_LENGTH_32_BITS)
1412 {
1413 *(volatile unsigned long *)psMessage->uladdress |= psMessage->uldataw2;
1414 }
1415
1416 //
1417 // Disable access to EALLOW-protected registers.
1418 //
1419 EDIS;
1420 }
1421
1422 //*****************************************************************************
1423 //
1424 //! Clears the designated bits in a 32-bit data word at a local CPU system
1425 //! address
1426 //!
1427 //! \param psMessage specifies the pointer to the message received from the
1428 //! remote CPU system.
1429 //!
1430 //! This function will allow the remote CPU system to clear the bits in a
1431 //! 16/32-bit word on the local CPU system via a local CPU address and mask
1432 //! passed in via the \e psMessage.
1433 //!
1434 //! \return None.
1435 //
1436 //*****************************************************************************
1437 void
IPCRtoLClearBits(tIpcMessage * psMessage)1438 IPCRtoLClearBits(tIpcMessage *psMessage)
1439 {
1440 uint16_t usLength;
1441
1442 //
1443 // Determine length of word at psMessage->uladdress and then clear bits
1444 // based on
1445 // either the 16-bit or 32-bit bit-mask in psMessage->uldataw2.
1446 // (16-bit length ignores upper 16-bits of psMessage->uldataw2)
1447 //
1448 usLength = (uint16_t)psMessage->uldataw1;
1449
1450 if (usLength == IPC_LENGTH_16_BITS)
1451 {
1452 *(volatile uint16_t*)psMessage->uladdress &=
1453 ~((uint16_t) psMessage->uldataw2);
1454 }
1455 else if (usLength == IPC_LENGTH_32_BITS)
1456 {
1457 *(volatile unsigned long *)psMessage->uladdress &=
1458 ~(psMessage->uldataw2);
1459 }
1460 }
1461
1462 //*****************************************************************************
1463 //
1464 //! Clears the designated bits in a write-protected 16/32-bit data word at a
1465 //! local CPU system address
1466 //!
1467 //! \param psMessage specifies the pointer to the message received from the
1468 //! remote CPU system.
1469 //!
1470 //! This function will allow the secondary CPU system to clear the bits in a
1471 //! 16/32-bit write-protected word on the local CPU system via a local
1472 //! CPU address and mask passed in via the \e psMessage.
1473 //!
1474 //! \return None.
1475 //
1476 //*****************************************************************************
1477 void
IPCRtoLClearBits_Protected(tIpcMessage * psMessage)1478 IPCRtoLClearBits_Protected(tIpcMessage *psMessage)
1479 {
1480 uint16_t usLength;
1481
1482 //
1483 // Allow access to EALLOW-protected registers.
1484 //
1485 EALLOW;
1486
1487 //
1488 // Determine length of word at psMessage->uladdress and then clear bits
1489 // based on
1490 // either the 16-bit or 32-bit bit-mask in psMessage->uldataw2.
1491 // (16-bit length ignores upper 16-bits of psMessage->uldataw2)
1492 //
1493 usLength = (uint16_t)psMessage->uldataw1;
1494
1495 if (usLength == IPC_LENGTH_16_BITS)
1496 {
1497 *(volatile uint16_t*)psMessage->uladdress &=
1498 ~((uint16_t) psMessage->uldataw2);
1499 }
1500 else if (usLength == IPC_LENGTH_32_BITS)
1501 {
1502 *(volatile unsigned long *)psMessage->uladdress &=
1503 ~(psMessage->uldataw2);
1504 }
1505
1506 //
1507 // Disable access to EALLOW-protected registers.
1508 //
1509 EDIS;
1510 }
1511
1512 //*****************************************************************************
1513 //
1514 //! Reads a block of data from a remote CPU system address and stores into
1515 //! shared RAM
1516 //!
1517 //! \param psMessage specifies the pointer to the message received from the
1518 //! remote CPU system.
1519 //!
1520 //! This function will respond to the remote CPU system request to read a block
1521 //! of data from the local control system, by reading the data and placing that
1522 //! data into the shared RAM location specified in \e psMessage.
1523 //!
1524 //! \return None.
1525 //
1526 //*****************************************************************************
1527 void
IPCRtoLBlockRead(tIpcMessage * psMessage)1528 IPCRtoLBlockRead(tIpcMessage *psMessage)
1529 {
1530
1531 uint16_t usLength;
1532 volatile uint16_t* pusRAddress;
1533 volatile uint16_t* pusWAddress;
1534 uint16_t usIndex;
1535
1536 pusRAddress = (volatile uint16_t *)psMessage->uladdress;
1537 pusWAddress = (volatile uint16_t *)psMessage->uldataw2;
1538 usLength = (uint16_t)psMessage->uldataw1;
1539
1540 for (usIndex=0; usIndex<usLength; usIndex++)
1541 {
1542 *pusWAddress = *pusRAddress;
1543 pusWAddress += 1;
1544 pusRAddress += 1;
1545 }
1546
1547 IpcRegs.IPCACK.all |= (psMessage->uldataw1 & 0xFFFF0000);
1548 }
1549
1550 //*****************************************************************************
1551 //
1552 //! Writes a block of data to a local CPU system address from shared RAM
1553 //!
1554 //! \param psMessage specifies the pointer to the message received from the
1555 //! remote CPU system.
1556 //!
1557 //! This function will write a block of data to an address on the local CPU
1558 //! system.
1559 //! The data is first written by the remote CPU to shared RAM. This function
1560 //! reads the shared RAM location, word size (16- or 32-bit), and block size
1561 //! from \e psMessage and writes the block to the local address specified
1562 //! in \e psMessage.
1563 //!
1564 //! \return None.
1565 //
1566 //*****************************************************************************
1567 void
IPCRtoLBlockWrite(tIpcMessage * psMessage)1568 IPCRtoLBlockWrite(tIpcMessage *psMessage)
1569 {
1570 uint16_t usLength;
1571 uint16_t usWLength;
1572 uint16_t usIndex;
1573
1574 usLength = (uint16_t)psMessage->uldataw1;
1575 usWLength = (uint16_t)((psMessage->uldataw1)>>16);
1576
1577 //
1578 // Determine data word access size to write to data block.
1579 //
1580 if (usWLength == IPC_LENGTH_16_BITS)
1581 {
1582 volatile uint16_t *pusWAddress = (volatile uint16_t *)psMessage->uladdress;
1583 volatile uint16_t *pusRAddress = (volatile uint16_t *)psMessage->uldataw2;
1584 for (usIndex=0; usIndex<usLength; usIndex++)
1585 {
1586 *pusWAddress = *pusRAddress;
1587 pusWAddress += 1;
1588 pusRAddress += 1;
1589 }
1590 } else if (usWLength == IPC_LENGTH_32_BITS)
1591 {
1592 volatile unsigned long *pulWAddress =
1593 (volatile unsigned long *)psMessage->uladdress;
1594 volatile unsigned long *pulRAddress =
1595 (volatile unsigned long *)psMessage->uldataw2;
1596
1597 for (usIndex=0; usIndex<usLength; usIndex++)
1598 {
1599 *pulWAddress = *pulRAddress;
1600 pulWAddress += 1;
1601 pulRAddress += 1;
1602 }
1603 }
1604 }
1605
1606 //*****************************************************************************
1607 //
1608 //! Writes a block of data to a local CPU system write-protected address from
1609 //! shared RAM
1610 //!
1611 //! \param psMessage specifies the pointer to the message received from the
1612 //! remote CPU system.
1613 //!
1614 //! This function will write a block of data to a write-protected group of
1615 //! addresses on the local CPU system. The data is first written by the
1616 //! remote CPU to shared RAM. This function reads the shared RAM location,
1617 //! word size (16- or 32-bit), and block size from \e psMessage and writes the
1618 //! block to the local address specified in \e psMessage.
1619 //!
1620 //! \return None.
1621 //
1622 //*****************************************************************************
1623 void
IPCRtoLBlockWrite_Protected(tIpcMessage * psMessage)1624 IPCRtoLBlockWrite_Protected(tIpcMessage *psMessage)
1625 {
1626 uint16_t usLength;
1627 uint16_t usWLength;
1628 uint16_t usIndex;
1629
1630 //
1631 // Allow access to EALLOW-protected registers.
1632 //
1633 EALLOW;
1634
1635 usLength = (uint16_t)psMessage->uldataw1;
1636 usWLength = (uint16_t)((psMessage->uldataw1)>>16);
1637
1638 //
1639 // Determine data word access size to write to data block.
1640 // (Writes registers accessible via APB bus must be 32-bits wide)
1641 //
1642 if (usWLength == IPC_LENGTH_16_BITS)
1643 {
1644 volatile uint16_t *pusWAddress = (volatile uint16_t *)psMessage->uladdress;
1645 volatile uint16_t *pusRAddress = (volatile uint16_t *)psMessage->uldataw2;
1646 for (usIndex=0; usIndex<usLength; usIndex++)
1647 {
1648 *pusWAddress = *pusRAddress;
1649 pusWAddress += 1;
1650 pusRAddress += 1;
1651 }
1652 } else if (usWLength == IPC_LENGTH_32_BITS)
1653 {
1654 volatile unsigned long *pulWAddress =
1655 (volatile unsigned long *)psMessage->uladdress;
1656 volatile unsigned long *pulRAddress =
1657 (volatile unsigned long *)psMessage->uldataw2;
1658
1659 for (usIndex=0; usIndex<usLength; usIndex++)
1660 {
1661 *pulWAddress = *pulRAddress;
1662 pulWAddress += 1;
1663 pulRAddress += 1;
1664 }
1665 }
1666
1667 //
1668 // Disable access to EALLOW-protected registers.
1669 //
1670 EDIS;
1671 }
1672
1673 //*****************************************************************************
1674 //
1675 //! Calls a local function with a single optional parameter.
1676 //!
1677 //! \param psMessage specifies the pointer to the message received from the
1678 //! remote CPU system.
1679 //!
1680 //! This function will allow the remote CPU system to call a local CPU function
1681 //! with a single optional parameter. There is no return value from the
1682 //! executed function.
1683 //!
1684 //! \return None.
1685 //
1686 //*****************************************************************************
1687 void
IPCRtoLFunctionCall(tIpcMessage * psMessage)1688 IPCRtoLFunctionCall(tIpcMessage *psMessage)
1689 {
1690 //
1691 // Executes function call with parameter at given address.
1692 //
1693 tfIpcFuncCall func_call = (tfIpcFuncCall)psMessage->uladdress;
1694 func_call(psMessage->uldataw1);
1695 }
1696
1697 //*****************************************************************************
1698 // Close the Doxygen group.
1699 //! @}
1700 //*****************************************************************************
1701
1702
1703