library for C++ CANOpen implementation. mbed independant, but is easy to attach into with mbed.

Dependents:   ppCANOpen_Example DISCO-F746NG_rtos_test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers canopen_api.cpp Source File

canopen_api.cpp

Go to the documentation of this file.
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>&copy; 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