Can_open_slavenode

Dependencies:   mbed

Committer:
sam_grove
Date:
Wed Sep 26 05:43:05 2012 +0000
Revision:
6:bc64031ac849
Parent:
0:6219434a0cb5
Change a typecast in can_mbed.cpp from unit8_t * to char * to fit the CANMessage constructor

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 0:6219434a0cb5 1 /*
sam_grove 0:6219434a0cb5 2 This file is part of CanFestival, a library implementing CanOpen Stack.
sam_grove 0:6219434a0cb5 3
sam_grove 0:6219434a0cb5 4 Copyright (C): Edouard TISSERANT and Francis DUPIN
sam_grove 0:6219434a0cb5 5
sam_grove 0:6219434a0cb5 6 See COPYING file for copyrights details.
sam_grove 0:6219434a0cb5 7
sam_grove 0:6219434a0cb5 8 This library is free software; you can redistribute it and/or
sam_grove 0:6219434a0cb5 9 modify it under the terms of the GNU Lesser General Public
sam_grove 0:6219434a0cb5 10 License as published by the Free Software Foundation; either
sam_grove 0:6219434a0cb5 11 version 2.1 of the License, or (at your option) any later version.
sam_grove 0:6219434a0cb5 12
sam_grove 0:6219434a0cb5 13 This library is distributed in the hope that it will be useful,
sam_grove 0:6219434a0cb5 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
sam_grove 0:6219434a0cb5 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
sam_grove 0:6219434a0cb5 16 Lesser General Public License for more details.
sam_grove 0:6219434a0cb5 17
sam_grove 0:6219434a0cb5 18 You should have received a copy of the GNU Lesser General Public
sam_grove 0:6219434a0cb5 19 License along with this library; if not, write to the Free Software
sam_grove 0:6219434a0cb5 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
sam_grove 0:6219434a0cb5 21 USA
sam_grove 0:6219434a0cb5 22 */
sam_grove 0:6219434a0cb5 23
sam_grove 0:6219434a0cb5 24
sam_grove 0:6219434a0cb5 25 /**
sam_grove 0:6219434a0cb5 26 ** @file dcf.c
sam_grove 0:6219434a0cb5 27 ** @author Edouard TISSERANT and Francis DUPIN
sam_grove 0:6219434a0cb5 28 ** @date Mon Jun 4 17:06:12 2007
sam_grove 0:6219434a0cb5 29 **
sam_grove 0:6219434a0cb5 30 ** @brief EXEMPLE OF SOMMARY
sam_grove 0:6219434a0cb5 31 **
sam_grove 0:6219434a0cb5 32 **
sam_grove 0:6219434a0cb5 33 */
sam_grove 0:6219434a0cb5 34
sam_grove 0:6219434a0cb5 35
sam_grove 0:6219434a0cb5 36 #include "data.h"
sam_grove 0:6219434a0cb5 37 #include "sysdep.h"
sam_grove 0:6219434a0cb5 38 //#include "sdo.h"
sam_grove 0:6219434a0cb5 39
sam_grove 0:6219434a0cb5 40 //extern UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index,
sam_grove 0:6219434a0cb5 41 // UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback, UNS8 endianize);
sam_grove 0:6219434a0cb5 42
sam_grove 0:6219434a0cb5 43
sam_grove 0:6219434a0cb5 44 static void send_consise_dcf_loop(CO_Data* d,UNS8 nodeId);
sam_grove 0:6219434a0cb5 45
sam_grove 0:6219434a0cb5 46 /* Seek to next NodeID's DCF */
sam_grove 0:6219434a0cb5 47 #define SEEK_NEXT_DCF() \
sam_grove 0:6219434a0cb5 48 nodeId=(nodeId+1) % d->dcf_odentry->bSubCount; \
sam_grove 0:6219434a0cb5 49 if(nodeId==0) nodeId=1; \
sam_grove 0:6219434a0cb5 50 d->dcf_cursor = NULL;
sam_grove 0:6219434a0cb5 51
sam_grove 0:6219434a0cb5 52 /**
sam_grove 0:6219434a0cb5 53 **
sam_grove 0:6219434a0cb5 54 **
sam_grove 0:6219434a0cb5 55 ** @param d
sam_grove 0:6219434a0cb5 56 ** @param nodeId
sam_grove 0:6219434a0cb5 57 */
sam_grove 0:6219434a0cb5 58 static void CheckSDOAndContinue(CO_Data* d, UNS8 nodeId)
sam_grove 0:6219434a0cb5 59 {
sam_grove 0:6219434a0cb5 60 UNS32 abortCode = 0;
sam_grove 0:6219434a0cb5 61
sam_grove 0:6219434a0cb5 62 if(getWriteResultNetworkDict (d, nodeId, &abortCode) != SDO_FINISHED)
sam_grove 0:6219434a0cb5 63 {
sam_grove 0:6219434a0cb5 64 MSG_ERR(0x1A01, "SDO error in consise DCF", abortCode);
sam_grove 0:6219434a0cb5 65 MSG_WAR(0x2A02, "server node : ", nodeId);
sam_grove 0:6219434a0cb5 66 }
sam_grove 0:6219434a0cb5 67
sam_grove 0:6219434a0cb5 68 closeSDOtransfer(d, nodeId, SDO_CLIENT);
sam_grove 0:6219434a0cb5 69 /* Timedout ? */
sam_grove 0:6219434a0cb5 70 if(abortCode == SDOABT_TIMED_OUT){
sam_grove 0:6219434a0cb5 71 /* Node may not be ready, try another one */
sam_grove 0:6219434a0cb5 72 /* Warning, this might leed to endless attempts */
sam_grove 0:6219434a0cb5 73 /* if node does never answer */
sam_grove 0:6219434a0cb5 74 SEEK_NEXT_DCF()
sam_grove 0:6219434a0cb5 75 }
sam_grove 0:6219434a0cb5 76 send_consise_dcf_loop(d,nodeId);
sam_grove 0:6219434a0cb5 77 }
sam_grove 0:6219434a0cb5 78
sam_grove 0:6219434a0cb5 79
sam_grove 0:6219434a0cb5 80 /**
sam_grove 0:6219434a0cb5 81 **
sam_grove 0:6219434a0cb5 82 **
sam_grove 0:6219434a0cb5 83 ** @param d
sam_grove 0:6219434a0cb5 84 ** @param nodeId
sam_grove 0:6219434a0cb5 85 **
sam_grove 0:6219434a0cb5 86 ** @return
sam_grove 0:6219434a0cb5 87 */
sam_grove 0:6219434a0cb5 88 UNS8 send_consise_dcf(CO_Data* d,UNS8 nodeId)
sam_grove 0:6219434a0cb5 89 {
sam_grove 0:6219434a0cb5 90 UNS32 szData;
sam_grove 0:6219434a0cb5 91 /* Fetch DCF OD entry, if not already done */
sam_grove 0:6219434a0cb5 92 if(!d->dcf_odentry)
sam_grove 0:6219434a0cb5 93 {
sam_grove 0:6219434a0cb5 94 UNS32 errorCode;
sam_grove 0:6219434a0cb5 95 ODCallback_t *Callback;
sam_grove 0:6219434a0cb5 96 d->dcf_odentry = (*d->scanIndexOD)(0x1F22, &errorCode, &Callback);
sam_grove 0:6219434a0cb5 97 /* If DCF entry do not exist... Nothing to do.*/
sam_grove 0:6219434a0cb5 98 if (errorCode != OD_SUCCESSFUL) goto DCF_finish;
sam_grove 0:6219434a0cb5 99 }
sam_grove 0:6219434a0cb5 100
sam_grove 0:6219434a0cb5 101 szData = d->dcf_odentry->pSubindex[nodeId].size;
sam_grove 0:6219434a0cb5 102
sam_grove 0:6219434a0cb5 103 /* if the entry for the nodeId is not empty. */
sam_grove 0:6219434a0cb5 104 if(szData!=0){
sam_grove 0:6219434a0cb5 105 /* if the entry for the nodeId is already been processing, quit.*/
sam_grove 0:6219434a0cb5 106 if(d->dcf_odentry->pSubindex[nodeId].bAccessType & DCF_TO_SEND) return 1;
sam_grove 0:6219434a0cb5 107
sam_grove 0:6219434a0cb5 108 d->dcf_odentry->pSubindex[nodeId].bAccessType|=DCF_TO_SEND;
sam_grove 0:6219434a0cb5 109 d->dcf_request++;
sam_grove 0:6219434a0cb5 110 if(d->dcf_request==1)
sam_grove 0:6219434a0cb5 111 send_consise_dcf_loop(d,nodeId);
sam_grove 0:6219434a0cb5 112 return 1;
sam_grove 0:6219434a0cb5 113 }
sam_grove 0:6219434a0cb5 114
sam_grove 0:6219434a0cb5 115 DCF_finish:
sam_grove 0:6219434a0cb5 116 return 0;
sam_grove 0:6219434a0cb5 117 }
sam_grove 0:6219434a0cb5 118
sam_grove 0:6219434a0cb5 119 static void send_consise_dcf_loop(CO_Data* d,UNS8 nodeId)
sam_grove 0:6219434a0cb5 120 {
sam_grove 0:6219434a0cb5 121 if(nodeId > d->dcf_odentry->bSubCount) return;
sam_grove 0:6219434a0cb5 122 /* Loop on all DCF subindexes, corresponding to node ID until there is no request*/
sam_grove 0:6219434a0cb5 123 //while (nodeId < d->dcf_odentry->bSubCount){
sam_grove 0:6219434a0cb5 124 while (d->dcf_request>0){
sam_grove 0:6219434a0cb5 125 if(d->dcf_odentry->pSubindex[nodeId].bAccessType & DCF_TO_SEND){
sam_grove 0:6219434a0cb5 126 UNS8* dcfend;
sam_grove 0:6219434a0cb5 127 UNS32 nb_entries;
sam_grove 0:6219434a0cb5 128 UNS32 szData = d->dcf_odentry->pSubindex[nodeId].size;
sam_grove 0:6219434a0cb5 129
sam_grove 0:6219434a0cb5 130 {
sam_grove 0:6219434a0cb5 131 UNS8* dcf = *((UNS8**)d->dcf_odentry->pSubindex[nodeId].pObject);
sam_grove 0:6219434a0cb5 132 dcfend = dcf + szData;
sam_grove 0:6219434a0cb5 133 if (!d->dcf_cursor){
sam_grove 0:6219434a0cb5 134 d->dcf_cursor = (UNS8*)dcf + 4;
sam_grove 0:6219434a0cb5 135 d->dcf_entries_count = 0;
sam_grove 0:6219434a0cb5 136 }
sam_grove 0:6219434a0cb5 137 nb_entries = UNS32_LE(*((UNS32*)dcf));
sam_grove 0:6219434a0cb5 138 }
sam_grove 0:6219434a0cb5 139
sam_grove 0:6219434a0cb5 140 /* condition on consise DCF string for NodeID, if big enough */
sam_grove 0:6219434a0cb5 141 if((UNS8*)d->dcf_cursor + 7 < (UNS8*)dcfend && d->dcf_entries_count < nb_entries){
sam_grove 0:6219434a0cb5 142
sam_grove 0:6219434a0cb5 143 UNS16 target_Index;
sam_grove 0:6219434a0cb5 144 UNS8 target_Subindex;
sam_grove 0:6219434a0cb5 145 UNS32 target_Size;
sam_grove 0:6219434a0cb5 146
sam_grove 0:6219434a0cb5 147 /* DCF data may not be 32/16b aligned,
sam_grove 0:6219434a0cb5 148 * we cannot directly dereference d->dcf_cursor
sam_grove 0:6219434a0cb5 149 * as UNS16 or UNS32
sam_grove 0:6219434a0cb5 150 * Do it byte per byte taking care on endianess*/
sam_grove 0:6219434a0cb5 151 #ifdef CANOPEN_BIG_ENDIAN
sam_grove 0:6219434a0cb5 152 target_Index = *(d->dcf_cursor++) << 8 |
sam_grove 0:6219434a0cb5 153 *(d->dcf_cursor++);
sam_grove 0:6219434a0cb5 154 #else
sam_grove 0:6219434a0cb5 155 memcpy(&target_Index, d->dcf_cursor,2);
sam_grove 0:6219434a0cb5 156 d->dcf_cursor+=2;
sam_grove 0:6219434a0cb5 157 #endif
sam_grove 0:6219434a0cb5 158
sam_grove 0:6219434a0cb5 159 target_Subindex = *(d->dcf_cursor++);
sam_grove 0:6219434a0cb5 160
sam_grove 0:6219434a0cb5 161 #ifdef CANOPEN_BIG_ENDIAN
sam_grove 0:6219434a0cb5 162 target_Size = *(d->dcf_cursor++) << 24 |
sam_grove 0:6219434a0cb5 163 *(d->dcf_cursor++) << 16 |
sam_grove 0:6219434a0cb5 164 *(d->dcf_cursor++) << 8 |
sam_grove 0:6219434a0cb5 165 *(d->dcf_cursor++);
sam_grove 0:6219434a0cb5 166 #else
sam_grove 0:6219434a0cb5 167 memcpy(&target_Size, d->dcf_cursor,4);
sam_grove 0:6219434a0cb5 168 d->dcf_cursor+=4;
sam_grove 0:6219434a0cb5 169 #endif
sam_grove 0:6219434a0cb5 170
sam_grove 0:6219434a0cb5 171 _writeNetworkDict(d, /* CO_Data* d*/
sam_grove 0:6219434a0cb5 172 nodeId, /* UNS8 nodeId*/
sam_grove 0:6219434a0cb5 173 target_Index, /* UNS16 index*/
sam_grove 0:6219434a0cb5 174 target_Subindex, /* UNS8 subindex*/
sam_grove 0:6219434a0cb5 175 (UNS8)target_Size, /* UNS8 count*/
sam_grove 0:6219434a0cb5 176 0, /* UNS8 dataType*/
sam_grove 0:6219434a0cb5 177 d->dcf_cursor,/* void *data*/
sam_grove 0:6219434a0cb5 178 CheckSDOAndContinue,/* SDOCallback_t
sam_grove 0:6219434a0cb5 179 Callback*/
sam_grove 0:6219434a0cb5 180 0); /* no endianize*/
sam_grove 0:6219434a0cb5 181 /* Push d->dcf_cursor to the end of data*/
sam_grove 0:6219434a0cb5 182
sam_grove 0:6219434a0cb5 183 d->dcf_cursor += target_Size;
sam_grove 0:6219434a0cb5 184 d->dcf_entries_count++;
sam_grove 0:6219434a0cb5 185
sam_grove 0:6219434a0cb5 186 /* send_consise_dcf_loop will be called by CheckSDOAndContinue for next DCF entry*/
sam_grove 0:6219434a0cb5 187 return;
sam_grove 0:6219434a0cb5 188 }
sam_grove 0:6219434a0cb5 189 else
sam_grove 0:6219434a0cb5 190 {
sam_grove 0:6219434a0cb5 191 /* We have finished with the dcf entry. Change the flag, decrement the request
sam_grove 0:6219434a0cb5 192 * and execute the bootup callback. */
sam_grove 0:6219434a0cb5 193 d->dcf_odentry->pSubindex[nodeId].bAccessType&=~DCF_TO_SEND;
sam_grove 0:6219434a0cb5 194 d->dcf_request--;
sam_grove 0:6219434a0cb5 195 (*d->post_SlaveBootup)(d, nodeId);
sam_grove 0:6219434a0cb5 196 }
sam_grove 0:6219434a0cb5 197 }
sam_grove 0:6219434a0cb5 198
sam_grove 0:6219434a0cb5 199 SEEK_NEXT_DCF()
sam_grove 0:6219434a0cb5 200 }
sam_grove 0:6219434a0cb5 201
sam_grove 0:6219434a0cb5 202 }