library for C++ CANOpen implementation. mbed independant, but is easy to attach into with mbed.
Dependents: ppCANOpen_Example DISCO-F746NG_rtos_test
canopen_api.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file 00004 * @author Paul Paterson 00005 * @version 00006 * @date 2015-12-14 00007 * @brief CANOpen api for STM32 Nucleo-F091RC in mbed 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2015 Paul Paterson 00012 * 00013 * All rights reserved. 00014 00015 This program is free software: you can redistribute it and/or modify 00016 it under the terms of the GNU General Public License as published by 00017 the Free Software Foundation, either version 3 of the License, or 00018 (at your option) any later version. 00019 00020 This program is distributed in the hope that it will be useful, 00021 but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 GNU General Public License for more details. 00024 00025 You should have received a copy of the GNU General Public License 00026 along with this program. If not, see <http://www.gnu.org/licenses/>. 00027 */ 00028 00029 #include "canopen_api.h" 00030 #include "canopen_config.h" 00031 00032 #include "CanOpenMessage.h" 00033 00034 #include "mbed.h" 00035 #include "CAN.h" /* use with CANNucleo library */ 00036 00037 #include "stdio.h" 00038 00039 00040 void *pServiceObject = 0; 00041 00042 /* Can declarations ---------------------------------------------------------*/ 00043 CAN * can; //(CANOPEN_PIN_RX, CANOPEN_PIN_TX); 00044 ServiceProviderRxInterruptCallback serviceRxCallback = 0; 00045 void CanReadInterruptCallback (void) { 00046 if (serviceRxCallback && pServiceObject) { 00047 serviceRxCallback(pServiceObject); 00048 } 00049 } 00050 00051 /* Ticker declarations ---------------------------------------------------------*/ 00052 Ticker updateTicker; 00053 ServiceProviderTickCallback serviceTickCallback = 0; 00054 void UpdateTickerCallback(void) { 00055 if (serviceTickCallback && pServiceObject) { 00056 serviceTickCallback(pServiceObject); 00057 } 00058 } 00059 00060 int CanOpenApiInit (void *object, ServiceProviderRxInterruptCallback rxCallback, ServiceProviderTickCallback tickCallback) 00061 { 00062 printf ("----------- CANOPEN API: API INIT\r\n"); 00063 00064 /* CAN instance to do all of the communication 00065 * 00066 * For some reason, I cannot use "static CAN can". It will compile, 00067 * but code get's stuck during initialization, and will not even enter 00068 * main(). Works great like this though! Only one ServiceProvider, though, 00069 * so mem leaks should not be an issue if we don't delete it??? 00070 */ 00071 //static CAN can(CANOPEN_PIN_RX, CANOPEN_PIN_TX); 00072 //can = new CAN(CANOPEN_PIN_RX, CANOPEN_PIN_TX); 00073 can = new CAN(CANOPEN_PIN_RX, CANOPEN_PIN_TX); 00074 //can.reset(); 00075 00076 /* init the callback system ---------------------------------------------*/ 00077 pServiceObject = object; 00078 00079 serviceRxCallback = rxCallback; 00080 serviceTickCallback = tickCallback; 00081 00082 can->attach(CanReadInterruptCallback); 00083 updateTicker.attach(UpdateTickerCallback, .0005); 00084 00085 return 1; 00086 } 00087 00088 int CanOpenApiRead (CanOpenMessage *canOpenMsg) 00089 { 00090 int result = 0; 00091 00092 /* CAUTON ******************************** 00093 * Could be used in interrupt!!! 00094 * *************************************** 00095 */ 00096 //printf("canopen_api: CanOpenApiRead()\r\n"); 00097 00098 if (can) { 00099 00100 CANMessage canMsg; 00101 00102 result = can->read (canMsg); 00103 if (result) { 00104 canOpenMsg->id = canMsg.id; 00105 canOpenMsg->dataCount = canMsg.len, 00106 canOpenMsg->type = canMsg.type == CANData ? CANOPEN_TYPE_DATA : CANOPEN_TYPE_REMOTE; 00107 canOpenMsg->format = canMsg.format == CANStandard ? CANOPEN_FORMAT_STANDARD : CANOPEN_FORMAT_EXTENDED; 00108 00109 // NOTE: memcpy is freezing execution 00110 //memcpy(canOpenMsg->data, canMsg.data, canMsg.len); 00111 canOpenMsg->data[0] = canMsg.data[0]; 00112 canOpenMsg->data[1] = canMsg.data[1]; 00113 canOpenMsg->data[2] = canMsg.data[2]; 00114 canOpenMsg->data[3] = canMsg.data[3]; 00115 canOpenMsg->data[4] = canMsg.data[4]; 00116 canOpenMsg->data[5] = canMsg.data[5]; 00117 canOpenMsg->data[6] = canMsg.data[6]; 00118 canOpenMsg->data[7] = canMsg.data[7]; 00119 00120 // DEBUG 00121 //printf(" ID: %d\r\n", (int)canOpenMsg->id); 00122 //printf(" Count: %d\r\n", (int)canOpenMsg->dataCount); 00123 //printf(" Type: %d\r\n", (int)canOpenMsg->type); 00124 //printf(" Format: %d\r\n", (int)canOpenMsg->format); 00125 //printf(" Data[0]: %d\r\n", (int)canOpenMsg->data[0]); 00126 } 00127 00128 } 00129 return result; 00130 } 00131 00132 int CanOpenApiWrite (CanOpenMessage *canOpenMsg) 00133 { 00134 int result = 0; 00135 00136 CANMessage canMsg; 00137 canMsg.id = canOpenMsg->id; 00138 canMsg.len = canOpenMsg->dataCount, 00139 canMsg.type = canOpenMsg->type == CANOPEN_TYPE_DATA ? CANData : CANRemote; 00140 canMsg.format = canOpenMsg->format == CANOPEN_FORMAT_STANDARD ? CANStandard : CANExtended; 00141 00142 // NOTE: memcpy is freezing execution 00143 //memcpy(canMsg.data, canOpenMsg->data, canOpenMsg->dataCount); 00144 canMsg.data[0] = canOpenMsg->data[0]; 00145 canMsg.data[1] = canOpenMsg->data[1]; 00146 canMsg.data[2] = canOpenMsg->data[2]; 00147 canMsg.data[3] = canOpenMsg->data[3]; 00148 canMsg.data[4] = canOpenMsg->data[4]; 00149 canMsg.data[5] = canOpenMsg->data[5]; 00150 canMsg.data[6] = canOpenMsg->data[6]; 00151 canMsg.data[7] = canOpenMsg->data[7]; 00152 00153 result = can->write (canMsg); 00154 00155 00156 return result; 00157 } 00158 00159 static int timeSyncOffset = 0; 00160 00161 uint32_t CanOpenApiGetHardwareTime (void) 00162 { 00163 return HAL_GetTick(); 00164 } 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174
Generated on Sun Jul 17 2022 07:51:19 by 1.7.2