CAN_ATY.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. /**
  2. * @file CAN_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2026 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief functions of can process for C platform
  20. *
  21. * @version
  22. * - 1_00_260116 > ATY
  23. * -# Preliminary version
  24. ********************************************************************************
  25. */
  26. #ifndef __CAN_ATY_C
  27. #define __CAN_ATY_C
  28. #include "CAN_ATY.h"
  29. #include "string.h"
  30. /******************************* For user *************************************/
  31. /******************************************************************************/
  32. void CAN_RegRW(struct CAN_ATY_Dev* dev,
  33. uint32_t frameId, uint8_t cmd, uint8_t regAddr, float value){
  34. uint8_t txData[8] = {0};
  35. txData[0] = cmd;
  36. txData[1] = regAddr;
  37. memcpy(&txData[2], &value, 4);
  38. txData[6] = 0;
  39. txData[7] = 0;
  40. dev->addTxMessage(frameId, txData, 8);
  41. }
  42. void CAN_Response(struct CAN_ATY_Dev* dev,
  43. uint8_t cmd, uint8_t regAddr, float value, uint8_t error){
  44. uint8_t txData[8] = {0};
  45. txData[0] = cmd;
  46. txData[1] = regAddr;
  47. memcpy(&txData[2], &value, 4);
  48. txData[6] = 0;
  49. txData[7] = error;
  50. dev->addTxMessage(CAN_STD_ID_RESPONSE + dev->addr, txData, 8);
  51. }
  52. void CAN_FaultReport(struct CAN_ATY_Dev* dev,
  53. uint8_t faultCode, uint8_t severity, float faultValue){
  54. uint8_t txData[8] = {0};
  55. txData[0] = faultCode;
  56. txData[1] = severity;
  57. memcpy(&txData[2], &faultValue, 4);
  58. txData[6] = 0;
  59. txData[7] = 0;
  60. dev->addTxMessage(CAN_STD_ID_FAULT + dev->addr, txData, 8);
  61. }
  62. void CAN_RX_Callback(struct CAN_ATY_Dev* dev, uint32_t stdId, float* data, uint8_t* rxData){
  63. uint8_t cmd = rxData[0];
  64. uint8_t regAddr = rxData[1];
  65. if(stdId == CAN_STD_ID_BROADCAST
  66. || stdId == (CAN_STD_ID_MULTICAST + dev->groupId)){
  67. memcpy(&data[regAddr], &rxData[2], 4);
  68. }
  69. else if(stdId == (CAN_STD_ID_P2P + dev->addr)){
  70. switch(cmd){
  71. case CAN_CMD_READ:
  72. CAN_Response(dev, cmd, regAddr, data[regAddr], CAN_ERR_NONE);
  73. break;
  74. case CAN_CMD_WRITE:
  75. memcpy(&data[regAddr], &rxData[2], 4);
  76. CAN_Response(dev, cmd, regAddr, data[regAddr], CAN_ERR_NONE);
  77. break;
  78. default:
  79. CAN_Response(dev, cmd, regAddr, data[regAddr], CAN_ERR_CMD);
  80. break;
  81. }
  82. }
  83. else if(stdId == (CAN_STD_ID_RESPONSE + dev->addr)){
  84. }
  85. else if(stdId == CAN_STD_ID_FAULT + dev->addr){
  86. }
  87. }
  88. #endif /* __CAN_ATY_C */
  89. /************************************ etc *************************************/
  90. /* init
  91. // CAN -------------------------------------------------------------------------
  92. #include "CAN_ATY.h"
  93. uint8_t CAN1_FilterConfig(uint8_t bankId){
  94. CAN_FilterTypeDef sFilterConfig;
  95. if(bankId > 14){
  96. sFilterConfig.FilterBank = CAN_FILTER_BROADCAST;
  97. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  98. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  99. sFilterConfig.FilterIdHigh = 0x0000;
  100. sFilterConfig.FilterIdLow = 0x0000;
  101. sFilterConfig.FilterMaskIdHigh = 0x0000;
  102. sFilterConfig.FilterMaskIdLow = 0x0000;
  103. sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
  104. sFilterConfig.FilterActivation = ENABLE;
  105. sFilterConfig.SlaveStartFilterBank = 0;
  106. if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  107. return 9;
  108. }
  109. if(bankId == 0 || bankId == CAN_FILTER_BROADCAST){
  110. sFilterConfig.FilterBank = CAN_FILTER_BROADCAST;
  111. sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  112. sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  113. sFilterConfig.FilterIdHigh = ((CAN_STD_ID_BROADCAST << 21) >> 16);
  114. sFilterConfig.FilterIdLow = (CAN_STD_ID_BROADCAST << 21) & 0xFFFF;
  115. sFilterConfig.FilterMaskIdHigh = 0xFFFF;
  116. sFilterConfig.FilterMaskIdLow = 0xFFFF;
  117. sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
  118. sFilterConfig.FilterActivation = ENABLE;
  119. sFilterConfig.SlaveStartFilterBank = 0;
  120. if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  121. return 1;
  122. }
  123. if(bankId == 0 || bankId == CAN_FILTER_MULTICAST){
  124. sFilterConfig.FilterBank = CAN_FILTER_MULTICAST;
  125. sFilterConfig.FilterIdHigh = (((CAN_STD_ID_MULTICAST + (uint8_t)RGF_SYS_GROUP_ID) << 21) >> 16);
  126. sFilterConfig.FilterIdLow = ((CAN_STD_ID_MULTICAST + (uint8_t)RGF_SYS_GROUP_ID) << 21) & 0xFFFF;
  127. sFilterConfig.FilterMaskIdHigh = 0xFFFF;
  128. sFilterConfig.FilterMaskIdLow = 0xFFFF;
  129. sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
  130. sFilterConfig.FilterActivation = ENABLE;
  131. if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  132. return 2;
  133. }
  134. if(bankId == 0 || bankId == CAN_FILTER_P2P){
  135. sFilterConfig.FilterBank = CAN_FILTER_P2P;
  136. sFilterConfig.FilterIdHigh = (((CAN_STD_ID_P2P + (uint8_t)RGF_SYS_ADDR) << 21) >> 16);
  137. sFilterConfig.FilterIdLow = ((CAN_STD_ID_P2P + (uint8_t)RGF_SYS_ADDR) << 21) & 0xFFFF;
  138. sFilterConfig.FilterMaskIdHigh = 0xFFFF;
  139. sFilterConfig.FilterMaskIdLow = 0xFFFF;
  140. sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
  141. sFilterConfig.FilterActivation = ENABLE;
  142. if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
  143. return 3;
  144. }
  145. return 0;
  146. }
  147. uint8_t CAN1_InitConfigStart(void){
  148. uint8_t err = 0;
  149. err = CAN1_FilterConfig(0);
  150. if(err != 0) return err;
  151. if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
  152. err = 10;
  153. if(HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)
  154. err = 11;
  155. if(HAL_CAN_Start(&hcan) != HAL_OK)
  156. err = 12;
  157. return err;
  158. }
  159. uint8_t CAN1_AddTxMessage(uint32_t stdId, uint8_t* data, uint8_t len){
  160. CAN_TxHeaderTypeDef txHeader;
  161. uint32_t mailBox;
  162. txHeader.StdId = stdId;
  163. txHeader.IDE = CAN_ID_STD;
  164. txHeader.RTR = CAN_RTR_DATA;
  165. txHeader.DLC = len;
  166. txHeader.TransmitGlobalTime = DISABLE;
  167. HAL_CAN_AddTxMessage(&hcan, &txHeader, data, &mailBox);
  168. return 0;
  169. }
  170. struct CAN_ATY_Dev CAN_ATY_Dev_1 = {
  171. .addTxMessage = CAN1_AddTxMessage,
  172. .addr = 0,
  173. .groupId = 0,
  174. .lock = __ATY_UNLOCKED
  175. };
  176. void CAN1_UpdateFilter(uint8_t addr, uint8_t groupId){
  177. if(CAN_ATY_Dev_1.addr != addr){
  178. CAN_ATY_Dev_1.addr = addr;
  179. CAN1_FilterConfig(0);
  180. }
  181. if(CAN_ATY_Dev_1.groupId != groupId){
  182. CAN_ATY_Dev_1.groupId = groupId;
  183. CAN1_FilterConfig(CAN_FILTER_MULTICAST);
  184. }
  185. }
  186. void CAN1_RxProcess(CAN_HandleTypeDef* hcan_t, uint32_t RxFifo){
  187. CAN_RxHeaderTypeDef rxHeader;
  188. uint8_t rxData[8] = {0};
  189. if(HAL_CAN_GetRxMessage(hcan_t, RxFifo, &rxHeader, rxData) != HAL_OK){
  190. return;
  191. }
  192. if(rxHeader.IDE != CAN_ID_STD || rxHeader.DLC < 2 || rxHeader.DLC < 6){
  193. return;
  194. }
  195. CAN_RX_Callback(&CAN_ATY_Dev_1, rxHeader.StdId, rgf, rxData);
  196. }
  197. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* hcan_t){
  198. if(hcan_t == &hcan){
  199. CAN1_RxProcess(hcan_t, CAN_RX_FIFO0);
  200. }
  201. }
  202. void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef* hcan_t){
  203. if(hcan_t == &hcan){
  204. CAN1_RxProcess(hcan_t, CAN_RX_FIFO1);
  205. }
  206. }
  207. */
  208. /* use
  209. // init
  210. CAN1_InitConfigStart();
  211. // cycles
  212. CAN1_UpdateFilter((uint8_t)RGF_SYS_ADDR, (uint8_t)RGF_SYS_GROUP_ID);
  213. */
  214. /******************************************************************************/
  215. /******************************** End Of File *********************************/