CANopen.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156
  1. /*
  2. * Main CANopen stack file. It combines Object dictionary (CO_OD) and all other
  3. * CANopen source files. Configuration information are read from CO_OD.h file.
  4. *
  5. * @file CANopen.c
  6. * @ingroup CO_CANopen
  7. * @author Janez Paternoster
  8. * @copyright 2010 - 2020 Janez Paternoster
  9. *
  10. * This file is part of CANopenNode, an opensource CANopen Stack.
  11. * Project home page is <https://github.com/CANopenNode/CANopenNode>.
  12. * For more information on CANopen see <http://www.can-cia.org/>.
  13. *
  14. * Licensed under the Apache License, Version 2.0 (the "License");
  15. * you may not use this file except in compliance with the License.
  16. * You may obtain a copy of the License at
  17. *
  18. * http://www.apache.org/licenses/LICENSE-2.0
  19. *
  20. * Unless required by applicable law or agreed to in writing, software
  21. * distributed under the License is distributed on an "AS IS" BASIS,
  22. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. * See the License for the specific language governing permissions and
  24. * limitations under the License.
  25. */
  26. #include "CANopen.h"
  27. #include <stdlib.h>
  28. /* Global variables ***********************************************************/
  29. /* #define CO_USE_GLOBALS */ /* If defined, global variables will be used
  30. instead of dynamically allocated. */
  31. extern const CO_OD_entry_t CO_OD[CO_OD_NoOfElements]; /* Object Dictionary */
  32. static CO_t COO; /* Pointers to CANopen objects */
  33. CO_t *CO = NULL; /* Pointer to COO */
  34. static CO_CANrx_t *CO_CANmodule_rxArray0;
  35. static CO_CANtx_t *CO_CANmodule_txArray0;
  36. static CO_OD_extension_t *CO_SDO_ODExtensions;
  37. static CO_HBconsNode_t *CO_HBcons_monitoredNodes;
  38. #if ((CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII) && !defined CO_GTWA_ENABLE
  39. #define CO_GTWA_ENABLE true
  40. #endif
  41. #if CO_NO_TRACE > 0
  42. static uint32_t *CO_traceTimeBuffers[CO_NO_TRACE];
  43. static int32_t *CO_traceValueBuffers[CO_NO_TRACE];
  44. static uint32_t CO_traceBufferSize[CO_NO_TRACE];
  45. #endif
  46. #ifndef CO_STATUS_FIRMWARE_DOWNLOAD_IN_PROGRESS
  47. #define CO_STATUS_FIRMWARE_DOWNLOAD_IN_PROGRESS 0
  48. #endif
  49. /* Verify number of CANopenNode objects from CO_OD.h **************************/
  50. #if CO_NO_SYNC > 1 \
  51. || CO_NO_EMERGENCY != 1 \
  52. || (CO_NO_SDO_SERVER < 1 || CO_NO_SDO_SERVER > 128) \
  53. || CO_NO_TIME > 1 \
  54. || CO_NO_SDO_CLIENT > 128 \
  55. || CO_NO_GFC > 1 \
  56. || CO_NO_SRDO > 64 \
  57. || (CO_NO_RPDO < 1 || CO_NO_RPDO > 0x200) \
  58. || (CO_NO_TPDO < 1 || CO_NO_TPDO > 0x200) \
  59. || ODL_consumerHeartbeatTime_arrayLength == 0 \
  60. || ODL_errorStatusBits_stringLength < 10 \
  61. || CO_NO_LSS_SLAVE > 1 \
  62. || CO_NO_LSS_MASTER > 1
  63. #error Features from CO_OD.h file are not corectly configured for this project!
  64. #endif
  65. /* Indexes of CO_CANrx_t objects in CO_CANmodule_t and total number of them. **/
  66. #define CO_RXCAN_NMT 0
  67. #define CO_RXCAN_SYNC (CO_RXCAN_NMT + CO_NO_NMT)
  68. #define CO_RXCAN_EMERG (CO_RXCAN_SYNC + CO_NO_SYNC)
  69. #define CO_RXCAN_TIME (CO_RXCAN_EMERG + CO_NO_EM_CONS)
  70. #define CO_RXCAN_GFC (CO_RXCAN_TIME + CO_NO_TIME)
  71. #define CO_RXCAN_SRDO (CO_RXCAN_GFC + CO_NO_GFC)
  72. #define CO_RXCAN_RPDO (CO_RXCAN_SRDO + CO_NO_SRDO*2)
  73. #define CO_RXCAN_SDO_SRV (CO_RXCAN_RPDO + CO_NO_RPDO)
  74. #define CO_RXCAN_SDO_CLI (CO_RXCAN_SDO_SRV + CO_NO_SDO_SERVER)
  75. #define CO_RXCAN_CONS_HB (CO_RXCAN_SDO_CLI + CO_NO_SDO_CLIENT)
  76. #define CO_RXCAN_LSS_SLV (CO_RXCAN_CONS_HB + CO_NO_HB_CONS)
  77. #define CO_RXCAN_LSS_MST (CO_RXCAN_LSS_SLV + CO_NO_LSS_SLAVE)
  78. #define CO_RXCAN_NO_MSGS (CO_NO_NMT + \
  79. CO_NO_SYNC + \
  80. CO_NO_EM_CONS + \
  81. CO_NO_TIME + \
  82. CO_NO_GFC + \
  83. CO_NO_SRDO*2 + \
  84. CO_NO_RPDO + \
  85. CO_NO_SDO_SERVER + \
  86. CO_NO_SDO_CLIENT + \
  87. CO_NO_HB_CONS + \
  88. CO_NO_LSS_SLAVE + \
  89. CO_NO_LSS_MASTER)
  90. /* Indexes of CO_CANtx_t objects in CO_CANmodule_t and total number of them. **/
  91. #define CO_TXCAN_NMT 0
  92. #define CO_TXCAN_SYNC (CO_TXCAN_NMT + CO_NO_NMT_MST)
  93. #define CO_TXCAN_EMERG (CO_TXCAN_SYNC + CO_NO_SYNC)
  94. #define CO_TXCAN_TIME (CO_TXCAN_EMERG + CO_NO_EMERGENCY)
  95. #define CO_TXCAN_GFC (CO_TXCAN_TIME + CO_NO_TIME)
  96. #define CO_TXCAN_SRDO (CO_TXCAN_GFC + CO_NO_GFC)
  97. #define CO_TXCAN_TPDO (CO_TXCAN_SRDO + CO_NO_SRDO*2)
  98. #define CO_TXCAN_SDO_SRV (CO_TXCAN_TPDO + CO_NO_TPDO)
  99. #define CO_TXCAN_SDO_CLI (CO_TXCAN_SDO_SRV + CO_NO_SDO_SERVER)
  100. #define CO_TXCAN_HB (CO_TXCAN_SDO_CLI + CO_NO_SDO_CLIENT)
  101. #define CO_TXCAN_LSS_SLV (CO_TXCAN_HB + CO_NO_HB_PROD)
  102. #define CO_TXCAN_LSS_MST (CO_TXCAN_LSS_SLV + CO_NO_LSS_SLAVE)
  103. #define CO_TXCAN_NO_MSGS (CO_NO_NMT_MST + \
  104. CO_NO_SYNC + \
  105. CO_NO_EMERGENCY + \
  106. CO_NO_TIME + \
  107. CO_NO_GFC + \
  108. CO_NO_SRDO*2 + \
  109. CO_NO_TPDO + \
  110. CO_NO_SDO_SERVER + \
  111. CO_NO_SDO_CLIENT + \
  112. CO_NO_HB_PROD + \
  113. CO_NO_LSS_SLAVE + \
  114. CO_NO_LSS_MASTER)
  115. /* Create objects from heap ***************************************************/
  116. #ifndef CO_USE_GLOBALS
  117. CO_ReturnError_t CO_new(uint32_t *heapMemoryUsed) {
  118. int16_t i;
  119. uint16_t errCnt = 0;
  120. uint32_t CO_memoryUsed = 0;
  121. /* If CANopen was initialized before, return. */
  122. if (CO != NULL) {
  123. return CO_ERROR_NO;
  124. }
  125. /* globals */
  126. CO = &COO;
  127. /* CANmodule */
  128. CO->CANmodule[0] = (CO_CANmodule_t *)calloc(1, sizeof(CO_CANmodule_t));
  129. if (CO->CANmodule[0] == NULL) errCnt++;
  130. CO_CANmodule_rxArray0 =
  131. (CO_CANrx_t *)calloc(CO_RXCAN_NO_MSGS, sizeof(CO_CANrx_t));
  132. if (CO_CANmodule_rxArray0 == NULL) errCnt++;
  133. CO_CANmodule_txArray0 =
  134. (CO_CANtx_t *)calloc(CO_TXCAN_NO_MSGS, sizeof(CO_CANtx_t));
  135. if (CO_CANmodule_txArray0 == NULL) errCnt++;
  136. CO_memoryUsed += sizeof(CO_CANmodule_t) +
  137. sizeof(CO_CANrx_t) * CO_RXCAN_NO_MSGS +
  138. sizeof(CO_CANtx_t) * CO_TXCAN_NO_MSGS;
  139. /* SDOserver */
  140. for (i = 0; i < CO_NO_SDO_SERVER; i++) {
  141. CO->SDO[i] = (CO_SDO_t *)calloc(1, sizeof(CO_SDO_t));
  142. if (CO->SDO[i] == NULL) errCnt++;
  143. }
  144. CO_SDO_ODExtensions = (CO_OD_extension_t *)calloc(
  145. CO_OD_NoOfElements, sizeof(CO_OD_extension_t));
  146. if (CO_SDO_ODExtensions == NULL) errCnt++;
  147. CO_memoryUsed += sizeof(CO_SDO_t) * CO_NO_SDO_SERVER +
  148. sizeof(CO_OD_extension_t) * CO_OD_NoOfElements;
  149. /* Emergency */
  150. CO->em = (CO_EM_t *)calloc(1, sizeof(CO_EM_t));
  151. if (CO->em == NULL) errCnt++;
  152. CO->emPr = (CO_EMpr_t *)calloc(1, sizeof(CO_EMpr_t));
  153. if (CO->emPr == NULL) errCnt++;
  154. CO_memoryUsed += sizeof(CO_EM_t) + sizeof(CO_EMpr_t);
  155. /* NMT_Heartbeat */
  156. CO->NMT = (CO_NMT_t *)calloc(1, sizeof(CO_NMT_t));
  157. if (CO->NMT == NULL) errCnt++;
  158. CO_memoryUsed += sizeof(CO_NMT_t);
  159. #if CO_NO_SYNC == 1
  160. /* SYNC */
  161. CO->SYNC = (CO_SYNC_t *)calloc(1, sizeof(CO_SYNC_t));
  162. if (CO->SYNC == NULL) errCnt++;
  163. CO_memoryUsed += sizeof(CO_SYNC_t);
  164. #endif
  165. #if CO_NO_TIME == 1
  166. /* TIME */
  167. CO->TIME = (CO_TIME_t *)calloc(1, sizeof(CO_TIME_t));
  168. if (CO->TIME == NULL) errCnt++;
  169. CO_memoryUsed += sizeof(CO_TIME_t);
  170. #endif
  171. #if CO_NO_GFC == 1
  172. CO->GFC = (CO_GFC_t *)calloc(1, sizeof(CO_GFC_t));
  173. if (CO->GFC == NULL) errCnt++;
  174. CO_memoryUsed += sizeof(CO_GFC_t);
  175. #endif
  176. #if CO_NO_SRDO != 0
  177. /* SRDO */
  178. CO->SRDOGuard = (CO_SRDOGuard_t *)calloc(1, sizeof(CO_SRDOGuard_t));
  179. if (CO->SRDOGuard == NULL) errCnt++;
  180. for (i = 0; i < CO_NO_SRDO; i++) {
  181. CO->SRDO[i] = (CO_SRDO_t *)calloc(1, sizeof(CO_SRDO_t));
  182. if (CO->SRDO[i] == NULL) errCnt++;
  183. }
  184. CO_memoryUsed += sizeof(CO_SRDO_t) * CO_NO_SRDO + sizeof(CO_SRDOGuard_t);
  185. #endif
  186. /* RPDO */
  187. for (i = 0; i < CO_NO_RPDO; i++) {
  188. CO->RPDO[i] = (CO_RPDO_t *)calloc(1, sizeof(CO_RPDO_t));
  189. if (CO->RPDO[i] == NULL) errCnt++;
  190. }
  191. CO_memoryUsed += sizeof(CO_RPDO_t) * CO_NO_RPDO;
  192. /* TPDO */
  193. for (i = 0; i < CO_NO_TPDO; i++) {
  194. CO->TPDO[i] = (CO_TPDO_t *)calloc(1, sizeof(CO_TPDO_t));
  195. if (CO->TPDO[i] == NULL) errCnt++;
  196. }
  197. CO_memoryUsed += sizeof(CO_TPDO_t) * CO_NO_TPDO;
  198. /* Heartbeat consumer */
  199. CO->HBcons = (CO_HBconsumer_t *)calloc(1, sizeof(CO_HBconsumer_t));
  200. if (CO->HBcons == NULL) errCnt++;
  201. CO_HBcons_monitoredNodes =
  202. (CO_HBconsNode_t *)calloc(CO_NO_HB_CONS, sizeof(CO_HBconsNode_t));
  203. if (CO_HBcons_monitoredNodes == NULL) errCnt++;
  204. CO_memoryUsed += sizeof(CO_HBconsumer_t) +
  205. sizeof(CO_HBconsNode_t) * CO_NO_HB_CONS;
  206. #if CO_NO_SDO_CLIENT != 0
  207. /* SDOclient */
  208. for (i = 0; i < CO_NO_SDO_CLIENT; i++) {
  209. CO->SDOclient[i] =
  210. (CO_SDOclient_t *)calloc(1, sizeof(CO_SDOclient_t));
  211. if (CO->SDOclient[i] == NULL) errCnt++;
  212. }
  213. CO_memoryUsed += sizeof(CO_SDOclient_t) * CO_NO_SDO_CLIENT;
  214. #endif
  215. #if (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE
  216. /* LEDs */
  217. CO->LEDs = (CO_LEDs_t *)calloc(1, sizeof(CO_LEDs_t));
  218. if (CO->LEDs == NULL) errCnt++;
  219. CO_memoryUsed += sizeof(CO_LEDs_t);
  220. #endif
  221. #if CO_NO_LSS_SLAVE == 1
  222. /* LSSslave */
  223. CO->LSSslave = (CO_LSSslave_t *)calloc(1, sizeof(CO_LSSslave_t));
  224. if (CO->LSSslave == NULL) errCnt++;
  225. CO_memoryUsed += sizeof(CO_LSSslave_t);
  226. #endif
  227. #if CO_NO_LSS_MASTER == 1
  228. /* LSSmaster */
  229. CO->LSSmaster = (CO_LSSmaster_t *)calloc(1, sizeof(CO_LSSmaster_t));
  230. if (CO->LSSmaster == NULL) errCnt++;
  231. CO_memoryUsed += sizeof(CO_LSSmaster_t);
  232. #endif
  233. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII
  234. /* Gateway-ascii */
  235. CO->gtwa = (CO_GTWA_t *)calloc(1, sizeof(CO_GTWA_t));
  236. if (CO->gtwa == NULL) errCnt++;
  237. CO_memoryUsed += sizeof(CO_GTWA_t);
  238. #endif
  239. #if CO_NO_TRACE > 0
  240. /* Trace */
  241. for (i = 0; i < CO_NO_TRACE; i++) {
  242. CO->trace[i] = (CO_trace_t *)calloc(1, sizeof(CO_trace_t));
  243. if (CO->trace[i] == NULL) errCnt++;
  244. }
  245. CO_memoryUsed += sizeof(CO_trace_t) * CO_NO_TRACE;
  246. for (i = 0; i < CO_NO_TRACE; i++) {
  247. CO_traceTimeBuffers[i] =
  248. (uint32_t *)calloc(OD_traceConfig[i].size, sizeof(uint32_t));
  249. CO_traceValueBuffers[i] =
  250. (int32_t *)calloc(OD_traceConfig[i].size, sizeof(int32_t));
  251. if (CO_traceTimeBuffers[i] != NULL &&
  252. CO_traceValueBuffers[i] != NULL) {
  253. CO_traceBufferSize[i] = OD_traceConfig[i].size;
  254. } else {
  255. CO_traceBufferSize[i] = 0;
  256. }
  257. CO_memoryUsed += CO_traceBufferSize[i] * sizeof(uint32_t) * 2;
  258. }
  259. #endif
  260. if (heapMemoryUsed != NULL) {
  261. *heapMemoryUsed = CO_memoryUsed;
  262. }
  263. return (errCnt == 0) ? CO_ERROR_NO : CO_ERROR_OUT_OF_MEMORY;
  264. }
  265. /******************************************************************************/
  266. void CO_delete(void *CANptr) {
  267. int16_t i;
  268. CO_CANsetConfigurationMode(CANptr);
  269. /* If CANopen isn't initialized, return. */
  270. if (CO == NULL) {
  271. return;
  272. }
  273. CO_CANmodule_disable(CO->CANmodule[0]);
  274. #if CO_NO_TRACE > 0
  275. /* Trace */
  276. for (i = 0; i < CO_NO_TRACE; i++) {
  277. free(CO->trace[i]);
  278. free(CO_traceTimeBuffers[i]);
  279. free(CO_traceValueBuffers[i]);
  280. }
  281. #endif
  282. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII
  283. /* Gateway-ascii */
  284. free(CO->gtwa);
  285. #endif
  286. #if CO_NO_LSS_MASTER == 1
  287. /* LSSmaster */
  288. free(CO->LSSmaster);
  289. #endif
  290. #if CO_NO_LSS_SLAVE == 1
  291. /* LSSslave */
  292. free(CO->LSSslave);
  293. #endif
  294. #if CO_NO_SDO_CLIENT != 0
  295. /* SDOclient */
  296. for (i = 0; i < CO_NO_SDO_CLIENT; i++) {
  297. free(CO->SDOclient[i]);
  298. }
  299. #endif
  300. /* Heartbeat consumer */
  301. free(CO_HBcons_monitoredNodes);
  302. free(CO->HBcons);
  303. #if CO_NO_GFC == 1
  304. /* GFC */
  305. free(CO->GFC);
  306. #endif
  307. #if CO_NO_SRDO != 0
  308. /* SRDO */
  309. for (i = 0; i < CO_NO_SRDO; i++) {
  310. free(CO->SRDO[i]);
  311. }
  312. free(CO->SRDOGuard);
  313. #endif
  314. /* TPDO */
  315. for (i = 0; i < CO_NO_TPDO; i++) {
  316. free(CO->TPDO[i]);
  317. }
  318. /* RPDO */
  319. for (i = 0; i < CO_NO_RPDO; i++) {
  320. free(CO->RPDO[i]);
  321. }
  322. #if CO_NO_TIME == 1
  323. /* TIME */
  324. free(CO->TIME);
  325. #endif
  326. #if CO_NO_SYNC == 1
  327. /* SYNC */
  328. free(CO->SYNC);
  329. #endif
  330. /* NMT_Heartbeat */
  331. free(CO->NMT);
  332. /* Emergency */
  333. free(CO->emPr);
  334. free(CO->em);
  335. /* SDOserver */
  336. free(CO_SDO_ODExtensions);
  337. for (i = 0; i < CO_NO_SDO_SERVER; i++) {
  338. free(CO->SDO[i]);
  339. }
  340. /* CANmodule */
  341. free(CO_CANmodule_txArray0);
  342. free(CO_CANmodule_rxArray0);
  343. free(CO->CANmodule[0]);
  344. /* globals */
  345. CO = NULL;
  346. }
  347. #endif /* #ifndef CO_USE_GLOBALS */
  348. /* Alternatively create objects as globals ************************************/
  349. #ifdef CO_USE_GLOBALS
  350. static CO_CANmodule_t COO_CANmodule;
  351. static CO_CANrx_t COO_CANmodule_rxArray0[CO_RXCAN_NO_MSGS];
  352. static CO_CANtx_t COO_CANmodule_txArray0[CO_TXCAN_NO_MSGS];
  353. static CO_SDO_t COO_SDO[CO_NO_SDO_SERVER];
  354. static CO_OD_extension_t COO_SDO_ODExtensions[CO_OD_NoOfElements];
  355. static CO_EM_t COO_EM;
  356. static CO_EMpr_t COO_EMpr;
  357. static CO_NMT_t COO_NMT;
  358. #if CO_NO_SYNC == 1
  359. static CO_SYNC_t COO_SYNC;
  360. #endif
  361. #if CO_NO_TIME == 1
  362. static CO_TIME_t COO_TIME;
  363. #endif
  364. #if CO_NO_GFC == 1
  365. static CO_GFC_t COO_GFC;
  366. #endif
  367. #if CO_NO_SRDO != 0
  368. static CO_SRDOGuard_t COO_SRDOGuard;
  369. static CO_SRDO_t COO_SRDO[CO_NO_SRDO];
  370. #endif
  371. static CO_RPDO_t COO_RPDO[CO_NO_RPDO];
  372. static CO_TPDO_t COO_TPDO[CO_NO_TPDO];
  373. static CO_HBconsumer_t COO_HBcons;
  374. static CO_HBconsNode_t COO_HBcons_monitoredNodes[CO_NO_HB_CONS];
  375. #if CO_NO_SDO_CLIENT != 0
  376. static CO_SDOclient_t COO_SDOclient[CO_NO_SDO_CLIENT];
  377. #endif
  378. #if (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE
  379. static CO_LEDs_t COO_LEDs;
  380. #endif
  381. #if CO_NO_LSS_SLAVE == 1
  382. static CO_LSSslave_t COO_LSSslave;
  383. #endif
  384. #if CO_NO_LSS_MASTER == 1
  385. static CO_LSSmaster_t COO_LSSmaster;
  386. #endif
  387. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII
  388. static CO_GTWA_t COO_gtwa;
  389. #endif
  390. #if CO_NO_TRACE > 0
  391. #ifndef CO_TRACE_BUFFER_SIZE_FIXED
  392. #define CO_TRACE_BUFFER_SIZE_FIXED 100
  393. #endif
  394. static CO_trace_t COO_trace[CO_NO_TRACE];
  395. static uint32_t COO_traceTimeBuffers[CO_NO_TRACE][CO_TRACE_BUFFER_SIZE_FIXED];
  396. static int32_t COO_traceValueBuffers[CO_NO_TRACE][CO_TRACE_BUFFER_SIZE_FIXED];
  397. #endif
  398. CO_ReturnError_t CO_new(uint32_t *heapMemoryUsed) {
  399. int16_t i;
  400. (void)heapMemoryUsed;
  401. /* If CANopen was initialized before, return. */
  402. if (CO != NULL) {
  403. return CO_ERROR_NO;
  404. }
  405. /* globals */
  406. CO = &COO;
  407. /* CANmodule */
  408. CO->CANmodule[0] = &COO_CANmodule;
  409. CO_CANmodule_rxArray0 = &COO_CANmodule_rxArray0[0];
  410. CO_CANmodule_txArray0 = &COO_CANmodule_txArray0[0];
  411. /* SDOserver */
  412. for (i = 0; i < CO_NO_SDO_SERVER; i++) {
  413. CO->SDO[i] = &COO_SDO[i];
  414. }
  415. CO_SDO_ODExtensions = &COO_SDO_ODExtensions[0];
  416. /* Emergency */
  417. CO->em = &COO_EM;
  418. CO->emPr = &COO_EMpr;
  419. /* NMT_Heartbeat */
  420. CO->NMT = &COO_NMT;
  421. #if CO_NO_SYNC == 1
  422. /* SYNC */
  423. CO->SYNC = &COO_SYNC;
  424. #endif
  425. #if CO_NO_TIME == 1
  426. /* TIME */
  427. CO->TIME = &COO_TIME;
  428. #endif
  429. #if CO_NO_GFC == 1
  430. /* GFC */
  431. CO->GFC = &COO_GFC;
  432. #endif
  433. #if CO_NO_SRDO != 0
  434. /* SRDO */
  435. CO->SRDOGuard = &COO_SRDOGuard;
  436. for (i = 0; i < CO_NO_SRDO; i++) {
  437. CO->SRDO[i] = &COO_SRDO[i];
  438. }
  439. #endif
  440. /* RPDO */
  441. for (i = 0; i < CO_NO_RPDO; i++) {
  442. CO->RPDO[i] = &COO_RPDO[i];
  443. }
  444. /* TPDO */
  445. for (i = 0; i < CO_NO_TPDO; i++) {
  446. CO->TPDO[i] = &COO_TPDO[i];
  447. }
  448. /* Heartbeat consumer */
  449. CO->HBcons = &COO_HBcons;
  450. CO_HBcons_monitoredNodes = &COO_HBcons_monitoredNodes[0];
  451. #if CO_NO_SDO_CLIENT != 0
  452. /* SDOclient */
  453. for (i = 0; i < CO_NO_SDO_CLIENT; i++) {
  454. CO->SDOclient[i] = &COO_SDOclient[i];
  455. }
  456. #endif
  457. #if (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE
  458. /* LEDs */
  459. CO->LEDs = &COO_LEDs;
  460. #endif
  461. #if CO_NO_LSS_SLAVE == 1
  462. /* LSSslave */
  463. CO->LSSslave = &COO_LSSslave;
  464. #endif
  465. #if CO_NO_LSS_MASTER == 1
  466. /* LSSmaster */
  467. CO->LSSmaster = &COO_LSSmaster;
  468. #endif
  469. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII
  470. /* Gateway-ascii */
  471. CO->gtwa = &COO_gtwa;
  472. #endif
  473. #if CO_NO_TRACE > 0
  474. /* Trace */
  475. for (i = 0; i < CO_NO_TRACE; i++) {
  476. CO->trace[i] = &COO_trace[i];
  477. CO_traceTimeBuffers[i] = &COO_traceTimeBuffers[i][0];
  478. CO_traceValueBuffers[i] = &COO_traceValueBuffers[i][0];
  479. CO_traceBufferSize[i] = CO_TRACE_BUFFER_SIZE_FIXED;
  480. }
  481. #endif
  482. return CO_ERROR_NO;
  483. }
  484. /******************************************************************************/
  485. void CO_delete(void *CANptr) {
  486. CO_CANsetConfigurationMode(CANptr);
  487. /* globals */
  488. CO = NULL;
  489. }
  490. #endif /* #ifdef CO_USE_GLOBALS */
  491. /******************************************************************************/
  492. CO_ReturnError_t CO_CANinit(void *CANptr,
  493. uint32_t bitRate)
  494. {
  495. CO_ReturnError_t err;
  496. CO->CANmodule[0]->CANnormal = false;
  497. CO_CANsetConfigurationMode(CANptr);
  498. /* CANmodule */
  499. err = CO_CANmodule_init(CO->CANmodule[0],
  500. CANptr,
  501. CO_CANmodule_rxArray0,
  502. CO_RXCAN_NO_MSGS,
  503. CO_CANmodule_txArray0,
  504. CO_TXCAN_NO_MSGS,
  505. bitRate);
  506. return err;
  507. }
  508. /******************************************************************************/
  509. #if CO_NO_LSS_SLAVE == 1
  510. CO_ReturnError_t CO_LSSinit(uint8_t *nodeId,
  511. uint16_t *bitRate)
  512. {
  513. CO_LSS_address_t lssAddress;
  514. CO_ReturnError_t err;
  515. /* LSSslave */
  516. lssAddress.identity.productCode = OD_identity.productCode;
  517. lssAddress.identity.revisionNumber = OD_identity.revisionNumber;
  518. lssAddress.identity.serialNumber = OD_identity.serialNumber;
  519. lssAddress.identity.vendorID = OD_identity.vendorID;
  520. err = CO_LSSslave_init(CO->LSSslave,
  521. &lssAddress,
  522. bitRate,
  523. nodeId,
  524. CO->CANmodule[0],
  525. CO_RXCAN_LSS_SLV,
  526. CO_CAN_ID_LSS_MST,
  527. CO->CANmodule[0],
  528. CO_TXCAN_LSS_SLV,
  529. CO_CAN_ID_LSS_SLV);
  530. return err;
  531. }
  532. #endif /* CO_NO_LSS_SLAVE == 1 */
  533. /******************************************************************************/
  534. CO_ReturnError_t CO_CANopenInit(uint8_t nodeId) {
  535. int16_t i;
  536. CO_ReturnError_t err;
  537. /* Verify CANopen Node-ID */
  538. CO->nodeIdUnconfigured = false;
  539. #if CO_NO_LSS_SLAVE == 1
  540. if (nodeId == CO_LSS_NODE_ID_ASSIGNMENT) {
  541. CO->nodeIdUnconfigured = true;
  542. }
  543. else
  544. #endif
  545. if (nodeId < 1 || nodeId > 127) {
  546. return CO_ERROR_ILLEGAL_ARGUMENT;
  547. }
  548. /* Verify parameters from CO_OD */
  549. #if CO_NO_SRDO != 0
  550. if (sizeof(OD_SRDOCommunicationParameter_t) != sizeof(CO_SRDOCommPar_t) ||
  551. sizeof(OD_SRDOMappingParameter_t) != sizeof(CO_SRDOMapPar_t)) {
  552. return CO_ERROR_OD_PARAMETERS;
  553. }
  554. #endif
  555. if (sizeof(OD_TPDOCommunicationParameter_t) != sizeof(CO_TPDOCommPar_t) ||
  556. sizeof(OD_TPDOMappingParameter_t) != sizeof(CO_TPDOMapPar_t) ||
  557. sizeof(OD_RPDOCommunicationParameter_t) != sizeof(CO_RPDOCommPar_t) ||
  558. sizeof(OD_RPDOMappingParameter_t) != sizeof(CO_RPDOMapPar_t)) {
  559. return CO_ERROR_OD_PARAMETERS;
  560. }
  561. #if CO_NO_SDO_CLIENT != 0
  562. if (sizeof(OD_SDOClientParameter_t) != sizeof(CO_SDOclientPar_t)) {
  563. return CO_ERROR_OD_PARAMETERS;
  564. }
  565. #endif
  566. #if (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE
  567. /* LEDs */
  568. err = CO_LEDs_init(CO->LEDs);
  569. if (err) return err;
  570. #endif
  571. #if CO_NO_LSS_SLAVE == 1
  572. if (CO->nodeIdUnconfigured) {
  573. return CO_ERROR_NODE_ID_UNCONFIGURED_LSS;
  574. }
  575. #endif
  576. /* SDOserver */
  577. for (i = 0; i < CO_NO_SDO_SERVER; i++) {
  578. uint32_t COB_IDClientToServer;
  579. uint32_t COB_IDServerToClient;
  580. if (i == 0) {
  581. /*Default SDO server must be located at first index*/
  582. COB_IDClientToServer = CO_CAN_ID_SDO_CLI + nodeId;
  583. COB_IDServerToClient = CO_CAN_ID_SDO_SRV + nodeId;
  584. }
  585. else {
  586. COB_IDClientToServer =
  587. OD_SDOServerParameter[i].COB_IDClientToServer;
  588. COB_IDServerToClient =
  589. OD_SDOServerParameter[i].COB_IDServerToClient;
  590. }
  591. err = CO_SDO_init(CO->SDO[i],
  592. COB_IDClientToServer,
  593. COB_IDServerToClient,
  594. OD_H1200_SDO_SERVER_PARAM + i,
  595. i == 0 ? 0 : CO->SDO[0],
  596. &CO_OD[0],
  597. CO_OD_NoOfElements,
  598. CO_SDO_ODExtensions,
  599. nodeId,
  600. 1000,
  601. CO->CANmodule[0],
  602. CO_RXCAN_SDO_SRV + i,
  603. CO->CANmodule[0],
  604. CO_TXCAN_SDO_SRV + i);
  605. if (err) return err;
  606. }
  607. /* Emergency */
  608. err = CO_EM_init(CO->em,
  609. CO->emPr,
  610. CO->SDO[0],
  611. &OD_errorStatusBits[0],
  612. ODL_errorStatusBits_stringLength,
  613. &OD_errorRegister,
  614. &OD_preDefinedErrorField[0],
  615. ODL_preDefinedErrorField_arrayLength,
  616. CO->CANmodule[0],
  617. CO_RXCAN_EMERG,
  618. CO->CANmodule[0],
  619. CO_TXCAN_EMERG,
  620. (uint16_t)CO_CAN_ID_EMERGENCY + nodeId);
  621. if (err) return err;
  622. /* NMT_Heartbeat */
  623. err = CO_NMT_init(CO->NMT,
  624. CO->emPr,
  625. nodeId,
  626. 500,
  627. CO->CANmodule[0],
  628. CO_RXCAN_NMT,
  629. CO_CAN_ID_NMT_SERVICE,
  630. CO->CANmodule[0],
  631. CO_TXCAN_NMT,
  632. CO_CAN_ID_NMT_SERVICE,
  633. CO->CANmodule[0],
  634. CO_TXCAN_HB,
  635. CO_CAN_ID_HEARTBEAT + nodeId);
  636. if (err) return err;
  637. #if CO_NO_SYNC == 1
  638. /* SYNC */
  639. err = CO_SYNC_init(CO->SYNC,
  640. CO->em,
  641. CO->SDO[0],
  642. &CO->NMT->operatingState,
  643. OD_COB_ID_SYNCMessage,
  644. OD_communicationCyclePeriod,
  645. OD_synchronousCounterOverflowValue,
  646. CO->CANmodule[0],
  647. CO_RXCAN_SYNC,
  648. CO->CANmodule[0],
  649. CO_TXCAN_SYNC);
  650. if (err) return err;
  651. #endif
  652. #if CO_NO_TIME == 1
  653. /* TIME */
  654. err = CO_TIME_init(CO->TIME,
  655. CO->em,
  656. CO->SDO[0],
  657. &CO->NMT->operatingState,
  658. OD_COB_ID_TIME,
  659. 1000*30,
  660. CO->CANmodule[0],
  661. CO_RXCAN_TIME,
  662. CO->CANmodule[0],
  663. CO_TXCAN_TIME);
  664. if (err) return err;
  665. #endif
  666. #if CO_NO_GFC == 1
  667. /* GFC */
  668. CO_GFC_init(CO->GFC,
  669. &OD_globalFailSafeCommandParameter,
  670. CO->CANmodule[0],
  671. CO_RXCAN_GFC,
  672. CO_CAN_ID_GFC,
  673. CO->CANmodule[0],
  674. CO_TXCAN_GFC,
  675. CO_CAN_ID_GFC);
  676. #endif
  677. #if CO_NO_SRDO != 0
  678. /* SRDO */
  679. err = CO_SRDOGuard_init(CO->SRDOGuard,
  680. CO->SDO[0],
  681. &CO->NMT->operatingState,
  682. &OD_configurationValid,
  683. OD_H13FE_SRDO_VALID,
  684. OD_H13FF_SRDO_CHECKSUM);
  685. if (err) return err;
  686. for (i = 0; i < CO_NO_SRDO; i++) {
  687. CO_CANmodule_t *CANdev = CO->CANmodule[0];
  688. uint16_t CANdevRxIdx = CO_RXCAN_SRDO + 2*i;
  689. uint16_t CANdevTxIdx = CO_TXCAN_SRDO + 2*i;
  690. err = CO_SRDO_init(CO->SRDO[i],
  691. CO->SRDOGuard,
  692. CO->em,
  693. CO->SDO[0],
  694. nodeId,
  695. ((i == 0) ? CO_CAN_ID_SRDO_1 : 0),
  696. (CO_SRDOCommPar_t*)&OD_SRDOCommunicationParameter[i],
  697. (CO_SRDOMapPar_t *)&OD_SRDOMappingParameter[i],
  698. &OD_safetyConfigurationChecksum[i],
  699. OD_H1301_SRDO_1_PARAM + i,
  700. OD_H1381_SRDO_1_MAPPING + i,
  701. CANdev,
  702. CANdevRxIdx,
  703. CANdevRxIdx + 1,
  704. CANdev,
  705. CANdevTxIdx,
  706. CANdevTxIdx + 1);
  707. if (err) return err;
  708. }
  709. #endif
  710. /* RPDO */
  711. for (i = 0; i < CO_NO_RPDO; i++) {
  712. CO_CANmodule_t *CANdevRx = CO->CANmodule[0];
  713. uint16_t CANdevRxIdx = CO_RXCAN_RPDO + i;
  714. err = CO_RPDO_init(CO->RPDO[i],
  715. CO->em,
  716. CO->SDO[0],
  717. #if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
  718. CO->SYNC,
  719. #endif
  720. &CO->NMT->operatingState,
  721. nodeId,
  722. ((i < 4) ? (CO_CAN_ID_RPDO_1 + i * 0x100) : 0),
  723. 0,
  724. (CO_RPDOCommPar_t*)&OD_RPDOCommunicationParameter[i],
  725. (CO_RPDOMapPar_t *)&OD_RPDOMappingParameter[i],
  726. OD_H1400_RXPDO_1_PARAM + i,
  727. OD_H1600_RXPDO_1_MAPPING + i,
  728. CANdevRx,
  729. CANdevRxIdx);
  730. if (err) return err;
  731. }
  732. /* TPDO */
  733. for (i = 0; i < CO_NO_TPDO; i++) {
  734. err = CO_TPDO_init(CO->TPDO[i],
  735. CO->em,
  736. CO->SDO[0],
  737. #if (CO_CONFIG_PDO) & CO_CONFIG_PDO_SYNC_ENABLE
  738. CO->SYNC,
  739. #endif
  740. &CO->NMT->operatingState,
  741. nodeId,
  742. ((i < 4) ? (CO_CAN_ID_TPDO_1 + i * 0x100) : 0),
  743. 0,
  744. (CO_TPDOCommPar_t*)&OD_TPDOCommunicationParameter[i],
  745. (CO_TPDOMapPar_t *)&OD_TPDOMappingParameter[i],
  746. OD_H1800_TXPDO_1_PARAM + i,
  747. OD_H1A00_TXPDO_1_MAPPING + i,
  748. CO->CANmodule[0],
  749. CO_TXCAN_TPDO + i);
  750. if (err) return err;
  751. }
  752. /* Heartbeat consumer */
  753. err = CO_HBconsumer_init(CO->HBcons,
  754. CO->em,
  755. CO->SDO[0],
  756. &OD_consumerHeartbeatTime[0],
  757. CO_HBcons_monitoredNodes,
  758. CO_NO_HB_CONS,
  759. CO->CANmodule[0],
  760. CO_RXCAN_CONS_HB);
  761. if (err) return err;
  762. #if CO_NO_SDO_CLIENT != 0
  763. /* SDOclient */
  764. for (i = 0; i < CO_NO_SDO_CLIENT; i++) {
  765. err = CO_SDOclient_init(CO->SDOclient[i],
  766. (void *)CO->SDO[0],
  767. (CO_SDOclientPar_t *)&OD_SDOClientParameter[i],
  768. CO->CANmodule[0],
  769. CO_RXCAN_SDO_CLI + i,
  770. CO->CANmodule[0],
  771. CO_TXCAN_SDO_CLI + i);
  772. if (err) return err;
  773. }
  774. #endif
  775. #if CO_NO_LSS_MASTER == 1
  776. /* LSSmaster */
  777. err = CO_LSSmaster_init(CO->LSSmaster,
  778. CO_LSSmaster_DEFAULT_TIMEOUT,
  779. CO->CANmodule[0],
  780. CO_RXCAN_LSS_MST,
  781. CO_CAN_ID_LSS_SLV,
  782. CO->CANmodule[0],
  783. CO_TXCAN_LSS_MST,
  784. CO_CAN_ID_LSS_MST);
  785. if (err) return err;
  786. #endif
  787. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII
  788. /* Gateway-ascii */
  789. err = CO_GTWA_init(CO->gtwa,
  790. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII_SDO
  791. CO->SDOclient[0],
  792. 500,
  793. false,
  794. #endif
  795. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII_NMT
  796. CO->NMT,
  797. #endif
  798. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII_LSS
  799. CO->LSSmaster,
  800. #endif
  801. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII_PRINT_LEDS
  802. CO->LEDs,
  803. #endif
  804. 0);
  805. if (err) return err;
  806. #endif /* (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII */
  807. #if CO_NO_TRACE > 0
  808. /* Trace */
  809. for (i = 0; i < CO_NO_TRACE; i++) {
  810. CO_trace_init(CO->trace[i],
  811. CO->SDO[0],
  812. OD_traceConfig[i].axisNo,
  813. CO_traceTimeBuffers[i],
  814. CO_traceValueBuffers[i],
  815. CO_traceBufferSize[i],
  816. &OD_traceConfig[i].map,
  817. &OD_traceConfig[i].format,
  818. &OD_traceConfig[i].trigger,
  819. &OD_traceConfig[i].threshold,
  820. &OD_trace[i].value,
  821. &OD_trace[i].min,
  822. &OD_trace[i].max,
  823. &OD_trace[i].triggerTime,
  824. OD_INDEX_TRACE_CONFIG + i,
  825. OD_INDEX_TRACE + i);
  826. }
  827. #endif
  828. return CO_ERROR_NO;
  829. }
  830. /******************************************************************************/
  831. CO_NMT_reset_cmd_t CO_process(CO_t *co,
  832. uint32_t timeDifference_us,
  833. uint32_t *timerNext_us)
  834. {
  835. uint8_t i;
  836. bool_t NMTisPreOrOperational = false;
  837. CO_NMT_reset_cmd_t reset = CO_RESET_NOT;
  838. CO_CANmodule_process(CO->CANmodule[0]);
  839. #if CO_NO_LSS_SLAVE == 1
  840. bool_t resetLSS = CO_LSSslave_process(co->LSSslave);
  841. #endif
  842. #if (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE
  843. bool_t unc = co->nodeIdUnconfigured;
  844. uint16_t CANerrorStatus = CO->CANmodule[0]->CANerrorStatus;
  845. CO_LEDs_process(co->LEDs,
  846. timeDifference_us,
  847. unc ? CO_NMT_INITIALIZING : co->NMT->operatingState,
  848. #if CO_NO_LSS_SLAVE == 1
  849. CO_LSSslave_getState(co->LSSslave)
  850. == CO_LSS_STATE_CONFIGURATION,
  851. #else
  852. false,
  853. #endif
  854. (CANerrorStatus & CO_CAN_ERRTX_BUS_OFF) != 0,
  855. (CANerrorStatus & CO_CAN_ERR_WARN_PASSIVE) != 0,
  856. 0, /* RPDO event timer timeout */
  857. unc ? false : CO_isError(co->em, CO_EM_SYNC_TIME_OUT),
  858. unc ? false : (CO_isError(co->em, CO_EM_HEARTBEAT_CONSUMER)
  859. || CO_isError(co->em, CO_EM_HB_CONSUMER_REMOTE_RESET)),
  860. OD_errorRegister != 0,
  861. CO_STATUS_FIRMWARE_DOWNLOAD_IN_PROGRESS,
  862. timerNext_us);
  863. #endif /* (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE */
  864. #if CO_NO_LSS_SLAVE == 1
  865. if (resetLSS) {
  866. reset = CO_RESET_COMM;
  867. }
  868. if (co->nodeIdUnconfigured) {
  869. return reset;
  870. }
  871. #endif
  872. if (co->NMT->operatingState == CO_NMT_PRE_OPERATIONAL ||
  873. co->NMT->operatingState == CO_NMT_OPERATIONAL)
  874. NMTisPreOrOperational = true;
  875. /* SDOserver */
  876. for (i = 0; i < CO_NO_SDO_SERVER; i++) {
  877. CO_SDO_process(co->SDO[i],
  878. NMTisPreOrOperational,
  879. timeDifference_us,
  880. timerNext_us);
  881. }
  882. /* Emergency */
  883. CO_EM_process(co->emPr,
  884. NMTisPreOrOperational,
  885. timeDifference_us,
  886. OD_inhibitTimeEMCY,
  887. timerNext_us);
  888. /* NMT_Heartbeat */
  889. reset = CO_NMT_process(co->NMT,
  890. timeDifference_us,
  891. OD_producerHeartbeatTime,
  892. OD_NMTStartup,
  893. OD_errorRegister,
  894. OD_errorBehavior,
  895. timerNext_us);
  896. #if CO_NO_TIME == 1
  897. /* TIME */
  898. CO_TIME_process(co->TIME,
  899. timeDifference_us);
  900. #endif
  901. /* Heartbeat consumer */
  902. CO_HBconsumer_process(co->HBcons,
  903. NMTisPreOrOperational,
  904. timeDifference_us,
  905. timerNext_us);
  906. #if (CO_CONFIG_GTW) & CO_CONFIG_GTW_ASCII
  907. /* Gateway-ascii */
  908. CO_GTWA_process(co->gtwa,
  909. CO_GTWA_ENABLE,
  910. timeDifference_us,
  911. timerNext_us);
  912. #endif
  913. return reset;
  914. }
  915. /******************************************************************************/
  916. #if CO_NO_SYNC == 1
  917. bool_t CO_process_SYNC(CO_t *co,
  918. uint32_t timeDifference_us,
  919. uint32_t *timerNext_us)
  920. {
  921. bool_t syncWas = false;
  922. #if CO_NO_LSS_SLAVE == 1
  923. if (co->nodeIdUnconfigured) {
  924. return syncWas;
  925. }
  926. #endif
  927. const CO_SYNC_status_t sync_process = CO_SYNC_process(co->SYNC,
  928. timeDifference_us,
  929. OD_synchronousWindowLength,
  930. timerNext_us);
  931. switch (sync_process) {
  932. case CO_SYNC_NONE:
  933. break;
  934. case CO_SYNC_RECEIVED:
  935. syncWas = true;
  936. break;
  937. case CO_SYNC_OUTSIDE_WINDOW:
  938. CO_CANclearPendingSyncPDOs(co->CANmodule[0]);
  939. break;
  940. }
  941. return syncWas;
  942. }
  943. #endif /* CO_NO_SYNC == 1 */
  944. /******************************************************************************/
  945. void CO_process_RPDO(CO_t *co,
  946. bool_t syncWas)
  947. {
  948. int16_t i;
  949. #if CO_NO_LSS_SLAVE == 1
  950. if (co->nodeIdUnconfigured) {
  951. return;
  952. }
  953. #endif
  954. for (i = 0; i < CO_NO_RPDO; i++) {
  955. CO_RPDO_process(co->RPDO[i], syncWas);
  956. }
  957. }
  958. /******************************************************************************/
  959. void CO_process_TPDO(CO_t *co,
  960. bool_t syncWas,
  961. uint32_t timeDifference_us,
  962. uint32_t *timerNext_us)
  963. {
  964. int16_t i;
  965. #if CO_NO_LSS_SLAVE == 1
  966. if (co->nodeIdUnconfigured) {
  967. return;
  968. }
  969. #endif
  970. /* Verify PDO Change Of State and process PDOs */
  971. for (i = 0; i < CO_NO_TPDO; i++) {
  972. if (!co->TPDO[i]->sendRequest)
  973. co->TPDO[i]->sendRequest = CO_TPDOisCOS(co->TPDO[i]);
  974. CO_TPDO_process(co->TPDO[i], syncWas, timeDifference_us, timerNext_us);
  975. }
  976. }
  977. /******************************************************************************/
  978. #if CO_NO_SRDO != 0
  979. void CO_process_SRDO(CO_t *co,
  980. uint32_t timeDifference_us,
  981. uint32_t *timerNext_us)
  982. {
  983. int16_t i;
  984. uint8_t firstOperational;
  985. #if CO_NO_LSS_SLAVE == 1
  986. if (co->nodeIdUnconfigured) {
  987. return;
  988. }
  989. #endif
  990. firstOperational = CO_SRDOGuard_process(co->SRDOGuard);
  991. /* Verify PDO Change Of State and process PDOs */
  992. for (i = 0; i < CO_NO_SRDO; i++) {
  993. CO_SRDO_process(co->SRDO[i], firstOperational, timeDifference_us, timerNext_us);
  994. }
  995. }
  996. #endif