library for C++ CANOpen implementation. mbed independant, but is easy to attach into with mbed.
Dependents: ppCANOpen_Example DISCO-F746NG_rtos_test
Example:
Import programppCANOpen_Example
I am no longer actively working on the ppCANOpen library, however, I want to publish this project so that anyone who wants to pick up any of the pieces can have a good example. This is a a project I was working on using the ppCANOpen library. It has a pretty in deep use of the object dictionary structure. And a number of functions to control high voltage pinball drivers, if you're into that sort of thing.
drivers/mbed-Nucleo-F091RC/canopen_api.cpp
- Committer:
- ptpaterson
- Date:
- 2016-02-13
- Revision:
- 5:22a337cdc0e3
- Parent:
- 4:2034b04c86d2
File content as of revision 5:22a337cdc0e3:
/**
******************************************************************************
* @file
* @author Paul Paterson
* @version
* @date 2015-12-14
* @brief CANOpen api for STM32 Nucleo-F091RC in mbed
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT(c) 2015 Paul Paterson
*
* All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "canopen_api.h"
#include "canopen_config.h"
#include "CanOpenMessage.h"
#include "mbed.h"
#include "CAN.h" /* use with CANNucleo library */
#include "stdio.h"
void *pServiceObject = 0;
/* Can declarations ---------------------------------------------------------*/
CAN * can; //(CANOPEN_PIN_RX, CANOPEN_PIN_TX);
ServiceProviderRxInterruptCallback serviceRxCallback = 0;
void CanReadInterruptCallback (void) {
if (serviceRxCallback && pServiceObject) {
serviceRxCallback(pServiceObject);
}
}
/* Ticker declarations ---------------------------------------------------------*/
Ticker updateTicker;
ServiceProviderTickCallback serviceTickCallback = 0;
void UpdateTickerCallback(void) {
if (serviceTickCallback && pServiceObject) {
serviceTickCallback(pServiceObject);
}
}
int CanOpenApiInit (void *object, ServiceProviderRxInterruptCallback rxCallback, ServiceProviderTickCallback tickCallback)
{
printf ("----------- CANOPEN API: API INIT\r\n");
/* CAN instance to do all of the communication
*
* For some reason, I cannot use "static CAN can". It will compile,
* but code get's stuck during initialization, and will not even enter
* main(). Works great like this though! Only one ServiceProvider, though,
* so mem leaks should not be an issue if we don't delete it???
*/
//static CAN can(CANOPEN_PIN_RX, CANOPEN_PIN_TX);
//can = new CAN(CANOPEN_PIN_RX, CANOPEN_PIN_TX);
can = new CAN(CANOPEN_PIN_RX, CANOPEN_PIN_TX);
//can.reset();
/* init the callback system ---------------------------------------------*/
pServiceObject = object;
serviceRxCallback = rxCallback;
serviceTickCallback = tickCallback;
can->attach(CanReadInterruptCallback);
updateTicker.attach(UpdateTickerCallback, .0005);
return 1;
}
int CanOpenApiRead (CanOpenMessage *canOpenMsg)
{
int result = 0;
/* CAUTON ********************************
* Could be used in interrupt!!!
* ***************************************
*/
//printf("canopen_api: CanOpenApiRead()\r\n");
if (can) {
CANMessage canMsg;
result = can->read (canMsg);
if (result) {
canOpenMsg->id = canMsg.id;
canOpenMsg->dataCount = canMsg.len,
canOpenMsg->type = canMsg.type == CANData ? CANOPEN_TYPE_DATA : CANOPEN_TYPE_REMOTE;
canOpenMsg->format = canMsg.format == CANStandard ? CANOPEN_FORMAT_STANDARD : CANOPEN_FORMAT_EXTENDED;
// NOTE: memcpy is freezing execution
//memcpy(canOpenMsg->data, canMsg.data, canMsg.len);
canOpenMsg->data[0] = canMsg.data[0];
canOpenMsg->data[1] = canMsg.data[1];
canOpenMsg->data[2] = canMsg.data[2];
canOpenMsg->data[3] = canMsg.data[3];
canOpenMsg->data[4] = canMsg.data[4];
canOpenMsg->data[5] = canMsg.data[5];
canOpenMsg->data[6] = canMsg.data[6];
canOpenMsg->data[7] = canMsg.data[7];
// DEBUG
//printf(" ID: %d\r\n", (int)canOpenMsg->id);
//printf(" Count: %d\r\n", (int)canOpenMsg->dataCount);
//printf(" Type: %d\r\n", (int)canOpenMsg->type);
//printf(" Format: %d\r\n", (int)canOpenMsg->format);
//printf(" Data[0]: %d\r\n", (int)canOpenMsg->data[0]);
}
}
return result;
}
int CanOpenApiWrite (CanOpenMessage *canOpenMsg)
{
int result = 0;
CANMessage canMsg;
canMsg.id = canOpenMsg->id;
canMsg.len = canOpenMsg->dataCount,
canMsg.type = canOpenMsg->type == CANOPEN_TYPE_DATA ? CANData : CANRemote;
canMsg.format = canOpenMsg->format == CANOPEN_FORMAT_STANDARD ? CANStandard : CANExtended;
// NOTE: memcpy is freezing execution
//memcpy(canMsg.data, canOpenMsg->data, canOpenMsg->dataCount);
canMsg.data[0] = canOpenMsg->data[0];
canMsg.data[1] = canOpenMsg->data[1];
canMsg.data[2] = canOpenMsg->data[2];
canMsg.data[3] = canOpenMsg->data[3];
canMsg.data[4] = canOpenMsg->data[4];
canMsg.data[5] = canOpenMsg->data[5];
canMsg.data[6] = canOpenMsg->data[6];
canMsg.data[7] = canOpenMsg->data[7];
result = can->write (canMsg);
return result;
}
static int timeSyncOffset = 0;
uint32_t CanOpenApiGetHardwareTime (void)
{
return HAL_GetTick();
}
