CO_GFC.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /**
  2. * CANopen Global fail-safe command protocol.
  3. *
  4. * @file CO_GFC.c
  5. * @ingroup CO_GFC
  6. * @author Robert Grüning
  7. * @copyright 2020 - 2020 Robert Grüning
  8. *
  9. * This file is part of CANopenNode, an opensource CANopen Stack.
  10. * Project home page is <https://github.com/CANopenNode/CANopenNode>.
  11. * For more information on CANopen see <http://www.can-cia.org/>.
  12. *
  13. * Licensed under the Apache License, Version 2.0 (the "License");
  14. * you may not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at
  16. *
  17. * http://www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an "AS IS" BASIS,
  21. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. */
  25. #include "304/CO_GFC.h"
  26. #if (CO_CONFIG_GFC) & CO_CONFIG_GFC_ENABLE
  27. #if (CO_CONFIG_GFC) & CO_CONFIG_GFC_CONSUMER
  28. static void CO_GFC_receive(void *object, void *msg)
  29. {
  30. CO_GFC_t *GFC;
  31. uint8_t DLC = CO_CANrxMsg_readDLC(msg);
  32. GFC = (CO_GFC_t *)
  33. object; /* this is the correct pointer type of the first argument */
  34. if ((*GFC->valid == 0x01) && (DLC == 0)) {
  35. #if (CO_CONFIG_GFC) & CO_CONFIG_GFC_CONSUMER
  36. /* Optional signal to RTOS, which can resume task, which handles SRDO.
  37. */
  38. if (GFC->pFunctSignalSafe != NULL) {
  39. GFC->pFunctSignalSafe(GFC->functSignalObjectSafe);
  40. }
  41. #endif
  42. }
  43. }
  44. void CO_GFC_initCallbackEnterSafeState(CO_GFC_t *GFC,
  45. void *object,
  46. void (*pFunctSignalSafe)(void *object))
  47. {
  48. if (GFC != NULL) {
  49. GFC->functSignalObjectSafe = object;
  50. GFC->pFunctSignalSafe = pFunctSignalSafe;
  51. }
  52. }
  53. #endif
  54. CO_ReturnError_t CO_GFC_init(CO_GFC_t *GFC,
  55. uint8_t *valid,
  56. CO_CANmodule_t *GFC_CANdevRx,
  57. uint16_t GFC_rxIdx,
  58. uint16_t CANidRxGFC,
  59. CO_CANmodule_t *GFC_CANdevTx,
  60. uint16_t GFC_txIdx,
  61. uint16_t CANidTxGFC)
  62. {
  63. if (GFC == NULL || valid == NULL || GFC_CANdevRx == NULL ||
  64. GFC_CANdevTx == NULL) {
  65. return CO_ERROR_ILLEGAL_ARGUMENT;
  66. }
  67. GFC->valid = valid;
  68. #if (CO_CONFIG_GFC) & CO_CONFIG_GFC_PRODUCER
  69. GFC->CANdevTx = GFC_CANdevTx;
  70. #endif
  71. #if (CO_CONFIG_GFC) & CO_CONFIG_GFC_CONSUMER
  72. GFC->functSignalObjectSafe = NULL;
  73. GFC->pFunctSignalSafe = NULL;
  74. #endif
  75. #if (CO_CONFIG_GFC) & CO_CONFIG_GFC_PRODUCER
  76. GFC->CANtxBuff = CO_CANtxBufferInit(
  77. GFC->CANdevTx, /* CAN device */
  78. GFC_txIdx, /* index of specific buffer inside CAN module */
  79. CANidTxGFC, /* CAN identifier */
  80. 0, /* rtr */
  81. 0, /* number of data bytes */
  82. 0); /* synchronous message flag bit */
  83. if (GFC->CANtxBuff == NULL) {
  84. return CO_ERROR_TX_UNCONFIGURED;
  85. }
  86. #else
  87. (void)GFC_txIdx; /* unused */
  88. (void)CANidTxGFC; /* unused */
  89. #endif
  90. #if (CO_CONFIG_GFC) & CO_CONFIG_GFC_CONSUMER
  91. const CO_ReturnError_t r = CO_CANrxBufferInit(
  92. GFC_CANdevRx, /* CAN device */
  93. GFC_rxIdx, /* rx buffer index */
  94. CANidRxGFC, /* CAN identifier */
  95. 0x7FF, /* mask */
  96. 0, /* rtr */
  97. (void *)GFC, /* object passed to receive function */
  98. CO_GFC_receive); /* this function will process received message */
  99. if (r != CO_ERROR_NO) {
  100. return r;
  101. }
  102. #else
  103. (void)GFC_rxIdx; /* unused */
  104. (void)CANidRxGFC; /* unused */
  105. #endif
  106. return CO_ERROR_NO;
  107. }
  108. #if (CO_CONFIG_GFC) & CO_CONFIG_GFC_PRODUCER
  109. CO_ReturnError_t CO_GFCsend(CO_GFC_t *GFC)
  110. {
  111. if (*GFC->valid == 0x01)
  112. return CO_CANsend(GFC->CANdevTx, GFC->CANtxBuff);
  113. return CO_ERROR_NO;
  114. }
  115. #endif
  116. #endif /* (CO_CONFIG_GFC) & CO_CONFIG_GFC_ENABLE */