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.
Dependencies: CANnucleo mbed ppCANOpen
Node_pin0808.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file 00004 * @author Paul Paterson 00005 * @version 00006 * @date 2015-12-14 00007 * @brief CANOpen implementation library 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 "Node_pin0808.h" 00030 #include "ServiceProvider.h" 00031 00032 #include "stdio.h" 00033 #include "mbed.h" 00034 00035 PortIn mbedInputs(PortB, 0x00FF); 00036 PortOut mbedOutputs(PortB, 0xFF00); 00037 00038 namespace ppCANOpen 00039 { 00040 00041 /****************************************************************************** 00042 * Constructor/Destructor 00043 ****************************************************************************** 00044 */ 00045 00046 Node_pin0808::Node_pin0808 (int id, ServiceProvider * provider, int bLoop) 00047 : Node(id, provider, bLoop) 00048 { 00049 dictionary = new ObjectData[22]; 00050 00051 00052 /* Init values ***********************************************************/ 00053 memset(prevInputBuffers, 0, sizeof(prevInputBuffers)); 00054 memset(inputDebounce, 0, sizeof(inputDebounce)); 00055 00056 memset(prevOutputBuffers,0, sizeof(prevOutputBuffers)); 00057 00058 /* Init Object Dictionary ************************************************/ 00059 00060 /* Communication Objects ================================================*/ 00061 00062 /* SDO ------------------------------------------------------------------*/ 00063 /* index 0x1200 */ 00064 Obj1200_highestSubIndex = 2; 00065 Obj1200_ReceiveCobId = 0x600 + nodeId; 00066 Obj1200_TransmitCobId = 0x580 + nodeId; 00067 Obj1200_entries[0] = EntryData((void*)&Obj1200_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00068 Obj1200_entries[1] = EntryData((void*)&Obj1200_ReceiveCobId, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00069 Obj1200_entries[2] = EntryData((void*)&Obj1200_TransmitCobId, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00070 Obj1200 = ObjectData(Obj1200_entries, 0x1200, sizeof(Obj1200_entries) / sizeof(Obj1200_entries[0])); 00071 00072 /* RPDO -----------------------------------------------------------------*/ 00073 /* index 0x1400 */ 00074 Obj1400_highestSubIndex = 5; 00075 Obj1400_CobId = 0x200 + nodeId; 00076 Obj1400_TransmissionType = 1; 00077 Obj1400_InhibitTime = 0; 00078 Obj1400_CompatibilityEntry = 0; 00079 Obj1400_EventTimer = 0; 00080 Obj1400_entries[0] = EntryData((void*)&Obj1400_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00081 Obj1400_entries[1] = EntryData((void*)&Obj1400_CobId, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00082 Obj1400_entries[2] = EntryData((void*)&Obj1400_TransmissionType, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00083 Obj1400_entries[3] = EntryData((void*)&Obj1400_InhibitTime, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00084 Obj1400_entries[4] = EntryData((void*)&Obj1400_CompatibilityEntry, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00085 Obj1400_entries[5] = EntryData((void*)&Obj1400_EventTimer, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00086 Obj1400 = ObjectData(Obj1400_entries, 0x1400, sizeof(Obj1400_entries) / sizeof(Obj1400_entries[0])); 00087 00088 /* index 0x1401 */ 00089 Obj1401_highestSubIndex = 5; 00090 Obj1401_CobId = 0x300 + nodeId; 00091 Obj1401_TransmissionType = 1; 00092 Obj1401_InhibitTime = 0; 00093 Obj1401_CompatibilityEntry = 0; 00094 Obj1401_EventTimer = 0; 00095 Obj1401_entries[0] = EntryData((void*)&Obj1401_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00096 Obj1401_entries[1] = EntryData((void*)&Obj1401_CobId, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00097 Obj1401_entries[2] = EntryData((void*)&Obj1401_TransmissionType, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00098 Obj1401_entries[3] = EntryData((void*)&Obj1401_InhibitTime, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00099 Obj1401_entries[4] = EntryData((void*)&Obj1401_CompatibilityEntry, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00100 Obj1401_entries[5] = EntryData((void*)&Obj1401_EventTimer, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00101 Obj1401 = ObjectData(Obj1401_entries, 0x1401, sizeof(Obj1401_entries) / sizeof(Obj1401_entries[0])); 00102 00103 /* index 0x1402 */ 00104 Obj1402_highestSubIndex = 5; 00105 Obj1402_CobId = 0x400 + nodeId; 00106 Obj1402_TransmissionType = 1; 00107 Obj1402_InhibitTime = 0; 00108 Obj1402_CompatibilityEntry = 0; 00109 Obj1402_EventTimer = 0; 00110 Obj1402_entries[0] = EntryData((void*)&Obj1402_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00111 Obj1402_entries[1] = EntryData((void*)&Obj1402_CobId, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00112 Obj1402_entries[2] = EntryData((void*)&Obj1402_TransmissionType, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00113 Obj1402_entries[3] = EntryData((void*)&Obj1402_InhibitTime, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00114 Obj1402_entries[4] = EntryData((void*)&Obj1402_CompatibilityEntry, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00115 Obj1402_entries[5] = EntryData((void*)&Obj1402_EventTimer, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00116 Obj1402 = ObjectData(Obj1402_entries, 0x1402, sizeof(Obj1402_entries) / sizeof(Obj1402_entries[0])); 00117 00118 /* index 0x1403 */ 00119 Obj1403_highestSubIndex = 5; 00120 Obj1403_CobId = 0x181; 00121 Obj1403_TransmissionType = 1; 00122 Obj1403_InhibitTime = 0; 00123 Obj1403_CompatibilityEntry = 0; 00124 Obj1403_EventTimer = 0; 00125 Obj1403_entries[0] = EntryData((void*)&Obj1403_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00126 Obj1403_entries[1] = EntryData((void*)&Obj1403_CobId, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00127 Obj1403_entries[2] = EntryData((void*)&Obj1403_TransmissionType, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00128 Obj1403_entries[3] = EntryData((void*)&Obj1403_InhibitTime, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00129 Obj1403_entries[4] = EntryData((void*)&Obj1403_CompatibilityEntry, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00130 Obj1403_entries[5] = EntryData((void*)&Obj1403_EventTimer, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00131 Obj1403 = ObjectData(Obj1403_entries, 0x1403, sizeof(Obj1403_entries) / sizeof(Obj1403_entries[0])); 00132 00133 /* index 0x1600 */ 00134 Obj1600_highestSubIndex = 1; 00135 Obj1600_Map = 0x62000108; 00136 Obj1600_entries[0] = EntryData((void*)&Obj1600_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00137 Obj1600_entries[1] = EntryData((void*)&Obj1600_Map, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00138 Obj1600 = ObjectData(Obj1600_entries, 0x1600, sizeof(Obj1600_entries) / sizeof(Obj1600_entries[0])); 00139 00140 /* index 0x1601 */ 00141 Obj1601_highestSubIndex = 1; 00142 Obj1601_Map = 0x20010140; 00143 Obj1601_entries[0] = EntryData((void*)&Obj1601_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00144 Obj1601_entries[1] = EntryData((void*)&Obj1601_Map, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00145 Obj1601 = ObjectData(Obj1601_entries, 0x1601, sizeof(Obj1601_entries) / sizeof(Obj1601_entries[0])); 00146 00147 /* index 0x1602 */ 00148 Obj1602_highestSubIndex = 1; 00149 Obj1602_Map = 0x22000140; 00150 Obj1602_entries[0] = EntryData((void*)&Obj1602_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00151 Obj1602_entries[1] = EntryData((void*)&Obj1602_Map, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00152 Obj1602 = ObjectData(Obj1602_entries, 0x1602, sizeof(Obj1602_entries) / sizeof(Obj1602_entries[0])); 00153 00154 /* index 0x1603 */ 00155 Obj1603_highestSubIndex = 1; 00156 Obj1603_Map = 0x22000238; 00157 Obj1603_entries[0] = EntryData((void*)&Obj1603_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00158 Obj1603_entries[1] = EntryData((void*)&Obj1603_Map, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00159 Obj1603 = ObjectData(Obj1603_entries, 0x1603, sizeof(Obj1603_entries) / sizeof(Obj1603_entries[0])); 00160 00161 /* TPDO -----------------------------------------------------------------*/ 00162 /* index 0x1800 */ 00163 Obj1800_highestSubIndex = 5; 00164 Obj1800_CobId = 0x181; 00165 Obj1800_TransmissionType = 0xFE; /* event driven Manuf specific */ 00166 Obj1800_InhibitTime = 0; // TODO review if this is needed 00167 Obj1800_CompatibilityEntry = 0; 00168 Obj1800_EventTimer = 0; 00169 Obj1800_entries[0] = EntryData((void*)&Obj1800_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00170 Obj1800_entries[1] = EntryData((void*)&Obj1800_CobId, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00171 Obj1800_entries[2] = EntryData((void*)&Obj1800_TransmissionType, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00172 Obj1800_entries[3] = EntryData((void*)&Obj1800_InhibitTime, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00173 Obj1800_entries[4] = EntryData((void*)&Obj1800_CompatibilityEntry, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00174 Obj1800_entries[5] = EntryData((void*)&Obj1800_EventTimer, sizeof(uint16_t), EntryData::TYPE_UINT16, EntryData::PROPERTY_READABLE); 00175 Obj1800 = ObjectData(Obj1800_entries, 0x1800, sizeof(Obj1800_entries) / sizeof(Obj1800_entries[0])); 00176 00177 /* index 0x1A00 */ 00178 Obj1A00_highestSubIndex = 5; 00179 Obj1A00_MapInput = 0x60000108; 00180 Obj1A00_MapVoid16 = 0x00000010; 00181 Obj1A00_MapChange = 0x21000108; 00182 Obj1A00_MapSourceId = 0x21000208; 00183 Obj1A00_entries[0] = EntryData((void*)&Obj1A00_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00184 Obj1A00_entries[1] = EntryData((void*)&Obj1A00_MapInput, sizeof(uint8_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00185 Obj1A00_entries[2] = EntryData((void*)&Obj1A00_MapVoid16, sizeof(uint16_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00186 Obj1A00_entries[3] = EntryData((void*)&Obj1A00_MapChange, sizeof(uint8_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00187 Obj1A00_entries[4] = EntryData((void*)&Obj1A00_MapVoid16, sizeof(uint16_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00188 Obj1A00_entries[5] = EntryData((void*)&Obj1A00_MapSourceId, sizeof(uint8_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00189 Obj1A00 = ObjectData(Obj1A00_entries, 0x1A00, sizeof(Obj1A00_entries) / sizeof(Obj1A00_entries[0])); 00190 00191 00192 /* Manufacturer Specific Objects ========================================*/ 00193 00194 /* index 0x2001 : Pin Output Configurations */ 00195 Obj2001_highestSubIndex = 8; 00196 memset(&writeOutputConfig, 0, sizeof(writeOutputConfig)); 00197 memset(outputConfigs, 0, sizeof(outputConfigs)); 00198 outputConfigs[0].type = 0x08; 00199 memset(outputTimers, 0, sizeof(outputTimers)); 00200 Obj2001_entries[0] = EntryData((void*)&Obj2001_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00201 Obj2001_entries[1] = EntryData((void*)&writeOutputConfig, sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00202 Obj2001_entries[2] = EntryData((void*)&outputConfigs[0], sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00203 Obj2001_entries[3] = EntryData((void*)&outputConfigs[1], sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00204 Obj2001_entries[4] = EntryData((void*)&outputConfigs[2], sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00205 Obj2001_entries[5] = EntryData((void*)&outputConfigs[3], sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00206 Obj2001_entries[6] = EntryData((void*)&outputConfigs[4], sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00207 Obj2001_entries[7] = EntryData((void*)&outputConfigs[5], sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00208 Obj2001_entries[8] = EntryData((void*)&outputConfigs[6], sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00209 Obj2001_entries[9] = EntryData((void*)&outputConfigs[7], sizeof(OutputConfiguration), EntryData::TYPE_UINT64, EntryData::PROPERTY_READ_WRITEABLE); 00210 Obj2001 = ObjectData(Obj2001_entries, 0x2001, sizeof(Obj2001_entries) / sizeof(Obj2001_entries[0])); 00211 00212 /* index 0x2002 : Output Schedule Configuration */ 00213 Obj2002_highestSubIndex = 1; 00214 scheduleConfig = 0x01; 00215 schedules[0] = 0xFF00F0F0; 00216 Obj2002_entries[0] = EntryData((void*)&Obj2002_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00217 Obj2002_entries[1] = EntryData((void*)&scheduleConfig, sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00218 Obj2002_entries[2] = EntryData((void*)&schedules[0], sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00219 Obj2002_entries[3] = EntryData((void*)&schedules[1], sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00220 Obj2002_entries[4] = EntryData((void*)&schedules[2], sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00221 Obj2002_entries[5] = EntryData((void*)&schedules[3], sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00222 Obj2002_entries[6] = EntryData((void*)&schedules[4], sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00223 Obj2002_entries[7] = EntryData((void*)&schedules[5], sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00224 Obj2002_entries[8] = EntryData((void*)&schedules[6], sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00225 Obj2002_entries[9] = EntryData((void*)&schedules[7], sizeof(uint32_t), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00226 Obj2002 = ObjectData(Obj2002_entries, 0x2002, sizeof(Obj2002_entries) / sizeof(Obj2002_entries[0])); 00227 00228 /* Index 2100 */ 00229 Obj2100_highestSubIndex = 2; 00230 inputChangeMask[0] = 0; 00231 /* nodeId; */ 00232 Obj2100_entries[0] = EntryData((void*)&Obj2100_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00233 Obj2100_entries[1] = EntryData((void*)&inputChangeMask[0], sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00234 Obj2100_entries[2] = EntryData((void*)&nodeId, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00235 Obj2100 = ObjectData(Obj2100_entries, 0x2100, sizeof(Obj2100_entries) / sizeof(Obj2100_entries[0])); 00236 00237 /* Index 2200 */ 00238 Obj2200_highestSubIndex = 2; 00239 memset(&writeRule, 0, sizeof(AutotriggerRule)); 00240 memset(&autotriggerMessage, 0, sizeof(AutotriggerMessage)); 00241 memset(rules, 0, sizeof(rules)); 00242 Obj2200_entries[0] = EntryData((void*)&Obj2200_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00243 Obj2200_entries[1] = EntryData((void*)&writeRule, sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00244 Obj2200_entries[2] = EntryData((void*)&autotriggerMessage, sizeof(AutotriggerMessage), EntryData::TYPE_UINT32, EntryData::PROPERTY_READ_WRITEABLE); 00245 Obj2200_entries[3] = EntryData((void*)&rules[0], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00246 Obj2200_entries[4] = EntryData((void*)&rules[1], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00247 Obj2200_entries[5] = EntryData((void*)&rules[2], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00248 Obj2200_entries[6] = EntryData((void*)&rules[3], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00249 Obj2200_entries[7] = EntryData((void*)&rules[4], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00250 Obj2200_entries[8] = EntryData((void*)&rules[5], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00251 Obj2200_entries[9] = EntryData((void*)&rules[6], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00252 Obj2200_entries[10] = EntryData((void*)&rules[7], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00253 Obj2200_entries[11] = EntryData((void*)&rules[8], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00254 Obj2200_entries[12] = EntryData((void*)&rules[9], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00255 Obj2200_entries[13] = EntryData((void*)&rules[10], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00256 Obj2200_entries[14] = EntryData((void*)&rules[11], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00257 Obj2200_entries[15] = EntryData((void*)&rules[12], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00258 Obj2200_entries[16] = EntryData((void*)&rules[13], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00259 Obj2200_entries[17] = EntryData((void*)&rules[14], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00260 Obj2200_entries[18] = EntryData((void*)&rules[15], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00261 Obj2200_entries[19] = EntryData((void*)&rules[16], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00262 Obj2200_entries[20] = EntryData((void*)&rules[17], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00263 Obj2200_entries[21] = EntryData((void*)&rules[18], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00264 Obj2200_entries[22] = EntryData((void*)&rules[19], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00265 Obj2200_entries[23] = EntryData((void*)&rules[20], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00266 Obj2200_entries[24] = EntryData((void*)&rules[21], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00267 Obj2200_entries[25] = EntryData((void*)&rules[22], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00268 Obj2200_entries[26] = EntryData((void*)&rules[23], sizeof(AutotriggerRule), EntryData::TYPE_UINT32, EntryData::PROPERTY_READABLE); 00269 Obj2200 = ObjectData(Obj2200_entries, 0x2200, sizeof(Obj2200_entries) / sizeof(Obj2200_entries[0])); 00270 00271 /* Device Profile Specific Objects ======================================*/ 00272 00273 /* Index 6000 */ 00274 Obj6000_highestSubIndex = 1; 00275 readInputBuffers[0] = 0; 00276 Obj6000_entries[0] = EntryData((void*)&Obj6000_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00277 Obj6000_entries[1] = EntryData((void*)&readInputBuffers, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00278 Obj6000 = ObjectData(Obj6000_entries, 0x6000, sizeof(Obj6000_entries) / sizeof(Obj6000_entries[0])); 00279 00280 /* Index 6005 */ 00281 Obj6005_highestSubIndex = 1; 00282 bInputInterruptEnable = 0x01; 00283 Obj6005_entries[0] = EntryData((void*)&Obj6005_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00284 Obj6005_entries[1] = EntryData((void*)&bInputInterruptEnable, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READ_WRITEABLE); 00285 Obj6005 = ObjectData(Obj6005_entries, 0x6005, sizeof(Obj6005_entries) / sizeof(Obj6005_entries[0])); 00286 00287 /* Index 6006 */ 00288 Obj6006_highestSubIndex = 1; 00289 inputInterruptMask[0] = 0xFF; 00290 Obj6006_entries[0] = EntryData((void*)&Obj6006_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00291 Obj6006_entries[1] = EntryData((void*)&inputInterruptMask, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READ_WRITEABLE); 00292 Obj6006 = ObjectData(Obj6006_entries, 0x6006, sizeof(Obj6006_entries) / sizeof(Obj6006_entries[0])); 00293 00294 /* Index 6200 */ 00295 Obj6200_highestSubIndex = 1; 00296 writeOutputBuffers[0] = 0; 00297 Obj6200_entries[0] = EntryData((void*)&Obj6200_highestSubIndex, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READABLE); 00298 Obj6200_entries[1] = EntryData((void*)&writeOutputBuffers, sizeof(uint8_t), EntryData::TYPE_UINT8, EntryData::PROPERTY_READ_WRITEABLE); 00299 Obj6200 = ObjectData(Obj6200_entries, 0x6200, sizeof(Obj6200_entries) / sizeof(Obj6200_entries[0])); 00300 00301 /* Set up the whole dictionary */ 00302 dictionary[0] = Obj1200; 00303 dictionary[1] = Obj1400; 00304 dictionary[2] = Obj1401; 00305 dictionary[3] = Obj1402; 00306 dictionary[4] = Obj1403; 00307 dictionary[5] = Obj1600; 00308 dictionary[6] = Obj1601; 00309 dictionary[7] = Obj1602; 00310 dictionary[8] = Obj1603; 00311 dictionary[10] = Obj1800; 00312 dictionary[11] = Obj1A00; 00313 dictionary[12] = Obj2001; 00314 dictionary[13] = Obj2002; 00315 dictionary[14] = Obj2100; 00316 dictionary[15] = Obj2200; 00317 dictionary[16] = Obj6000; 00318 dictionary[17] = Obj6005; 00319 dictionary[18] = Obj6006; 00320 dictionary[19] = Obj6200; 00321 00322 } 00323 00324 Node_pin0808::~Node_pin0808(void) 00325 { 00326 delete dictionary; 00327 } 00328 00329 /****************************************************************************** 00330 * Application Run Implementation 00331 ****************************************************************************** 00332 */ 00333 00334 void Node_pin0808::OnFixedUpdate (void) 00335 { 00336 /************************************************************************** 00337 * INPUTS 00338 ************************************************************************** 00339 */ 00340 00341 uint8_t inputSample = ~(uint8_t)(mbedInputs.read()); 00342 00343 uint8_t inputChange = readInputBuffers[0] ^ inputSample; 00344 00345 /* Loop through all of the inputs */ 00346 for (int in = 0; in < 8; in++) { 00347 if (inputChange & (1 << in)) { 00348 00349 inputDebounce[in] += (uint8_t)(timeSinceLastTick); 00350 if (inputDebounce[in] > DEBOUNCE_TIME) { 00351 readInputBuffers[0] &= ~(1 << in); 00352 readInputBuffers[0] |= (inputSample & (1 << in)); 00353 00354 inputDebounce[in] = 0; 00355 } 00356 00357 } else { 00358 inputDebounce[in] = 0; 00359 } 00360 } 00361 00362 00363 /************************************************************************** 00364 * OUTPUTS 00365 ************************************************************************** 00366 */ 00367 00368 /* create a copy of the current outputs and edit as we go */ 00369 uint8_t newOutput = (uint8_t)(mbedOutputs >> 8); 00370 00371 /* big operation, so let's only do it once! */ 00372 int scheduleIndexer = 1 << ((timeCurrentTick * 100) / 3125) % 32; 00373 00374 /* Loop through all of the outputs */ 00375 for (int out = 0; out < 8; out++) { 00376 00377 if (scheduleConfig & (1 << out)) { 00378 00379 if (schedules[out] & scheduleIndexer) { 00380 writeOutputBuffers[0] |= (1 << out); 00381 } else { 00382 writeOutputBuffers[0] &= ~(1 << out); 00383 } 00384 } 00385 00386 /* update GPIO's immediately only if new signal was given */ 00387 int outputBufferChanges = writeOutputBuffers[0] ^ prevOutputBuffers[0]; 00388 00389 if (outputBufferChanges & (1 << out)) { 00390 if ((1 << out) & writeOutputBuffers[0]) { 00391 /* switched on */ 00392 newOutput |= (1 << out); 00393 00394 /* reset timers */ 00395 if (outputConfigs[out].type) { 00396 outputTimers[out] = OutputConfiguration(outputConfigs[out]); 00397 } 00398 } else { 00399 /* switched off */ 00400 newOutput &= ~(1 << out); 00401 memset(&outputTimers[out], 0, sizeof(outputTimers[out])); 00402 } 00403 } 00404 00405 /* if there is a pulse run down the timer */ 00406 if (outputTimers[out].type & 0x01) { 00407 00408 if (outputTimers[out].pulse_ms >= timeSinceLastTick) { 00409 outputTimers[out].pulse_ms -= timeSinceLastTick; 00410 } else { 00411 /* time past would put timer below 0 */ 00412 outputTimers[out].pulse_ms = 0; 00413 } 00414 00415 /* if time has run out */ 00416 if (0 == outputTimers[out].pulse_ms) { 00417 00418 /* just turn off pulse */ 00419 outputTimers[out].type &= 0xFE; 00420 newOutput &= ~(1 << out); 00421 00422 /* if there is a patter, then output buffer will stay on */ 00423 /* but if there is a pulsed-patter, then it should still turn off */ 00424 if (!(outputTimers[out].type & 0x02) || 00425 (outputTimers[out].type & (0x02 | 0x04))) { 00426 /* turn buffer off */ 00427 outputTimers[out].type = 0; 00428 writeOutputBuffers[0] &= ~(1 << out); 00429 } 00430 } 00431 } 00432 00433 /* two ways to patter: 00434 * wait until after pulse (pulse-then-patter), 00435 * or config so pulse happens at same time (pulsed-patter) 00436 */ 00437 if (((outputTimers[out].type & 0x02) && !(outputTimers[out].type & 0x01)) || 00438 ((outputTimers[out].type & (0x02 | 0x04)) && (outputTimers[out].type & 0x01))) { 00439 00440 /* if output is on, run down pwm_on, else tun down pwm_off */ 00441 uint8_t *pw_timer; 00442 if (newOutput & (1 << out)) { 00443 pw_timer = &outputTimers[out].pwm_on; 00444 } else { 00445 pw_timer = &outputTimers[out].pwm_off; 00446 } 00447 00448 if (*pw_timer >= timeSinceLastTick) { 00449 *pw_timer -= timeSinceLastTick; 00450 } else { 00451 *pw_timer = 0; 00452 } 00453 00454 if (*pw_timer == 0) { 00455 newOutput ^= (1 << out); 00456 00457 outputTimers[out].pwm_on = outputConfigs[out].pwm_on; 00458 outputTimers[out].pwm_off = outputConfigs[out].pwm_off; 00459 } 00460 } 00461 00462 00463 } 00464 00465 mbedOutputs = ((uint16_t)newOutput) << 8; 00466 00467 prevOutputBuffers[0] = writeOutputBuffers[0]; 00468 } 00469 00470 void Node_pin0808::OnUpdate (void) 00471 { 00472 /* Check for output configurations --------------------------------------*/ 00473 if (writeOutputConfig.writeData) { 00474 uint8_t out = (uint8_t)(writeOutputConfig.writeData); 00475 00476 writeOutputConfig.writeData = 0; 00477 outputConfigs[out] = writeOutputConfig; 00478 00479 memset(&writeOutputConfig, 0, sizeof(writeOutputConfig)); 00480 } 00481 00482 00483 /* Check for rule configurations ----------------------------------------*/ 00484 if (writeRule.sourceId) { 00485 printf(" Configuring Rules...\r\n"); 00486 if (writeRule.sourceId & 0x80) { 00487 /* write new rule*/ 00488 00489 /* scan through array of rules for available (8th bit cleared) */ 00490 int ruleNum = 0; 00491 while (ruleNum < 24) { 00492 if (!(rules[ruleNum].sourceId & 0x80)) { 00493 00494 rules[ruleNum] = writeRule; 00495 printf(" Rule added: #%d\r\n", ruleNum); 00496 ruleNum = 24; 00497 } else { 00498 ruleNum++; 00499 if (ruleNum == 24) { 00500 printf(" ERROR: Not enough rules available"); 00501 } 00502 } 00503 } 00504 00505 } else { 00506 /* clear rules */ 00507 00508 /* scan through array of rules matching input and disable */ 00509 for (int ruleNum = 0; ruleNum < 24; ruleNum++) { 00510 00511 /* check if rule enabled and input num matches */ 00512 if ((rules[ruleNum].sourceId & 0x80) && 00513 ((rules[ruleNum].sourceId & 0x7F) == writeRule.sourceId) && 00514 ((rules[ruleNum].input & 0x1F) == (writeRule.input & 0x1F))) 00515 { 00516 memset(&rules[ruleNum], 0, sizeof(AutotriggerRule)); 00517 printf(" Rule removed: #%d\r\n", ruleNum); 00518 } 00519 00520 } 00521 } 00522 00523 memset(&writeRule, 0, sizeof(AutotriggerRule)); 00524 } 00525 00526 /* check for input changes from other devices---------------------------*/ 00527 if (autotriggerMessage.sourceId) { 00528 00529 printf(" detected change from node: %#04x\r\n", (autotriggerMessage.sourceId & 0x7F)); 00530 /* scan through array of rules matching inputs and direction */ 00531 for (int ruleNum = 0; ruleNum < 24; ruleNum++) { 00532 00533 /* check if rule enabled and input num matches */ 00534 if ((rules[ruleNum].sourceId & 0x80) && /* rule is active AND */ 00535 (rules[ruleNum].sourceId == autotriggerMessage.sourceId) && /* rule source matches message source AND */ 00536 (autotriggerMessage.change[0] & (1 << (rules[ruleNum].input & 0x1F)))) /* change exists at input num */ 00537 { 00538 00539 int ruleActivity = rules[ruleNum].input >> 5; 00540 int inputActivity = (autotriggerMessage.input[0] >> (rules[ruleNum].input & 0x1F)) & 1; 00541 00542 printf(" id match: %#04x\r\n", ruleNum); 00543 printf(" ruleActivity: %#04x\r\n", ruleActivity); 00544 printf(" inputActivity: %#04x\r\n", inputActivity); 00545 00546 if ((2 == ruleActivity) || (inputActivity == ruleActivity)) { 00547 00548 printf(" activating Rule...\r\n"); 00549 printf(" setMask: %#10x\r\n", rules[ruleNum].setMask[0]); 00550 printf(" clearMask: %#10x\r\n", ~rules[ruleNum].clearMask[0]); 00551 00552 writeOutputBuffers[0] |= rules[ruleNum].setMask[0]; 00553 //writeOutputBuffers[1] |= rules[ruleNum].setMask[1]; 00554 //writeOutputBuffers[2] |= rules[ruleNum].setMask[2]; 00555 00556 writeOutputBuffers[0] &= ~rules[ruleNum].clearMask[0]; 00557 //writeOutputBuffers[1] &= ~rules[ruleNum].clearMask[1]; 00558 //writeOutputBuffers[2] &= ~rules[ruleNum].clearMask[2]; 00559 } 00560 } 00561 00562 } 00563 00564 memset(&autotriggerMessage, 0, sizeof(AutotriggerMessage)); 00565 } 00566 00567 /* check for input changes from this device -----------------------------*/ 00568 /* update Index 2101-01 */ 00569 inputChangeMask[0] = readInputBuffers[0] ^ prevInputBuffers[0]; 00570 00571 /* check for rules against this devices inputs */ 00572 if (inputChangeMask[0]) { 00573 /* scan through array of rules matching inputs and direction */ 00574 for (int ruleNum = 0; ruleNum < 24; ruleNum++) { 00575 00576 /* check if rule enabled and input num matches */ 00577 if ((rules[ruleNum].sourceId & 0x80) && /* rule is active AND */ 00578 ((rules[ruleNum].sourceId & 0x7F) == nodeId) && /* rule source is this nodeId AND */ 00579 (inputChangeMask[0] & (1 << (rules[ruleNum].input & 0x1F)))) /* change exists at input num */ 00580 { 00581 00582 int ruleActivity = rules[ruleNum].input >> 5; 00583 int inputActivity = (readInputBuffers[0] >> (rules[ruleNum].input & 0x1F)) & 1; 00584 00585 if ((2 == ruleActivity) || (inputActivity == ruleActivity)) { 00586 writeOutputBuffers[0] |= rules[ruleNum].setMask[0]; 00587 //writeOutputBuffers[1] |= rules[ruleNum].setMask[1]; 00588 //writeOutputBuffers[2] |= rules[ruleNum].setMask[2]; 00589 00590 writeOutputBuffers[0] &= ~rules[ruleNum].clearMask[0]; 00591 //writeOutputBuffers[1] &= ~rules[ruleNum].clearMask[1]; 00592 //writeOutputBuffers[2] &= ~rules[ruleNum].clearMask[2]; 00593 } 00594 } 00595 00596 } 00597 } 00598 00599 /* index 6005-01 configured to enable interrupt messages */ 00600 if (bInputInterruptEnable) { 00601 00602 /* if change is within index 6006-01, interrupt mask */ 00603 if (inputChangeMask[0] & inputInterruptMask[0]) { 00604 00605 /* send a message immediately */ 00606 PostTPDO(0x181); 00607 } 00608 00609 } 00610 00611 prevInputBuffers[0] = readInputBuffers[0]; 00612 } 00613 00614 /****************************************************************************** 00615 * SYNC Implementation 00616 ****************************************************************************** 00617 */ 00618 00619 void Node_pin0808::OnSync (uint8_t counter) 00620 { 00621 00622 } 00623 00624 /****************************************************************************** 00625 * NMT Control Implementation 00626 ****************************************************************************** 00627 */ 00628 00629 void Node_pin0808::OnInitialize (void) 00630 { 00631 printf(" Node_pin0808::INITIALIZE!\r\n"); 00632 00633 mbedOutputs = 0xFFFF; 00634 wait(1.0); 00635 mbedOutputs = 0; 00636 00637 prevOutputBuffers[0] = 0; 00638 writeOutputBuffers[0] = 0; 00639 00640 prevInputBuffers[0] = 0; 00641 readInputBuffers[0] = 0; 00642 } 00643 00644 void Node_pin0808::OnPreoperational (void) 00645 { 00646 printf(" Node_pin0808::PRE-OPERATIONAL!\r\n"); 00647 } 00648 00649 void Node_pin0808::OnOperational (void) 00650 { 00651 printf(" Node_pin0808::OPERATIONAL!\r\n"); 00652 00653 mbedOutputs = (writeOutputBuffers[0] << 16); 00654 } 00655 00656 void Node_pin0808::OnStopped (void) 00657 { 00658 printf(" Node_pin0808::STOPPED!\r\n"); 00659 00660 mbedOutputs = 0; 00661 } 00662 00663 /****************************************************************************** 00664 * Object Dictionary Handling 00665 ****************************************************************************** 00666 */ 00667 00668 ObjectData * Node_pin0808::ScanIndex(IndexSize index) 00669 { 00670 ObjectData * result = 0; 00671 00672 switch(index) { 00673 case 0x1200: result = &dictionary[0]; break; 00674 case 0x1400: result = &dictionary[1]; break; 00675 case 0x1401: result = &dictionary[2]; break; 00676 case 0x1402: result = &dictionary[3]; break; 00677 case 0x1403: result = &dictionary[4]; break; 00678 case 0x1600: result = &dictionary[5]; break; 00679 case 0x1601: result = &dictionary[6]; break; 00680 case 0x1602: result = &dictionary[7]; break; 00681 case 0x1603: result = &dictionary[8]; break; 00682 case 0x1800: result = &dictionary[10]; break; 00683 case 0x1A00: result = &dictionary[11]; break; 00684 case 0x2001: result = &dictionary[12]; break; 00685 case 0x2002: result = &dictionary[13]; break; 00686 case 0x2100: result = &dictionary[14]; break; 00687 case 0x2200: result = &dictionary[15]; break; 00688 case 0x6000: result = &dictionary[16]; break; 00689 case 0x6005: result = &dictionary[17]; break; 00690 case 0x6006: result = &dictionary[18]; break; 00691 case 0x6200: result = &dictionary[19]; break; 00692 default: 00693 // TODO add error handling 00694 break; 00695 } 00696 00697 return result; 00698 } 00699 00700 } /* namespace ppCANOpen */
Generated on Thu Jul 14 2022 21:26:01 by 1.7.2