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@5:22a337cdc0e3, 2016-02-13 (annotated)
- Committer:
- ptpaterson
- Date:
- Sat Feb 13 20:22:59 2016 +0000
- Revision:
- 5:22a337cdc0e3
- Parent:
- 4:2034b04c86d2
PDO receive complete
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| ptpaterson | 0:1865da4a634c | 1 | /** |
| ptpaterson | 0:1865da4a634c | 2 | ****************************************************************************** |
| ptpaterson | 1:666f30541db5 | 3 | * @file |
| ptpaterson | 0:1865da4a634c | 4 | * @author Paul Paterson |
| ptpaterson | 1:666f30541db5 | 5 | * @version |
| ptpaterson | 0:1865da4a634c | 6 | * @date 2015-12-14 |
| ptpaterson | 0:1865da4a634c | 7 | * @brief CANOpen api for STM32 Nucleo-F091RC in mbed |
| ptpaterson | 0:1865da4a634c | 8 | ****************************************************************************** |
| ptpaterson | 0:1865da4a634c | 9 | * @attention |
| ptpaterson | 0:1865da4a634c | 10 | * |
| ptpaterson | 0:1865da4a634c | 11 | * <h2><center>© COPYRIGHT(c) 2015 Paul Paterson |
| ptpaterson | 0:1865da4a634c | 12 | * |
| ptpaterson | 0:1865da4a634c | 13 | * All rights reserved. |
| ptpaterson | 1:666f30541db5 | 14 | |
| ptpaterson | 0:1865da4a634c | 15 | This program is free software: you can redistribute it and/or modify |
| ptpaterson | 0:1865da4a634c | 16 | it under the terms of the GNU General Public License as published by |
| ptpaterson | 0:1865da4a634c | 17 | the Free Software Foundation, either version 3 of the License, or |
| ptpaterson | 0:1865da4a634c | 18 | (at your option) any later version. |
| ptpaterson | 1:666f30541db5 | 19 | |
| ptpaterson | 0:1865da4a634c | 20 | This program is distributed in the hope that it will be useful, |
| ptpaterson | 0:1865da4a634c | 21 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| ptpaterson | 0:1865da4a634c | 22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| ptpaterson | 0:1865da4a634c | 23 | GNU General Public License for more details. |
| ptpaterson | 1:666f30541db5 | 24 | |
| ptpaterson | 0:1865da4a634c | 25 | You should have received a copy of the GNU General Public License |
| ptpaterson | 0:1865da4a634c | 26 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
| ptpaterson | 0:1865da4a634c | 27 | */ |
| ptpaterson | 1:666f30541db5 | 28 | |
| ptpaterson | 0:1865da4a634c | 29 | #include "canopen_api.h" |
| ptpaterson | 2:c724ff3a4e4d | 30 | #include "canopen_config.h" |
| ptpaterson | 1:666f30541db5 | 31 | |
| ptpaterson | 4:2034b04c86d2 | 32 | #include "CanOpenMessage.h" |
| ptpaterson | 4:2034b04c86d2 | 33 | |
| ptpaterson | 5:22a337cdc0e3 | 34 | #include "mbed.h" |
| ptpaterson | 5:22a337cdc0e3 | 35 | #include "CAN.h" /* use with CANNucleo library */ |
| ptpaterson | 5:22a337cdc0e3 | 36 | |
| ptpaterson | 5:22a337cdc0e3 | 37 | #include "stdio.h" |
| ptpaterson | 5:22a337cdc0e3 | 38 | |
| ptpaterson | 5:22a337cdc0e3 | 39 | |
| ptpaterson | 5:22a337cdc0e3 | 40 | void *pServiceObject = 0; |
| ptpaterson | 5:22a337cdc0e3 | 41 | |
| ptpaterson | 5:22a337cdc0e3 | 42 | /* Can declarations ---------------------------------------------------------*/ |
| ptpaterson | 5:22a337cdc0e3 | 43 | CAN * can; //(CANOPEN_PIN_RX, CANOPEN_PIN_TX); |
| ptpaterson | 5:22a337cdc0e3 | 44 | ServiceProviderRxInterruptCallback serviceRxCallback = 0; |
| ptpaterson | 5:22a337cdc0e3 | 45 | void CanReadInterruptCallback (void) { |
| ptpaterson | 5:22a337cdc0e3 | 46 | if (serviceRxCallback && pServiceObject) { |
| ptpaterson | 5:22a337cdc0e3 | 47 | serviceRxCallback(pServiceObject); |
| ptpaterson | 5:22a337cdc0e3 | 48 | } |
| ptpaterson | 5:22a337cdc0e3 | 49 | } |
| ptpaterson | 5:22a337cdc0e3 | 50 | |
| ptpaterson | 5:22a337cdc0e3 | 51 | /* Ticker declarations ---------------------------------------------------------*/ |
| ptpaterson | 5:22a337cdc0e3 | 52 | Ticker updateTicker; |
| ptpaterson | 5:22a337cdc0e3 | 53 | ServiceProviderTickCallback serviceTickCallback = 0; |
| ptpaterson | 5:22a337cdc0e3 | 54 | void UpdateTickerCallback(void) { |
| ptpaterson | 5:22a337cdc0e3 | 55 | if (serviceTickCallback && pServiceObject) { |
| ptpaterson | 5:22a337cdc0e3 | 56 | serviceTickCallback(pServiceObject); |
| ptpaterson | 5:22a337cdc0e3 | 57 | } |
| ptpaterson | 5:22a337cdc0e3 | 58 | } |
| ptpaterson | 5:22a337cdc0e3 | 59 | |
| ptpaterson | 5:22a337cdc0e3 | 60 | int CanOpenApiInit (void *object, ServiceProviderRxInterruptCallback rxCallback, ServiceProviderTickCallback tickCallback) |
| ptpaterson | 0:1865da4a634c | 61 | { |
| ptpaterson | 3:12b3c25bdeba | 62 | printf ("----------- CANOPEN API: API INIT\r\n"); |
| ptpaterson | 3:12b3c25bdeba | 63 | |
| ptpaterson | 5:22a337cdc0e3 | 64 | /* CAN instance to do all of the communication |
| ptpaterson | 5:22a337cdc0e3 | 65 | * |
| ptpaterson | 5:22a337cdc0e3 | 66 | * For some reason, I cannot use "static CAN can". It will compile, |
| ptpaterson | 5:22a337cdc0e3 | 67 | * but code get's stuck during initialization, and will not even enter |
| ptpaterson | 5:22a337cdc0e3 | 68 | * main(). Works great like this though! Only one ServiceProvider, though, |
| ptpaterson | 5:22a337cdc0e3 | 69 | * so mem leaks should not be an issue if we don't delete it??? |
| ptpaterson | 5:22a337cdc0e3 | 70 | */ |
| ptpaterson | 3:12b3c25bdeba | 71 | //static CAN can(CANOPEN_PIN_RX, CANOPEN_PIN_TX); |
| ptpaterson | 5:22a337cdc0e3 | 72 | //can = new CAN(CANOPEN_PIN_RX, CANOPEN_PIN_TX); |
| ptpaterson | 5:22a337cdc0e3 | 73 | can = new CAN(CANOPEN_PIN_RX, CANOPEN_PIN_TX); |
| ptpaterson | 5:22a337cdc0e3 | 74 | //can.reset(); |
| ptpaterson | 3:12b3c25bdeba | 75 | |
| ptpaterson | 5:22a337cdc0e3 | 76 | /* init the callback system ---------------------------------------------*/ |
| ptpaterson | 5:22a337cdc0e3 | 77 | pServiceObject = object; |
| ptpaterson | 5:22a337cdc0e3 | 78 | |
| ptpaterson | 5:22a337cdc0e3 | 79 | serviceRxCallback = rxCallback; |
| ptpaterson | 5:22a337cdc0e3 | 80 | serviceTickCallback = tickCallback; |
| ptpaterson | 5:22a337cdc0e3 | 81 | |
| ptpaterson | 5:22a337cdc0e3 | 82 | can->attach(CanReadInterruptCallback); |
| ptpaterson | 5:22a337cdc0e3 | 83 | updateTicker.attach(UpdateTickerCallback, .0005); |
| ptpaterson | 3:12b3c25bdeba | 84 | |
| ptpaterson | 0:1865da4a634c | 85 | return 1; |
| ptpaterson | 0:1865da4a634c | 86 | } |
| ptpaterson | 0:1865da4a634c | 87 | |
| ptpaterson | 5:22a337cdc0e3 | 88 | int CanOpenApiRead (CanOpenMessage *canOpenMsg) |
| ptpaterson | 0:1865da4a634c | 89 | { |
| ptpaterson | 2:c724ff3a4e4d | 90 | int result = 0; |
| ptpaterson | 2:c724ff3a4e4d | 91 | |
| ptpaterson | 5:22a337cdc0e3 | 92 | /* CAUTON ******************************** |
| ptpaterson | 5:22a337cdc0e3 | 93 | * Could be used in interrupt!!! |
| ptpaterson | 5:22a337cdc0e3 | 94 | * *************************************** |
| ptpaterson | 5:22a337cdc0e3 | 95 | */ |
| ptpaterson | 5:22a337cdc0e3 | 96 | //printf("canopen_api: CanOpenApiRead()\r\n"); |
| ptpaterson | 4:2034b04c86d2 | 97 | |
| ptpaterson | 5:22a337cdc0e3 | 98 | if (can) { |
| ptpaterson | 3:12b3c25bdeba | 99 | |
| ptpaterson | 3:12b3c25bdeba | 100 | CANMessage canMsg; |
| ptpaterson | 2:c724ff3a4e4d | 101 | |
| ptpaterson | 5:22a337cdc0e3 | 102 | result = can->read (canMsg); |
| ptpaterson | 3:12b3c25bdeba | 103 | if (result) { |
| ptpaterson | 3:12b3c25bdeba | 104 | canOpenMsg->id = canMsg.id; |
| ptpaterson | 3:12b3c25bdeba | 105 | canOpenMsg->dataCount = canMsg.len, |
| ptpaterson | 3:12b3c25bdeba | 106 | canOpenMsg->type = canMsg.type == CANData ? CANOPEN_TYPE_DATA : CANOPEN_TYPE_REMOTE; |
| ptpaterson | 3:12b3c25bdeba | 107 | canOpenMsg->format = canMsg.format == CANStandard ? CANOPEN_FORMAT_STANDARD : CANOPEN_FORMAT_EXTENDED; |
| ptpaterson | 3:12b3c25bdeba | 108 | |
| ptpaterson | 3:12b3c25bdeba | 109 | // NOTE: memcpy is freezing execution |
| ptpaterson | 3:12b3c25bdeba | 110 | //memcpy(canOpenMsg->data, canMsg.data, canMsg.len); |
| ptpaterson | 3:12b3c25bdeba | 111 | canOpenMsg->data[0] = canMsg.data[0]; |
| ptpaterson | 3:12b3c25bdeba | 112 | canOpenMsg->data[1] = canMsg.data[1]; |
| ptpaterson | 3:12b3c25bdeba | 113 | canOpenMsg->data[2] = canMsg.data[2]; |
| ptpaterson | 3:12b3c25bdeba | 114 | canOpenMsg->data[3] = canMsg.data[3]; |
| ptpaterson | 3:12b3c25bdeba | 115 | canOpenMsg->data[4] = canMsg.data[4]; |
| ptpaterson | 3:12b3c25bdeba | 116 | canOpenMsg->data[5] = canMsg.data[5]; |
| ptpaterson | 3:12b3c25bdeba | 117 | canOpenMsg->data[6] = canMsg.data[6]; |
| ptpaterson | 3:12b3c25bdeba | 118 | canOpenMsg->data[7] = canMsg.data[7]; |
| ptpaterson | 5:22a337cdc0e3 | 119 | |
| ptpaterson | 5:22a337cdc0e3 | 120 | // DEBUG |
| ptpaterson | 5:22a337cdc0e3 | 121 | //printf(" ID: %d\r\n", (int)canOpenMsg->id); |
| ptpaterson | 5:22a337cdc0e3 | 122 | //printf(" Count: %d\r\n", (int)canOpenMsg->dataCount); |
| ptpaterson | 5:22a337cdc0e3 | 123 | //printf(" Type: %d\r\n", (int)canOpenMsg->type); |
| ptpaterson | 5:22a337cdc0e3 | 124 | //printf(" Format: %d\r\n", (int)canOpenMsg->format); |
| ptpaterson | 5:22a337cdc0e3 | 125 | //printf(" Data[0]: %d\r\n", (int)canOpenMsg->data[0]); |
| ptpaterson | 3:12b3c25bdeba | 126 | } |
| ptpaterson | 3:12b3c25bdeba | 127 | |
| ptpaterson | 3:12b3c25bdeba | 128 | } |
| ptpaterson | 2:c724ff3a4e4d | 129 | return result; |
| ptpaterson | 2:c724ff3a4e4d | 130 | } |
| ptpaterson | 2:c724ff3a4e4d | 131 | |
| ptpaterson | 5:22a337cdc0e3 | 132 | int CanOpenApiWrite (CanOpenMessage *canOpenMsg) |
| ptpaterson | 2:c724ff3a4e4d | 133 | { |
| ptpaterson | 3:12b3c25bdeba | 134 | int result = 0; |
| ptpaterson | 3:12b3c25bdeba | 135 | |
| ptpaterson | 5:22a337cdc0e3 | 136 | CANMessage canMsg; |
| ptpaterson | 5:22a337cdc0e3 | 137 | canMsg.id = canOpenMsg->id; |
| ptpaterson | 5:22a337cdc0e3 | 138 | canMsg.len = canOpenMsg->dataCount, |
| ptpaterson | 5:22a337cdc0e3 | 139 | canMsg.type = canOpenMsg->type == CANOPEN_TYPE_DATA ? CANData : CANRemote; |
| ptpaterson | 5:22a337cdc0e3 | 140 | canMsg.format = canOpenMsg->format == CANOPEN_FORMAT_STANDARD ? CANStandard : CANExtended; |
| ptpaterson | 2:c724ff3a4e4d | 141 | |
| ptpaterson | 5:22a337cdc0e3 | 142 | // NOTE: memcpy is freezing execution |
| ptpaterson | 5:22a337cdc0e3 | 143 | //memcpy(canMsg.data, canOpenMsg->data, canOpenMsg->dataCount); |
| ptpaterson | 5:22a337cdc0e3 | 144 | canMsg.data[0] = canOpenMsg->data[0]; |
| ptpaterson | 5:22a337cdc0e3 | 145 | canMsg.data[1] = canOpenMsg->data[1]; |
| ptpaterson | 5:22a337cdc0e3 | 146 | canMsg.data[2] = canOpenMsg->data[2]; |
| ptpaterson | 5:22a337cdc0e3 | 147 | canMsg.data[3] = canOpenMsg->data[3]; |
| ptpaterson | 5:22a337cdc0e3 | 148 | canMsg.data[4] = canOpenMsg->data[4]; |
| ptpaterson | 5:22a337cdc0e3 | 149 | canMsg.data[5] = canOpenMsg->data[5]; |
| ptpaterson | 5:22a337cdc0e3 | 150 | canMsg.data[6] = canOpenMsg->data[6]; |
| ptpaterson | 5:22a337cdc0e3 | 151 | canMsg.data[7] = canOpenMsg->data[7]; |
| ptpaterson | 5:22a337cdc0e3 | 152 | |
| ptpaterson | 5:22a337cdc0e3 | 153 | result = can->write (canMsg); |
| ptpaterson | 5:22a337cdc0e3 | 154 | |
| ptpaterson | 3:12b3c25bdeba | 155 | |
| ptpaterson | 3:12b3c25bdeba | 156 | return result; |
| ptpaterson | 0:1865da4a634c | 157 | } |
| ptpaterson | 0:1865da4a634c | 158 | |
| ptpaterson | 5:22a337cdc0e3 | 159 | static int timeSyncOffset = 0; |
| ptpaterson | 5:22a337cdc0e3 | 160 | |
| ptpaterson | 5:22a337cdc0e3 | 161 | uint32_t CanOpenApiGetHardwareTime (void) |
| ptpaterson | 5:22a337cdc0e3 | 162 | { |
| ptpaterson | 5:22a337cdc0e3 | 163 | return HAL_GetTick(); |
| ptpaterson | 5:22a337cdc0e3 | 164 | } |
| ptpaterson | 5:22a337cdc0e3 | 165 | |
| ptpaterson | 0:1865da4a634c | 166 | |
| ptpaterson | 0:1865da4a634c | 167 | |
| ptpaterson | 0:1865da4a634c | 168 | |
| ptpaterson | 0:1865da4a634c | 169 | |
| ptpaterson | 0:1865da4a634c | 170 | |
| ptpaterson | 0:1865da4a634c | 171 | |
| ptpaterson | 0:1865da4a634c | 172 | |
| ptpaterson | 0:1865da4a634c | 173 | |
| ptpaterson | 0:1865da4a634c | 174 |
