F2837xD_Ipc.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. //###########################################################################
  2. //
  3. // FILE: F2837xD_Ipc.c
  4. //
  5. // TITLE: Inter-Processor Communication module support functions
  6. //
  7. //###########################################################################
  8. // $TI Release: F2837xD Support Library v3.05.00.00 $
  9. // $Release Date: Tue Jun 26 03:15:23 CDT 2018 $
  10. // $Copyright:
  11. // Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
  12. //
  13. // Redistribution and use in source and binary forms, with or without
  14. // modification, are permitted provided that the following conditions
  15. // are met:
  16. //
  17. // Redistributions of source code must retain the above copyright
  18. // notice, this list of conditions and the following disclaimer.
  19. //
  20. // Redistributions in binary form must reproduce the above copyright
  21. // notice, this list of conditions and the following disclaimer in the
  22. // documentation and/or other materials provided with the
  23. // distribution.
  24. //
  25. // Neither the name of Texas Instruments Incorporated nor the names of
  26. // its contributors may be used to endorse or promote products derived
  27. // from this software without specific prior written permission.
  28. //
  29. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  30. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  31. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  32. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  33. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  34. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  35. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  36. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  37. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  39. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40. // $
  41. //###########################################################################
  42. //
  43. // Included Files
  44. //
  45. #include "F2837xD_device.h"
  46. #include "F2837xD_Examples.h"
  47. #include <string.h>
  48. //
  49. // InitIpc - Initialize all IPC registers and clear all flags
  50. //
  51. void InitIpc()
  52. {
  53. //
  54. //Clear sent flags. Received flags must not be cleared locally
  55. //to handle the case where the remote CPU starts executing first.
  56. //In this case, a remote flag could be sent correctly and be
  57. //incorrectly cleared by this function. Unfortunately, we're
  58. //still left with a startup synchronization problem if the
  59. //remote CPU has flags left over from a previous run. There's
  60. //probably a better way of handling this.
  61. //
  62. IpcRegs.IPCCLR.all = 0xFFFFFFFF;
  63. //
  64. //Clear commands
  65. //
  66. IpcRegs.IPCSENDCOM = 0;
  67. IpcRegs.IPCSENDADDR = 0;
  68. IpcRegs.IPCSENDDATA = 0;
  69. IpcRegs.IPCLOCALREPLY = 0;
  70. //
  71. //Clear boot status and pump semaphore
  72. //
  73. #if defined(CPU1)
  74. IpcRegs.IPCBOOTMODE = 0;
  75. #elif defined(CPU2)
  76. IpcRegs.IPCBOOTSTS = 0;
  77. #endif
  78. ReleaseFlashPump();
  79. }
  80. //
  81. // ReadIpcTimer - Read the current IPC timer value. The low register must be
  82. // read first to latch a value in the high register.
  83. //
  84. unsigned long long ReadIpcTimer()
  85. {
  86. Uint32 low, high;
  87. low = IpcRegs.IPCCOUNTERL;
  88. high = IpcRegs.IPCCOUNTERH;
  89. return ((unsigned long long)high << 32) | (unsigned long long)low;
  90. }
  91. //
  92. // SendIpcData - Copy data into the IPC send message RAM for this CPU and set
  93. // a flag. If the specified 16-bit word length is greater than
  94. // the size of the message RAM, the data is truncated.
  95. //
  96. void SendIpcData(void *data, Uint16 word_length, Uint16 flag)
  97. {
  98. word_length = (word_length < MSG_RAM_SIZE) ? word_length : MSG_RAM_SIZE;
  99. memcpy(SEND_MSG_RAM, data, word_length);
  100. if (flag != NO_IPC_FLAG)
  101. {
  102. SendIpcFlag(flag);
  103. }
  104. }
  105. //
  106. // RecvIpcData - Copy data out of the IPC receive message RAM for this CPU. If
  107. // the specified 16-bit word length is greater than the size of
  108. // the message RAM, the data is truncated.
  109. //
  110. void RecvIpcData(void *recv_buf, Uint16 word_length)
  111. {
  112. word_length = (word_length < MSG_RAM_SIZE) ? word_length : MSG_RAM_SIZE;
  113. memcpy(recv_buf, RECV_MSG_RAM, word_length);
  114. }
  115. //
  116. // FillIpcSendData - Fill the IPC send message RAM for this CPU with a constant
  117. // value
  118. //
  119. void FillIpcSendData(Uint16 fill_data)
  120. {
  121. memset(SEND_MSG_RAM, fill_data, MSG_RAM_SIZE);
  122. }
  123. //
  124. // SendIpcCommand - Write the send command, address, and data registers with
  125. // the specified values, then set an IPC flag.
  126. //
  127. void SendIpcCommand(Uint32 command, Uint32 address, Uint32 data, Uint16 flag)
  128. {
  129. IpcRegs.IPCSENDCOM = command;
  130. IpcRegs.IPCSENDADDR = address;
  131. IpcRegs.IPCSENDDATA = data;
  132. if (flag != NO_IPC_FLAG)
  133. {
  134. SendIpcFlag(flag);
  135. }
  136. }
  137. //
  138. // SendIpcFlag - Set an IPC flag bit for the other CPU. Flags 0-3 will generate
  139. // PIE interrupts.
  140. //
  141. void SendIpcFlag(Uint16 flag)
  142. {
  143. IpcRegs.IPCSET.all = 1UL << flag;
  144. }
  145. //
  146. // AckIpcFlag - Acknowledge/clear a received IPC flag
  147. //
  148. void AckIpcFlag(Uint16 flag)
  149. {
  150. IpcRegs.IPCACK.all = 1UL << flag;
  151. }
  152. //
  153. // CancelIpcFlag - Clear a sent IPC flag bit before the other CPU acknowledges
  154. // it. You will normally never use this function. To clear a
  155. // received flag, call AckIpcFlag() instead.
  156. //
  157. void CancelIpcFlag(Uint16 flag)
  158. {
  159. IpcRegs.IPCCLR.all = 1UL << flag;
  160. }
  161. //
  162. // WaitForIpcFlag - Wait for any IPC flag in the specified mask to be set.
  163. // WARNING: If you use this function to wait for an IPC
  164. // interrupt, you must not clear the IPC flag in the interrupt
  165. // handler. Otherwise, this function will never return.
  166. //
  167. void WaitForIpcFlag(Uint16 flag)
  168. {
  169. //
  170. //WARNING: Don't use this function to wait for an IPC interrupt!
  171. //
  172. while ((IpcRegs.IPCSTS.all & (1UL << flag)) == 0x00000000) {;}
  173. }
  174. //
  175. // WaitForIpcAck - Wait for any IPC flag in the specified mask to be
  176. // acknowledged.
  177. //
  178. void WaitForIpcAck(Uint16 flag)
  179. {
  180. while ((IpcRegs.IPCFLG.all & (1UL << flag)) != 0x00000000) {;}
  181. }
  182. //
  183. // IpcSync - Synchronize the two CPUs. Neither CPU will return from this
  184. // function call before the other one enters it. Must be called with
  185. // the same flag number on both CPUs.
  186. //
  187. void IpcSync(Uint16 flag)
  188. {
  189. SendIpcFlag(flag);
  190. WaitForIpcFlag(flag);
  191. AckIpcFlag(flag);
  192. WaitForIpcAck(flag);
  193. }
  194. //
  195. // End of file
  196. //