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 //
44 // Included Files
45 //
46 #include "F2837xD_device.h"
47 #include "F2837xD_Examples.h"
48 #include <string.h>
49
50 //
51 // InitIpc - Initialize all IPC registers and clear all flags
52 //
InitIpc()53 void InitIpc()
54 {
55 //
56 //Clear sent flags. Received flags must not be cleared locally
57 //to handle the case where the remote CPU starts executing first.
58 //In this case, a remote flag could be sent correctly and be
59 //incorrectly cleared by this function. Unfortunately, we're
60 //still left with a startup synchronization problem if the
61 //remote CPU has flags left over from a previous run. There's
62 //probably a better way of handling this.
63 //
64 IpcRegs.IPCCLR.all = 0xFFFFFFFF;
65
66 //
67 //Clear commands
68 //
69 IpcRegs.IPCSENDCOM = 0;
70 IpcRegs.IPCSENDADDR = 0;
71 IpcRegs.IPCSENDDATA = 0;
72 IpcRegs.IPCLOCALREPLY = 0;
73
74 //
75 //Clear boot status and pump semaphore
76 //
77 #if defined(CPU1)
78 IpcRegs.IPCBOOTMODE = 0;
79 #elif defined(CPU2)
80 IpcRegs.IPCBOOTSTS = 0;
81 #endif
82 ReleaseFlashPump();
83 }
84
85 //
86 // ReadIpcTimer - Read the current IPC timer value. The low register must be
87 // read first to latch a value in the high register.
88 //
ReadIpcTimer()89 unsigned long long ReadIpcTimer()
90 {
91 Uint32 low, high;
92
93 low = IpcRegs.IPCCOUNTERL;
94 high = IpcRegs.IPCCOUNTERH;
95 return ((unsigned long long)high << 32) | (unsigned long long)low;
96 }
97
98 //
99 // SendIpcData - Copy data into the IPC send message RAM for this CPU and set
100 // a flag. If the specified 16-bit word length is greater than
101 // the size of the message RAM, the data is truncated.
102 //
SendIpcData(void * data,Uint16 word_length,Uint16 flag)103 void SendIpcData(void *data, Uint16 word_length, Uint16 flag)
104 {
105 word_length = (word_length < MSG_RAM_SIZE) ? word_length : MSG_RAM_SIZE;
106
107 memcpy(SEND_MSG_RAM, data, word_length);
108
109 if (flag != NO_IPC_FLAG)
110 {
111 SendIpcFlag(flag);
112 }
113 }
114
115 //
116 // RecvIpcData - Copy data out of the IPC receive message RAM for this CPU. If
117 // the specified 16-bit word length is greater than the size of
118 // the message RAM, the data is truncated.
119 //
RecvIpcData(void * recv_buf,Uint16 word_length)120 void RecvIpcData(void *recv_buf, Uint16 word_length)
121 {
122 word_length = (word_length < MSG_RAM_SIZE) ? word_length : MSG_RAM_SIZE;
123 memcpy(recv_buf, RECV_MSG_RAM, word_length);
124 }
125
126 //
127 // FillIpcSendData - Fill the IPC send message RAM for this CPU with a constant
128 // value
129 //
FillIpcSendData(Uint16 fill_data)130 void FillIpcSendData(Uint16 fill_data)
131 {
132 memset(SEND_MSG_RAM, fill_data, MSG_RAM_SIZE);
133 }
134
135 //
136 // SendIpcCommand - Write the send command, address, and data registers with
137 // the specified values, then set an IPC flag.
138 //
SendIpcCommand(Uint32 command,Uint32 address,Uint32 data,Uint16 flag)139 void SendIpcCommand(Uint32 command, Uint32 address, Uint32 data, Uint16 flag)
140 {
141 IpcRegs.IPCSENDCOM = command;
142 IpcRegs.IPCSENDADDR = address;
143 IpcRegs.IPCSENDDATA = data;
144
145 if (flag != NO_IPC_FLAG)
146 {
147 SendIpcFlag(flag);
148 }
149 }
150
151 //
152 // SendIpcFlag - Set an IPC flag bit for the other CPU. Flags 0-3 will generate
153 // PIE interrupts.
154 //
SendIpcFlag(Uint16 flag)155 void SendIpcFlag(Uint16 flag)
156 {
157 IpcRegs.IPCSET.all = 1UL << flag;
158 }
159
160 //
161 // AckIpcFlag - Acknowledge/clear a received IPC flag
162 //
AckIpcFlag(Uint16 flag)163 void AckIpcFlag(Uint16 flag)
164 {
165 IpcRegs.IPCACK.all = 1UL << flag;
166 }
167
168 //
169 // CancelIpcFlag - Clear a sent IPC flag bit before the other CPU acknowledges
170 // it. You will normally never use this function. To clear a
171 // received flag, call AckIpcFlag() instead.
172 //
CancelIpcFlag(Uint16 flag)173 void CancelIpcFlag(Uint16 flag)
174 {
175 IpcRegs.IPCCLR.all = 1UL << flag;
176 }
177
178 //
179 // WaitForIpcFlag - Wait for any IPC flag in the specified mask to be set.
180 // WARNING: If you use this function to wait for an IPC
181 // interrupt, you must not clear the IPC flag in the interrupt
182 // handler. Otherwise, this function will never return.
183 //
WaitForIpcFlag(Uint16 flag)184 void WaitForIpcFlag(Uint16 flag)
185 {
186 //
187 //WARNING: Don't use this function to wait for an IPC interrupt!
188 //
189 while ((IpcRegs.IPCSTS.all & (1UL << flag)) == 0x00000000) {;}
190 }
191
192 //
193 // WaitForIpcAck - Wait for any IPC flag in the specified mask to be
194 // acknowledged.
195 //
WaitForIpcAck(Uint16 flag)196 void WaitForIpcAck(Uint16 flag)
197 {
198 while ((IpcRegs.IPCFLG.all & (1UL << flag)) != 0x00000000) {;}
199 }
200
201 //
202 // IpcSync - Synchronize the two CPUs. Neither CPU will return from this
203 // function call before the other one enters it. Must be called with
204 // the same flag number on both CPUs.
205 //
IpcSync(Uint16 flag)206 void IpcSync(Uint16 flag)
207 {
208 SendIpcFlag(flag);
209 WaitForIpcFlag(flag);
210 AckIpcFlag(flag);
211 WaitForIpcAck(flag);
212 }
213
214 //
215 // End of file
216 //
217