F2837xD_Ipc_Driver.c 66 KB

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